rgl/0000755000176200001440000000000014146502162011037 5ustar liggesusersrgl/NAMESPACE0000644000176200001440000001514414146177624012276 0ustar liggesusersexport(.check3d, abclines3d, addNormals, addToSubscene3d, arc3d, arrow3d, as.mesh3d, as.rglscene, as.tmesh3d, as.triangles3d, asRow, ageSetter, asEuclidean, asEuclidean2, asHomogeneous, asHomogeneous2, aspect3d, axes3d, axis3d, box3d, bbox3d, bg3d, bgplot3d, Buffer, checkDeldir, clear3d, clearSubsceneList, clipplanes3d, clipplaneSlider, clipMesh3d, clipObj3d, close3d, compare_proxy.mesh3d, contourLines3d, cube3d, cuboctahedron3d, cur3d, currentSubscene3d, cylinder3d, decorate3d, deform.mesh3d, delFromSubscene3d, divide.mesh3d, dodecahedron3d, dot3d, drape3d, ellipse3d, expect_known_scene, extrude3d, facing3d, figWidth, figHeight, filledContour3d, gc3d, getBoundary3d, getr3dDefaults, getWidgetId, GramSchmidt, grid3d, highlevel, hook_rgl, hook_webgl, icosahedron3d, identify3d, identityMatrix, ids3d, in_pkgdown_example, layout3d, legend3d, light3d, lines3d, lowlevel, makeDependency, material3d, matrixSetter, mergeVertices, mesh3d, mfrow3d, movie3d, mtext3d, newSubscene3d, next3d, normalize.mesh3d, observer3d, octahedron3d, oh3d, open3d, par3d, par3dinterp, par3dinterpControl, par3dinterpSetter, particles3d, pch3d, persp3d, planes3d, play3d, plot3d, plotmath3d, points3d, polygon3d, pop3d, projectDown, propertySetter, propertySlider, qmesh3d, quads3d, readOBJ, readSTL, rgl.abclines, rgl.bbox, rgl.bg, rgl.bringtotop, rgl.clear, rgl.getAxisCallback, rgl.getMouseCallbacks, rgl.getWheelCallback, rgl.close, rgl.cur, rgl.ids, rgl.init, rgl.light, rgl.lines, rgl.linestrips, rgl.clipplanes, rgl.material, rgl.open, rgl.pixels, rgl.planes, rgl.points, rgl.pop, rgl.postscript, rgl.primitive, rgl.projection, rgl.quads, rgl.quit, rgl.Sweave, rgl.Sweave.off, rgl.select, rgl.select3d, rgl.set, rgl.snapshot, rgl.spheres, rgl.sprites, rgl.surface, rgl.texts, rgl.triangles, rgl.user2window, rgl.attrib, rgl.attrib.count, rgl.attrib.info, rgl.dev.list, rgl.useNULL, rgl.viewpoint, rgl.window2user, rglExtrafonts, rglFonts, rglId, rglMouse, rglShared, rglToLattice, rglToBase, r3dDefaults, rotate3d, rotationMatrix, scale3d, scaleMatrix, scene3d, segments3d, select3d, selectionFunction3d, selectpoints3d, rgl.setAxisCallback, rgl.setMouseCallbacks, rgl.setWheelCallback, set3d, setAxisCallbacks, setGraphicsDelay, setupKnitr, setUserCallbacks, setUserShaders, shade3d, shadow3d, shapelist3d, shinyGetPar3d, shinySetPar3d, shinyResetBrush, show2d, snapshot3d, spheres3d, spin3d, sprites3d, subdivision3d, subsceneInfo, subsceneList, subsetSetter, subsetSlider, Sweave.snapshot, surface3d, tagged3d, terrain3d, tetrahedron3d, text3d, texts3d, thigmophobe3d, title3d, tkpar3dsave, tkspinControl, tkspin3d, toggleButton, toggleWidget, triangulate, tmesh3d, transform3d, translate3d, translationMatrix, triangles3d, turn3d, useSubscene3d, vertexSetter, view3d, wire3d, writeASY, writeOBJ, writePLY, writeSTL, writeWebGL) S3method(dot3d, shapelist3d) S3method(wire3d, shapelist3d) S3method(shade3d, shapelist3d) S3method(translate3d, shapelist3d) S3method(rotate3d, shapelist3d) S3method(scale3d, shapelist3d) S3method(addNormals, shapelist3d) S3method(dot3d, mesh3d) S3method(translate3d, mesh3d) S3method(rotate3d, mesh3d) S3method(scale3d, mesh3d) S3method(merge, mesh3d) S3method(wire3d, mesh3d) S3method(shade3d, mesh3d) S3method(subdivision3d, mesh3d) S3method(addNormals, mesh3d) S3method(plot3d, mesh3d) S3method(all.equal, mesh3d) S3method(all.equal, rglscene) S3method(as.mesh3d, deldir) S3method(as.mesh3d, tri) S3method(as.mesh3d, triSht) S3method(as.mesh3d, ashape3d) S3method(as.mesh3d, rglId) S3method(as.mesh3d, rglobject) S3method(as.mesh3d, default) S3method(as.tmesh3d, mesh3d) S3method(as.tmesh3d, default) S3method(as.triangles3d, mesh3d) S3method(as.triangles3d, rglId) S3method(translate3d, default) S3method(rotate3d, default) S3method(scale3d, default) S3method(ellipse3d, default) S3method(ellipse3d, lm) S3method(ellipse3d, glm) S3method(ellipse3d, nls) S3method(plot3d, default) S3method(persp3d, default) S3method(persp3d, "function") S3method(persp3d, deldir) S3method(persp3d, tri) S3method(persp3d, triSht) S3method(persp3d, ashape3d) S3method(persp3d, formula) S3method(plot3d, rglscene) S3method(plot3d, rglobject) S3method(plot3d, rglbboxdeco) S3method(plot3d, rglbackground) S3method(plot3d, rglsubscene) S3method(plot3d, rglWebGL) S3method(plot3d, "function") S3method(plot3d, deldir) S3method(plot3d, tri) S3method(plot3d, triSht) S3method(plot3d, ashape3d) S3method(plot3d, formula) S3method(plot3d, lm) S3method(print, rglscene) S3method(print, rglobject) S3method(print, rglsubscene) S3method(print, indexedSetter) S3method(print, rglId) S3method(print, rglOpen3d) S3method(print, mesh3d) S3method(print, shapelist3d) S3method(print, rglMouseSelection) S3method(knit_print, rglId) S3method(knit_print, rglOpen3d) S3method(summary, rglscene) S3method(summary, rglsubscene) S3method(drape3d, default) S3method(drape3d, mesh3d) S3method(contourLines3d, rglId) S3method(contourLines3d, mesh3d) S3method(filledContour3d, rglId) S3method(filledContour3d, mesh3d) S3method(sew, rglRecordedplot) S3method(is_low_change, rglRecordedplot) if(.Platform$OS.type == "windows") { importFrom(utils, getWindowsHandle) } importFrom(graphics, legend, par, plot, plot.new, polygon, strwidth, strheight) importFrom(grDevices, col2rgb, colorRamp, dev.cur, dev.new, dev.off, png, postscript, rgb, xy.coords, xyz.coords) importFrom(stats, approxfun, get_all_vars, model.frame, qchisq, qf, splinefun, terms, var) importFrom(utils, capture.output, count.fields, file_test, flush.console, packageVersion, read.table, head, tail) importFrom(R6, R6Class) # These were in rglwidget export(rglwidget, renderRglwidget, rglwidgetOutput, playwidget, renderPlaywidget, playwidgetOutput, subsetControl, propertyControl, clipplaneControl, ageControl, vertexControl, elementId2Prefix, registerSceneChange, sceneChange, "%>%") importFrom(htmlwidgets, createWidget, prependContent, saveWidget, shinyRenderWidget, shinyWidgetOutput, sizingPolicy) importFrom(htmltools, css, HTML, htmlDependency, img, includeScript, tags, tagAppendAttributes, tagHasAttribute, tagList, browsable, resolveDependencies) importFrom(jsonlite, toJSON, base64_dec) importFrom(knitr, asis_output, fig_path, hook_plot_custom, image_uri, include_graphics, is_low_change, knit_hooks, knit_meta_add, knit_print, opts_current, opts_hooks, opts_knit, pandoc_to, sew) importFrom(magrittr, "%>%") importFrom(stats, coef, predict, residuals) rgl/demo/0000755000176200001440000000000014137472630011771 5ustar liggesusersrgl/demo/lollipop3d.R0000644000176200001440000001115714100762640014173 0ustar liggesusers cone3d <- function(base,tip,rad,n=30,...) { degvec <- seq(0,2*pi,length=n) ax <- tip-base ## what do if ax[1]==0? if (ax[1]!=0) { p1 <- c(-ax[2]/ax[1],1,0) p1 <- p1/sqrt(sum(p1^2)) if (p1[1]!=0) { p2 <- c(-p1[2]/p1[1],1,0) p2[3] <- -sum(p2*ax) p2 <- p2/sqrt(sum(p2^2)) } else { p2 <- c(0,0,1) } } else if (ax[2]!=0) { p1 <- c(0,-ax[3]/ax[2],1) p1 <- p1/sqrt(sum(p1^2)) if (p1[1]!=0) { p2 <- c(0,-p1[3]/p1[2],1) p2[3] <- -sum(p2*ax) p2 <- p2/sqrt(sum(p2^2)) } else { p2 <- c(1,0,0) } } else { p1 <- c(0,1,0); p2 <- c(1,0,0) } ecoord2 <- function(theta) { base+rad*(cos(theta)*p1+sin(theta)*p2) } for (i in seq_len(n-1)) { li <- ecoord2(degvec[i]) lj <- ecoord2(degvec[i+1]) triangles3d(c(li[1],lj[1],tip[1]),c(li[2],lj[2],tip[2]),c(li[3],lj[3],tip[3]),...) } } lollipop3d <- function(data.x,data.y,data.z,surf.fun,surf.n=50, xlim=range(data.x), ylim=range(data.y), zlim=range(data.z), asp=c(y=1,z=1), xlab=deparse(substitute(x)), ylab=deparse(substitute(y)), zlab=deparse(substitute(z)), alpha.surf=0.4, col.surf=fg,col.stem=c(fg,fg), col.pt="gray",type.surf="line",ptsize, lwd.stem=2,lit=TRUE,bg="white",fg="black", col.axes=fg,col.axlabs=fg, axis.arrow=TRUE,axis.labels=TRUE, box.col=bg, axes=c("lines","box")) { axes <- match.arg(axes) col.stem <- rep(col.stem,length=2) x.ticks <- pretty(xlim) x.ticks <- x.ticks[x.ticks>=min(xlim) & x.ticks<=max(xlim)] x.ticklabs <- if (axis.labels) as.character(x.ticks) else NULL y.ticks <- pretty(ylim) y.ticks <- y.ticks[y.ticks>=min(ylim) & y.ticks<=max(ylim)] y.ticklabs <- if (axis.labels) as.character(y.ticks) else NULL z.ticks <- pretty(zlim) z.ticks <- z.ticks[z.ticks>=min(zlim) & z.ticks<=max(zlim)] z.ticklabs <- if (axis.labels) as.character(z.ticks) else NULL if (!missing(surf.fun)) { surf.x <- seq(xlim[1],xlim[2],length=surf.n) surf.y <- seq(ylim[1],ylim[2],length=surf.n) surf.z <- outer(surf.x,surf.y,surf.fun) ## requires surf.fun be vectorized z.interc <- surf.fun(data.x,data.y) zdiff <- diff(range(c(surf.z,data.z))) } else { z.interc <- rep(min(data.z),length(data.x)) zdiff <- diff(range(data.z)) } xdiff <- diff(xlim) ydiff <- diff(ylim) y.adj <- if (asp[1]<=0) 1 else asp[1]*xdiff/ydiff data.y <- y.adj*data.y y.ticks <- y.adj*y.ticks ylim <- ylim*y.adj ydiff <- diff(ylim) z.adj <- if (asp[2]<=0) 1 else asp[2]*xdiff/zdiff data.z <- z.adj*data.z if (!missing(surf.fun)) { surf.y <- y.adj*surf.y surf.z <- z.adj*surf.z } z.interc <- z.adj*z.interc z.ticks <- z.adj*z.ticks zlim <- z.adj*zlim open3d() clear3d("all") light3d() bg3d(color=c(bg,fg)) if (!missing(surf.fun)) surface3d(surf.x,surf.y,surf.z,alpha=alpha.surf, front=type.surf,back=type.surf, col=col.surf,lit=lit) if (missing(ptsize)) ptsize <- 0.02*xdiff ## draw points spheres3d(data.x,data.y,data.z,r=ptsize,lit=lit,color=col.pt) ## draw lollipops apply(cbind(data.x,data.y,data.z,z.interc),1, function(X) { lines3d(x=rep(X[1],2), y=rep(X[2],2), z=c(X[3],X[4]), col=ifelse(X[3]>X[4],col.stem[1], col.stem[2]),lwd=lwd.stem) }) if (axes=="box") { bbox3d(xat=x.ticks,xlab=x.ticklabs, yat=y.ticks,ylab=y.ticklabs, zat=z.ticks,zlab=z.ticklabs,lit=lit) } else if (axes=="lines") { ## set up axis lines axis3d(edge="x",at=x.ticks,labels=x.ticklabs, col=col.axes,arrow=axis.arrow) axis3d(edge="y",at=y.ticks,labels=y.ticklabs, col=col.axes,arrow=axis.arrow) axis3d(edge="z",at=z.ticks,labels=z.ticklabs, col=col.axes,arrow=axis.arrow) box3d(col=col.axes) } decorate3d(xlab=xlab, ylab=ylab, zlab=zlab, box=FALSE, axes=FALSE, col=col.axlabs) } x <- 1:5 y <- x*10 z <- (x+y)/20 open3d() spheres3d(x,y,z) axes3d() set.seed(1001) x <- runif(30) y <- runif(30,max=2) dfun <- function(x,y) 2*x+3*y+2*x*y+3*y^2 z <- dfun(x,y)+rnorm(30,sd=0.5) ## lollipops only lollipop3d(x,y,z) ## lollipops plus theoretical surface lollipop3d(x,y,z,dfun,col.pt="red",col.stem=c("red","blue")) ## lollipops plus regression fit linmodel <- lm(z~x+y) dfun <- function(x,y) predict(linmodel,newdata=data.frame(x=x,y=y)) lollipop3d(x,y,z,dfun,col.pt="red",col.stem=c("red","blue")) #### rgl/demo/shinyMouse.R0000644000176200001440000000656714137472630014275 0ustar liggesusers# Use the mouse to select points # Original version written by Yohann Demont if (!require("shiny")) stop("This demo requires shiny.") if (!requireNamespace("crosstalk")) stop("This demo requires crosstalk.") library(rgl) ui <- fluidPage( sidebarLayout( mainPanel(tabsetPanel(id = "navbar", selected = "3D", tabPanel(title = "2D", plotOutput("plot_2D", brush = brushOpts(id = "plot_2D_brush", resetOnNew = TRUE, direction = "xy")), verbatimTextOutput("brush_info_2D")), tabPanel(title = "3D", uiOutput("plot_3D_mousemode"), rglwidgetOutput("plot_3D"), verbatimTextOutput("brush_info_3D"), verbatimTextOutput("selected")) )), sidebarPanel(selectInput("plot_x", label = "x feature", choices = colnames(iris)[-5], selected = colnames(iris)[1]), selectInput("plot_y", label = "y feature", choices = colnames(iris)[-5], selected = colnames(iris)[2]), selectInput("plot_z", label = "z feature", choices = colnames(iris)[-5], selected = colnames(iris)[3]), actionButton(inputId = "reset_brush", label = "reset brush")) )) server <- function(input, output, session) { # 2D output$plot_2D <- renderPlot({ plot(x = iris[, input$plot_x], y = iris[, input$plot_y], col = as.integer(iris[, "Species"])) }) output$brush_info_2D <- renderPrint(str(input$plot_2D_brush)) # 3D sharedData <- NULL output$brush_info_3D <- renderPrint(print(input$rgl_3D_brush, verbose = TRUE)) # How to use selectionFunction3d ? output$selected <- renderPrint({ if(length(input$rgl_3D_brush) == 0 || input$rgl_3D_brush$state == "inactive") return(NULL) cat("Selections from crosstalk:\n") # Need as.logical because selection() might return NULL print(which(as.logical(sharedData$selection()))) cat("Selections using function:\n") f <- selectionFunction3d(input$rgl_3D_brush) which(f(iris[, c(input$plot_x, input$plot_y, input$plot_z)])) }) output$plot_3D_mousemode <- renderUI({ rglMouse( default = "trackball", stayActive = FALSE, choices = c("trackball", "selecting"), sceneId = "plot_3D") }) open3d(useNULL = TRUE) output$plot_3D <- renderRglwidget({ clear3d() dat <- iris[, c(input$plot_x, input$plot_y, input$plot_z, "Species")] dat$id <-as.character(seq_len(nrow(iris))) plot3d(x = dat[, 1:3], type = "s", size = 1, col = as.integer(iris[, "Species"]), aspect = TRUE) sharedData <<- rglShared(id = text3d(dat[, 1:3], text = dat[, "id"], adj = -0.5), group = "SharedData_plot_3D_ids", deselectedFade = 0, selectedIgnoreNone = FALSE) shinyResetBrush(session, "rgl_3D_brush") rglwidget(shared = sharedData, shinyBrush = "rgl_3D_brush") }) observeEvent(input$reset_brush, { session$resetBrush("plot_2D_brush") shinyResetBrush(session, "rgl_3D_brush") }) } shinyApp(ui, server) rgl/demo/mouseCallbacks.R0000644000176200001440000002134614100762640015043 0ustar liggesusersxprod <- function(a, b) c(a[2]*b[3] - a[3]*b[2], a[3]*b[1] - a[1]*b[3], a[1]*b[2] - a[2]*b[1]) vlen <- function(a) sqrt(sum(a^2)) angle <- function(a,b) { dot <- sum(a*b) acos(dot/vlen(a)/vlen(b)) } clamp <- function(x, min, max) pmin(pmax(x, min), max) mouseNone <- function(button = 1, dev = cur3d() ) { cur <- cur3d() for (i in dev) { set3d(i, TRUE) rgl.setMouseCallbacks(button, begin = NULL, update = NULL, end = NULL, dev = dev) } set3d(cur) } mouseTrackball <- function(button = 1, dev = cur3d() ) { width <- height <- rotBase <- NULL userMatrix <- list() cur <- cur3d() screenToVector <- function(x, y) { radius <- max(width, height)/2 centre <- c(width, height)/2 pt <- (c(x, y) - centre)/radius len <- vlen(pt) if (len > 1.e-6) pt <- pt/len maxlen <- sqrt(2) angle <- (maxlen - len)/maxlen*pi/2 z <- sin(angle) len <- sqrt(1 - z^2) pt <- pt * len return(c(pt, z)) } trackballBegin <- function(x, y) { vp <- par3d("viewport") width <<- vp[3] height <<- vp[4] cur <<- cur3d() for (i in dev) { if (inherits(try(set3d(i, TRUE)), "try-error")) dev <<- dev[dev != i] else userMatrix[[i]] <<- par3d("userMatrix") } set3d(cur, TRUE) rotBase <<- screenToVector(x, height - y) } trackballUpdate <- function(x,y) { rotCurrent <- screenToVector(x, height - y) angle <- angle(rotBase, rotCurrent) axis <- xprod(rotBase, rotCurrent) mouseMatrix <- rotationMatrix(angle, axis[1], axis[2], axis[3]) for (i in dev) { if (inherits(try(set3d(i, TRUE)), "try-error")) dev <<- dev[dev != i] else par3d(userMatrix = mouseMatrix %*% userMatrix[[i]]) } set3d(cur, TRUE) } for (i in dev) { set3d(i, TRUE) rgl.setMouseCallbacks(button, begin = trackballBegin, update = trackballUpdate, end = NULL, dev = dev) } set3d(cur, TRUE) } mouseXAxis<- function(button = 1, dev = cur3d() , left=TRUE) { mouseOneAxis(button, dev, axis=c(1,0,0), left=left) } mouseYAxis<- function(button = 1, dev = cur3d(), left = TRUE ) { mouseOneAxis(button, dev, axis=c(0,1,0), left=left) } mouseZAxis<- function(button = 1, dev = cur3d(), left=TRUE) { mouseOneAxis(button, dev, axis=c(0,0,1), left=left) } mouseOneAxis <- function(button = 1, dev = cur3d(), axis = c(1,0,0), left = TRUE ) { width <- height <- rotBase <- NULL userMatrix <- list() cur <- cur3d() screenToVector <- function(x, y) { radius <- max(width, height)/2 centre <- c(width, height)/2 pt <- (c(x, y) - centre)/radius len <- vlen(pt) if (len > 1.e-6) pt <- pt/len maxlen <- sqrt(2) angle <- (maxlen - len)/maxlen*pi/2 z <- sin(angle) len <- sqrt(1 - z^2) pt <- pt * len return(c(pt, z)) } oneAxisBegin <- function(x, y) { vp <- par3d("viewport") width <<- vp[3] height <<- vp[4] cur <<- cur3d() for (i in dev) { if (inherits(try(set3d(i, TRUE)), "try-error")) dev <<- dev[dev != i] else userMatrix[[i]] <<- par3d("userMatrix") } set3d(cur, TRUE) rotBase <<- screenToVector(x, height/2) } oneAxisUpdate <- function(x,y) { rotCurrent <- screenToVector(x, height/2) angle <- rotCurrent[1] - rotBase[1] mouseMatrix <- rotationMatrix(angle, axis[1], axis[2], axis[3]) for (i in dev) { if (inherits(try(set3d(i, TRUE)), "try-error")) dev <<- dev[dev != i] else { if (left) par3d(userMatrix = mouseMatrix %*% userMatrix[[i]]) else par3d(userMatrix = userMatrix[[i]] %*% mouseMatrix) } } set3d(cur, TRUE) } for (i in dev) { set3d(i, TRUE) rgl.setMouseCallbacks(button, begin = oneAxisBegin, update = oneAxisUpdate, end = NULL, dev = dev) } set3d(cur, TRUE) } mousePolar <- function(button = 1, dev = cur3d()) { screenToPolar <- function(x,y) { r <- min(width, height)/2 dx <- clamp(x - width/2, -r, r) dy <- clamp(y - height/2, -r, r) return( asin( c(dx, -dy)/r ) ) } cur <- cur3d() width <- height <- dragBase <- dragCurrent <- NULL camBase <- list() polarBegin <- function(x, y) { vp <- par3d("viewport") width <<- vp[3] height <<- vp[4] dragBase <<- screenToPolar(x, y) cur <<- cur3d() for (i in dev) { if (inherits(try(set3d(i, TRUE)), "try-error")) dev <<- dev[dev != i] else { m <- par3d("userMatrix") svd <- svd(m[1:3, 1:3]) m[1:3, 1:3] <- svd$u %*% t(svd$v) theta <- atan2(-m[1,3], m[1,1]) m <- m %*% rotationMatrix(theta, 0,1,0) svd <- svd(m[1:3, 1:3]) m[1:3,1:3] <- svd$u %*% t(svd$v) phi <- atan2(-m[2,3], m[3,3]) camBase[[i]] <<- c(theta, phi) } } set3d(cur, TRUE) } polarUpdate <- function(x,y) { dragCurrent <<- screenToPolar(x, y) for (i in dev) { if (inherits(try(set3d(i, TRUE)), "try-error")) dev <<- dev[dev != i] else { newpos <- camBase[[i]] - ( dragCurrent - dragBase ) newpos[2] <- clamp(newpos[2], -pi/2, pi/2) mouseMatrix <- rotationMatrix(newpos[2], 1, 0, 0) %*% rotationMatrix(-newpos[1], 0, 1, 0) par3d(userMatrix = mouseMatrix) } } set3d(cur, TRUE) } for (i in dev) { set3d(i, TRUE) rgl.setMouseCallbacks(button, begin = polarBegin, update = polarUpdate, end = NULL, dev = dev) } set3d(cur, TRUE) } # Set background colour based on x,y position in the window mouseBG <- function(button = 1, dev = cur3d(), init = "white", rate = cbind(c(1,0,1),c(0,1,1)), space = c("rgb", "hsv")) { cur <- cur3d() space <- match.arg(space) init <- col2rgb(init)/255 if (space == "hsv") init <- rgb2hsv(init*255) width <- height <- lambda0 <- lambda <- NULL bgBegin <- function(x, y) { lambda0 <<- c(x/width, 1-y/height) # nolint vp <- par3d("viewport") width <<- vp[3] height <<- vp[4] } bgUpdate <- function(x,y) { lambda <<- c(x/width, 1-y/height) - lambda0 color <- clamp(init + rate %*% lambda, 0, 1) x <- color[1] y <- color[2] z <- color[3] if (space == "rgb") color <- rgb(x,y,z) else color <- hsv(x,y,z) for (i in dev) { if (inherits(try(set3d(i, TRUE)), "try-error")) dev <<- dev[dev != i] else bg3d(color=color) } set3d(cur, TRUE) } bgEnd <- function() { init <<- clamp(init + rate %*% lambda, 0, 1) } for (i in dev) { set3d(i, TRUE) rgl.setMouseCallbacks(button, begin = bgBegin, update = bgUpdate, end = bgEnd, dev = dev) } set3d(cur, TRUE) } # Set time using an arbitrary par3dinterp function mouseInterp <- function(button = 1, dev = cur3d(), fn, init = 0, range = NULL, direction=c(1,0)) { cur <- cur3d() time <- init x0 <- width <- NULL interpBegin <- function(x, y) { vp <- par3d("viewport") width <<- vp[3] x0 <<- sum(direction*c(x,y)) } interpUpdate <- function(x,y) { time <<- init + (sum(direction*c(x,y)) - x0)/width if (!is.null(range)) time <<- clamp(time, range[1], range[2]) for (i in dev) { if (inherits(try(set3d(i, TRUE)), "try-error")) dev <<- dev[dev != i] else par3d(fn(time)) } set3d(cur, TRUE) } interpEnd <- function() { init <<- time } for (i in dev) { set3d(i, TRUE) rgl.setMouseCallbacks(button, begin = interpBegin, update = interpUpdate, end = interpEnd, dev = dev) } set3d(cur, TRUE) } mouseZoom <- function(button = 1, dev = cur3d()) mouseInterp(button,dev=dev,fn=par3dinterp(times=c(-4,4)/4, zoom=c(10^(-4),10^4),method="linear"), init=log10(par3d("zoom"))/4,range=c(-4,4)/4,direction=c(0,-1)) mouseFOV <- function(button = 1, dev = cur3d()) mouseInterp(button,dev=dev,fn=par3dinterp(times=c(1,179)/180, FOV=c(1,179),method="linear"), init=par3d("FOV")/180, range = c(1,179)/180, direction=c(0,1)) # Synchronize mouse control of two windows for stereo view example(surface3d, echo = FALSE) par3d(windowRect= c(0,32,512,544), userMatrix = rotationMatrix(5*pi/180, 0,1,0) %*% par3d("userMatrix") ) w1 <- cur3d() example(surface3d, echo = FALSE) par3d(windowRect = c(512,32,1024,544)) w2 <- cur3d() mouseTrackball(dev=c(w1,w2)) mouseZoom(2,dev=c(w1,w2)) mouseFOV(3,dev=c(w1,w2)) rgl/demo/shinyToggle.R0000644000176200001440000000132214100762640014377 0ustar liggesusersif (!require("shiny")) stop("This demo requires shiny.") library(rgl) open3d(useNULL = TRUE) ids <- plot3d(rnorm(100), rnorm(100), rnorm(100))["data"] scene <- scene3d() close3d() ui <- fluidPage( checkboxInput("chk", label = "Display", value = FALSE), playwidgetOutput("control"), rglwidgetOutput("wdg") ) server <- function(input, output, session) { options(rgl.useNULL = TRUE) save <- options(rgl.inShiny = TRUE) on.exit(options(save)) output$wdg <- renderRglwidget({ rglwidget(scene, controllers = "control") }) output$control <- renderPlaywidget({ toggleWidget("wdg", respondTo = "chk", ids = ids) }) } if (interactive()) shinyApp(ui = ui, server = server) rgl/demo/stereo.R0000644000176200001440000001246514100762640013416 0ustar liggesusersrandomDot <- function(left, right, rightOffset=c(200, 0), n=3000, ...) { old <- cur3d() on.exit(set3d(old)) force(left) force(right) set3d(left) leftViewport <- par3d("viewport") leftSize <- leftViewport[3:4] leftProj <- rgl.projection() leftDepth <- rgl.pixels("depth") leftUR <- leftViewport[1:2] + leftSize - 1 set3d(right) rightViewport <- par3d("viewport") rightSize <- rightViewport[3:4] rightProj <- rgl.projection() rightDepth <- rgl.pixels("depth") rightUR <- rightViewport[1:2] + rightSize - 1 size <- pmax(leftViewport[3:4], rightViewport[3:4]+rightOffset) pts <- matrix(c(sample(leftSize[1], n, replace=TRUE), sample(leftSize[2], n, replace=TRUE)), n, 2) cols <- 1:n startpt <- pts startcols <- cols keep <- startpt[,1] < leftSize[1] & startpt[,2] < leftSize[2] pt <- startpt[keep,,drop=FALSE] cl <- startcols[keep] while (length(pt)) { depth <- leftDepth[pt] user <- rgl.window2user((pt[,1]-0.5)/leftSize[1], (pt[,2]-0.5)/leftSize[2], depth, projection=leftProj) win <- rgl.user2window(user, projection=rightProj) bkgd <- cbind((pt[,1] - 0.5)/rightSize[1], (pt[,2] - 0.5)/rightSize[2], 1) usewin <- rep(depth < 1, 3) rightPt <- structure(ifelse(usewin, win, bkgd), dim=dim(win)) rightPti <- round(cbind(rightSize[1]*rightPt[,1], rightSize[2]*rightPt[,2]) + 0.5) keep <- rightPti[,1] >= 1 & rightPti[,1] <= rightUR[1] & rightPti[,2] >= 1 & rightPti[,2] <= rightUR[2] rightPti <- rightPti[keep,,drop=FALSE] rightPt <- rightPt[keep,,drop=FALSE] cl <- cl[keep] keep <- TRUE | rightPt[,3] <= rightDepth[ rightPti ]+0.001 rightPti <- rightPti[keep,,drop=FALSE] cl <- cl[keep] pt <- cbind(rightPti[,1] + rightOffset[1], rightPti[,2] + rightOffset[2]) pts <- rbind(pts, pt) cols <- c(cols, cl) keep <- apply(pt, 1, min) >= 1 & pt[,1] <= leftUR[1] & pt[,2] <= leftUR[2] pt <- pt[keep,,drop=FALSE] cl <- cl[keep] } pt <- cbind(startpt[,1] - rightOffset[1], startpt[,2] - rightOffset[2]) keep <- pt[,1] > 1 & pt[,1] < rightSize[1] & pt[,2] > 1 & pt[,2] < rightSize[2] pt <- pt[ keep,,drop=FALSE ] cl <- startcols[ keep ] while (length(pt)) { depth <- rightDepth[pt] user <- rgl.window2user((pt[,1]-0.5)/rightSize[1], (pt[,2]-0.5)/rightSize[2], depth, projection=rightProj) win <- rgl.user2window(user, projection=leftProj) bkgd <- cbind((pt[,1] - 0.5)/leftSize[1], (pt[,2] - 0.5)/leftSize[2], 1) usewin <- rep(depth < 1, 3) leftPt <- structure(ifelse(usewin, win, bkgd), dim=dim(win)) leftPti <- round(cbind(leftSize[1]*leftPt[,1], leftSize[2]*leftPt[,2]) + 0.5) keep <- leftPti[,1] >= 1 & leftPti[,1] <= leftUR[1] & leftPti[,2] >= 1 & leftPti[,2] <= leftUR[2] leftPti <- leftPti[keep,,drop=FALSE] leftPt <- leftPt[keep,,drop=FALSE] cl <- cl[keep] keep <- TRUE | leftPt[,3] <= leftDepth[ leftPti ]+0.001 leftPti <- leftPti[keep,,drop=FALSE] cl <- cl[keep] pt <- leftPti pts <- rbind(pts, pt) cols <- c(cols, cl) pt <- cbind(pt[,1] - rightOffset[1], pt[,2] - rightOffset[2]) keep <- apply(pt, 1, min) >= 1 & pt[,1] <= rightUR[1] & pt[,2] <= rightUR[2] pt <- pt[keep,,drop=FALSE] cl <- cl[keep] } plot(pts, col = cols, pch=16, axes=FALSE,cex=0.25+cols/n/2,xlab="",ylab="",...) rug((size[1] + c(-1,1)*rightOffset[1])/2, side=1) rug((size[1] + c(-1,1)*rightOffset[1])/2, side=3) rug((size[2] + c(-1,1)*rightOffset[2])/2, side=2) rug((size[2] + c(-1,1)*rightOffset[2])/2, side=4) } #red #cyan anaglyph <- function(left, right, leftColor = c(1,0,0), rightColor = c(0,1,1), dimens = dim(leftPixels)) { old <- cur3d() on.exit(set3d(old)) force(left) force(right) set3d(left) vp <- par3d("viewport") leftPixels <- rgl.pixels(viewport=vp) leftPixels <- t((leftPixels[,,1]+leftPixels[,,2]+leftPixels[,,3])/3) leftPixels <- leftPixels[rev(seq_len(dimens[1])), seq_len(dimens[2])] set3d(right) rightPixels <- rgl.pixels(viewport=vp) rightPixels <- t((rightPixels[,,1]+rightPixels[,,2]+rightPixels[,,3])/3) rightPixels <- rightPixels[rev(seq_len(dimens[1])), seq_len(dimens[2])] red <- pmin(leftPixels*leftColor[1] + rightPixels*rightColor[1], 1) green <- pmin(leftPixels*leftColor[2] + rightPixels*rightColor[2], 1) blue <- pmin(leftPixels*leftColor[3] + rightPixels*rightColor[3], 1) z <- as.raster(array(c(red, green, blue), dim = c(dimens, 3))) if (length(z)) { par(mar = c(0,0,0,0)) plot(z) } else { cat("Unable to read pixels:\nstr(leftPixels):\n") str(leftPixels) cat("str(rightPixels):\n") str(rightPixels) } } if (!rgl.useNULL()) { source(system.file("demo/mouseCallbacks.R", package="rgl"), echo=FALSE ) # This version assumes the eyes diverge for the stereo view. # Reverse the two arguments for the cross-eyed view. dev.new(width=9, height=7) randomDot(cur3d()-1, cur3d()) # A red-cyan anaglyph (for 3D glasses). Use optional args to anaglyph for other glasses. dev.new() anaglyph(cur3d()-1, cur3d()) } else cat("Can't read pixels from a NULL device\n") rgl/demo/rgl.r0000644000176200001440000000020214100762640012723 0ustar liggesusers# all rgl demos demo(hist3d) demo(abundance) demo(regression) demo(lsystem) demo(subdivision) # requires MASS library demo(bivar) rgl/demo/flag.R0000644000176200001440000000137114100762640013020 0ustar liggesusers wave <- function(time) { x <- seq(0,2, len=100) wavefn <- function(x) x * sin(-5*time + 1.5 * (x/2) * 2*pi)/10 deriv <- function(x) (wavefn(x + 0.01) - wavefn(x - 0.01))/0.02 arclen <- cumsum(sqrt(1 + deriv(x)^2))*(x[2]-x[1]) keep <- arclen < 2 x <- x[keep] y <- matrix(wavefn(x), length(x),20) z <- matrix(seq(0,1, len=20), length(x), 20, byrow=TRUE) arclen <- arclen[keep] par3d(skipRedraw = TRUE) if (nrow(ids3d())) pop3d() surface3d(x,y,z, texture_s=matrix(arclen/2, length(x), 20), texture_t=z, col="white") c(list(skipRedraw = FALSE), spin(time)) } open3d() material3d(texture = system.file("textures","rgl2.png", package="rgl")) spin <- spin3d(rpm=6,axis=c(0,0,1)) if (!rgl.useNULL()) play3d(wave, 10, startTime = 5) rgl/demo/shinyDemo.R0000644000176200001440000001137614100762640014054 0ustar liggesusersif (!require("shiny")) stop("This demo requires shiny.") library(rgl) library(misc3d) options(rgl.useNULL = TRUE) set.seed(123) ui <- fluidPage( registerSceneChange(), titlePanel("Nelder-Mead"), sidebarLayout( sidebarPanel( helpText("The Nelder-Mead algorithm evaluates the function", "on the vertices of a simplex. At each step it", "moves one vertex of the simplex to a better value."), sliderInput("Slider", min=0, max=59, step=1, value=0, label="Steps", animate=animationOptions(200, loop=TRUE)), sliderInput("Slider2", min=0, max=59, step=1, value=0, label="Cumulative", animate=animationOptions(200, loop=TRUE)), playwidgetOutput('thecontroller'), playwidgetOutput('thecontroller2'), actionButton('newStart', 'Restart')), mainPanel( rglwidgetOutput('thewidget', width = "100%", height = 512)) ) ) u1 <- runif(1) u2 <- runif(1)*(1-u1) u3 <- 1 - u1 - u2 # Example modified from ?contour3d #Example 2: Nested contours of mixture of three tri-variate normal densities nmix3 <- function(x, y, z, m, s) { u1 * dnorm(x, m, s) * dnorm(y, m, s) * dnorm(z, m, s) + u2 * dnorm(x, -m, s) * dnorm(y, -m, s) * dnorm(z, -m, s) + u3 * dnorm(x, m, s) * dnorm(y, -1.5 * m, s) * dnorm(z, m, s) } f <- function(x,y,z) nmix3(x,y,z,.5,.5) g <- function(n = 40, k = 5, alo = 0.1, ahi = 0.5, cmap = heat.colors) { th <- seq(0.05, 0.2, len = k) col <- rev(cmap(length(th))) al <- seq(alo, ahi, len = length(th)) x <- seq(-2, 2, len=n) bg3d(col="white") contour3d(f,th,x,x,x,color=col,alpha=al) # nolint } f3 <- function(x) -f(x[1], x[2], x[3]) g(20,3) surface <- scene3d() close3d() neldermead <- function(x, f) { n <- nrow(x) p <- ncol(x) if (n != p + 1) stop(paste('Need', p + 1, 'starting points')) fx <- rep(NA, n) for (i in 1:n) fx[i] <- f(x[i,]) o <- order(fx) fx <- fx[o] x <- x[o,] xmid <- apply(x[1:p,], 2, mean) z1 <- xmid - (x[n,] - xmid) fz1 <- f(z1) if (fz1 < fx[1]) { z2 <- xmid - 2*(x[n,] - xmid) fz2 <- f(z2) if (fz2 < fz1) { x[n,] <- z2 } else { x[n,] <- z1 } } else if (fz1 < fx[p]) { x[n,] <- z1 } else { if (fz1 < fx[n]) { x[n,] <- z1 fx[n] <- fz1 } z3 <- xmid + (x[n,] - xmid)/2 fz3 <- f(z3) if (fz3 < fx[n]) { x[n,] <- z3 } else { for (i in 2:n) { x[i,] <- x[1,] + (x[i,] - x[1,])/2 } } } return(x) } showsimplex <- function(x, f, col="blue") { n <- nrow(x) z <- numeric(n) for (i in 1:n) z[i] <- f(x[i,]) xyz <- cbind(x, z) # This is tricky: # 1. draw all lines, taking vertices two at a time: c(segments3d(xyz[as.numeric(combn(n, 2)),], col="black", depth_test = "lequal"), # 2. draw all faces, taking vertices three at a time: triangles3d(xyz[as.numeric(combn(n, 3)),], col=col, alpha=0.3)) } setStartPoint <- function() { xyz <- matrix(rnorm(12, sd=0.1) + rep(rnorm(3,sd=2), each=4), 4, 3) subsets <-list() for (i in 1:60) { xyz <- neldermead(xyz,f3) subset <- showsimplex(xyz,f3) subsets <-c(subsets,list(subset)) } names(subsets) <- seq_along(subsets) subsets } server <- function(input, output, session) { plot3d(surface) dev <- cur3d() save <- options(rgl.inShiny = TRUE) on.exit(options(save)) session$onSessionEnded(function() { set3d(dev) close3d() }) path <- reactiveValues(subsets = setStartPoint()) observeEvent(input$newStart, { set3d(dev) deletes <- unique(unlist(path$subsets)) if (length(deletes)) delFromSubscene3d(deletes) subsets <- setStartPoint() adds <- unique(unlist(subsets)) session$sendCustomMessage("sceneChange", sceneChange("thewidget", delete = deletes, add = adds, skipRedraw = TRUE)) path$subsets <- subsets updateSliderInput(session, "Slider", value=0) updateSliderInput(session, "Slider2", value=0) session$onFlushed(function() session$sendCustomMessage("sceneChange", sceneChange("thewidget", skipRedraw = FALSE))) }) output$thewidget <- renderRglwidget({ rglwidget(controllers=c("thecontroller", "thecontroller2")) }) output$thecontroller <- renderPlaywidget({ if (length(path$subsets)) playwidget("thewidget", respondTo = "Slider", subsetControl(1, path$subsets), start = 1, stop = length(path$subsets)) }) output$thecontroller2 <- renderPlaywidget({ if (length(path$subsets)) playwidget("thewidget", respondTo = "Slider2", subsetControl(1, path$subsets, accumulate = TRUE)) }) } if (interactive()) shinyApp(ui = ui, server = server) rgl/demo/regression.r0000644000176200001440000000214514100762640014327 0ustar liggesusers# demo: regression # author: Daniel Adler rgl.demo.regression <- function(n=100,xa=3,za=8,xb=0.02,zb=0.01,xlim=c(0,100),zlim=c(0,100)) { rgl.clear("all") rgl.bg(sphere = TRUE, color = c("black", "green"), lit = FALSE, size=2, alpha=0.2, back = "lines") rgl.light() rgl.bbox() x <- runif(n,min=xlim[1],max=xlim[2]) z <- runif(n,min=zlim[1],max=zlim[2]) ex <- rnorm(n,sd=3) ez <- rnorm(n,sd=2) esty <- (xa+xb*x) * (za+zb*z) + ex + ez rgl.spheres(x,esty,z,color="gray",radius=1.5,specular="green", texture=system.file("textures/bump_dust.png",package="rgl"), texmipmap=TRUE, texminfilter="linear.mipmap.linear") regx <- seq(xlim[1],xlim[2],len=100) regz <- seq(zlim[1],zlim[2],len=100) regy <- (xa+regx*xb) %*% t(za+regz*zb) rgl.surface(regx,regz,regy,color="blue",alpha=0.5,shininess=128) lx <- c(xlim[1],xlim[2],xlim[2],xlim[1]) lz <- c(zlim[1],zlim[1],zlim[2],zlim[2]) f <- function(x,z) (xa+x*xb) * t(za+z*zb) ly <- f(lx,lz) rgl.quads(lx,ly,lz,color="red",size=5,front="lines",back="lines",lit=FALSE) } rgl.open() rgl.demo.regression() rgl/demo/shapes3d.R0000644000176200001440000000654614100762640013632 0ustar liggesusers cone3d <- function(base=c(0,0,0),tip=c(0,0,1),rad=1,n=30,draw.base=TRUE,qmesh=FALSE, trans = par3d("userMatrix"), ...) { ax <- tip-base if (missing(trans) && !cur3d()) trans <- diag(4) ### is there a better way? if (ax[1]!=0) { p1 <- c(-ax[2]/ax[1],1,0) p1 <- p1/sqrt(sum(p1^2)) if (p1[1]!=0) { p2 <- c(-p1[2]/p1[1],1,0) p2[3] <- -sum(p2*ax) p2 <- p2/sqrt(sum(p2^2)) } else { p2 <- c(0,0,1) } } else if (ax[2]!=0) { p1 <- c(0,-ax[3]/ax[2],1) p1 <- p1/sqrt(sum(p1^2)) if (p1[1]!=0) { p2 <- c(0,-p1[3]/p1[2],1) p2[3] <- -sum(p2*ax) p2 <- p2/sqrt(sum(p2^2)) } else { p2 <- c(1,0,0) } } else { p1 <- c(0,1,0); p2 <- c(1,0,0) } degvec <- seq(0,2*pi,length=n+1)[-1] ecoord2 <- function(theta) { base+rad*(cos(theta)*p1+sin(theta)*p2) } i <- rbind(1:n,c(2:n,1),rep(n+1,n)) v <- cbind(sapply(degvec,ecoord2),tip) if (qmesh) ## minor kluge for quads -- draw tip twice i <- rbind(i,rep(n+1,n)) if (draw.base) { v <- cbind(v,base) i.x <- rbind(c(2:n,1),1:n,rep(n+2,n)) if (qmesh) ## add base twice i.x <- rbind(i.x,rep(n+2,n)) i <- cbind(i,i.x) } if (qmesh) v <- rbind(v,rep(1,ncol(v))) ## homogeneous if (!qmesh) triangles3d(v[1,i],v[2,i],v[3,i],...) else return(rotate3d(qmesh3d(v,i,material=list(...)), matrix=trans)) } ellipsoid3d <- function(rx=1,ry=1,rz=1,n=30,ctr=c(0,0,0), qmesh=FALSE, trans = par3d("userMatrix"),...) { if (missing(trans) && !cur3d()) trans <- diag(4) degvec <- seq(0,pi,length=n) ecoord2 <- function(p) c(rx*cos(p[1])*sin(p[2]),ry*sin(p[1])*sin(p[2]),rz*cos(p[2])) v <- apply(expand.grid(2*degvec,degvec),1,ecoord2) if (qmesh) v <- rbind(v,rep(1,ncol(v))) ## homogeneous e <- expand.grid(1:(n-1),1:n) i1 <- apply(e,1,function(z)z[1]+n*(z[2]-1)) i2 <- i1+1 i3 <- (i1+n-1) %% n^2 + 1 i4 <- (i2+n-1) %% n^2 + 1 i <- rbind(i1,i2,i4,i3) if (!qmesh) quads3d(v[1,i],v[2,i],v[3,i],...) else return(rotate3d(qmesh3d(v,i,material=list(...)),matrix=trans)) } ############ open3d() ellipsoid3d(ctr=c(2,2,2),rx=3,ry=2,col="red",alpha=0.4) cone3d(base=c(-2,-2,-2),rad=0.5,tip=c(-3,0,-4),col="blue",front="lines",back="lines") shade3d(translate3d(cube3d(),3,-2,3,col="purple")) ### now with qmesh() open3d() q1 <- cone3d(qmesh=TRUE,trans=diag(4)) ## the "unit cone"; ## height=1,radius=1, base at (0,0,0) shade3d(q1) ## various transformations and rotations wire3d(translate3d(q1,3,0,0),col="green") wire3d(translate3d(scale3d(q1,1,1,2),6,0,0),col="green") dot3d(translate3d(q1,0,3,0),col="green") dot3d(translate3d(scale3d(q1,2,1,1),0,6,0),col="green") shade3d(translate3d(q1,0,0,3),col="red") shade3d(translate3d(rotate3d(scale3d(q1,1,1,2),pi/4,0,1,0),0,0,6),col="red") axes3d() open3d() s1 <- ellipsoid3d(qmesh=TRUE,trans=diag(4)) ## the "unit sphere"; ## radius=1, ctr at (0,0,0) shade3d(s1) ## various transformations and rotations wire3d(translate3d(s1,3,0,0),col="green") wire3d(translate3d(scale3d(s1,1,1,2),6,0,0),col="green") dot3d(translate3d(s1,0,3,0),col="green") dot3d(translate3d(scale3d(s1,2,1,1),0,6,0),col="green") shade3d(translate3d(s1,0,0,3),col="red") shade3d(translate3d(rotate3d(scale3d(s1,1,1,2),pi/4,0,1,0),0,0,6),col="red") axes3d() rgl/demo/bivar.r0000644000176200001440000000202114100762640013243 0ustar liggesusers# rgl demo: rgl-bivar.r # author: Daniel Adler rgl.demo.bivar <- function() { if (!requireNamespace("MASS", quietly = TRUE)) stop("This demo requires MASS") # parameters: n<-50; ngrid<-40 # generate samples: set.seed(31415) x<-rnorm(n); y<-rnorm(n) # estimate non-parameteric density surface via kernel smoothing denobj <- MASS::kde2d(x, y, n=ngrid) den.z <-denobj$z # generate parametric density surface of a bivariate normal distribution xgrid <- denobj$x ygrid <- denobj$y bi.z <- dnorm(xgrid)%*%t(dnorm(ygrid)) # visualize: zscale<-20 # New window open3d() # clear scene: clear3d("all") # setup env: bg3d(color="#887777") light3d() # Draws the simulated data as spheres on the baseline spheres3d(x,y,rep(0,n),radius=0.1,color="#CCCCFF") # Draws non-parametric density surface3d(xgrid,ygrid,den.z*zscale,color="#FF2222",alpha=0.5) # Draws parametric density surface3d(xgrid,ygrid,bi.z*zscale,color="#CCCCFF",front="lines") } rgl.demo.bivar() rgl/demo/rglExamples.R0000644000176200001440000001055014100762640014371 0ustar liggesusersdirname <- tempfile() dir.create(dirname) olddir <- setwd(dirname) show <- c() # list topics to show only those skip <- c("rgl-package", "shinyGetPar3d", "tkpar3dsave", "tkrgl", "tkspin3d", "tkspinControl") # Ones to skip library(tools) db <- Rd_db("rgl") names <- names(db) if (length(show)) names <- names[sub("[.]Rd$", "", names) %in% show] Rmdnames <- sub("[.]Rd$", ".Rmd", names) htmlnames <- sub("[.]Rd$", ".html", names) # These functions are based on similar ones from tools .Rd_deparse <- function (x, tag = TRUE) { if (!tag) attr(x, "Rd_tag") <- "Rd" paste(as.character(x), collapse = "") } .Rd_drop_nodes_with_tags <- function (x, tags) { recurse <- function(e) { if (is.list(e)) structure(lapply(e[is.na(match(RdTags(e), tags))], recurse), Rd_tag = attr(e, "Rd_tag")) else e } recurse(x) } .Rd_drop_comments <- function (x) .Rd_drop_nodes_with_tags(x, "COMMENT") RdTags <- function (Rd) { res <- sapply(Rd, attr, "Rd_tag") if (!length(res)) res <- character() res } .Rd_get_section <- function (x, which, predefined = TRUE) { if (predefined) x <- x[RdTags(x) == paste0("\\", which)] else { x <- x[RdTags(x) == "\\section"] if (length(x)) { ind <- sapply(x, function(e) .Rd_get_text(e[[1L]])) == which x <- lapply(x[ind], `[[`, 2L) } } if (!length(x)) x else structure(x[[1L]], class = "Rd") } .Rd_get_example_code <- function (x) { x <- .Rd_get_section(x, "examples") if (!length(x)) return(character()) x <- .Rd_drop_comments(x) recurse <- function(e) { if (is.list(e)) { unlist(lapply(e[is.na(match(RdTags(e), c(#"\\donttest", "\\dontrun")))], recurse)) } else e } .Rd_deparse(recurse(x), tag = FALSE) } writeIndex <- function(names, htmlnames, cols = 4) { result <- character() if (!is.null(text)) { o <- order(names) names <- names[o] htmlnames <- htmlnames[o] entries <- paste0("[", names, "](", htmlnames, ")") len <- length(entries) padding <- ((len + cols - 1) %/% cols) * cols - len if (padding) entries <- c(entries, rep("", length.out=padding)) result <- c(result, '\n
\n') result <- c(result, knitr::kable(matrix(entries, ncol=cols), format="markdown", col.names = rep(" ", cols))) result <- c(result, "
\n") } } library(rgl) saveopts <- options(rgl.useNULL = TRUE) prevlink <- "[Prev](index.html)" indexlink <- "[Index](index.html)" for (i in seq_along(names)) { Rmd <- file(Rmdnames[i], open = "wt") nextlink <- if (i < length(htmlnames)) paste0("[Next](", htmlnames[i+1], ")") else "" writeLines(c('---', paste0('title: ', names[i]), 'output: html_document --- ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE) initialWd <- getwd() saveopts <- options() options(rgl.useNULL = TRUE) library(rgl) setupKnitr(autoprint = TRUE) example <- function(...) { saveopts <- options(rgl.printRglwidget = FALSE) on.exit(options(saveopts)) utils::example(...) lowlevel(numeric()) } options(ask = FALSE, examples.ask = FALSE, device.ask.default = FALSE) ``` '), Rmd) writeLines(paste(prevlink, nextlink, indexlink), Rmd) if (file_path_sans_ext(Rmdnames[i]) %in% skip) writeLines( '```{r eval = FALSE} # This example is skipped in the demo.', Rmd) else writeLines('```{r}', Rmd) code <- .Rd_get_example_code(db[[names[i]]]) if (length(code)) writeLines(code, Rmd) else writeLines("# No example code", Rmd) writeLines( '``` ```{r echo=FALSE,include=FALSE} setwd(initialWd) while(length(rgl.dev.list())) close3d() rm(examples) options(saveopts) ``` ', Rmd) writeLines(paste(prevlink, nextlink, indexlink), Rmd) close(Rmd) prevlink <- paste0("[Prev](", htmlnames[i], ")") rmarkdown::render(Rmdnames[i]) while(length(rgl.dev.list())) close3d() } indexname <- "index.Rmd" index <- file(indexname, open = "wt") writeLines(c( '--- title: "rgl Examples" author: "Duncan Murdoch" output: html_document --- These files show examples from almost every help file in `rgl`. ', writeIndex(names, htmlnames)), index) close(index) browseURL(rmarkdown::render(indexname)) options(saveopts) setwd(olddir) rgl/demo/lsystem.r0000644000176200001440000001116714100762640013653 0ustar liggesusers# demo: lsystem.r # author: Daniel Adler # # geometry # deg2rad <- function( degree ) { return( degree*pi/180 ) } rotZ.m3x3 <- function( degree ) { kc <- cos(deg2rad(degree)) ks <- sin(deg2rad(degree)) return( matrix( c( kc, -ks, 0, ks, kc, 0, 0, 0, 1 ),ncol=3,byrow=TRUE ) ) } rotX.m3x3 <- function( degree ) { kc <- cos(deg2rad(degree)) ks <- sin(deg2rad(degree)) return( matrix( c( 1, 0, 0, 0, kc, -ks, 0, ks, kc ),ncol=3,byrow=TRUE ) ) } rotY.m3x3 <- function( degree ) { kc <- cos(deg2rad(degree)) ks <- sin(deg2rad(degree)) return( matrix( c( kc, 0, ks, 0, 1, 0, -ks, 0, kc ),ncol=3,byrow=TRUE ) ) } rotZ <- function( v, degree ) { return( rotZ.m3x3(degree) %*% v) } rotX <- function( v, degree ) { return( rotX.m3x3(degree) %*% v) } rotY <- function( v, degree ) { return( rotY.m3x3(degree) %*% v) } # # turtle graphics, rgl implementation: # turtle.init <- function(pos=c(0,0,0),head=0,pitch=90,roll=0,level=0) { rgl.clear("all") rgl.bg(color="black") rgl.light() return( list(pos=pos,head=head,pitch=pitch,roll=roll,level=level) ) } turtle.move <- function(turtle, steps, color) { rm <- rotX.m3x3(turtle$pitch) %*% rotY.m3x3(turtle$head) %*% rotZ.m3x3(turtle$roll) from <- as.vector( turtle$pos ) dir <- rm %*% c(0,0,-1) to <- from + dir * steps x <- c( from[1], to[1] ) y <- c( from[2], to[2] ) z <- c( from[3], to[3] ) rgl.lines(x,y,z,col=color,size=1.5,alpha=0.5) turtle$pos <- to return(turtle) } turtle.pitch <- function(turtle, degree) { turtle$pitch <- turtle$pitch + degree return(turtle) } turtle.head <- function(turtle, degree) { turtle$head <- turtle$head + degree return(turtle) } turtle.roll <- function(turtle, degree) { turtle$roll <- turtle$roll + degree return(turtle) } # # l-system general # lsystem.code <- function( x ) substitute( x ) lsystem.gen <- function( x, grammar, levels=0 ) { code <- eval( substitute( substitute( REPLACE , grammar ), list(REPLACE=x) ) ) if (levels) return( lsystem.gen( code , grammar , levels-1 ) ) else return( code ) } # # l-system plot # lsystem.plot <- function( expr, level ) { turtle <- turtle.init(level=level) lsystem.eval( expr, turtle ) } lsystem.eval <- function( expr, turtle ) { if ( length(expr) == 3 ) { turtle <- lsystem.eval( expr[[2]], turtle ) turtle <- lsystem.eval( expr[[3]], turtle ) turtle <- lsystem.eval( expr[[1]], turtle ) } else if ( length(expr) == 2 ) { saved <- turtle turtle <- lsystem.eval( expr[[1]], turtle ) turtle <- lsystem.eval( expr[[2]], turtle ) turtle <- saved } else if ( length(expr) == 1 ) { if ( as.name(expr) == "stem" ) turtle <- turtle.move(turtle, 5, "brown") else if ( as.name(expr) == "short") turtle <- turtle.move(turtle, 5, "brown") else if ( as.name(expr) == "leaf" ) { rgl.spheres(turtle$pos[1],turtle$pos[2],turtle$pos[3],radius=0.1+turtle$level*0.3,color="green") rgl.sprites(turtle$pos[1],turtle$pos[2],turtle$pos[3],radius=0.5+turtle$level*0.3 ,color="green",texture=system.file("textures/particle.png",package="rgl"),textype="alpha",alpha=0.5) } else if ( as.name(expr) == "roll" ) turtle <- turtle.head(turtle, 60) else if ( as.name(expr) == "down" ) turtle <- turtle.pitch(turtle,10) else if ( as.name(expr) == "up" ) turtle <- turtle.pitch(turtle,-10) else if ( as.name(expr) == "left" ) turtle <- turtle.head(turtle, 1) else if ( as.name(expr) == "right") turtle <- turtle.head(turtle,-1.5) else if ( as.name(expr) == "turnleft") turtle <- turtle.head(turtle,20) else if ( as.name(expr) == "turnright") turtle <- turtle.head(turtle,-20) else if ( as.name(expr) == "turn") turtle <- turtle.roll(turtle,180) } return(turtle) } # # example # simple <- function(level=0) { grammar <- list( stem=lsystem.code( stem-(up-stem-leaf)-stem-(down-stem-leaf)-stem-leaf ) ) plant <- lsystem.gen(lsystem.code(stem), grammar, level ) lsystem.plot(plant,level) } rgl.demo.lsystem <- function(level=0) { gen <- list( stem=lsystem.code( stem-left-stem-branch( turnleft-down-short-turnleft-down-stem-leaf)-right-right-stem--branch( turnright-up-short-turnright-up-short-turnright-short-stem-leaf)-left-left-left-stem-branch( turnleft-down-short-turnright-down-stem-leaf )-branch( up-turnright-short-up-turnleft-up-stem-leaf ) ) ) plant <- lsystem.gen(lsystem.code(stem), gen, level ) lsystem.plot(plant,level) } rgl.open() rgl.demo.lsystem(level=1) rgl/demo/envmap.r0000644000176200001440000000073314100762640013436 0ustar liggesusers# RGL-Demo: environment mapping # Author: Daniel Adler rgl.demo.envmap <- function() { open3d() # Clear scene: clear3d("all") light3d() bg3d(sphere=TRUE, color="white", back="filled" , texture=system.file("textures/refmap.png",package="rgl") ) data(volcano) surface3d( 10*seq_len(nrow(volcano)),10*seq_len(ncol(volcano)),5*volcano , texture=system.file("textures/refmap.png",package="rgl") , texenvmap=TRUE , color = "white" ) } rgl.demo.envmap() rgl/demo/hist3d.r0000644000176200001440000000666614100762640013361 0ustar liggesusers ########## ### 3D HIST EXAMPLE: ########## ################################################################################ ##### Required functions 'binplot' and 'hist3d': binplot.3d<-function(x,y,z,alpha=1,topcol="#ff0000",sidecol="#aaaaaa") { save <- par3d(skipRedraw=TRUE) on.exit(par3d(save)) x1<-c(rep(c(x[1],x[2],x[2],x[1]),3),rep(x[1],4),rep(x[2],4)) z1<-c(rep(0,4),rep(c(0,0,z,z),4)) y1<-c(y[1],y[1],y[2],y[2],rep(y[1],4),rep(y[2],4),rep(c(y[1],y[2],y[2],y[1]),2)) x2<-c(rep(c(x[1],x[1],x[2],x[2]),2),rep(c(x[1],x[2],rep(x[1],3),rep(x[2],3)),2)) z2<-c(rep(c(0,z),4),rep(0,8),rep(z,8) ) y2<-c(rep(y[1],4),rep(y[2],4),rep(c(rep(y[1],3),rep(y[2],3),y[1],y[2]),2) ) rgl.quads(x1,z1,y1,col=rep(sidecol,each=4),alpha=alpha) rgl.quads(c(x[1],x[2],x[2],x[1]),rep(z,4),c(y[1],y[1],y[2],y[2]), col=rep(topcol,each=4),alpha=1) rgl.lines(x2,z2,y2,col="#000000") } hist3d<-function(x,y=NULL,nclass="auto",alpha=1,col="#ff0000",scale=10) { save <- par3d(skipRedraw=TRUE) on.exit(par3d(save)) xy <- xy.coords(x,y) x <- xy$x y <- xy$y n<-length(x) if (nclass == "auto") nclass<-ceiling(sqrt(nclass.Sturges(x))) breaks.x <- seq(min(x),max(x),length=(nclass+1)) breaks.y <- seq(min(y),max(y),length=(nclass+1)) z<-matrix(0,(nclass),(nclass)) for (i in seq_len(nclass)) { for (j in seq_len(nclass)) { z[i, j] <- (1/n)*sum(x < breaks.x[i+1] & y < breaks.y[j+1] & x >= breaks.x[i] & y >= breaks.y[j]) binplot.3d(c(breaks.x[i],breaks.x[i+1]),c(breaks.y[j],breaks.y[j+1]), scale*z[i,j],alpha=alpha,topcol=col) } } } ################################################################################ rgl.open() rgl.bg(color="gray") rgl.light() # Drawing a 'bin' for given coordinates: binplot.3d(c(-0.5,0.5),c(4.5,5.5),2,alpha=0.6) # Setting the viewpoint ('theta' and 'phi' have the same meaning as in persp): rgl.viewpoint(theta=40,phi=40) # Choosing a lightgrey background: rgl.bg(col="#cccccc") ##### QUADS FORMING BIN: rgl.open() # Defining transparency and colors: alpha<-0.7; topcol<-"#ff0000"; sidecol<-"#aaaaaa" # Setting up coordinates for the quads and adding them to the scene: y<-x<-c(-1,1) ; z<-4; of<-0.3 x12<-c(x[1],x[2],x[2],x[1]); x11<-rep(x[1],4); x22<-rep(x[2],4) z00<-rep(0,4); z0z<-c(0,0,z,z); zzz<-rep(z,4); y11<-rep(y[1],4) y1122<-c(y[1],y[1],y[2],y[2]); y12<-c(y[1],y[2],y[2],y[1]); y22<-rep(y[2],4) rgl.quads(c(x12,x12,x11-of,x12,x22+of,x12), c(z00-of,rep(z0z,4),zzz+of), c(y1122,y11-of,y12,y22+of,y12,y1122), col=rep(c(rep(sidecol,5),topcol),each=4),alpha=c(rep(alpha,5),1)) # Setting up coordinates for the border-lines of the quads and drawing them: yl1<-c(y[1],y[2],y[1],y[2]); yl2<-c(y[1]-of,y[1]-of) xl<-c(rep(x[1],8),rep(x[1]-of,8),rep(c(x[1],x[2]),8),rep(x[2],8),rep(x[2]+of,8)) zl<-c(0,z,0,z,z+of,z+of,-of,-of,0,0,z,z,0,z,0,z,rep(0,4),rep(z,4),rep(-of,4), rep(z+of,4),z+of,z+of,-of,-of,rep(c(0,z),4),0,0,z,z) yl<-c(yl2,y[2]+of,y[2]+of,rep(c(y[1],y[2]),4),y[1],y[1],y[2],y[2],yl2, rep(y[2]+of,4),yl2,y[2],y[2],rep(y[1],4),y[2],y[2],yl1,yl2,y[2]+of, y[2]+of,y[1],y[1],y[2],y[2],yl1) rgl.lines(xl,zl,yl,col="#000000") ##### COMPLETE HISTOGRAM: rgl.open() # Choosing a lightgrey background: rgl.bg(col="#cccccc") # Setting the rng to a fixed value: set.seed(1000) # Drawing a 3d histogramm of 2500 normaly distributed observations: hist3d(rnorm(2500),rnorm(2500),alpha=0.4,nclass=7,scale=30) rgl/demo/simpleShinyRgl.R0000644000176200001440000000106314100762640015056 0ustar liggesusers# A simple Shiny demo written by Dieter Menne options(rgl.useNULL = TRUE) if (!require(shiny)) stop("This demo requires shiny.") library(rgl) app <- shinyApp( ui = bootstrapPage( checkboxInput("rescale", "Rescale"), rglwidgetOutput("rglPlot") ), server = function(input, output) { output$rglPlot <- renderRglwidget({ try(close3d(), silent = TRUE) if (input$rescale) aspect3d(1,1,10) else aspect3d(1,1,1) spheres3d(rnorm(100), rnorm(100), rnorm(100,sd = 0.1), col = "red", radius = 0.1) axes3d() rglwidget() }) }) runApp(app) rgl/demo/00Index0000644000176200001440000000214614100762640013117 0ustar liggesusersrgl RGL Demonstration rglExamples All examples displayed in HTML hist3d 3D histogram using basic building blocks bivar Bivariate densities: kernel smoothing using rgl.surface and alpha-channel (requires MASS package) abundance Animal abundance, visualization of multi-dimension data using multiple techniques lsystem Plant modelling using a turtle and L-system subdivision Subdivision surfaces using generic meshes (preview of generic 3D interface) regression Bivariate regression envmap Environment mapping shapes3d 3D shape primitives (cones, ellipsoids, cubes), some taken from qmesh3d lollipop3d "Lollipop" plots (3D scatterplot with lines between points and a surface) flag play3d() function that waves a flag mouseCallbacks Standard mouse handlers implemented in R, for a stereo view stereo Stereo views using a random dot stereogram & an anaglyph simpleShinyRgl Shiny demo with checkbox shinyToggle Shiny with togglewidget shinyTabs Shiny with tabs shinyDemo rglwidget in Shiny: Nelder-Mead demonstration shinyMouse Mouse selection in Shiny rgl/demo/shinyTabs.R0000644000176200001440000000144014100762640014050 0ustar liggesusersif (!require("shiny")) stop("This demo requires shiny.") library(rgl) options(rgl.useNULL = TRUE) ui <- fluidPage( mainPanel( tabsetPanel( tabPanel("red", rglwidgetOutput('thewidget1')), tabPanel("green", rglwidgetOutput('thewidget2')) )) ) server <- function(input, output, session) { x <- rnorm(100) y <- 2*rnorm(100) z <- 10*rnorm(100) open3d() plot3d(x, y, z, col = "red") scene1 <- scene3d() plot3d(z, y, x, col = "green") scene2 <- scene3d() close3d() save <- options(rgl.inShiny = TRUE) on.exit(options(save)) output$thewidget1 <- renderRglwidget( rglwidget(scene1) ) output$thewidget2 <- renderRglwidget( rglwidget(scene2) ) } if (interactive()) shinyApp(ui = ui, server = server)rgl/demo/subdivision.r0000644000176200001440000000122214100762640014500 0ustar liggesusers# RGL-demo: subdivision surfaces # author: Daniel Adler rgl.demo.subdivision <- function() { # setup environment clear3d("all") view3d() bg3d(color="gray") light3d() # generate basic mesh obj <- oh3d() part <- function( level, tx, ... ) { shade3d( translate3d( obj, tx, 0, 0 ) , color="gray30", front="lines",alpha=0.5,back="lines", override=TRUE ) shade3d( translate3d( subdivision3d( obj, depth=level ), tx, 0, 0 ) , override=TRUE, ... ) } part(0, -5.50, color="blue" ) part(1, -1.75, color="yellow" ) part(2, 1.75, color="red" ) part(3, 5.50, color="green" ) } open3d() rgl.demo.subdivision() rgl/demo/abundance.r0000644000176200001440000000244714100762640014074 0ustar liggesusers# RGL-Demo: animal abundance # Authors: Oleg Nenadic, Daniel Adler rgl.demo.abundance <- function() { open3d() clear3d("all") # remove all shapes, lights, bounding-box, and restore viewpoint # Setup environment: bg3d(col="#cccccc") # setup background light3d() # setup head-light # Importing animal data (created with wisp) terrain<-dget(system.file("demodata/region.dat",package="rgl")) pop<-dget(system.file("demodata/population.dat",package="rgl")) # Define colors for terrain zlim <- range(terrain) colorlut <- terrain.colors(82) col1 <- colorlut[9*sqrt(3.6*(terrain-zlim[1])+2)] # Set color to (water-)blue for regions with zero 'altitude' col1[terrain==0]<-"#0000FF" # Add terrain surface shape (i.e. population density): surface3d( 1:100,seq(1,60,length=100),terrain, col=col1,spec="#000000", ambient="#333333", back="lines" ) # Define colors for simulated populations (males:blue, females:red): col2<-pop[,4] col2[col2==0]<-"#3333ff" col2[col2==1]<-"#ff3333" # Add simulated populations as sphere-set shape spheres3d( pop[,1], pop[,2], terrain[cbind( ceiling(pop[,1]),ceiling(pop[,2]*10/6) )]+0.5, radius=0.2*pop[,3], col=col2, alpha=(1-(pop[,5])/10 ) ) } rgl.demo.abundance() rgl/tools/0000755000176200001440000000000014100762641012177 5ustar liggesusersrgl/tools/winlibs.R0000644000176200001440000000060714100762641013774 0ustar liggesusersVERSION <- commandArgs(TRUE) if(!file.exists(sprintf("../windows/freetype-%s/include/freetype2/ft2build.h", VERSION))){ if(getRversion() < "3.3.0") setInternet2() download.file(sprintf("https://github.com/rwinlib/freetype/archive/v%s.zip", VERSION), "lib.zip", quiet = TRUE) dir.create("../windows", showWarnings = FALSE) unzip("lib.zip", exdir = "../windows") unlink("lib.zip") } rgl/README.md0000644000176200001440000001542714146473076012342 0ustar liggesusers # RGL - 3D visualization device system for R using OpenGL ![](man/figures/READMEpolyhedra-1-rgl.png) ## INTRODUCTION The RGL package is a visualization device system for R, using OpenGL or WebGL as the rendering backend. An OpenGL rgl device at its core is a real-time 3D engine written in C++. It provides an interactive viewpoint navigation facility (mouse + wheel support) and an R programming interface. WebGL, on the other hand, is rendered in a web browser; rgl produces the input file, and the browser shows the images. ## WEBSITE A `pkgdown` website is here: The unreleased development version website is here: See [this vignette](https://dmurdoch.github.io/rgl/dev/articles/pkgdown.html) for details on producing your own `pkgdown` website that includes `rgl` graphics. The currently active development site is here: ## NOTE ABOUT DEVEL VERSIONS `rgl` can make use of development versions of some packages: `webshot2`, `chromote`, `pkgdown`. Though it doesn’t require any of these, they each provide some nice features: - `webshot2` and `chromote` support good quality PNG snapshots of `rgl` scenes, even on servers that don’t have a graphics display. - The devel version of `pkgdown` supports inclusion of `rgl` graphics in example code in automatically built package websites. (It also supports inclusion of `htmlwidgets` for other dynamic web packages like `plotly`, `leaflet`, etc.) Unfortunately, being development versions, these packages sometimes introduce bugs that break `rgl` usage. Currently (November 8, 2021) the main branches of all packages are fine. I recommend the following code to install them: ``` r remotes::install_github(c("rstudio/webshot2", "rstudio/chromote", "r-lib/pkgdown")) ``` ## INSTALLATION Most users will want to install the latest CRAN release. For Windows, macOS and some Linux platforms, installation can be easy, as CRAN distributes binary versions: # Install latest release from CRAN install.packages("rgl") To install the latest development version from Github, you’ll need to do a source install. Those aren’t easy! Try # Install development version from Github remotes::install_github("dmurdoch/rgl") If that fails, read the instructions below. ## LICENSE The software is released under the GNU Public License. See [COPYING](./COPYING) for details. ## FEATURES - portable R package using OpenGL (if available) on macOS, Win32 and X11 - can produce 3D graphics in web pages using WebGL - R programming interface - interactive viewpoint navigation - automatic data focus - geometry primitives: points, lines, triangles, quads, texts, point sprites - high-level geometry: surface, spheres - up to 8 light sources - alpha-blending (transparency) - side-dependent fill-mode rendering (dots, wired and filled) - texture-mapping with mipmapping and environment mapping support - environmental effects: fogging, background sphere - bounding box with axis ticks marks - undo operation: shapes and light-sources are managed on type stacks, where the top-most objects can be popped, or any item specified by an identifier can be removed ## PLATFORMS macOS Windows 7/10 Unix-derivatives ## BUILD TOOLS R recommended tools (gcc toolchain) On Windows, Rtools40 (or earlier versions for pre-R-4.0.0) ## REQUIREMENTS **For OpenGL display:** Windowing System (unix/x11 or Windows) OpenGL Library OpenGL Utility Library (GLU) **For WebGL display:** A browser with WebGL enabled. See . ## Installing OpenGL support **Debian:** aptitude install libgl1-mesa-dev libglu1-mesa-dev **Fedora:** yum install mesa-libGL-devel mesa-libGLU-devel libpng-devel **macOS:** Install XQuartz. `rgl` should work with XQuartz 2.7.11 or newer, but it will probably need rebuilding if the XQuartz version changes. XQuartz normally needs re-installation whenever the macOS version changes. **Windows:** Windows normally includes OpenGL support, but to get the appropriate include files etc., you will need the appropriate version of [Rtools](https://cran.r-project.org/bin/windows/Rtools/) matched to your R version. ## Options The **libpng** library version 1.2.9 or newer is needed for pixmap import/export support. The **freetype** library is needed for resizable anti-aliased fonts. On Windows, it will be downloaded from during the install. ## BUILDING/INSTALLING Binary builds of `rgl` are available for some platforms on CRAN. For source builds, install the prerequisites as described above, download the tarball and at the command line run R CMD INSTALL rgl_0.108.3.tar.gz (with the appropriate version of the tarball). The build uses an `autoconf` configure script; to see the options, expand the tarball and run `./configure --help`. Alternatively, in R run install.packages("rgl") to install from CRAN, or remotes::install_github("dmurdoch/rgl") to install the development version from Github. Sometimes binary development versions are available for Windows and macOS using install.packages("rgl", repos = "https://dmurdoch.github.io/drat", type = "binary") but these are not always kept up to date. ## BUILDING WITHOUT OPENGL As of version 0.104.1, it is possible to build the package without OpenGL support on Unix-alikes (including macOS) with the configure option –disable-opengl For example, R CMD INSTALL --configure-args="--disable-opengl" rgl_0.108.3.tar.gz On Windows, OpenGL support cannot currently be disabled. ## DOCUMENTATION and DEMOS: library(rgl) browseVignettes("rgl") demo(rgl) ## CREDITS Daniel Adler Duncan Murdoch Oleg Nenadic Simon Urbanek Ming Chen Albrecht Gebhardt Ben Bolker Gabor Csardi Adam Strzelecki Alexander Senger The R Core Team for some code from R. Dirk Eddelbuettel The authors of Shiny for their private RNG code. The authors of `knitr` for their graphics inclusion code. Jeroen Ooms for `Rtools40` and `FreeType` help. Yohann Demont for Shiny code, suggestions, and testing. Joshua Ulrich for a lot of help with the Github migration. Xavier Fernandez i Marin for help debugging the build. George Helffrich for draping code. Ivan Krylov for window_group code in X11. Michael Sumner for as.mesh3d.default enhancement. Tomas Kalibera for `winutf8` help. rgl/man/0000755000176200001440000000000014146473375011627 5ustar liggesusersrgl/man/snapshot.Rd0000644000176200001440000000656014100762641013747 0ustar liggesusers\name{snapshot3d} \alias{rgl.snapshot} \alias{snapshot3d} \title{Export screenshot} \description{ Saves the screenshot to a file. } \usage{ rgl.snapshot( filename, fmt = "png", top = TRUE ) snapshot3d( filename = tempfile(fileext = ".png"), fmt = "png", top = TRUE, ..., scene, width = NULL, height = NULL, webshot = TRUE) } \arguments{ \item{filename}{path to file to save.} \item{fmt}{image export format, currently supported: png. Ignored if \code{webshot = TRUE}. } \item{top}{whether to call \code{\link{rgl.bringtotop}}. Ignored if \code{webshot = TRUE}.} \item{...}{arguments to pass to \code{webshot2::webshot} } \item{scene}{an optional result of \code{\link{scene3d}} or \code{\link{rglwidget}} to plot} \item{width, height}{optional specifications of output size in pixels} \item{webshot}{Use the \pkg{webshot2} package to take the snapshot} } \details{ \code{rgl.snapshot()} is a low-level function that copies the current RGL window from the screen. Users should use \code{snapshot3d()} instead; it is more flexible, and (if \pkg{webshot2} is installed) can take images even if no window is showing, and they can be larger than the physical screen. Animations can be created in a loop modifying the scene and saving each screenshot to a file. Various graphics programs (e.g. ImageMagick) can put these together into a single animation. (See \code{\link{movie3d}} or the example below.) } \value{ These functions are mainly called for the side effects. The filename of the saved file is returned invisibly. } \note{ When \code{rgl.useNULL()} is \code{TRUE}, only \code{webshot = TRUE} will produce a snapshot. It requires the \pkg{webshot2} package, which as of this writing is not available on CRAN; to install it, use \code{remotes::install_github("rstudio/webshot2")} \code{rgl.snapshot} works by taking an image from the displayed window on-screen. On some systems, the snapshot will include content from other windows if they cover the active RGL window. Setting \code{top = TRUE} (the default) will use \code{\link{rgl.bringtotop}} before the snapshot to avoid this. There are likely limits to how large \code{width} and \code{height} can be set based on the display hardware; if these are exceeded the results are undefined. A typical result is that the snapshot will still be made but at a smaller size. There are slight differences between the displays with \code{webshot = TRUE} and \code{webshot = FALSE}, as the former are rendered using WebGL while the latter are rendered using OpenGL. Often the \code{webshot = TRUE} displays have better quality. } \seealso{\code{\link{movie3d}}, \code{\link{rgl.viewpoint}}} \examples{ if (interactive() && !in_pkgdown_example()) { saveopts <- options(rgl.useNULL = TRUE) plot3d(matrix(rnorm(300), ncol = 3, dimnames = list(NULL, c("x", "y", "z"))), col = "red") options(saveopts) browseURL(snapshot3d()) } \dontrun{ # # create animation # shade3d(oh3d(), color = "red") rgl.bringtotop() view3d(0, 20) olddir <- setwd(tempdir()) for (i in 1:45) { view3d(i, 20) filename <- paste("pic", formatC(i, digits = 1, flag = "0"), ".png", sep = "") snapshot3d(filename) } ## Now run ImageMagick in tempdir(). Use 'convert' instead of 'magick' ## if you have an older version of ImageMagick: ## magick -delay 10 *.png -loop 0 pic.gif setwd(olddir) } } \keyword{dynamic} rgl/man/import.Rd0000644000176200001440000000062614100762640013416 0ustar liggesusers\name{import} \alias{\%>\%} \alias{pipe} \docType{import} \title{Imported from magrittr} \description{ This object is imported from \pkg{magrittr}. Follow the link to its documentation. \describe{ \item{magrittr}{\code{\link[magrittr:pipe]{\%>\%}}} } Pipes can be used to string together \code{\link{rglwidget}} calls and \code{\link{playwidget}} calls. See \code{\link{ageControl}} for an example. } rgl/man/rgl.Sweave.Rd0000644000176200001440000000631514100762641014123 0ustar liggesusers\name{rgl.Sweave} \alias{rgl.Sweave} \alias{rgl.Sweave.off} \alias{Sweave.snapshot} \title{ Integrating RGL with Sweave } \description{ As of \R 2.13.0, it is possible to include RGL graphics into a \link{Sweave} document. These functions support that integration. } \usage{ Sweave.snapshot() rgl.Sweave(name, width, height, options, ...) rgl.Sweave.off() } \arguments{ \item{name, width, height, options, ...}{ These arguments are passed by \code{\link{Sweave}} to \code{rgl.Sweave} when it opens the device. } } \details{ The \code{rgl.Sweave} function is not normally called by the user. The user specifies it as the graphics driver when opening the code chunk, e.g. by using \preformatted{<>=} When the RGL device is closed at the end of the code chunk, \code{rgl.Sweave.off()} will be called automatically. It will save a snapshot of the last image (by default in \file{.png} format) for inclusion in the Sweave document and (by default) close the device. Alternatively, the \code{Sweave.snapshot()} function can be called to save the image before the end of the chunk. Only one snapshot will be taken per chunk. Several chunk options are used by the \code{rgl.Sweave} device: \describe{ \item{stayopen}{(default \code{FALSE}). If \code{TRUE} then the RGL device will \emph{not} be closed at the end of the chunk, instead a call to \code{Sweave.snapshot()} will be used if it has not been called explicitly. Subsequent chunks can add to the scene.} \item{outputtype}{(default \code{png}). The output may be specified as \code{outputtype = pdf} or \code{outputtype = eps} instead, in which case the \code{\link{rgl.postscript}} function will be used to write output in the specified format. Note that \code{\link{rgl.postscript}} has limitations and does not always render scenes correctly.} \item{delay}{(default 0.1). After creating the display window, \code{\link{Sys.sleep}} will be called to delay this many seconds, to allow the display system to initialize. This is needed in X11 systems which open the display asynchronously. If the default time is too short, \code{rgl.Sweave} may falsely report that the window is too large to open.} } } \note{ We recommend turning off all other graphics drivers in a chunk that uses \code{grdevice = rgl.Sweave}. The RGL functions do not write to a standard graphics device. } \note{ The \pkg{rgl} package relies on your graphics hardware to render OpenGL scenes, and the default \file{.png} output copies a bitmap from the hardware device. All such devices have limitations on the size of the bitmap, but they do not always signal these limitations in a way that RGL will detect. If you find that images are not being produced properly, try reducing the size using the \code{resolution}, \code{width} or \code{height} chunk options. } \value{ These functions are called for their side effects. } \author{ Duncan Murdoch } \seealso{ \code{\link{RweaveLatex}} for a description of alternate graphics drivers in Sweave, and standard options that can be used in code chunks. \code{\link{hook_rgl}} and \code{\link{hook_webgl}} allow fixed or interactive RGL scenes to be embedded in \pkg{knitr} documents. } \keyword{ utilities } rgl/man/rglwidget.Rd0000644000176200001440000001635014100762641014076 0ustar liggesusers\name{rglwidget} \alias{rglwidget} \alias{rgl.printRglwidget} \title{ An htmlwidget to hold an RGL scene } \description{ The \pkg{htmlwidgets} package provides a framework for embedding graphical displays in HTML documents of various types. This function provides the necessities to embed an RGL scene in one. } \usage{ rglwidget(x = scene3d(minimal), width = figWidth(), height = figHeight(), controllers = NULL, elementId = NULL, reuse = FALSE, webGLoptions = list(preserveDrawingBuffer = TRUE), shared = NULL, minimal = TRUE, webgl, snapshot, shinyBrush = NULL, ..., oldConvertBBox = FALSE) } \arguments{ \item{x}{ An RGL scene produced by the \code{\link[rgl]{scene3d}} function. } \item{width, height}{ The width and height of the display in pixels. } \item{controllers}{Names of \code{\link{playwidget}} objects associated with this scene, or objects (typically piped in). See Details below. } \item{snapshot,webgl}{Control of mode of display of scene. See Details below. } \item{elementId}{The id to use on the HTML \code{div} component that will hold the scene. } \item{reuse}{Ignored. See Details below. } \item{webGLoptions}{A list of options to pass to WebGL when the drawing context is created. See the Details below.} \item{shared}{An object produced by \code{\link{rglShared}}, or a list of such objects.} \item{minimal}{Should attributes be skipped if they currently have no effect? See \code{\link{scene3d}}.} \item{shinyBrush}{The name of a Shiny \code{input} element to receive information about mouse selections.} \item{oldConvertBBox}{See Details below.} \item{...}{Additional arguments to pass to \code{htmlwidgets::\link{createWidget}}.} } \details{ This produces a WebGL version of an RGL scene using the \pkg{htmlwidgets} framework. This allows display of the scene in the RStudio IDE, a browser, an \pkg{rmarkdown} document or in a \pkg{shiny} app. \code{options(rgl.printRglwidget = TRUE)} will cause \code{rglwidget()} to be called and displayed when the result of an RGL call that changes the scene is printed. In RMarkdown or in standalone code, you can use a \pkg{magrittr}-style \dQuote{pipe} command to join an \code{rglwidget} with a \code{\link{playwidget}} or \code{\link{toggleWidget}}. If the control widget comes first, it should be piped into the \code{controllers} argument. If the \code{rglwidget} comes first, it can be piped into the first argument of \code{playwidget} or \code{toggleWidget}. In earlier versions, the \code{reuse} argument let one output scene share data from earlier ones. This is no longer supported. If \code{elementId} is \code{NULL} and we are not in a Shiny app, \code{elementId} is set to a random value to facilitate re-use of information. To save the display to a file, use \code{htmlwidgets::\link{saveWidget}}. This requires \command{pandoc} to be installed. For a snapshot, you can use \code{htmltools::save_html(img(src=rglwidget(snapshot=TRUE)), file = ...)}. The \code{webGLoptions} argument is a list which will be passed when the WebGL context is created. See the WebGL 1.0 specification on \url{https://www.khronos.org/registry/webgl/specs/} for possible settings. The default in \code{rglwidget} differs from the WebGL default by setting \code{preserveDrawingBuffer = TRUE} in order to allow other tools to read the image, but please note that some implementations of WebGL contain bugs with this setting. We have attempted to work around them, but may change our default in the future if this proves unsatisfactory. The \code{webgl} argument controls whether a dynamic plot is displayed in HTML. In LaTeX and some other formats dynamic plots can't be displayed, so if the \code{snapshot} argument is \code{TRUE}, \code{webgl} must be \code{FALSE}. (In previous versions of the \pkg{rgl} package, both \code{webgl} and \code{snapshot} could be \code{TRUE}; that hasn't worked for a while and is no longer allowed as of version 0.105.6.) The \code{snapshot} argument controls whether a snapshot is displayed: it must be \code{!webgl} if both are specified. Prior to \pkg{rgl} 0.106.21, \code{rglwidget} converted bounding box decorations into separate objects: a box, text for the labels, segments for the ticks. By default it now generates these in Javascript, allowing axis labels to move as they do in the display in \R. If you prefer the old conversion, set \code{oldConvertBBox = TRUE}. } \section{Shiny specifics}{ This widget is designed to work with Shiny for interactive displays linked to a server running R. In a Shiny app, there will often be one or more \code{\link{playwidget}} objects in the app, taking input from the user. In order to be sure that the initial value of the user control is reflected in the scene, you should list all players in the \code{controllers} argument. See the sample application in \code{system.file("shinyDemo", package = "rglwidget")} for an example. In Shiny, it is possible to find out information about mouse selections by specifying the name of an \code{input} item in the \code{shinyBrush} argument. For example, with \code{shinyBrush = "brush3d"}, each change to the mouse selection will send data to \code{input$brush3d} in an object of class \code{"rglMouseSelection"} with the following components: \describe{ \item{subscene}{The ID of the subscene where the mouse is selecting.} \item{state}{Either \code{"changing"} or \code{"inactive"}.} \item{region}{The coordinates of the corners of the selected region in the window, in order \code{c(x1, y1, x2, y2)}.} \item{model, proj, view}{The model matrix, projection matrix and viewport in effect at that location.} } This object can be used as the first argument to \code{\link{selectionFunction3d}} to produce a test function for whether a particular location is in the selected region. If the brush becomes inactive, an object containing only the \code{state} field will be sent, with value \code{"inactive"}. } \value{ An object of class \code{"htmlwidget"} (or \code{"shiny.tag.list"} if pipes are used) that will intelligently print itself into HTML in a variety of contexts including the R console, within R Markdown documents, and within Shiny output bindings. If objects are passed in the \code{shared} argument, then the widget will respond to selection and filtering applied to those as shared datasets. See \code{\link{rglShared}} for more details and an example. } \section{Appearance}{ The appearance of the display is set by the stylesheet in \code{system.file("htmlwidgets/lib/rglClass/rgl.css")}. The widget is of class \code{rglWebGL}, with id set according to \code{elementId}. (As of this writing, no special settings are given for class \code{rglWebGL}, but you can add your own.) } \author{ Duncan Murdoch } \seealso{ \code{\link{hook_webgl}} for an earlier approach to this problem. \code{\link{rglwidgetOutput}} for Shiny details. } \examples{ save <- getOption("rgl.useNULL") options(rgl.useNULL=TRUE) example("plot3d", "rgl") widget <- rglwidget() if (interactive() || in_pkgdown_example()) widget \donttest{ if (interactive() && !in_pkgdown_example()) { # Save it to a file. This requires pandoc filename <- tempfile(fileext = ".html") htmlwidgets::saveWidget(rglwidget(), filename) browseURL(filename) } } } rgl/man/persp3d.deldir.Rd0000644000176200001440000000517614145464133014740 0ustar liggesusers\name{persp3d.deldir} \alias{persp3d.deldir} \alias{plot3d.deldir} \alias{as.mesh3d.deldir} \title{ Plot a Delaunay triangulation } \description{ The \code{\link[deldir]{deldir}()} function in the \pkg{deldir} package computes a Delaunay triangulation of a set of points. These functions display it as a surface. } \usage{ \method{plot3d}{deldir}(x, ...) \method{persp3d}{deldir}(x, ..., add = FALSE) \method{as.mesh3d}{deldir}(x, col = "gray", coords = c("x", "y", "z"), smooth = TRUE, normals = NULL, texcoords = NULL, ...) } \arguments{ \item{x}{ A \code{"deldir"} object, produced by the \code{\link[deldir]{deldir}()} function. It must contain \code{z} values. } \item{add}{ Whether to add surface to existing plot (\code{add = TRUE}) or create a new plot (\code{add = FALSE}, the default). } \item{col}{ Colors to apply to each vertex in the triangulation. Will be recycled as needed. } \item{coords}{ See Details below. } \item{smooth}{ Whether to average normals at vertices for a smooth appearance. } \item{normals}{ User-specified normals at each vertex. Requires \code{smooth = FALSE}. } \item{texcoords}{ Texture coordinates at each vertex. } \item{...}{ See Details below. } } \details{ These functions construct a \code{\link{mesh3d}} object corresponding to the triangulation in \code{x}. The \code{plot3d} and \code{persp3d} methods plot it. The \code{coords} parameter allows surfaces to be plotted over any coordinate plane. It should be a permutation of the column names \code{c("x", "y", "z")} from the \code{"deldir"} object. The first will be used as the x coordinate, the second as the y coordinate, and the third as the z coordinate. The \code{...} parameters in \code{plot3d.deldir} are passed to \code{persp3d.deldir}; in \code{persp3d.deldir} they are passed to both \code{as.mesh3d.deldir} and \code{persp3d.mesh3d}; in \code{as.mesh3d.deldir} they are used as material parameters in a \code{\link{tmesh3d}} call. } \examples{ x <- rnorm(200, sd = 5) y <- rnorm(200, sd = 5) r <- sqrt(x^2 + y^2) z <- 10 * sin(r)/r col <- cm.colors(20)[1 + round(19*(z - min(z))/diff(range(z)))] save <- options(rgl.meshColorWarning = FALSE) # This code is awkward: to work with demo(rglExamples), # we need auto-printing of the plots. This means we # have to repeat the test for deldir. haveDeldir <- checkDeldir() if (haveDeldir) { dxyz <- deldir::deldir(x, y, z = z, suppressMsge = TRUE) persp3d(dxyz, col = col) } if (haveDeldir) { open3d() # Do it without smoothing and with a different orientation. persp3d(dxyz, col = col, coords = c("z", "x", "y"), smooth = FALSE) } options(save) } \keyword{graphics} rgl/man/rgl.setAxisCallback.Rd0000644000176200001440000000525414137472630015735 0ustar liggesusers\name{rgl.setAxisCallback} \alias{rgl.setAxisCallback} \alias{rgl.getAxisCallback} \title{ User-defined axis labelling callbacks. } \description{ These are low level functions to set or get user-defined axis labelling callbacks in R. } \usage{ rgl.setAxisCallback(axis, draw = NULL, dev = cur3d(), subscene = currentSubscene3d(dev)) rgl.getAxisCallback(axis, dev = cur3d(), subscene = currentSubscene3d(dev)) } \arguments{ \item{axis}{ Which axis? Can be value from \code{1:3}. } \item{draw}{ The function to draw the axis. See Details below. } \item{dev, subscene}{ The RGL device and subscene to work with. } } \details{ This function only works if a bounding box decoration (set by \code{\link{bbox3d}}, for example) exists. When it tries to label the axis specified in \code{rgl.setAxisCallback}, it will call \code{draw}, which is assumed to be a function with header \code{function(margin)}. The \code{margin} argument will be a single string like \code{"x++"}, indicating that RGL is drawing the x axis, and suggests putting it on the edge represented by the high values of the other two axes. The function may use \code{\link{par3d}("bbox")} to determine the current size of the bounding box and should draw an appropriate axis. See \code{\link{mtext3d}} for a discussion of drawing in the margins. The box outlining the plot region will always be drawn, but can be made invisible by setting \code{front = "cull", back = "cull"} in the call to \code{\link{bbox3d}}. } \value{ Called for the side effect of setting the callback. The set function returns \code{NULL} invisibly. } \seealso{\code{\link{setAxisCallbacks}} to work with \code{\link{rglwidget}}. } \author{ Duncan Murdoch } \examples{ datelabels <- local({ id <- 0 bbox <- NULL function(margin) { # Only need to redraw when the bbox changes if (!identical(bbox, par3d("bbox"))) { if (id > 0) pop3d(id = id) axis <- match(substr(margin, 1, 1), c("x", "y", "z")) range <- as.Date(par3d("bbox")[2*axis + (-1):0], origin = "1970-01-01") where <- pretty(range) where <- where[range[1] <= where & where <= range[2]] id <<- mtext3d(format(where, format="\%b \%d"), margin, at = where, line = 1) bbox <<- par3d("bbox") } } }) # This doesn't work in WebGL displays if (!in_pkgdown_example()) { xyz <- cbind(Sys.Date() + rnorm(10, mean = 10), rnorm(10), rnorm(10)) open3d() # The default plots dates numerically: plot3d(xyz, xlab = "Date", ylab = "y", zlab = "z") rgl.setAxisCallback(1, datelabels) # Repeat the data 5 days later points3d(xyz + rep(c(5, 0, 0), each = 10)) # Make the plot square again aspect3d(1,1,1) } } rgl/man/light.Rd0000644000176200001440000000510514145447077013225 0ustar liggesusers\name{light} \alias{rgl.light} \alias{light3d} \title{Add light source} \description{ add a light source to the scene. } \usage{ light3d(theta = 0, phi = 15, x = NULL, ...) rgl.light( theta = 0, phi = 0, viewpoint.rel = TRUE, ambient = "#FFFFFF", diffuse = "#FFFFFF", specular = "#FFFFFF", x = NULL, y = NULL, z = NULL) } \arguments{ \item{theta, phi}{polar coordinates, used by default} \item{viewpoint.rel}{logical, if TRUE light is a viewpoint light that is positioned relative to the current viewpoint} \item{ambient, diffuse, specular }{ light color values used for lighting calculation } \item{x, y, z}{cartesian coordinates, optional} \item{...}{generic arguments passed through to RGL-specific (or other) functions} } \details{ Up to 8 light sources are supported. They are positioned either in world space or relative to the camera. By providing polar coordinates to theta and phi a directional light source is used. If numerical values are given to x, y and z, a point-like light source with finite distance to the objects in the scene is set up. If \code{x} is non-null, \code{\link{xyz.coords}} will be used to form the location values, so all three coordinates can be specified in \code{x}. See \code{\link{material3d}} for a discussion of how the components of the light affect the display of objects. } \value{ This function is called for the side effect of adding a light. A light ID is returned to allow \code{\link{pop3d}} to remove it. } \seealso{ \code{\link{rgl.clear}} \code{\link{pop3d}} } \examples{ # # a lightsource moving through the scene # data(volcano) z <- 2 * volcano # Exaggerate the relief x <- 10 * (1:nrow(z)) # 10 meter spacing (S to N) y <- 10 * (1:ncol(z)) # 10 meter spacing (E to W) zlim <- range(z) zlen <- zlim[2] - zlim[1] + 1 colorlut <- terrain.colors(zlen) # height color lookup table col <- colorlut[ z - zlim[1] + 1 ] # assign colors to heights for each point open3d() bg3d("gray50") surface3d(x, y, z, color = col, back = "lines") r <- max(y) - mean(y) lightid <- spheres3d(1, 1, 1, alpha = 0) frame <- function(time) { a <- pi*(time - 1) save <- par3d(skipRedraw = TRUE) clear3d(type = "lights") pop3d(id = lightid) xyz <- matrix(c(r*sin(a) + mean(x), r*cos(a) + mean(y), max(z)), ncol = 3) light3d(x = xyz, diffuse = "gray75", specular = "gray75", viewpoint.rel = FALSE) light3d(diffuse = "gray10", specular = "gray25") lightid <<- spheres3d(xyz, emission = "white", radius = 4) par3d(save) Sys.sleep(0.02) NULL } play3d(frame, duration = 2) } \keyword{dynamic} rgl/man/matrices.Rd0000644000176200001440000001103014145464133013707 0ustar liggesusers\name{matrices} \alias{matrices} \alias{identityMatrix} \alias{scaleMatrix} \alias{translationMatrix} \alias{rotationMatrix} \alias{scale3d} \alias{translate3d} \alias{rotate3d} \alias{transform3d} \alias{asHomogeneous} \alias{asEuclidean} \alias{asHomogeneous2} \alias{asEuclidean2} \title{Work with homogeneous coordinates } \description{ These functions construct 4x4 matrices for transformations in the homogeneous coordinate system used by OpenGL, and translate vectors between homogeneous and Euclidean coordinates. } \usage{ identityMatrix() scaleMatrix(x, y, z) translationMatrix(x, y, z) rotationMatrix(angle, x, y, z, matrix) asHomogeneous(x) asEuclidean(x) asHomogeneous2(x) asEuclidean2(x) scale3d(obj, x, y, z, ...) translate3d(obj, x, y, z, ...) rotate3d(obj, angle, x, y, z, matrix, ...) transform3d(obj, matrix, ...) } \arguments{ \item{x, y, z, angle, matrix}{See details} \item{obj}{An object to be transformed} \item{...}{Additional parameters to be passed to methods} } \details{ OpenGL uses homogeneous coordinates to handle perspective and affine transformations. The homogeneous point \code{(x, y, z, w)} corresponds to the Euclidean point \code{(x/w, y/w, z/w)}. The matrices produced by the functions \code{scaleMatrix}, \code{translationMatrix}, and \code{rotationMatrix} are to be left-multiplied by a row vector of homogeneous coordinates; alternatively, the transpose of the result can be right-multiplied by a column vector. The generic functions \code{scale3d}, \code{translate3d} and \code{rotate3d} apply these transformations to the \code{obj} argument. The \code{transform3d} function is a synonym for \code{rotate3d(obj, matrix = matrix)}. By default, it is assumed that \code{obj} is a row vector (or a matrix of row vectors) which will be multiplied on the right by the corresponding matrix, but users may write methods for these generics which operate differently. Methods are supplied for \code{\link{mesh3d}} objects. To compose transformations, use matrix multiplication. The effect is to apply the matrix on the left first, followed by the one on the right. \code{identityMatrix} returns an identity matrix. \code{scaleMatrix} scales each coordinate by the given factor. In Euclidean coordinates, \code{(u, v, w)} is transformed to \code{(x*u, y*v, z*w)}. \code{translationMatrix} translates each coordinate by the given translation, i.e. \code{(u, v, w)} is transformed to \code{(u + x, v + y, w + z)}. \code{rotationMatrix} can be called in three ways. With arguments \code{angle, x, y, z} it represents a rotation of \code{angle} radians about the axis \code{x, y, z}. If \code{matrix} is a 3x3 rotation matrix, it will be converted into the corresponding matrix in 4x4 homogeneous coordinates. Finally, if a 4x4 matrix is given, it will be returned unchanged. (The latter behaviour is used to allow \code{transform3d} to act like a generic function, even though it is not.) Use \code{asHomogeneous(x)} to convert the Euclidean vector \code{x} to homogeneous coordinates, and \code{asEuclidean(x)} for the reverse transformation. These functions accept the following inputs: \itemize{ \item n x 3 matrices: rows are assumed to be Euclidean \item n x 4 matrices: rows are assumed to be homogeneous \item vectors of length 3n or 4n: assumed to be vectors concatenated. For the ambiguous case of vectors that are length 12n (so both 3n and 4n are possible), the assumption is that the conversion is necessary: \code{asEuclidean} assumes the vectors are homogeneous, and \code{asHomogeneous} assumes the vectors are Euclidean. } Outputs are n x 4 or n x 3 matrices for \code{asHomogeneous} and \code{asEuclidean} respectively. The functions \code{asHomogeneous2} and \code{asEuclidean2} act similarly, but they assume inputs are 3 x n or 4 x n and outputs are in similar shapes. } \value{ \code{identityMatrix}, \code{scaleMatrix}, \code{translationMatrix}, and \code{rotationMatrix} produce a 4x4 matrix representing the requested transformation in homogeneous coordinates. \code{scale3d}, \code{translate3d} and \code{rotate3d} transform the object and produce a new object of the same class. } \author{ Duncan Murdoch } \seealso{\code{\link{par3d}} for a description of how RGL uses matrices in rendering.} \examples{ # A 90 degree rotation about the x axis: rotationMatrix(pi/2, 1, 0, 0) # Find what happens when you rotate (2, 0, 0) by 45 degrees about the y axis: x <- asHomogeneous(c(2, 0, 0)) y <- x \%*\% rotationMatrix(pi/4, 0, 1, 0) asEuclidean(y) # or more simply... rotate3d(c(2, 0, 0), pi/4, 0, 1, 0) } \keyword{ dynamic } rgl/man/mergeVertices.Rd0000644000176200001440000000301214100762640014700 0ustar liggesusers\name{mergeVertices} \alias{mergeVertices} \title{ Merge duplicate vertices in mesh object } \description{ A mesh object can have the same vertex listed twice. Each copy is allowed to have separate normals, texture coordinates, and color. However, it is more efficient to have just a single copy if those differences aren't needed. For automatic smoothing using \code{\link{addNormals}}, triangles and quads need to share vertices. This function merges identical (or similar) vertices to achieve this. } \usage{ mergeVertices(mesh, notEqual = NULL, attribute = "vertices", tolerance = sqrt(.Machine$double.eps)) } \arguments{ \item{mesh}{ A \code{\link{mesh3d}} object. } \item{notEqual}{ A logical matrix indicating that certain pairs should not be merged even if they appear identical. } \item{attribute}{ Which attribute(s) should be considered in comparing vertices? A vector chosen from \code{c("vertices", "colors", "normals", "texcoords"))} } \item{tolerance}{ When comparing vertices using \code{\link{all.equal}}, this tolerance will be used to ignore rounding error. } } \value{ A new mesh object. } \author{ Duncan Murdoch } \seealso{ \code{\link{as.mesh3d.rglId}}, which often constructs mesh objects containing a lot of duplication. } \examples{ open3d() (mesh1 <- cuboctahedron3d(col = rainbow(14), meshColor = "face")) id <- shade3d(mesh1) (mesh2 <- as.mesh3d(id)) shade3d(translate3d(mesh2, 3, 0, 0)) (mesh3 <- mergeVertices(mesh2)) shade3d(translate3d(mesh3, 6, 0, 0)) } rgl/man/playwidget.Rd0000644000176200001440000001350014100762641014251 0ustar liggesusers\name{playwidget} \alias{playwidget} \title{ Add a widget to play animations } \description{ This is a widget that can be put in a web page to allow animations with or without Shiny. } \usage{ playwidget(sceneId, controls, start = 0, stop = Inf, interval = 0.05, rate = 1, components = c("Reverse", "Play", "Slower", "Faster", "Reset", "Slider", "Label"), loop = TRUE, step = 1, labels = NULL, precision = 3, elementId = NULL, respondTo = NULL, reinit = NULL, buttonLabels = components, pause = "Pause", height = 40, ...) } \arguments{ \item{sceneId}{ The HTML id of the RGL scene being controlled, or an object. See the Details below. } \item{controls}{ A single \code{"rglControl"} object, e.g. \code{\link{propertyControl}}, or a list of several. } \item{start, stop}{ The starting and stopping values of the animation. If \code{labels} is supplied \code{stop} will default to step through the labels. } \item{interval}{ The requested interval (in seconds) between updates. Updates may occur at longer intervals. } \item{rate}{ The number of units of \dQuote{nominal} time per real world second. } \item{components}{ Which components should be displayed? See Details below. } \item{loop}{ When the player reaches the end of the interval, should it loop back to the beginning? } \item{step}{ Step size in the slider. } \item{labels}{ Optional labels to use, corresponding to slider steps. Set to \code{NULL} for auto-generated labels. } \item{precision}{ If \code{labels=NULL}, the precision to use when displaying timer values. } \item{elementId}{ The HTML id of the generated widget, containing buttons, slider, etc. } \item{respondTo}{ The HTML ID of a Shiny input control (e.g. a \code{\link[shiny]{sliderInput}} control) to respond to.} \item{reinit}{ A vector of ids that will need re-initialization before being drawn again. } \item{buttonLabels, pause}{ These are the labels that will be shown on the buttons if they are displayed. \code{pause} will be shown on the \code{"Play"} button while playing. } \item{height}{ The height of the widget in pixels. In a pipe, this is a relative height. } \item{...}{Additional arguments to pass to to \code{htmlwidgets::\link{createWidget}}.} } \details{ The \code{components} are buttons to control the animation, a slider for manual control, and a label to show the current value. They will be displayed in the order given in \code{components}. Not all need be included. The buttons have the following behaviour: \describe{ \item{Reverse}{Reverse the direction.} \item{Play}{Play the animation.} \item{Slower}{Decrease the playing speed.} \item{Faster}{Increase the playing speed.} \item{Reset}{Stop the animation and reset to the start value.} } If \code{respondTo} is used, no \code{components} are shown, as it is assumed Shiny (or whatever control is being referenced) will provide the UI components. The \code{sceneId} component can be another \code{playwidget}, a \code{\link{rglwidget}} result, or a result of \code{htmltools::\link[htmltools:builder]{tags}} or \code{htmltools::\link[htmltools:tag]{tagList}}. This allows you to use a \pkg{magrittr}-style \dQuote{pipe} command to join an \code{rglwidget} with one or more \code{\link{playwidget}}s. If a \code{playwidget} comes first, \code{sceneId} should be set to \code{NA}. If the \code{\link{rglwidget}} does not come first, previous values should be piped into its \code{controllers} argument. Other HTML code (including other widgets) can be used in the chain if wrapped in \code{htmltools::\link[htmltools:tag]{tagList}}. } \section{Appearance}{ The appearance of the controls is set by the stylesheet in \code{system.file("htmlwidgets/lib/rglClass/rgl.css")}. The overall widget is of class \code{rglPlayer}, with id set according to \code{elementId}. The buttons are of HTML class \code{rgl-button}, the slider is of class \code{rgl-slider}, and the label is of class \code{rgl-label}. Each element has an id prefixed by the widget id, e.g. \code{elementId-button-Reverse}, \code{elementId-slider}, etc. (where \code{elementId} should be replaced by the actual id). The \code{reinit} parameter handles the case where an object needs re-initialization after each change. For example, plane objects may need this if their intersection with the bounding box changes shape. Note that re-initialization is generally incompatible with the \code{\link{vertexControl}} as it modifies values which are set during initialization. } \value{ A widget suitable for use in an \pkg{Rmarkdown}-generated web page, or elsewhere. } \author{ Duncan Murdoch } \seealso{ \code{\link{subsetControl}}, \code{\link{propertyControl}}, \code{\link{ageControl}} and \code{\link{vertexControl}} are possible controls to use. \code{\link{toggleWidget}} is a wrapper for \code{playwidget} and \code{\link{subsetControl}} to insert a single button to toggle some elements in a display. } \examples{ saveopts <- options(rgl.useNULL = TRUE) objid <- plot3d(1:10, 1:10, rnorm(10), col=c("red", "red"), type = "s")["data"] control <- ageControl(value=0, births=1:10, ages = c(-5,0,5), colors = c("green", "yellow", "red"), objids = objid) \donttest{ # This example uses explicit names rglwidget(elementId = "theplot", controllers = "theplayer", height = 300, width = 300) playwidget("theplot", control, start = -5, stop = 5, rate = 3, elementId = "theplayer", components = c("Play", "Slider")) } # This example uses pipes, and can skip the names widget <- rglwidget(height = 300, width = 300) \%>\% playwidget(control, start = -5, stop = 5, rate = 3, components = c("Play", "Slider")) if (interactive() || in_pkgdown_example()) widget options(saveopts) } rgl/man/persp3d.Rd0000644000176200001440000001337614146471736013507 0ustar liggesusers\name{persp3d} \alias{persp3d} \alias{persp3d.default} \title{ Surface plots } \description{ This function draws plots of surfaces in 3-space. \code{persp3d} is a generic function.} \usage{ persp3d(x, \dots) \method{persp3d}{default}(x = seq(0, 1, len = nrow(z)), y = seq(0, 1, len = ncol(z)), z, xlim = NULL, ylim = NULL, zlim = NULL, xlab = NULL, ylab = NULL, zlab = NULL, add = FALSE, aspect = !add, forceClipregion = FALSE, ...) } \arguments{ \item{x, y, z}{points to plot on surface. See Details below.} \item{xlim, ylim, zlim}{x-, y- and z-limits. If present, the plot is clipped to this region.} \item{xlab, ylab, zlab}{titles for the axes. N.B. These must be character strings; expressions are not accepted. Numbers will be coerced to character strings.} \item{add}{whether to add the points to an existing plot.} \item{aspect}{either a logical indicating whether to adjust the aspect ratio, or a new ratio.} \item{forceClipregion}{force a clipping region to be used, whether or not limits are given.} \item{\dots}{additional material parameters to be passed to \code{\link{surface3d}} and \code{\link{decorate3d}}.} } \details{ The default method plots a surface defined as a grid of \code{(x,y,z)} locations in space. The grid may be specified in several ways: \itemize{ \item{As with \code{\link[graphics]{persp}}, \code{x} and \code{y} may be given as vectors in ascending order, with \code{z} given as a matrix. There should be one \code{x} value for each row of \code{z} and one \code{y} value for each column. The surface drawn will have \code{x} constant across rows and \code{y} constant across columns. This is the most convenient format when \code{z} is a function of \code{x} and \code{y} which are measured on a regular grid.} \item{\code{x} and \code{y} may also be given as matrices, in which case they should have the same dimensions as \code{z}. The surface will combine corresponding points in each matrix into locations \code{(x,y,z)} and draw the surface through those. This allows general surfaces to be drawn, as in the example of a spherical Earth shown below.} \item{If \code{x} is a \code{list}, its components \code{x$x}, \code{x$y} and \code{x$z} are used for \code{x}, \code{y} and \code{z} respectively, though an explicitly specified \code{z} value will have priority.}} One difference from \code{\link[graphics]{persp}} is that colors are specified on each vertex, rather than on each facet of the surface. To emulate the \code{\link[graphics]{persp}} color handling, you need to do the following. First, convert the color vector to an \code{(nx - 1)} by \code{(ny - 1)} matrix; then add an extra row before row 1, and an extra column after the last column, to convert it to \code{nx} by \code{ny}. (These extra colors will not be used). For example, \code{col <- rbind(1, cbind(matrix(col, nx - 1, ny - 1), 1))}. Finally, call \code{persp3d} with material property \code{smooth = FALSE}. See the \dQuote{Clipping} section in \code{\link{plot3d}} for more details on \code{xlim, ylim, zlim} and \code{forceClipregion}. } \value{ This function is called for the side effect of drawing the plot. A vector of shape IDs is returned invisibly. } \author{Duncan Murdoch} \seealso{\code{\link{plot3d}}, \code{\link{persp}}. There is a \code{\link{persp3d.function}} method for drawing functions, and \code{\link{persp3d.deldir}} can be used to draw surfaces defined by an irregular collection of points. A formula method \code{\link{persp3d.formula}} draws surfaces using this method. The \code{\link{surface3d}} function is used to draw the surface without the axes etc. } \examples{ # (1) The Obligatory Mathematical surface. # Rotated sinc function. x <- seq(-10, 10, length = 20) y <- x f <- function(x, y) { r <- sqrt(x^2 + y^2); 10 * sin(r)/r } z <- outer(x, y, f) z[is.na(z)] <- 1 open3d() # Draw the surface twice: the first draws the solid part, # the second draws the grid. Offset the first so it doesn't # obscure the lines. persp3d(x, y, z, aspect = c(1, 1, 0.5), col = "lightblue", xlab = "X", ylab = "Y", zlab = "Sinc( r )", polygon_offset = 1) persp3d(x, y, z, front = "lines", back = "lines", lit = FALSE, add = TRUE) highlevel() # trigger the plot # (2) Add to existing persp plot: xE <- c(-10, 10); xy <- expand.grid(xE, xE) points3d(xy[, 1], xy[, 2], 6, col = "red") lines3d(x, y = 10, z = 6 + sin(x), col = "green") phi <- seq(0, 2*pi, len = 201) r1 <- 7.725 # radius of 2nd maximum xr <- r1 * cos(phi) yr <- r1 * sin(phi) lines3d(xr, yr, f(xr, yr), col = "pink", lwd = 2) # (3) Visualizing a simple DEM model z <- 2 * volcano # Exaggerate the relief x <- 10 * (1:nrow(z)) # 10 meter spacing (S to N) y <- 10 * (1:ncol(z)) # 10 meter spacing (E to W) open3d() invisible(bg3d("slategray")) # suppress display material3d(col = "black") persp3d(x, y, z, col = "green3", aspect = "iso", axes = FALSE, box = FALSE) # (4) A globe lat <- matrix(seq(90, -90, len = 50)*pi/180, 50, 50, byrow = TRUE) long <- matrix(seq(-180, 180, len = 50)*pi/180, 50, 50) r <- 6378.1 # radius of Earth in km x <- r*cos(lat)*cos(long) y <- r*cos(lat)*sin(long) z <- r*sin(lat) open3d() persp3d(x, y, z, col = "white", texture = system.file("textures/worldsmall.png", package = "rgl"), specular = "black", axes = FALSE, box = FALSE, xlab = "", ylab = "", zlab = "", normal_x = x, normal_y = y, normal_z = z) \dontrun{ # This looks much better, but is slow because the texture is very big persp3d(x, y, z, col = "white", texture = system.file("textures/world.png", package = "rgl"), specular = "black", axes = FALSE, box = FALSE, xlab = "", ylab = "", zlab = "", normal_x = x, normal_y = y, normal_z = z) } } \keyword{ dynamic } \keyword{ graphics } rgl/man/viewpoint.Rd0000644000176200001440000000434114100762641014127 0ustar liggesusers\name{viewpoint} \alias{rgl.viewpoint} \alias{view3d} \title{Set up viewpoint} \description{ Set the viewpoint orientation. } \usage{ view3d( theta = 0, phi = 15, ...) rgl.viewpoint( theta = 0, phi = 15, fov = 60, zoom = 1, scale = par3d("scale"), interactive = TRUE, userMatrix, type = c("userviewpoint", "modelviewpoint") ) } \arguments{ \item{theta, phi}{polar coordinates} \item{...}{additional parameters to pass to \code{rgl.viewpoint}} \item{fov}{field-of-view angle in degrees} \item{zoom}{zoom factor} \item{scale}{real length 3 vector specifying the rescaling to apply to each axis} \item{interactive}{logical, specifying if interactive navigation is allowed} \item{userMatrix}{4x4 matrix specifying user point of view} \item{type}{which viewpoint to set?} } \details{ The data model can be rotated using the polar coordinates \code{theta} and \code{phi}. Alternatively, it can be set in a completely general way using the 4x4 matrix \code{userMatrix}. If \code{userMatrix} is specified, \code{theta} and \code{phi} are ignored. The pointing device of your graphics user-interface can also be used to set the viewpoint interactively. With the pointing device the buttons are by default set as follows: \describe{ \item{left}{adjust viewpoint position} \item{middle}{adjust field of view angle} \item{right or wheel}{adjust zoom factor} } The user's view can be set with \code{fov} and \code{zoom}. If the \code{fov} angle is set to 0, a parallel or orthogonal projection is used. Small non-zero values (e.g. 0.01 or less, but not 0.0) are likely to lead to rendering errors due to OpenGL limitations. Prior to version 0.94, all of these characteristics were stored in one viewpoint object. With that release the characteristics are split into those that affect the projection (the user viewpoint) and those that affect the model (the model viewpoint). By default, this function sets both, but the \code{type} argument can be used to limit the effect. } \seealso{\code{\link{par3d}}} \examples{ \dontrun{ # animated round trip tour for 10 seconds rgl.open() shade3d(oh3d(), color = "red") start <- proc.time()[3] while ((i <- 36*(proc.time()[3] - start)) < 360) { rgl.viewpoint(i, i/4); } } } \keyword{dynamic} rgl/man/expect_known_scene.Rd0000644000176200001440000000311314100762640015757 0ustar liggesusers\name{expect_known_scene} \alias{expect_known_scene} \title{ Helper for \pkg{testthat} testing. } \description{ Gets the current scene using \code{\link{scene3d}}, and compares the result to a saved value, optionally closing the window afterwards. } \usage{ expect_known_scene(name, close = TRUE, file = paste0("testdata/", name, ".rds"), ...) } \arguments{ \item{name}{ By default, the base name of the file to save results in. Not used if \code{file} is specified. } \item{close}{ Whether to close the \pkg{rgl} window after the comparison. } \item{file}{ The file in which to save the result. } \item{...}{ Other arguments which will be passed to \code{\link[testthat]{expect_known_value}}. } } \details{ This function uses \code{\link[testthat]{expect_known_value}} to save a representation of the scene. During the comparison, the scene is modified so that non-reproducible aspects are standardized or omitted: \itemize{ \item{object ids are changed to start at 1.} \item{system-specific font names and texture names are deleted.} \item{the window is shifted to the top left of the screen.} } Calls to \code{expect_known_scene()} enable \code{testthat::\link[testthat]{local_edition}(2)} for the duration of the call, so it will work in \pkg{testthat} \dQuote{3rd edition}. } \value{ A value describing the changes to the saved object, suitable for use in \code{\link[testthat]{test_that}()}. } \examples{ \dontrun{ # These lines can be included in testthat::test_that() code. plot3d(1:10, 1:10, 1:10) expect_known_scene("plot") } }rgl/man/GramSchmidt.Rd0000644000176200001440000000245414100762640014307 0ustar liggesusers\name{GramSchmidt} \alias{GramSchmidt} \title{ The Gram-Schmidt algorithm } \description{ Generate a 3x3 orthogonal matrix using the Gram-Schmidt algorithm. } \usage{ GramSchmidt(v1, v2, v3, order = 1:3) } \arguments{ \item{v1, v2, v3}{ Three length 3 vectors (taken as row vectors). } \item{order}{ The precedence order for the vectors; see Details. } } \details{ This function orthogonalizes the matrix \code{rbind(v1, v2, v3)} using the Gram-Schmidt algorithm. It can handle rank 2 matrices (returning a rank 3 matrix). If the original is rank 1, it is likely to fail. The \code{order} vector determines the precedence of the original vectors. For example, if it is \code{c(i, j, k)}, then row \code{i} will be unchanged (other than normalization); row \code{j} will normally be transformed within the span of rows \code{i} and \code{j}. Row \code{k} will be transformed orthogonally to the span of the others. } \value{ A 3x3 matrix whose rows are the orthogonalization of the original row vectors. } \author{ Duncan Murdoch } \examples{ # Proceed through the rows in order print(A <- matrix(rnorm(9), 3, 3)) GramSchmidt(A[1, ], A[2, ], A[3, ]) # Keep the middle row unchanged print(A <- matrix(c(rnorm(2), 0, 1, 0, 0, rnorm(3)), 3, 3, byrow = TRUE)) GramSchmidt(A[1, ], A[2, ], A[3, ], order = c(2, 1, 3)) } rgl/man/makeDependency.Rd0000644000176200001440000000556114146450032015022 0ustar liggesusers\name{makeDependency} \alias{makeDependency} \alias{RGL_DEBUGGING} \title{ Process Javascript for HTML dependency } \description{ A utility function to help in development of internal Javascript code, this function processes the Javascript to minify it and report on errors and bad style. } \usage{ makeDependency(name, src, script = NULL, package, version = packageVersion(package), minifile = paste0(basename(src), ".min.js"), debugging = FALSE, ...) } \arguments{ \item{name, src, script, package, version, ...}{ Arguments to pass to \code{htmltools::\link[htmltools]{htmlDependency}.} } \item{minifile}{Basename of minified file.} \item{debugging}{ See details below. } } \details{ This is a utility function used by RGL to process its Javascript code used when displaying \code{\link{rglwidget}} values. It may be helpful in other packages to use in their own installation. If the \pkg{js} package version 1.2 or greater is installed, the Javascript code will be minified and stored in the file named by \code{minifile} in the \code{src} directory. Syntax errors in the code will stop the process; unused variables will be reported. If \code{debugging} is \code{TRUE}, the locations of Javascript syntax errors will be reported, along with hints about improvements, and the original files will be used in the dependency object that is created. If \code{debugging} is \code{FALSE} (the default), the minified file will be used in the dependency object, hints won't be given, and syntax errors will lead to an uninformative failure to minify. } \value{ An object that can be included in a list of dependencies passed to \code{htmltools::\link[htmltools:htmlDependencies]{attachDependencies}}. } \author{ Duncan Murdoch } \examples{ \dontrun{ # This is the code used to produce one of the dependencies # for rglwidget(). # It writes to the system library copy of rgl so # has been marked not to run in the example code. makeDependency("rglwidgetClass", src = "htmlwidgets/lib/rglClass", script = c("rglClass.src.js", "utils.src.js", "buffer.src.js", "subscenes.src.js", "shaders.src.js", "textures.src.js", "projection.src.js", "mouse.src.js", "init.src.js", "pieces.src.js", "draw.src.js", "controls.src.js", "selection.src.js", "rglTimer.src.js", "pretty.src.js", "axes.src.js"), stylesheet = "rgl.css", package = "rgl", debugging = isTRUE(as.logical(Sys.getenv("RGL_DEBUGGING", "FALSE")))) } } rgl/man/setGraphicsDelay.Rd0000644000176200001440000000237214100762641015340 0ustar liggesusers\name{setGraphicsDelay} \alias{setGraphicsDelay} \alias{RGL_SLOW_DEV} \title{ Set a one-time slowdown on opening standard graphics } \description{ This function is mainly for internal use, to work around a bug in macOS Catalina: if base plotting happens too quickly after opening RGL and the first call to quartz, R crashes. This inserts a delay after the first call to open the graphics device. The default is no delay, unless on Catalina with no graphics device currently open but the \code{\link{quartz}} device set as the default, when a 1 second delay will be added. Use environment variable "RGL_SLOW_DEV = value" to set a different default delay. It works by changing the value of \code{\link{options}("device")}, so explicit calls to the device will not be affected. It is called automatically when the \pkg{rgl} package is loaded. } \usage{ setGraphicsDelay(delay = Sys.getenv("RGL_SLOW_DEV", 0), unixos = "none") } \arguments{ \item{delay}{ Number of seconds for the delay. } \item{unixos}{ The name of the Unix OS. If set to \code{"Darwin"}, and the version is 19.0.0 or greater, the default delay is changed to 1 second. } } \value{ Called for the side effect of adding the delay to the first opening of the graphics device. } rgl/man/arc3d.Rd0000644000176200001440000000643314100762640013102 0ustar liggesusers\name{arc3d} \alias{arc3d} \title{ Draw arcs } \description{ Given starting and ending points on a sphere and the center of the sphere, draw the great circle arc between the starting and ending points. If the starting and ending points have different radii, a segment of a logarithmic spiral will join them. } \usage{ arc3d(from, to, center, radius, n, circle = 50, base = 0, plot = TRUE, ...) } \arguments{ \item{from}{ One or more points from which to start arcs. } \item{to}{ One or more destination points. } \item{center}{ One or more center points. } \item{radius}{ If not missing, a vector of length \code{n} giving the radii at each point between \code{from} and \code{to}. If missing, the starting and ending points will be joined by a logarithmic spiral. } \item{n}{ If not missing, how many segments to use between the first and last point. If missing, a value will be calculated based on the angle between starting and ending points as seen from the center. } \item{circle}{ How many segments would be used if the arc went completely around a circle. } \item{base}{ See Details below. } \item{plot}{ Should the arcs be plotted, or returned as a matrix? } \item{\dots}{ Additional parameters to pass to \code{\link{points3d}}. } } \details{ If any of \code{from}, \code{to} or \code{center} is an n by 3 matrix with n > 1, multiple arcs will be drawn by recycling each of these parameters to the number of rows of the longest one. If the vector lengths of \code{from - center} and \code{to - center} differ, then instead of a spherical arc, the function will draw a segment of a logarithmic spiral joining the two points. By default, the arc is drawn along the shortest great circle path from \code{from} to \code{to}, but the \code{base} parameter can be used to modify this. If \code{base = 1} is used, the longer arc will be followed. Larger positive integer values will result in \code{base - 1} loops in that direction completely around the sphere. Negative values will draw the curve in the same direction as the shortest arc, but with \code{abs(base)} full loops. It doesn't make much sense to ask for such loops unless the radii of \code{from} and \code{to} differ, because spherical arcs would overlap. Normally the \code{base} parameter is left at its default value of \code{0}. When \code{base} is non-zero, the curve will be constructed in multiple pieces, between \code{from}, \code{to}, \code{-from} and \code{-to}, for as many steps as necessary. If \code{n} is specified, it will apply to each of these pieces. } \value{ If \code{plot = TRUE}, called mainly for the side effect of drawing arcs. Invisibly returns the object ID of the collection of arcs. If \code{plot = FALSE}, returns a 3 column matrix containing the points that would be drawn as the arcs. } \author{ Duncan Murdoch } \examples{ normalize <- function(v) v/sqrt(sum(v^2)) # These vectors all have the same length from <- t(apply(matrix(rnorm(9), ncol = 3), 1, normalize)) to <- normalize(rnorm(3)) center <- c(0, 0, 0) open3d() spheres3d(center, radius = 1, col = "white", alpha = 0.2) arc3d(from, to, center, col = "red") arc3d(from, 2*to, center, col = "blue") text3d(rbind(from, to, center, 2*to), text = c(paste0("from", 1:3), "to", "center", "2*to"), depth_mask = FALSE, depth_test = "always") } rgl/man/rgl.texts.Rd0000644000176200001440000001357114145464133014046 0ustar liggesusers\name{rgl.texts} \alias{rgl.texts} \alias{rglFonts} \title{ Low-level functions for plotting text } \description{ This is a low-level function for plotting text. Users should normally use the high-level function \code{\link{text3d}} instead. } \usage{ rgl.texts(x, y = NULL, z = NULL, text, adj = 0.5, pos = NULL, offset = 0.5, family = par3d("family"), font = par3d("font"), cex = par3d("cex"), useFreeType = par3d("useFreeType"), ...) rglFonts(...) } \arguments{ \item{x, y, z}{point coordinates. Any reasonable way of defining the coordinates is acceptable. See the function \code{\link[grDevices]{xyz.coords}} for details.} \item{text}{text character vector to draw} \item{adj}{ one value specifying the horizontal adjustment, or two, specifying horizontal and vertical adjustment respectively, or three, specifying adjustment in all three directions.} \item{pos}{ a position specifier for the text. If specified, this overrides any \code{adj} value given. Values of 0, 1, 2, 3, 4, 5 and 6 respectively indicate positions on, below, to the left of, above, to the right of, in front of and behind the specified coordinates.} \item{offset}{ when \code{pos} is specified, this value gives the offset of the label from the specified coordinate in fractions of a character width.} \item{ family }{A device-independent font family name, or "" } \item{ font }{A numeric font number from 1 to 4 } \item{ cex }{A numeric character expansion value } \item{ useFreeType }{logical. Should FreeType be used to draw text? (See details below.)} \item{ ... }{In \code{rgl.texts}, material properties; see \code{\link{rgl.material}} for details. In \code{rglFonts}, device dependent font definitions for use with FreeType.} } \details{ The \code{adj} parameter determines the position of the text relative to the specified coordinate. Use \code{adj = c(0, 0)} to place the left bottom corner at \code{(x, y, z)}, \code{adj = c(0.5, 0.5)} to center the text there, and \code{adj = c(1, 1)} to put the right top corner there. All coordinates default to \code{0.5}. Placement is done using the "advance" of the string and the "ascent" of the font relative to the baseline, when these metrics are known. } \section{Fonts}{ Fonts are specified using the \code{family}, \code{font}, \code{cex}, and \code{useFreeType} arguments. Defaults for the currently active device may be set using \code{\link{par3d}}, or for future devices using \code{\link{r3dDefaults}}. The \code{family} specification is the same as for standard graphics, i.e. families \cr \code{c("serif", "sans", "mono", "symbol")} \cr are normally available, but users may add additional families. \code{font} numbers are restricted to the range 1 to 4 for standard, bold, italic and bold italic respectively. Font 5 is recoded as family \code{"symbol"} font 1, but that is not supported unless specifically installed, so should be avoided. Using an unrecognized value for \code{"family"} will result in the system standard font as used in RGL up to version 0.76. That font is not resizable and \code{font} values are ignored. If \code{useFreeType} is \code{TRUE}, then RGL will use the FreeType anti-aliased fonts for drawing. This is generally desirable, and it is the default on non-Windows systems if RGL was built to support FreeType. FreeType fonts are specified using the \code{rglFonts} function. This function takes a vector of four filenames of TrueType font files which will be used for the four styles regular, bold, italic and bold italic. The vector is passed with a name to be used as the family name, e.g. \code{rglFonts(sans = c("/path/to/FreeSans.ttf", ...))}. In order to limit the file size, the \pkg{rgl} package ships with just 3 font files, for regular versions of the \code{serif}, \code{sans} and \code{mono} families. Additional free font files were available in the past from the Amaya project, though currently the \code{\link{rglExtrafonts}} function provides an easier way to register new fonts. On Windows the system fonts are acceptable and are used when \code{useFreeType = FALSE} (the current default in \code{\link{r3dDefaults}}). Mappings to \code{family} names are controlled by the \code{grDevices::windowsFonts()} function. Full pathnames should normally be used to specify font files. If relative paths are used, they are interpreted differently by platform. Currently Windows fonts are looked for in the Windows fonts folder, while other platforms use the current working directory. If FreeType fonts are not used, then bitmapped fonts will be used instead. On Windows these will be based on the fonts specified using the #ifdef windows \code{\link{windowsFonts}} #endif #ifndef windows \code{windowsFonts} #endif function, and are resizable. Other platforms will use the default bitmapped font which is not resizable. Bitmapped fonts have a limited number of characters supported; if any unsupported characters are used, an error will be thrown. } \value{ \code{rgl.texts} returns the object ID of the text object (or sprites, in case of \code{usePlotmath = TRUE}) invisibly. \code{rglFonts} returns the current set of font definitions. } \examples{ \dontrun{ # These FreeType fonts are available from the Amaya project, and are not shipped # with rgl. You would normally install them to the rgl/fonts directory # and use fully qualified pathnames, e.g. # system.file("fonts/FreeSerif.ttf", package = "rgl") rglFonts(serif = c("FreeSerif.ttf", "FreeSerifBold.ttf", "FreeSerifItalic.ttf", "FreeSerifBoldItalic.ttf"), sans = c("FreeSans.ttf", "FreeSansBold.ttf", "FreeSansOblique.ttf", "FreeSansBoldOblique.ttf"), mono = c("FreeMono.ttf", "FreeMonoBold.ttf", "FreeMonoOblique.ttf", "FreeMonoBoldOblique.ttf"), symbol= c("ESSTIX10.TTF", "ESSTIX12.TTF", "ESSTIX9_.TTF", "ESSTIX11.TTF")) } } rgl/man/axes3d.Rd0000644000176200001440000001502014137472630013274 0ustar liggesusers\name{axes3d} \alias{axes3d} \alias{axis3d} \alias{mtext3d} \alias{title3d} \alias{box3d} \title{ Draw boxes, axes and other text outside the data } \description{ These functions draw axes, boxes and text outside the range of the data. \code{axes3d}, \code{box3d} and \code{title3d} are the higher level functions; normally the others need not be called directly by users. } \usage{ axes3d(edges = "bbox", labels = TRUE, tick = TRUE, nticks = 5, box = FALSE, expand = 1.03, ...) box3d(...) title3d(main = NULL, sub = NULL, xlab = NULL, ylab = NULL, zlab = NULL, line = NA, level = NA, floating = NULL, ...) axis3d(edge, at = NULL, labels = TRUE, tick = TRUE, line = 0, pos = NULL, nticks = 5, ...) mtext3d(text, edge, at = NULL, line = 0, level = 0, floating = FALSE, pos = NA, ...) } \arguments{ \item{edges}{ a code to describe which edge(s) of the box to use; see Details below } \item{labels}{ whether to label the axes, or (for \code{axis3d}) the labels to use} \item{tick}{ whether to use tick marks } \item{nticks}{ suggested number of ticks } \item{box}{ draw the full box if \code{"bbox"} axes are used } \item{expand}{ how much to expand the box around the data } \item{main}{ the main title for the plot } \item{sub}{ the subtitle for the plot } \item{xlab, ylab, zlab}{ the axis labels for the plot } \item{line, level}{ the "line" of the plot margin to draw the label on, and "level" above or below it } \item{floating}{ which mode of axis labels? One of \code{TRUE}, \code{FALSE} or \code{NA}. (\code{NULL} may also be used in \code{title3d} calls). See Details for how these are handled.} \item{edge, pos}{ the position at which to draw the axis or text } \item{text}{ the text to draw } \item{at}{ the value of a coordinate at which to draw the axis or labels. } \item{\dots}{ additional parameters which are passed to \code{\link{bbox3d}} or \code{\link{material3d}} } } \details{ The rectangular prism holding the 3D plot has 12 edges. They are identified using 3 character strings. The first character (`x', `y', or `z') selects the direction of the axis. The next two characters are each `-' or `+', selecting the lower or upper end of one of the other coordinates. If only one or two characters are given, the remaining characters normally default to `-' (but with \code{mtext3d(..., floating = TRUE)} the default is `+'; see below). For example \code{edge = 'x+'} draws an x-axis at the high level of y and the low level of z. By default, \code{axes3d} uses the \code{\link{bbox3d}} function to draw the axes. The labels will move so that they do not obscure the data. Alternatively, a vector of arguments as described above may be used, in which case fixed axes are drawn using \code{axis3d}. As of \pkg{rgl} version 0.106.21, axis drawing has changed significantly. Text drawn in the margins will adapt to the margins (see \code{\link{bbox3d}}). The \code{edge} and \code{floating} parameters will be recorded in the \code{margin} and \code{floating} material properties for the object. If \code{floating = FALSE}, they will be drawn on the specified edge. If \code{floating = TRUE}, they will move as the axis labels move when the scene is rotated. The signs on the edge specification are interpreted as agreeing with the axis ticks `+' or disagreeing `-'. For example, \code{"x++"} will draw text on the x axis in the same edge as the ticks, while \code{"x--"} will draw on the opposite edge. The final possible value for \code{floating} in \code{mtext3d} is \code{NA}, which reproduces legacy \pkg{rgl} behaviour. In this case the labels are not tied to the bounding box, so they should be drawn last, or they could appear inside the box, overlapping the data. In \code{title3d} \code{floating = NULL} (the default) indicates the main title and subtitle will be fixed while the axis labels will be floating. The default locations for title and subtitle are \code{line = 2} and \code{level = 2} on edges \code{"x++"} and \code{"x--"} respectively. The axis labels float at \code{line = 4} and \code{level = 1} on the same edge as the ticks. The \code{at} parameter in \code{axis3d} is the location of the ticks, defaulting to \code{\link{pretty}} locations. In \code{mtext3d} the \code{at} parameter is the location on the specified axis at which to draw the text, defaulting to the middle of the bounding box. The \code{line} parameter is the line counting out from the box in the same direction as the axis ticks, and \code{level} is the line out in the orthogonal direction. The ticks run from \code{line = 0} to \code{line = 1}, and the tick labels are drawn at \code{line = 2}. Both are drawn at level 0. The \code{pos} parameter is only supported in legacy mode. If it is a numeric vector of length 3, \code{edge} determines the direction of the axis and the tick marks, and the values of the other two coordinates in \code{pos} determine the position. The \code{level} parameter is ignored in legacy mode. For \code{mtext3d} in \code{floating = TRUE} or \code{floating = FALSE} mode, there are 3 special values for the \code{at} parameter: it may be \code{-Inf}, \code{NA} or \code{+Inf}, referring to the bottom, middle or top of the given axis respectively. } \note{\code{mtext3d} is a wrapper for \code{\link{text3d}} that sets the \code{margin} and \code{floating} material properties. In fact, these properties can be set for many kinds of objects (most kinds where it would make sense), with the effect that the object will be drawn in the margin, with \code{x} coordinate corresponding to \code{at}, \code{y} corresponding to \code{line}, and \code{z} corresponding to \code{level}. } \value{ These functions are called for their side effects. They return the object IDs of objects added to the scene. } \author{ Duncan Murdoch } \seealso{Classic graphics functions \code{\link{axis}}, \code{\link{box}}, \code{\link{title}}, \code{\link{mtext}}, and RGL function \code{\link{bbox3d}}.} \examples{ open3d() points3d(rnorm(10), rnorm(10), rnorm(10)) # First add standard axes axes3d() # and one in the middle (the NA will be ignored, a number would # do as well) axis3d('x', pos = c(NA, 0, 0)) # add titles title3d('main', 'sub', 'xlab', 'ylab', 'zlab') rgl.bringtotop() open3d() points3d(rnorm(10), rnorm(10), rnorm(10)) # Use fixed axes axes3d(c('x', 'y', 'z')) # Put 4 x-axes on the plot axes3d(c('x--', 'x-+', 'x+-', 'x++')) axis3d('x', pos = c(NA, 0, 0)) title3d('main', 'sub', 'xlab', 'ylab', 'zlab') } \keyword{dynamic}%-- one or more ... rgl/man/vertexControl.Rd0000644000176200001440000000665314145464133014775 0ustar liggesusers\name{vertexControl} \alias{vertexControl} \title{ Set attributes of vertices } \description{ This is a function to produce actions in a web display. A \code{\link{playwidget}} or Shiny input control (e.g. a \code{\link[shiny]{sliderInput}} control) sets a value which controls attributes of a selection of vertices. } \usage{ vertexControl(value = 0, values = NULL, vertices = 1, attributes, objid = tagged3d(tag), tag, param = seq_len(NROW(values)) - 1, interp = TRUE) } \arguments{ \item{value}{The value to use for input (typically \code{input$value} in a Shiny app.) Not needed with \code{\link{playwidget}}.} \item{values}{ A matrix of values, each row corresponding to an input value. } \item{vertices}{ Which vertices are being controlled? Specify \code{vertices} as a number from 1 to the number of vertices in the \code{objid}. } \item{attributes}{A vector of attributes of a vertex, from \code{c("x", "y", "z", "red", "green", "blue", "alpha", "nx", "ny", "nz", "radii", "ox", "oy", "oz", "ts", "tt", "offset")}. See Details.} \item{objid}{ A single RGL object id. } \item{tag}{ An alternate way to specify \code{objid}. } \item{param}{ Parameter values corresponding to each row of \code{values}. } \item{interp}{ Whether to interpolate between rows of \code{values}. } } \details{ This function modifies attributes of vertices in a single object. The \code{attributes} are properties of each vertex in a scene; not all are applicable to all objects. In order, they are: coordinates of the vertex \code{"x", "y", "z"}, color of the vertex \code{"red", "green", "blue", "alpha"}, normal at the vertex \code{"nx", "ny", "nz"}, radius of a sphere at the vertex \code{"radius"}, origin within a texture \code{"ox", "oy"} and perhaps \code{"oz"}, texture coordinates \code{"ts", "tt"}. Planes are handled specially. The coefficients \code{a, b, c} in the \code{\link{planes3d}} or \code{\link{clipplanes3d}} specification are controlled using \code{"nx", "ny", "nz"}, and \code{d} is handled as \code{"offset"}. The \code{vertices} argument is interpreted as the indices of the planes when these attributes are set. If only one attribute of one vertex is specified, \code{values} may be given as a vector and will be treated as a one-column matrix. Otherwise \code{values} must be given as a matrix with \code{ncol(values) == max(length(vertices), length(attributes))}. The \code{vertices} and \code{attributes} vectors will be recycled to the same length, and entries from column \code{j} of \code{values} will be applied to vertex \code{vertices[j]}, attribute \code{attributes[j]}. The \code{value} argument is translated into a row (or two rows if \code{interp = TRUE}) of \code{values} by finding its location in \code{param}. } \value{ A list of class \code{"rglControl"} of cleaned up parameter values, to be used in an RGL widget. } \author{ Duncan Murdoch } \examples{ saveopts <- options(rgl.useNULL = TRUE) theta <- seq(0, 6*pi, len=100) xyz <- cbind(sin(theta), cos(theta), theta) plot3d(xyz, type="l") id <- spheres3d(xyz[1,,drop=FALSE], col="red") widget <- rglwidget(width=500, height=300) \%>\% playwidget(vertexControl(values=xyz, attributes=c("x", "y", "z"), objid = id, param=1:100), start = 1, stop = 100, rate=10) if (interactive() || in_pkgdown_example()) widget options(saveopts) } rgl/man/select3d.Rd0000644000176200001440000000413614100762641013613 0ustar liggesusers\name{select3d} \alias{select3d} \alias{rgl.select3d} \alias{selectionFunction3d} \title{ Select a rectangle in an RGL scene } \description{ This function allows the user to use the mouse to select a region in an RGL scene. } \usage{ rgl.select3d(button = c("left", "middle", "right"), dev = cur3d(), subscene = currentSubscene3d(dev)) select3d(...) selectionFunction3d(proj, region = proj$region) } \arguments{ \item{ button }{ Which button to use for selection.} \item{ dev, subscene}{ The RGL device and subscene to work with } \item{ ... }{ Button argument to pass to \code{rgl.select3d}} \item{proj}{An object returned from \code{\link{rgl.projection}} containing details of the current projection.} \item{region}{Corners of a rectangular region in the display.} } \details{ \code{select3d} and \code{rgl.select3d} select 3-dimensional regions by allowing the user to use a mouse to draw a rectangle showing the projection of the region onto the screen. They return a function which tests points for inclusion in the selected region. \code{selectionFunction3d} constructs such a test function given coordinates and current transformation matrices. If the scene is later moved or rotated, the selected region will remain the same, though no longer corresponding to a rectangle on the screen. } \value{ All of these return a function \code{f(x, y, z)} which tests whether each of the points \code{(x, y, z)} is in the selected region, returning a logical vector. This function accepts input in a wide variety of formats as it uses \code{\link[grDevices]{xyz.coords}} to interpret its parameters. } \author{ Ming Chen / Duncan Murdoch } \seealso{ \code{\link{selectpoints3d}}, \code{\link{locator}} } \examples{ # Allow the user to select some points, and then redraw them # in a different color if (interactive()) { x <- rnorm(1000) y <- rnorm(1000) z <- rnorm(1000) open3d() points3d(x, y, z) f <- select3d() if (!is.null(f)) { keep <- f(x, y, z) pop3d() points3d(x[keep], y[keep], z[keep], color = 'red') points3d(x[!keep], y[!keep], z[!keep]) } } } \keyword{dynamic} rgl/man/rgl-internal.Rd0000644000176200001440000000246514100762641014506 0ustar liggesusers\name{rgl-internal} \title{Internal RGL functions and data} \alias{rgl.bool} \alias{rgl.numeric} \alias{rgl.vertex} \alias{rgl.nvertex} \alias{rgl.color} \alias{rgl.mcolor} \alias{rgl.clamp} \alias{rgl.attr} \alias{rgl.enum} \alias{rgl.enum.gl2ps} \alias{rgl.enum.nodetype} \alias{rgl.enum.pixfmt} \alias{rgl.enum.polymode} \alias{rgl.enum.textype} \alias{rgl.enum.fogtype} \alias{rgl.enum.primtype} \alias{rgl.enum.texmagfilter} \alias{rgl.enum.texminfilter} \alias{rgl.selectstate} \alias{rgl.setselectstate} \alias{edgemap} \alias{edgeindex} \alias{cube3d.ib} \alias{cube3d.vb} \alias{oh3d.ib} \alias{oh3d.vb} \alias{dev3d} \description{ Internal RGL functions } \usage{ rgl.bool(x) rgl.numeric(x) rgl.vertex(x, y = NULL, z = NULL) rgl.nvertex(vertex) rgl.color(color) rgl.mcolor(colors) rgl.clamp(value, low, high) rgl.attr(vattr, nvertex) rgl.enum(name, ..., multi = FALSE) rgl.enum.gl2ps(postscripttype) rgl.enum.nodetype(type) rgl.enum.pixfmt(fmt) rgl.enum.polymode(mode) rgl.enum.textype(textype) rgl.enum.fogtype(fogtype) rgl.enum.primtype(primtype) rgl.enum.texmagfilter(magfiltertype) rgl.enum.texminfilter(minfiltertype) rgl.selectstate(dev, subscene) rgl.setselectstate(state, dev, subscene) edgemap(size) edgeindex(from, to, size, row, col) } \details{ These are not to be called by the user. } \keyword{internal} rgl/man/r3d.Rd0000644000176200001440000000771714100762641012605 0ustar liggesusers\name{r3d} \alias{r3d} \title{Generic 3D interface} \description{Generic 3D interface for 3D rendering and computational geometry.} \details{ R3d is a design for an interface for 3d rendering and computation without dependency on a specific rendering implementation. R3d includes a collection of 3D objects and geometry algorithms. All r3d interface functions are named \code{*3d}. They represent generic functions that delegate to implementation functions. The interface can be grouped into 8 categories: Scene Management, Primitive Shapes, High-level Shapes, Geometry Objects, Visualization, Interaction, Transformation, Subdivision. The rendering interface gives an abstraction to the underlying rendering model. It can be grouped into four categories: \describe{ \item{Scene Management:}{A 3D scene consists of shapes, lights and background environment.} \item{Primitive Shapes:}{Generic primitive 3D graphics shapes such as points, lines, triangles, quadrangles and texts.} \item{High-level Shapes:}{Generic high-level 3D graphics shapes such as spheres, sprites and terrain.} \item{Interaction:}{Generic interface to select points in 3D space using the pointer device.} } In this package we include an implementation of r3d using the underlying \code{rgl.*} functions. 3D computation is supported through the use of object structures that live entirely in R. \describe{ \item{Geometry Objects:}{Geometry and mesh objects allow to define high-level geometry for computational purpose such as triangle or quadrangle meshes (see \code{\link{mesh3d}}).} \item{Transformation:}{Generic interface to transform 3d objects.} \item{Visualization:}{Generic rendering of 3d objects such as dotted, wired or shaded.} \item{Computation:}{Generic subdivision of 3d objects.} } At present, the main practical differences between the r3d functions and the \code{rgl.*} functions are as follows. The r3d functions call \code{\link{open3d}} if there is no device open, and the \code{rgl.*} functions call \code{\link{rgl.open}}. By default \code{\link{open3d}} sets the initial orientation of the coordinate system in 'world coordinates', i.e. a right-handed coordinate system in which the x-axis increases from left to right, the y-axis increases with depth into the scene, and the z-axis increases from bottom to top of the screen. \code{rgl.*} functions, on the other hand, use a right-handed coordinate system similar to that used in OpenGL. The x-axis matches that of r3d, but the y-axis increases from bottom to top, and the z-axis decreases with depth into the scene. Since the user can manipulate the scene, either system can be rotated into the other one. The r3d functions also preserve the \code{rgl.material} setting across calls (except for texture elements, in the current implementation), whereas the \code{rgl.*} functions leave it as set by the last call. The example code below illustrates the two coordinate systems. } \seealso{ \code{\link{points3d}}, \code{\link{lines3d}}, \code{\link{segments3d}}, \code{\link{triangles3d}}, \code{\link{quads3d}}, \code{\link{text3d}}, \code{\link{spheres3d}}, \code{\link{sprites3d}}, \code{\link{terrain3d}}, \code{\link{select3d}}, \code{\link{dot3d}}, \code{\link{wire3d}}, \code{\link{shade3d}}, \code{\link{transform3d}}, \code{\link{rotate3d}}, \code{\link{subdivision3d}}, \code{\link{mesh3d}}, \code{\link{cube3d}}, \code{\link{rgl}} } \examples{ x <- c(0, 1, 0, 0) y <- c(0, 0, 1, 0) z <- c(0, 0, 0, 1) labels <- c("Origin", "X", "Y", "Z") i <- c(1, 2, 1, 3, 1, 4) # rgl.* interface rgl.open() rgl.texts(x, y, z, labels) rgl.texts(1, 1, 1, "rgl.* coordinates") rgl.lines(x[i], y[i], z[i]) # *3d interface open3d() text3d(x, y, z, labels) text3d(1, 1, 1, "*3d coordinates") segments3d(x[i], y[i], z[i]) } \keyword{dynamic} rgl/man/polygon3d.Rd0000644000176200001440000000422714100762641014024 0ustar liggesusers\name{polygon3d} \alias{polygon3d} \title{ Draw a polygon in three dimensions } \description{ This function takes a description of a flat polygon in x, y and z coordinates, and draws it in three dimensions. } \usage{ polygon3d(x, y = NULL, z = NULL, fill = TRUE, plot = TRUE, coords = 1:2, random = TRUE, ...) } \arguments{ \item{x, y, z}{ Vertices of the polygon in a form accepted by \code{\link{xyz.coords}}. } \item{fill}{ logical; should the polygon be filled? } \item{plot}{ logical; should the polygon be displayed? } \item{coords}{ Which two coordinates (\code{x = 1}, \code{y = 2}, \code{z = 3}) describe the polygon. } \item{random}{ Should a random triangulation be used? } \item{\dots}{ Other parameters to pass to \code{\link{lines3d}} or \code{\link{shade3d}} if \code{plot = TRUE}. } } \details{ The function triangulates the two dimensional polygon described by \code{coords}, then applies the triangulation to all three coordinates. No check is made that the polygon is actually all in one plane, but the results may be somewhat unpredictable (especially if \code{random = TRUE}) if it is not. Polygons need not be simple; use \code{NA} to indicate separate closed pieces. For \code{fill = FALSE} there are no other restrictions on the pieces, but for \code{fill = TRUE} the resulting two-dimensional polygon needs to be one that \code{\link{triangulate}} can handle. } \value{ If \code{plot = TRUE}, the id number of the lines (for \code{fill = FALSE}) or triangles (for \code{fill = TRUE}) that have been plotted. If \code{plot = FALSE}, then for \code{fill = FALSE}, a vector of indices into the XYZ matrix that could be used to draw the polygon. For \code{fill = TRUE}, a triangular mesh object representing the triangulation. } \author{ Duncan Murdoch } \seealso{ \code{\link{extrude3d}} for a solid extrusion of a polygon, \code{\link{triangulate}} for the triangulation. } \examples{ theta <- seq(0, 4*pi, len = 50) r <- theta + 1 r <- c(r[-50], rev(theta*0.8) + 1) theta <- c(theta[-50], rev(theta)) x <- r*cos(theta) y <- r*sin(theta) open3d() plot(x, y, type = "n") polygon(x, y) polygon3d(x, y, x + y, col = "blue") } \keyword{ graphics } rgl/man/planes.Rd0000644000176200001440000000445714100762641013375 0ustar liggesusers\name{planes3d} \alias{planes3d} \alias{clipplanes3d} \title{Add planes} \description{ \code{planes3d} adds mathematical planes to a scene. Their intersection with the current bounding box will be drawn. \code{clipplanes3d} adds clipping planes to a scene. } \usage{ planes3d(a, b = NULL, c = NULL, d = 0, ...) clipplanes3d(a, b = NULL, c = NULL, d = 0) } \arguments{ \item{a, b, c}{ Coordinates of the normal to the plane. Any reasonable way of defining the coordinates is acceptable. See the function \code{\link[grDevices]{xyz.coords}} for details. } \item{d}{ Coordinates of the "offset". See the details. } \item{\dots}{ Material properties. See \code{\link{rgl.material}} for details. } } \details{ \code{planes3d} draws planes using the parametrization \eqn{a x + b y + c z + d = 0}. Multiple planes may be specified by giving multiple values for any of \code{a, b, c, d}; the other values will be recycled as necessary. \code{clipplanes3d} defines clipping planes using the same equations. Clipping planes suppress the display of other objects (or parts of them) in the subscene, based on their coordinates. Points (or parts of lines or surfaces) where the coordinates \code{x, y, z} satisfy \eqn{a x + b y + c z + d < 0} will be suppressed. The number of clipping planes supported by the OpenGL driver is implementation dependent; use \code{par3d("maxClipPlanes")} to find the limit. } \value{ A shape ID of the planes or clipplanes object is returned invisibly. } \seealso{ \code{\link{abclines3d}} for mathematical lines. \code{\link{triangles3d}} or the corresponding functions for quadrilaterals may be used to draw sections of planes that do not adapt to the bounding box. The example in \link{subscene3d} shows how to combine clipping planes to suppress complex shapes. } \examples{ # Show regression plane with z as dependent variable open3d() x <- rnorm(100) y <- rnorm(100) z <- 0.2*x - 0.3*y + rnorm(100, sd = 0.3) fit <- lm(z ~ x + y) plot3d(x, y, z, type = "s", col = "red", size = 1) coefs <- coef(fit) a <- coefs["x"] b <- coefs["y"] c <- -1 d <- coefs["(Intercept)"] planes3d(a, b, c, d, alpha = 0.5) open3d() ids <- plot3d(x, y, z, type = "s", col = "red", size = 1, forceClipregion = TRUE) oldid <- useSubscene3d(ids["clipregion"]) clipplanes3d(a, b, c, d) useSubscene3d(oldid) } \keyword{dynamic} rgl/man/setAxisCallbacks.Rd0000644000176200001440000000734714137472630015342 0ustar liggesusers\name{setAxisCallbacks} \alias{setAxisCallbacks} \title{ User-defined axis labelling callbacks. } \description{ This function sets user callbacks to construct axes in R or \code{\link{rglwidget}} displays. } \usage{ setAxisCallbacks(axes, fns, javascript = NULL, subscene = scene$rootSubscene$id, scene = scene3d(minimal = FALSE), applyToScene = TRUE, applyToDev = missing(scene)) } \arguments{ \item{axes}{ Which axes? Specify as number in \code{1:3} or letter in \code{c("x", "y", "z")}. } \item{fns}{ Function or list of functions or character vector giving names of functions. } \item{javascript}{ Optional block of Javascript code to be included (at the global level). } \item{subscene}{ Which subscene do these callbacks apply to? } \item{scene}{ Which scene? } \item{applyToScene}{ Should these changes apply to the scene object? } \item{applyToDev}{ Should these changes apply to the current device? } } \details{ If \code{applyToScene} is \code{TRUE}, this function adds Javascript callbacks to the \code{scene} object. If \code{applyToDev} is \code{TRUE}, it adds R callbacks to the current RGL device. For Javascript, the callbacks are specified as strings; these will be evaluated within the browser in the global context to define the functions, which will then be called with the Javascript \code{this} object set to the current \code{rglwidgetClass} object. For R, they may be strings or R functions. Both options may be \code{TRUE}, in which case the callbacks must be specified as strings which are both valid Javascript and valid R. The usual way to do this is to give just a function name, with the function defined elsewhere, as in the Example below. The functions should have a header of the form \code{function(margin)}. The \code{margin} argument will be a string like \code{"x++"} indicating which margin would be chosen by R. If RGL would not choose to draw any axis annotations (which happens with \code{\link{rglwidget}}, though not currently in R itself), only the letter will be passed, e.g. \code{"x"}. } \value{ Invisibly returns an \code{rglScene} object. This object will record the changes if \code{applyToScene} is \code{TRUE}. If \code{applyToDev} is \code{TRUE}, it will also have the side effect of attempting to install the callbacks using \code{\link{rgl.setAxisCallback}}. } \seealso{ \code{\link{setUserCallbacks}} for mouse callbacks. } \author{ Duncan Murdoch } \examples{ # Draw arrows instead of tick marks on axes arrowAxis <- local({ ids <- c(NA, NA, NA) bbox <- c(NA, NA, NA, NA, NA, NA) function(margin) { dim <- if (grepl("x", margin)) 1 else if (grepl("y", margin)) 2 else 3 inds <- 2*dim + (-1):0 range <- par3d("bbox")[inds] if (!identical(bbox[inds], range)) { if (!is.na(ids[dim])) pop3d(id = ids[dim]) bbox[inds] <<- range center <- mean(range) from <- mean(c(range[1], center)) to <- mean(c(center, range[2])) # margin should agree with suggestion, so use "x++" etc. margin <- gsub("-", "+", margin) ids[dim] <- arrow3d(p0 = c(from, 1, 1), p1 = c(to, 1, 1), n = 4, type = "lines", margin = margin, floating = TRUE) } } }) # Define the Javascript function with the same name to use in WebGL # Since Javascript won't change the bounding box, this function # doesn't need to do anything. js <- " window.arrowAxis = function(margin) {} ; " xyz <- matrix(rnorm(60), ncol = 3) plot3d(xyz, xlab = "x", ylab = "y", zlab = "z") setAxisCallbacks(1:3, "arrowAxis", javascript = js) rglwidget() } rgl/man/mfrow3d.Rd0000644000176200001440000001034214100762640013461 0ustar liggesusers\name{mfrow3d} \alias{mfrow3d} \alias{layout3d} \alias{next3d} \alias{subsceneList} \alias{clearSubsceneList} \title{ Set up multiple figure layouts } \description{ The \code{mfrow3d} and \code{layout3d} functions provide functionality in RGL similar to \code{\link{par}("mfrow")} and \code{\link{layout}} in classic R graphics. } \usage{ subsceneList(value, window = cur3d()) mfrow3d(nr, nc, byrow = TRUE, parent = NA, sharedMouse = FALSE, ...) layout3d(mat, widths = rep.int(1, ncol(mat)), heights = rep.int(1, nrow(mat)), parent = NA, sharedMouse = FALSE, ...) next3d(current = NA, clear = TRUE, reuse = TRUE) clearSubsceneList(delete = currentSubscene3d() \%in\% subsceneList(), window = cur3d()) } \arguments{ \item{value}{ A new subscene list to set. If missing, return the current one (or \code{NULL}). } \item{window}{ Which window to operate on. } \item{nr, nc}{ Number of rows and columns of figures. } \item{byrow}{ Whether figures progress by row (as with \code{\link{par}("mfrow")}) or by column (as with \code{\link{par}("mfcol")}). } \item{mat, widths, heights}{ Layout parameters; see \code{\link{layout}} for their interpretation. } \item{parent}{ The parent subscene. \code{NA} indicates the current subscene. See Details below. } \item{sharedMouse}{ Whether to make all subscenes \code{\link{par3d}("listeners")} to each other. } \item{\dots}{ Additional parameters to pass to \code{\link{newSubscene3d}} as each subscene is created. } \item{current}{ The subscene to move away from. \code{NA} indicates the current subscene. } \item{clear}{ Whether the newly entered subscene should be cleared upon entry. } \item{reuse}{ Whether to skip advancing if the current subscene has no objects in it. } \item{delete}{ If \code{TRUE}, delete the subscenes in the current window. } } \details{ rgl can maintain a list of subscenes; the \code{mfrow3d} and \code{layout3d} functions create that list. When the list is in place, \code{next3d} causes RGL to move to the next scene in the list, or cycle back to the first one. Unlike the classic R graphics versions of these functions, these functions are completely compatible with each other. You can mix them within a single RGL window. In the default case where \code{parent} is missing, \code{mfrow3d} and \code{layout3d} will call \code{clearSubsceneList()} at the start. By default \code{clearSubsceneList()} checks whether the current subscene is in the current subscene list; if so, it will delete all subscenes in the list, and call \code{\link{gc3d}} to delete any objects that are no longer shown. The subscene list will be set to a previous value if one was recorded, or \code{NULL} if not. If \code{parent} is specified in \code{mfrow3d} or \code{layout3d} (even as \code{NA}), the new subscenes will be created within the parent. The \code{next3d()} function first finds out if the current subscene is in the current list. If not, it moves to the previous list, and looks there. Once it finds a list containing the current subscene, it moves to the next entry in that list. If it can't find one, it creates a length one list containing just the current subscene. } \value{ \code{mfrow3d} and \code{layout3d} return a vector of subscene id values that have just been created. If a previous subscene list was in effect and was not automatically cleared, it is attached as an attribute \code{"prev"}. } \author{ Duncan Murdoch } \seealso{ \code{\link{newSubscene3d}}, \code{\link{par}}, \code{\link{layout}}. } \examples{ shapes <- list(Tetrahedron = tetrahedron3d(), Cube = cube3d(), Octahedron = octahedron3d(), Icosahedron = icosahedron3d(), Dodecahedron = dodecahedron3d(), Cuboctahedron = cuboctahedron3d()) col <- rainbow(6) open3d() mfrow3d(3, 2) for (i in 1:6) { next3d() # won't advance the first time, since it is empty shade3d(shapes[[i]], col = col[i]) } highlevel(integer()) # To trigger display as rglwidget open3d() mat <- matrix(1:4, 2, 2) mat <- rbind(mat, mat + 4, mat + 8) layout3d(mat, height = rep(c(3, 1), 3), sharedMouse = TRUE) for (i in 1:6) { next3d() shade3d(shapes[[i]], col = col[i]) next3d() text3d(0, 0, 0, names(shapes)[i]) } highlevel(integer()) } \keyword{graphics } rgl/man/persp3d.function.Rd0000644000176200001440000001313314100762641015306 0ustar liggesusers\name{persp3d.function} \alias{plot3d.function} \alias{persp3d.function} \title{ Plot a function of two variables } \description{ Plot a function \code{z(x, y)} or a parametric function \code{(x(s, t), y(s, t), z(s, t))}. } \usage{ \method{persp3d}{function}(x, xlim = c(0, 1), ylim = c(0, 1), slim = NULL, tlim = NULL, n = 101, xvals = seq.int(min(xlim), max(xlim), length.out = n[1]), yvals = seq.int(min(ylim), max(ylim), length.out = n[2]), svals = seq.int(min(slim), max(slim), length.out = n[1]), tvals = seq.int(min(tlim), max(tlim), length.out = n[2]), xlab, ylab, zlab, col = "gray", otherargs = list(), normal = NULL, texcoords = NULL, \dots) \method{plot3d}{function}(x, \ldots) } \arguments{ \item{x}{ A function of two arguments. See the details below. } \item{xlim, ylim}{ By default, the range of x and y values. For a parametric surface, if these are not missing, they are used as limits on the displayed x and y values. } \item{slim, tlim}{ If not \code{NULL}, these give the range of s and t in the parametric specification of the surface. If only one is given, the other defaults to \code{c(0, 1)}. } \item{n}{ A one or two element vector giving the number of steps in the x and y (or s and t) grid. } \item{xvals, yvals}{ The values at which to evaluate x and y. Ignored for a parametric surface. If used, \code{xlim} and/or \code{ylim} are ignored. } \item{svals, tvals}{ The values at which to evaluate s and t for a parametric surface. Only used if \code{slim} or \code{tlim} is not \code{NULL}. As with \code{xvals} and \code{yvals}, these override the corresponding \code{slim} or \code{tlim} specification. } \item{xlab, ylab, zlab}{ The axis labels. See the details below for the defaults. } \item{col}{ The color to use for the plot. See the details below. } \item{otherargs}{ Additional arguments to pass to the function. } \item{normal, texcoords}{ Functions to set surface normals or texture coordinates. See the details below. } \item{\dots}{ Additional arguments to pass to \code{\link{persp3d}}. } } \details{ The \code{"function"} method for \code{plot3d} simply passes all arguments to \code{persp3d}. Thus this description applies to both. The first argument \code{x} is required to be a function. It is named \code{x} only because of the requirements of the S3 system; in the remainder of this help page, we will assume that the assignment \code{f <- x} has been made, and will refer to the function \code{f()}. \code{persp3d.function} evaluates \code{f()} on a two-dimensional grid of values, and displays the resulting surface. The values on the grid will be passed in as vectors in the first two arguments to the function, so \code{f()} needs to be vectorized. Other optional arguments to \code{f()} can be specified in the \code{otherargs} list. In the default form where \code{slim} and \code{tlim} are both \code{NULL}, it is assumed that \code{f(x, y)} returns heights, which will be plotted in the z coordinate. The default axis labels will be taken from the argument names to \code{f()} and the expression passed as argument \code{x} to this function. If \code{slim} or \code{tlim} is specified, a parametric surface is plotted. The function \code{f(s, t)} must return a 3-column matrix, giving x, y and z coordinates of points on the surface. The default axis labels will be the column names if those are present. In this case \code{xlim}, \code{ylim} and \code{zlim} are used to define a clipping region only if specified; the defaults are ignored. The color of the surface may be specified as the name of a color, or a vector or matrix of color names. In this case the colors will be recycled across the points on the grid of values. Alternatively, a function may be given: it should be a function like \code{\link{rainbow}} that takes an integer argument and returns a vector of colors. In this case the colors are mapped to z values. The \code{normal} argument allows specification of a function to compute normal vectors to the surface. This function is passed the same arguments as \code{f()} (including \code{otherargs} if present), and should produce a 3-column matrix containing the x, y and z coordinates of the normals. The \code{texcoords} argument is a function similar to \code{normal}, but it produces a 2-column matrix containing texture coordinates. Both \code{normal} and \code{texcoords} may also contain matrices, with 3 and 2 columns respectively, and rows corresponding to the points that were passed to \code{f()}. } \value{ This function constructs a call to \code{\link{persp3d}} and returns the value from that function. } \author{ Duncan Murdoch } \seealso{ The \code{\link{curve}} function in base graphics does something similar for functions of one variable. See the example below for space curves. } \examples{ # (1) The Obligatory Mathematical surface. # Rotated sinc function, with colors f <- function(x, y) { r <- sqrt(x^2 + y^2) ifelse(r == 0, 10, 10 * sin(r)/r) } open3d() plot3d(f, col = colorRampPalette(c("blue", "white", "red")), xlab = "X", ylab = "Y", zlab = "Sinc( r )", xlim = c(-10, 10), ylim = c(-10, 10), aspect = c(1, 1, 0.5)) # (2) A cylindrical plot f <- function(s, t) { r <- 1 + exp( -pmin( (s - t)^2, (s - t - 1)^2, (s - t + 1)^2 )/0.01 ) cbind(r*cos(t*2*pi), r*sin(t*2*pi), s) } open3d() plot3d(f, slim = c(0, 1), tlim = c(0, 1), col = "red", alpha = 0.8) # Add a curve to the plot, fixing s at 0.5. plot3d(f(0.5, seq.int(0, 1, length.out = 100)), type = "l", add = TRUE, lwd = 3, depth_test = "lequal") } \keyword{ graphics } rgl/man/ageSetter.Rd0000644000176200001440000000550214145464133014032 0ustar liggesusers\name{ageSetter} \alias{ageSetter} \title{ Obsolete function to set WebGL scene properties based on the age of components of objects } \description{ Many RGL shapes contain lists of vertices with various attributes (available via \code{\link{rgl.attrib}}). This function modifies the data for those attributes in a WebGL scene. } \usage{ ageSetter(births, ages, colors = NULL, alpha = NULL, radii = NULL, vertices = NULL, normals = NULL, origins = NULL, texcoords = NULL, objids, prefixes = "", digits = 7, param = seq(floor(min(births)), ceiling(max(births)))) } \arguments{ \item{births}{ Numeric vector with one value per vertex, used to determine the \dQuote{age} of the vertex when displaying it. } \item{ages}{ A non-decreasing sequence of \dQuote{ages}. } \item{colors, alpha, radii, vertices, normals, origins, texcoords}{ Attributes of the vertices. Non-\code{NULL} attributes will be interpolated from these values. See the Details section below. } \item{objids, prefixes}{ The object ids and scene prefixes to modify. These are recycled to the same length. } \item{digits}{ How many digits to output in the generated Javascript code. } \item{param}{ Default values to be used by a slider control calling the generated function. } } \details{ The vertex attributes are specified as follows: \describe{ \item{colors}{A vector of colors in a format suitable for input to \code{\link{col2rgb}}} \item{alpha}{A numeric vector of alpha values between 0 and 1.} \item{radii}{A numeric vector of sphere radii.} \item{vertices}{A 3-column matrix of vertex coordinates.} \item{normals}{A 3-column matrix of vertex normals.} \item{origins}{A 2-column matrix of origins for text or sprites.} \item{texcoords}{A 2-column matrix of texture coordinates.} } All attributes must have the same number of entries (rows for the matrices) as the \code{ages} vector. The \code{births} vector must have the same number of entries as the number of vertices in the object. Not all objects contain all attributes listed here; if one is chosen that is not a property of the corresponding object, a Javascript \code{alert()} will be generated. } \value{ A character vector of class \code{c("ageSetter", "propertySetter")} containing Javascript code defining a function suitable for use in a \code{\link{propertySlider}}. The function takes a single argument, \code{time}, and uses it to compute the \dQuote{age} of vertex \code{i} as \code{time - births[i]}. Those are then used with the \code{ages} argument to linearly interpolate settings of the specified attributes. Extrapolation is constant. Repeated values in \code{ages} can be used to obtain discontinuities in the settings. } \author{ Duncan Murdoch } \seealso{ \code{\link{propertySlider}}; more detailed control is available in \code{\link{vertexSetter}}. } rgl/man/identify3d.Rd0000644000176200001440000000317414100762640014147 0ustar liggesusers\name{identify3d} \alias{identify3d} \title{ Identify points in plot } \description{ Identify points in a plot, similarly to the \code{\link{identify}} function in base graphics. } \usage{ identify3d(x, y = NULL, z = NULL, labels = seq_along(x), n = length(x), plot = TRUE, adj = c(-0.1, 0.5), tolerance = 20, buttons = c("right", "middle")) } \arguments{ \item{x, y, z}{coordinates of points in a scatter plot. Alternatively, any object which defines coordinates (see \code{\link{xyz.coords}}) can be given as \code{x}, and \code{y} and \code{z} left missing.} \item{labels}{an optional character vector giving labels for the points. Will be coerced using \code{\link{as.character}}, and recycled if necessary to the length of \code{x}.} \item{n}{the maximum number of points to be identified.} \item{plot}{logical: if \code{plot} is \code{TRUE}, the labels are printed near the points and if \code{FALSE} they are omitted.} \item{adj}{numeric vector to use as \code{adj} parameter to \code{\link{text3d}} when plotting the labels.} \item{tolerance}{the maximal distance (in pixels) for the pointer to be \sQuote{close enough} to a point.} \item{buttons}{a length 1 or 2 character vector giving the buttons to use for selection and quitting.} } \details{ If \code{buttons} is length 1, the user can quit by reaching \code{n} selections, or by hitting the escape key, but the result will be lost if escape is used. } \value{ A vector of selected indices. } \author{ Duncan Murdoch } \seealso{ \code{\link{identify}} for base graphics, \code{\link{select3d}} for selecting regions. } \keyword{ graphics } rgl/man/abclines.Rd0000644000176200001440000000224314100762640013661 0ustar liggesusers\name{abclines3d} \alias{abclines3d} \title{ Lines intersecting the bounding box } \description{ This adds mathematical lines to a scene. Their intersection with the current bounding box will be drawn. } \usage{ abclines3d(x, y = NULL, z = NULL, a, b = NULL, c = NULL, ...) } \arguments{ \item{x, y, z}{ Coordinates of points through which each line passes. } \item{a, b, c}{ Coordinates of the direction vectors for the lines. } \item{...}{ Material properties. } } \details{ Draws the segment of a line that intersects the current bounding box of the scene using the parametrization \eqn{ (x, y, z) + (a, b, c) * s } where \eqn{s} is a real number. Any reasonable way of defining the coordinates \code{x, y, z} and \code{a, b, c} is acceptable. See the function \code{\link[grDevices]{xyz.coords}} for details. } \value{ A shape ID of the object is returned invisibly. } \seealso{ \code{\link{planes3d}}, \code{\link{rgl.planes}} for mathematical planes. \code{\link{segments3d}} draws sections of lines that do not adapt to the bounding box. } \examples{ plot3d(rnorm(100), rnorm(100), rnorm(100)) abclines3d(0, 0, 0, a = diag(3), col = "gray") } \keyword{ dynamic } rgl/man/triangulate.Rd0000644000176200001440000000555614100762641014433 0ustar liggesusers\name{triangulate} \alias{triangulate} \title{ Triangulate a two-dimensional polygon } \description{ This algorithm decomposes a general polygon into simple polygons and uses the \dQuote{ear-clipping} algorithm to triangulate it. Polygons with holes are supported. } \usage{ triangulate(x, y = NULL, z = NULL, random = TRUE, plot = FALSE, partial = NA) } \arguments{ \item{x, y, z}{ Coordinates of a two-dimensional polygon in a format supported by \code{\link{xyz.coords}}. See Details for how \code{z} is handled. } \item{random}{ Whether to use a random or deterministic triangulation. } \item{plot}{ Whether to plot the triangulation; mainly for debugging purposes. } \item{partial}{ If the triangulation fails, should partial results be returned? } } \details{ Normally \code{triangulate} looks only at the \code{x} and \code{y} coordinates. However, if one of those is constant, it is replaced with the \code{z} coordinate if present. The algorithm works as follows. First, it breaks the polygon into pieces separated by \code{NA} values in \code{x} or \code{y}. Each of these pieces should be a simple, non-self-intersecting polygon, separate from the other pieces. (Though some minor exceptions to this rule may work, none are guaranteed). The nesting of these pieces is determined. The \dQuote{outer} polygon(s) are then merged with the polygons that they immediately contain, and each of these pieces is triangulated using the ear-clipping algorithm. Finally, all the triangulated pieces are put together into one result. } \value{ A three-by-n array giving the indices of the vertices of each triangle. (No vertices are added; only the original vertices are used in the triangulation.) The array has an integer vector attribute \code{"nextvert"} with one entry per vertex, giving the index of the next vertex to proceed counter-clockwise around outer polygon boundaries, clockwise around inner boundaries. } \references{ See the Wikipedia article \dQuote{polygon triangulation} for a description of the ear-clipping algorithm. } \author{ Duncan Murdoch } \note{ Not all inputs will succeed, even when a triangulation is possible. Generally using \code{random = TRUE} will find a successful triangulation if one exists, but it may occasionally take more than one try. } \seealso{ \code{\link{extrude3d}} for a solid extrusion of a polygon, \code{\link{polygon3d}} for a flat display; both use \code{triangulate}. } \examples{ theta <- seq(0, 2*pi, len = 25)[-25] theta <- c(theta, NA, theta, NA, theta, NA, theta, NA, theta) r <- c(rep(1.5, 24), NA, rep(0.5, 24), NA, rep(0.5, 24), NA, rep(0.3, 24), NA, rep(0.1, 24)) dx <- c(rep(0, 24), NA, rep(0.6, 24), NA, rep(-0.6, 24), NA, rep(-0.6, 24), NA, rep(-0.6, 24)) x <- r*cos(theta) + dx y <- r*sin(theta) plot(x, y, type = "n") polygon(x, y) triangulate(x, y, plot = TRUE) open3d() polygon3d(x, y, x - y, col = "red") } \keyword{ graphics } rgl/man/selectpoints3d.Rd0000644000176200001440000000570114100762641015047 0ustar liggesusers\name{selectpoints3d} \alias{selectpoints3d} \title{ Select points from a scene } \description{ This function uses the \code{\link{select3d}} function to allow the user to choose a point or region in the scene, then reports on all the vertices in or near that selection. } \usage{ selectpoints3d(objects = ids3d()$id, value = TRUE, closest = TRUE, % $ multiple = FALSE, ...) } \arguments{ \item{objects}{ A vector of object id values to use for the search. } \item{value}{ If \code{TRUE}, return the coordinates of the points; otherwise, return their indices. } \item{closest}{ If \code{TRUE}, return the points closest to the selection of no points are exactly within it. } \item{multiple}{ If \code{TRUE} or a function, do multiple selections. See the Details below. } \item{\dots}{ Other parameters to pass to \code{\link{select3d}}. } } \details{ The \code{multiple} argument may be a logical value or a function. If logical, it controls whether multiple selections will be performed. If \code{multiple} is \code{FALSE}, a single selection will be performed; it might contain multiple points. If \code{TRUE}, multiple selections will occur and the results will be combined into a single matrix. If \code{multiple} is a function, it should take a single argument. This function will be called with the argument set to a matrix containing newly added rows to the value, i.e. it will contain coordinates of the newly selected points (if \code{value = TRUE}), or the indices of the points (if \code{value = FALSE}). It should return a logical value, \code{TRUE} to indicate that selection should continue, \code{FALSE} to indicate that it should stop. In either case, if multiple selections are being performed, the \code{ESC} key will stop the process. } \value{ If \code{value} is \code{TRUE}, a 3-column matrix giving the coordinates of the selected points. All rows in the matrix will be unique even if multiple vertices have the same coordinates. If \code{value} is \code{FALSE}, a 2-column matrix containing columns: \item{id}{The object id containing the point.} \item{index}{The index of the point within \code{\link{rgl.attrib}(id, "vertices")}. If multiple points have the same coordinates, all indices will be returned.} } \author{ Duncan Murdoch } \seealso{ \code{\link{select3d}} to return a selection function. } \examples{ xyz <- cbind(rnorm(20), rnorm(20), rnorm(20)) ids <- plot3d( xyz ) if (interactive()) { # Click near a point to select it and put a sphere there. # Press ESC to quit... # This version returns coordinates selectpoints3d(ids["data"], multiple = function(x) { spheres3d(x, color = "red", alpha = 0.3, radius = 0.2) TRUE }) # This one returns indices selectpoints3d(ids["data"], value = FALSE, multiple = function(ids) { spheres3d(xyz[ids[, "index"], , drop = FALSE], color = "blue", alpha = 0.3, radius = 0.2) TRUE }) } } \keyword{ graphics } rgl/man/scene.Rd0000644000176200001440000000546214146446052013212 0ustar liggesusers\name{scene} \alias{clear3d} \alias{pop3d} \alias{ids3d} \title{Scene management} \description{ Clear shapes, lights, bbox } \usage{ clear3d( type = c("shapes", "bboxdeco", "material"), defaults, subscene = 0 ) pop3d( type = "shapes", id = 0, tag = NULL) ids3d( type = "shapes", subscene = NA, tags = FALSE ) } \arguments{ \item{type}{Select subtype(s): \describe{ \item{"shapes"}{shape stack} \item{"lights"}{light stack} \item{"bboxdeco"}{bounding box} \item{"userviewpoint"}{user viewpoint} \item{"modelviewpoint"}{model viewpoint} \item{"material"}{material properties} \item{"background"}{scene background} \item{"subscene"}{subscene list} \item{"all"}{all of the above} } } \item{defaults}{default values to use after clearing} \item{subscene}{which subscene to work with. \code{NA} means the current one, \code{0} means the whole scene} \item{id}{vector of ID numbers of items to remove} \item{tag}{override \code{id} with objects matching these \code{tag} material properties} \item{tags}{logical; whether to return \code{tag} column.} } \details{ RGL holds several lists of objects in each scene. There are lists for shapes, lights, bounding box decorations, subscenes, etc. \code{clear3d} clears the specified stack, or restores the defaults for the bounding box (not visible) or viewpoint. With \code{id = 0} \code{pop3d} removes the last added node on the list (except for subscenes: there it removes the active subscene). The \code{id} argument may be used to specify arbitrary item(s) to remove; if \code{id != 0}, the \code{type} argument is ignored. \code{clear3d} may also be used to clear material properties back to their defaults. \code{clear3d} has an optional \code{defaults} argument, which defaults to \code{\link{r3dDefaults}}. Only the \code{materials} component of this argument is currently used by \code{clear3d}. \code{ids3d} returns a dataframe containing the IDs in the currently active subscene by default, or a specified subscene, or if \code{subscene = 0}, in the whole rgl window along with an indicator of their type and if \code{tags = TRUE}, the \code{tag} value for each. Note that clearing the light stack leaves the scene in darkness; it should normally be followed by a call to \code{\link{light3d}} or \code{\link{light3d}}. } \seealso{ \code{\link{rgl}}, \code{\link{bbox3d}}, \code{\link{light3d}}, \code{\link{open3d}} to open a new window. } \examples{ x <- rnorm(100) y <- rnorm(100) z <- rnorm(100) p <- plot3d(x, y, z, type = 's', tag = "plot") ids3d() lines3d(x, y, z) ids3d(tags = TRUE) if (interactive() && !rgl.useNULL()) { readline("Hit enter to change spheres") pop3d(id = p["data"]) spheres3d(x, y, z, col = "red", radius = 1/5) box3d() } } \keyword{dynamic} rgl/man/turn3d.Rd0000644000176200001440000000153114145464133013324 0ustar liggesusers\name{turn3d} \alias{turn3d} \title{ Create a solid of rotation from a two-dimensional curve } \description{ This function \dQuote{turns} the curve (as on a lathe) to form a solid of rotation along the x axis. } \usage{ turn3d(x, y = NULL, n = 12, smooth = FALSE, ...) } \arguments{ \item{x, y}{ Points on the curve, in a form suitable for \code{\link{xy.coords}}. The \code{y} values must be non-negative. } \item{n}{ How many steps in the rotation? } \item{smooth}{ logical; whether to add normals for a smooth appearance. } \item{...}{ Additional parameters to pass to \code{\link{tmesh3d}}. } } \value{ A mesh object containing triangles and/or quadrilaterals. } \author{ Fang He and Duncan Murdoch } \seealso{ \code{\link{extrude3d}} } \examples{ x <- 1:10 y <- rnorm(10)^2 open3d() shade3d(turn3d(x, y), col = "green") } \keyword{ graphics } rgl/man/shapelist3d.Rd0000644000176200001440000000345614100762641014334 0ustar liggesusers\name{shapelist3d} \alias{shapelist3d} \title{ Create and plot a list of shapes } \description{ These functions create and plot a list of shapes. } \usage{ shapelist3d(shapes, x = 0, y = NULL, z = NULL, size = 1, matrix = NULL, override = TRUE, ..., plot = TRUE) } \arguments{ \item{shapes}{ A single \code{shape3d} object, or a list of them. } \item{x, y, z}{ Translation(s) to apply } \item{size}{ Scaling(s) to apply } \item{matrix}{ A single matrix transformation, or a list of them. } \item{override}{ Whether the material properties should override the ones in the shapes. } \item{\dots}{ Material properties to apply. } \item{plot}{ Whether to plot the result. } } \details{ \code{shapelist3d} is a quick way to create a complex object made up of simpler ones. Each of the arguments \code{shapes} through \code{override} may be a vector of values (a list in the case of \code{shapes} or \code{matrix}). All values will be recycled to produce a list of shapes as long as the longest of them. The \code{\link{xyz.coords}} function will be used to process the \code{x}, \code{y} and \code{z} arguments, so a matrix may be used as \code{x} to specify all three. If a vector is used for \code{x} but \code{y} or \code{z} is missing, default values of \code{0} will be used. The \code{"shapelist3d"} class is simply a list of \code{"shape3d"} objects. Methods for \code{\link{dot3d}}, \code{\link{wire3d}}, \code{\link{shade3d}}, \code{\link{translate3d}}, \code{\link{scale3d}}, and \code{\link{rotate3d}} are defined for these objects. } \value{ An object of class \code{c("shapelist3d", "shape3d")}. } \author{ Duncan Murdoch } \seealso{ \code{\link{mesh3d}} } \examples{ shapelist3d(icosahedron3d(), x = rnorm(10), y = rnorm(10), z = rnorm(10), col = 1:5, size = 0.3) } \keyword{ dynamic } rgl/man/plotmath3d.Rd0000644000176200001440000000435714142256754014202 0ustar liggesusers\name{plotmath3d} \alias{plotmath3d} \title{ Draw text using base graphics math plotting } \description{ To plot mathematical text, this function uses base graphics functions to plot it to a \file{.png} file, then uses that file as a texture in a sprite. } \usage{ plotmath3d(x, y = NULL, z = NULL, text, cex = par("cex"), adj = 0.5, pos = NULL, offset = 0.5, fixedSize = TRUE, startsize = 480, initCex = 5, ...) } \arguments{ \item{x, y, z}{coordinates. Any reasonable way of defining the coordinates is acceptable. See the function \code{\link[grDevices]{xyz.coords}} for details.} \item{text}{ A character vector or expression. See \code{\link[grDevices]{plotmath}} for how expressions are interpreted. } \item{cex}{ Character size expansion. } \item{adj}{ one value specifying the horizontal adjustment, or two, specifying horizontal and vertical adjustment respectively, or three, for depth as well. } \item{pos, offset}{ alternate way to specify \code{adj}; see \code{\link{text3d}}} \item{fixedSize}{ Should the resulting sprite behave like the default ones, and resize with the scene, or like text, and stay at a fixed size? } \item{startsize, initCex}{ These parameters are unlikely to be needed by users. \code{startsize} is an over-estimate of the size (in pixels) of the largest expression. Increase this if large expressions are cut off. \code{initCex} is the size of text used to form the bitmap. Increase this if letters look too blurry at the desired size. } \item{\dots}{ Additional arguments to pass to \code{\link[graphics]{text}} when drawing the text. } } \note{ The \code{\link{text3d}} function passes calls to this function if its \code{usePlotmath} argument is \code{TRUE}. The default value is determined by examining its \code{texts} argument; if it looks like an expression, \code{plotmath3d} is used. } \value{ Called for the side effect of displaying the sprites. The shape ID of the displayed object is returned. } \author{ Duncan Murdoch } \seealso{ \code{\link{text3d}} } \examples{ open3d() plotmath3d(1:3, 1:3, 1:3, expression(x[1] == 1, x[2] == 2, x[3] == 3)) # This lets the text resize with the plot text3d(4, 4, 4, "resizeable text", usePlotmath = TRUE, fixedSize = FALSE) }rgl/man/rgl.select.Rd0000644000176200001440000000144014100762641014142 0ustar liggesusers\name{rgl.select} \alias{rgl.select} \title{ Switch to select mode, and return the mouse position selected } \description{ Mostly for internal use, this function temporarily installs a handler on a button of the mouse that will return the mouse coordinates of one click and drag rectangle. } \usage{ rgl.select(button = c("left", "middle", "right"), dev = cur3d(), subscene = currentSubscene3d(dev)) } \arguments{ \item{button}{ Which button to use? } \item{dev, subscene}{ The RGL device and subscene to work with } } \value{ A vector of four coordinates: the X and Y coordinates of the start and end of the dragged rectangle. } \author{ Duncan Murdoch } \seealso{ \code{\link{rgl.select3d}}, a version that allows the selection region to be used to select points in the scene. } rgl/man/bg.Rd0000644000176200001440000000665114100762640012500 0ustar liggesusers\name{bg3d} \alias{rgl.bg} \alias{bg3d} \title{Set up background} \description{ Set up the background of the scene. } \usage{ bg3d(...) rgl.bg( sphere = FALSE, fogtype = "none", color = c("black", "white"), back = "lines", fogScale = 1, ...) } \arguments{ \item{fogtype}{fog type: \describe{ \item{"none"}{no fog} \item{"linear"}{linear fog function} \item{"exp"}{exponential fog function} \item{"exp2"}{squared exponential fog function} } Fog only applies to objects with \code{\link{material3d}} property \code{fog} set to \code{TRUE}. } \item{sphere}{ logical, if true, an environmental sphere geometry is used for the background decoration. } \item{color}{ Primary color is used for background clearing and as fog color. Secondary color is used for background sphere geometry. See \code{\link{material3d}} for details. } \item{back}{ Specifies the fill style of the sphere geometry. See \code{\link{material3d}} for details. } \item{fogScale}{ Scaling for fog. See Details. } \item{ ... }{Material properties. See \code{\link{material3d}} for details.} } \details{ If sphere is set to \code{TRUE}, an environmental sphere enclosing the whole scene is drawn. If not, but the material properties include a bitmap as a texture, the bitmap is drawn in the background of the scene. (The bitmap colors modify the general color setting.) If neither a sphere nor a bitmap background is drawn, the background is filled with a solid color. The \code{fogScale} parameter should be a positive value to change the density of the fog in the plot. For \code{fogtype = "linear"} it multiplies the density of the fog; for the exponential fog types it multiplies the density parameter used in the display. See \href{https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glFog.xml}{the OpenGL 2.1 reference} for the formulas used in the fog calculations within \R (though the \code{"exp2"} formula appears to be wrong, at least on my system). In WebGL displays, the following rules are used. They appear to match the rules used in \R on my system. \itemize{ \item{For \code{"linear"} fog, the near clipping plane is taken as \eqn{c=0}, and the far clipping plane is taken as \eqn{c=1}. The amount of fog is \eqn{s * c} clamped to a 0 to 1 range, where \eqn{s = fogScale}.} \item{For \code{"exp"} and \code{"exp2"} fog, the observer location is negative at a distance depending on the field of view. The formula for the distance is \deqn{c = [1-sin(theta)]/[1 + sin(theta)]} where \eqn{theta = FOV/2}. We calculate \deqn{c' = d(1-c) + c} so \eqn{c'} runs from 0 at the observer to 1 at the far clipping plane.} \item{For \code{"exp"} fog, the amount of fog is \eqn{1 - exp(-s * c')}.} \item{For \code{"exp2"} fog, the amount of fog is \eqn{1 - exp[-(s * c')^2]}.} } } \examples{ open3d() # a simple white background bg3d("white") # the holo-globe (inspired by star trek): bg3d(sphere = TRUE, color = c("black", "green"), lit = FALSE, back = "lines" ) # an environmental sphere with a nice texture. bg3d(sphere = TRUE, texture = system.file("textures/sunsleep.png", package = "rgl"), back = "filled" ) # The same texture as a fixed background open3d() bg3d(texture = system.file("textures/sunsleep.png", package = "rgl"), col = "white") } \seealso{ \code{\link{material3d}}, \code{\link{bgplot3d}} to add a 2D plot as background. } \keyword{dynamic} rgl/man/check3d.Rd0000644000176200001440000000070314100762640013404 0ustar liggesusers\name{.check3d} \alias{.check3d} \alias{check3d} \title{ Check for an open RGL window. } \description{ Mostly for internal use, this function returns the current device number if one exists, or opens a new device and returns that. } \usage{ .check3d() } \value{ The device number of an RGL device. } \author{ Duncan Murdoch } \seealso{ \code{\link{open3d}} } \examples{ rgl.dev.list() .check3d() rgl.dev.list() .check3d() rgl.dev.list() rgl.close() } rgl/man/primitive.Rd0000644000176200001440000000645414145464133014126 0ustar liggesusers\name{rgl.primitive} \alias{rgl.primitive} \alias{rgl.points} \alias{rgl.lines} \alias{rgl.linestrips} \alias{rgl.triangles} \alias{rgl.quads} \title{Add primitive set shape} \description{ Adds a shape node to the current scene. These low-level functions should not normally be called by users. } \usage{ rgl.points(x, y = NULL, z = NULL, ... ) rgl.lines(x, y = NULL, z = NULL, ... ) rgl.linestrips(x, y = NULL, z = NULL, ...) rgl.triangles(x, y = NULL, z = NULL, normals = NULL, texcoords = NULL, ... ) rgl.quads(x, y = NULL, z = NULL, normals = NULL, texcoords = NULL, ... ) } \arguments{ \item{x, y, z}{coordinates. Any reasonable way of defining the coordinates is acceptable. See the function \code{\link[grDevices]{xyz.coords}} for details.} \item{normals}{Normals at each point.} \item{texcoords}{Texture coordinates at each point.} \item{ ... }{Material properties (see \code{\link{rgl.material}} for details) or \code{indices} (see the note below).} } \details{ Adds a shape node to the scene. The appearance is defined by the material properties. See \code{\link{rgl.material}} for details. The names of these functions correspond to OpenGL primitives. They all take a sequence of vertices in \code{x, y, z}. The only non-obvious ones are \code{rgl.lines} which draws line segments based on pairs of vertices, and \code{rgl.linestrips} which joins the vertices. For triangles and quads, the normals at each vertex may be specified using \code{normals}. These may be given in any way that would be acceptable as a single argument to \code{\link[grDevices]{xyz.coords}}. These need not match the actual normals to the polygon: curved surfaces can be simulated by using other choices of normals. Texture coordinates may also be specified. These may be given in any way that would be acceptable as a single argument to \code{\link[grDevices]{xy.coords}}, and are interpreted in terms of the bitmap specified as the material texture, with \code{(0, 0)} at the lower left, \code{(1, 1)} at the upper right. The texture is used to modulate the color of the polygon. These are the lower level functions called by \code{\link{points3d}}, \code{\link{segments3d}}, \code{\link{lines3d}}, etc. The two principal differences between the \code{rgl.*} functions and the \code{*3d} functions are that the former set all unspecified material properties to defaults, whereas the latter use current values as defaults; the former make persistent changes to material properties with each call, whereas the latter make temporary changes only for the duration of the call. } \note{ All of these functions support an argument called \code{indices}, which allows vertices (and other attributes) to be re-used, as they are in objects created by \code{\link{mesh3d}} and related functions. This is intended to be used on smooth surfaces, where each shared vertex has just one value for normals, colors and texture coordinates. For shapes with flat-looking faces (e.g. polyhedra like \code{\link{cube3d}}), the vertices \bold{must} be duplicated to be rendered properly. } \value{ Each primitive function returns the integer object ID of the shape that was added to the scene. These can be passed to \code{\link{pop3d}} to remove the object from the scene. } \keyword{internal} rgl/man/sceneChange.Rd0000644000176200001440000000470214100762641014307 0ustar liggesusers\name{sceneChange} \alias{sceneChange} \alias{registerSceneChange} \title{ Make large change to a scene from Shiny } \description{ These functions allow Shiny apps to make relatively large changes to a scene, adding and removing objects from it. } \usage{ sceneChange(elementId, x = scene3d(minimal), delete = NULL, add = NULL, replace = NULL, material = FALSE, rootSubscene = FALSE, delfromSubscenes = NULL, skipRedraw = FALSE, minimal = TRUE) registerSceneChange() } \arguments{ \item{elementId}{ The id of the element holding the \code{rglClass} instance. } \item{x}{ The new scene to use as a source for objects to add. } \item{delete, add, replace}{ Object ids to modify in the scene. The \code{delete} and \code{replace} ids must be present in the old scene in the browser; the \code{add} and \code{replace} ids must be present in \code{x}. } \item{material}{ Logical to indicate whether default material should be updated. } \item{rootSubscene}{ Logical to indicate whether root subscene should be updated. } \item{delfromSubscenes}{ A vector of subscene ids that may have been changed by deletions. By default, all subscenes in \code{x} are used, but the objects may be included in subscenes in the browser that are different. } \item{skipRedraw}{ If \code{TRUE}, stop the scene from redrawing until \code{skipRedraw=FALSE} is sent. If \code{NA}, don't redraw this time, but don't change the state of the \code{skipRedraw} flag. } \item{minimal}{ See \code{\link{scene3d}}. } } \details{ \code{registerSceneChange} must be called in the UI component of a Shiny app to register the \code{"sceneChange"} custom message. } \value{ \code{registerSceneChange} returns the HTML code to register the message. \code{sceneChange} returns a list to be used as the \code{"sceneChange"} message to change the scene. Use \code{\link[shiny:session]{shiny::session$sendCustomMessage}} to send it. } \author{ Duncan Murdoch } \seealso{ \code{\link{playwidget}} for a different approach to modifying scenes that can be much faster, but may be less flexible. The Shiny demo in this package makes use of all of these approaches. } \examples{ \dontrun{ shinyUI(fluidPage( registerSceneChange(), actionButton("thebutton", "Change") )) shinyServer(function(input, output, session) { observeEvent(input$thebutton, { session$sendCustomMessage("sceneChange", sceneChange("thewidget", delete = deletes, add = adds)) }) }) } } rgl/man/observer3d.Rd0000644000176200001440000000312014100762640014152 0ustar liggesusers\name{observer3d} \alias{observer3d} \title{ Set the observer location } \description{ This function sets the location of the viewer. } \usage{ observer3d(x, y = NULL, z = NULL, auto = FALSE) } \arguments{ \item{x, y, z}{ The location as a 3 vector, using the usual \code{xyz.coords} conventions for specification. If \code{x} is missing or any coordinate is \code{NA}, no change will be made to the location. } \item{auto}{ If \code{TRUE}, the location will be set automatically by RGL to make the whole bounding box visible. } } \details{ This function sets the location of the viewer relative to the scene, after the model transformations (scaling, rotation) have been done, but before lighting or projection have been applied. (See \code{\link{par3d}} for details on the rendering pipeline.) The coordinate system is a slightly strange one: the X coordinate moves the observer location from left to right, and the Y coordinate moves up and down. The Z coordinate changes the depth from the viewer. All are measured relative to the center of the bounding box (\code{par("bbox")}) of the subscene. The observer always looks in the positive Z direction after the model rotation have been done. The coordinates are in post-scaling units. } \note{ This function is likely to change in future versions of RGL, to allow more flexibility in the specification of the observer's location and orientation. } \value{ Invisibly returns the previous value. } \author{ Duncan Murdoch } \examples{ example(surface3d) # The volcano data observer3d(0, 0, 440) # Viewed from very close up } \keyword{ graphics } rgl/man/bgplot3d.Rd0000644000176200001440000000422314145464133013624 0ustar liggesusers\name{bgplot3d} \alias{bgplot3d} \alias{legend3d} \title{Use base graphics for RGL background} \description{ Add a 2D plot or a legend in the background of an RGL window. } \usage{ bgplot3d(expression, bg.color = getr3dDefaults("bg", "color"), magnify = 1, ...) legend3d(...) } \arguments{ \item{expression}{ Any plotting commands to produce a plot. } \item{bg.color}{ The color to use for the background. } \item{magnify}{ Multiplicative factor to apply to size of window when producing background plot. } \item{...}{ For \code{legend3d}, arguments to pass to \code{bgplot3d} or \code{\link{legend}}; for \code{bgplot3d}, arguments to pass to \code{\link{bg3d}}. } } \details{ The \code{bgplot3d} function opens a \code{\link{png}} device and executes \code{expression}, producing a plot there. This plot is then used as a bitmap background for the current RGL subscene. The \code{legend3d} function draws a standard 2D legend to the background of the current subscene by calling \code{bgplot3d} to open a device, and setting up a plot region there to fill the whole display. } \value{ The \code{bgplot3d} function invisibly returns the ID of the background object that was created, with attribute \code{"value"} holding the value returned when the \code{expression} was evaluated. The \code{legend3d} function does similarly. The \code{"value"} attribute is the result of the call to \code{\link{legend}}. The scaling of the coordinates runs from 0 to 1 in X and Y. } \author{ Duncan Murdoch } \note{ Because the background plots are drawn as bitmaps, they do not resize very gracefully. It's best to size your window first, then draw the background at that size. } \seealso{ \code{\link{bg3d}} for other background options. } \examples{ x <- rnorm(100) y <- rnorm(100) z <- rnorm(100) open3d() # Needs to be a bigger window than the default par3d(windowRect = c(100, 100, 612, 612)) parent <- currentSubscene3d() mfrow3d(2, 2) plot3d(x, y, z) next3d(reuse = FALSE) bgplot3d(plot(y, z)) next3d(reuse = FALSE) bgplot3d(plot(x, z)) next3d(reuse = FALSE) legend3d("center", c("2D Points", "3D Points"), pch = c(1, 16)) useSubscene3d(parent) } \keyword{ graphics } rgl/man/par3dinterp.Rd0000644000176200001440000000605014100762640014334 0ustar liggesusers\name{par3dinterp} \alias{par3dinterp} \title{Interpolator for par3d parameters} \description{ Returns a function which interpolates \code{par3d} parameter values, suitable for use in animations. } \usage{ par3dinterp(times = NULL, userMatrix, scale, zoom, FOV, method = c("spline", "linear"), extrapolate = c("oscillate", "cycle", "constant", "natural"), dev = cur3d(), subscene = par3d("listeners", dev = dev)) } \arguments{ \item{times}{ Times at which values are recorded or a list; see below } \item{userMatrix}{ Values of \code{par3d("userMatrix")} } \item{scale}{ Values of \code{par3d("scale")} } \item{zoom}{ Values of \code{par3d("zoom")} } \item{FOV}{ Values of \code{par3d("FOV")} } \item{method}{ Method of interpolation } \item{extrapolate}{ How to extrapolate outside the time range } \item{dev}{ Which RGL device to use } \item{subscene}{ Which subscene to use } } \details{ This function is intended to be used in constructing animations. It produces a function that returns a list suitable to pass to \code{\link{par3d}}, to set the viewpoint at a given point in time. All of the parameters are optional. Only those \code{par3d} parameters that are specified will be returned. The input values other than \code{times} may each be specified as lists, giving the parameter value settings at a fixed time, or as matrices or arrays. If not lists, the following formats should be used: \code{userMatrix} can be a \code{4 x 4 x n} array, or a \code{4 x 4n} matrix; \code{scale} should be an \code{n x 3} matrix; \code{zoom} and \code{FOV} should be length \code{n} vectors. An alternative form of input is to put all of the above arguments into a list (i.e. a list of lists, or a list of arrays/matrices/vectors), and pass it as the first argument. This is the most convenient way to use this function with the function \code{\link{tkpar3dsave}}. Interpolation is by cubic spline or linear interpolation in an appropriate coordinate-wise fashion. Extrapolation may oscillate (repeat the sequence forward, backward, forward, etc.), cycle (repeat it forward), be constant (no repetition outside the specified time range), or be natural (linear on an appropriate scale). In the case of cycling, the first and last specified values should be equal, or the last one will be dropped. Natural extrapolation is only supported with spline interpolation. } \value{ A function is returned. The function takes one argument, and returns a list of \code{par3d} settings interpolated to that time. } \note{ Prior to \pkg{rgl} version 0.95.1476, the \code{subscene} argument defaulted to the current subscene, and any additional entries would be ignored by \code{\link{play3d}}. The current default value of \code{par3d("listeners", dev = dev)} means that all subscenes that share mouse responses will also share modifications by this function. } \author{Duncan Murdoch } \seealso{ \code{\link{play3d}} to play the animation. } \examples{ f <- par3dinterp( zoom = c(1, 2, 3, 1) ) f(0) f(1) f(0.5) \dontrun{ play3d(f) } } \keyword{ dplot } rgl/man/subdivision3d.Rd0000644000176200001440000000416114100762641014670 0ustar liggesusers\name{subdivision3d} \alias{subdivision3d} \alias{subdivision3d.mesh3d} \alias{divide.mesh3d} \alias{normalize.mesh3d} \alias{deform.mesh3d} \title{Subdivide a mesh} \description{ The subdivision surface algorithm divides and refines (deforms) a given mesh recursively to certain degree (depth). The mesh3d algorithm consists of two stages: divide and deform. The divide step generates for each triangle or quad four new triangles or quads, the deform step drags the points (refinement step). } \usage{ subdivision3d( x, ...) \method{subdivision3d}{mesh3d}( x, depth = 1, normalize = FALSE, deform = TRUE, ... ) divide.mesh3d(mesh, vb = mesh$vb, ib = mesh$ib, it = mesh$it ) normalize.mesh3d(mesh) deform.mesh3d(mesh, vb = mesh$vb, ib = mesh$ib, it = mesh$it ) } \arguments{ \item{x}{3d geometry mesh} \item{mesh}{3d geometry mesh} \item{depth}{recursion depth} \item{normalize}{normalize mesh3d coordinates after division if \code{deform} is \code{TRUE}} \item{deform}{deform mesh} \item{it}{indices for triangular faces} \item{ib}{indices for quad faces} \item{vb}{matrix of vertices: 4 x n matrix (rows x, y, z, h) or equivalent vector, where h indicates scaling of each plotted quad} \item{...}{other arguments (unused)} } \details{ \code{subdivision3d} takes a mesh object and replaces each triangle or quad with 4 new ones by adding vertices half-way along the edges (and one in the centre of a quad). The positions of the vertices are deformed so that the resulting surface is smoother than the original. These operations are repeated \code{depth} times. The other functions do the individual steps of the subdivision. \code{divide.mesh3d} adds the extra vertices. \code{deform.mesh3d} does the smoothing by replacing each vertex with the average of each of its neighbours. \code{normalize.mesh3d} normalizes the homogeneous coordinates, by setting the 4th coordinate to 1. (The 4th coordinate is used as a weight in the deform step.) } \examples{ open3d() shade3d( subdivision3d( cube3d(), depth = 3 ), color = "red", alpha = 0.5 ) } \seealso{ \code{\link{r3d}} \code{\link{mesh3d}} } \keyword{dynamic} rgl/man/rgl.fns.Rd0000644000176200001440000000313414146446052013460 0ustar liggesusers\name{rgl.fns} \alias{rgl.abclines} \alias{rgl.planes} \alias{rgl.clipplanes} \alias{rgl.sprites} \alias{rgl.spheres} \alias{rgl.clear} \alias{rgl.pop} \alias{rgl.ids} \title{ Low level functions that should not be called by users. } \description{ These functions provide the implementation for various \code{*3d} functions designed for users to call. } \usage{ rgl.abclines(x, y = NULL, z = NULL, a, b = NULL, c = NULL, ...) rgl.planes(a, b = NULL, c = NULL, d = 0, ...) rgl.clipplanes(a, b = NULL, c = NULL, d = 0) rgl.sprites(x, y = NULL, z = NULL, radius = 1, shapes = NULL, userMatrix, fixedSize = FALSE, adj = 0.5, pos = NULL, offset = 0.25, ...) rgl.spheres(x, y = NULL, z = NULL, radius, fastTransparency = TRUE, ...) rgl.clear( type = "shapes", subscene = 0 ) rgl.pop( type = "shapes", id = 0, tag = NULL ) rgl.ids( type = "shapes", subscene = NA, tags = FALSE ) } \arguments{ \item{x, y, z}{ Coordinates of points } \item{a, b, c}{ Coordinates of the direction vectors for the lines, or normals for the planes. } \item{d}{Plane offset.} \item{radius}{Size of sprites or spheres.} \item{fastTransparency}{Sphere drawing strategy.} \item{type, id, subscene}{Selecting objects.} \item{adj, pos, offset}{Positioning.} \item{tag}{Select objects with material property \code{tag} in this vector.} \item{tags}{Whether to return tags.} \item{...}{ Material properties. } } \details{ See the corresponding \code{*3d} function: \code{\link{abclines3d}}, \code{\link{planes3d}}, \code{\link{clipplanes3d}}, \code{\link{sprites3d}}, \code{\link{spheres3d}}. } \keyword{internal} rgl/man/plot3d.lm.Rd0000644000176200001440000000763514100762641013730 0ustar liggesusers\name{plot3d.lm} \alias{plot3d.lm} \title{ Method for plotting simple linear fit } \description{ This function provides several plots of the result of fitting a two-predictor model. } \usage{ \method{plot3d}{lm}(x, which = 1, plane.col = "gray", plane.alpha = 0.5, sharedMouse = TRUE, use_surface3d, do_grid = TRUE, grid.col = "black", grid.alpha = 1, grid.steps = 5, sub.steps = 4, vars = get_all_vars(terms(x), x$model), clip_to_density = 0, ...) } \arguments{ \item{x}{ An object inheriting from class \code{"lm"} obtained by fitting a two-predictor model. } \item{which}{ Which plot to show? See Details below. } \item{plane.col, plane.alpha}{ These parameters control the colour and transparency of a plane or surface. } \item{sharedMouse}{ If multiple plots are requested, should they share mouse controls, so that they move in sync? } \item{use_surface3d}{ Use the \code{\link{surface3d}} function to plot the surface rather than \code{\link{planes3d}}. This allows curved surfaces to be shown. The default is \code{FALSE} if the model looks like a simple 2 parameter linear fit, otherwise \code{TRUE}. } \item{do_grid}{Plot a grid.} \item{grid.col, grid.alpha, grid.steps}{ Characteristics of the grid. } \item{sub.steps}{If \code{use_surface3d} is \code{TRUE}, use an internal grid of \code{grid.steps*sub.steps} to draw the surface. \code{sub.steps > 1} allows curvature within facets. Similarly, if \code{do_grid} is \code{TRUE}, it allows curvature within grid lines.} \item{vars}{A dataframe containing the variables to plot in the first three columns, with the response assumed to be in column 1. See the Note below.} \item{clip_to_density}{ If positive, the surface, plane or grid will be clipped to a region with sufficient data. } \item{\dots}{ Other parameters to pass to the default \code{\link{plot3d}} method, to control the appearance of aspects of the plot other than the plane. } } \details{ Three plots are possible, depending on the value(s) in \code{which}: \enumerate{ \item{(default) Show the points and the fitted plane or surface.} \item{Show the residuals and the plane at \code{z = 0}.} \item{Show the predicted values on the fitted plane or surface.} } If \code{clip_to_density} is positive, then the surface, plane or grid will be clipped to the region where a non-parametric density estimate (using \code{MASS::\link{kde2d}}), normalized to have a maximum value of 1, is greater than the given value. This will suppress parts of the plot that aren't supported by the observed data. } \value{ Called for the side effect of drawing one or more plots. Invisibly returns a high-level vector of object ids. Names of object ids have the plot number (in drawing order) appended. } \note{ The default value for the \code{vars} argument will handle simple linear models with a response and two predictors, and some models with functions of those two predictors. For models that fail (e.g. models using \code{\link{poly}}), you can include the observed values as in the third example below. If \code{clip_to_density > 0}, \enumerate{ \item{The clipping is approximate, so it may not agree perfectly between surfaces, planes and grids.} \item{This option requires the suggested packages \pkg{MASS} and \pkg{akima}, and will be ignored with a warning if either is not installed.} } } \author{ Duncan Murdoch } \examples{ open3d() ids <- plot3d(lm(mpg ~ wt + qsec, data = mtcars), which = 1:3) names(ids) open3d() plot3d(lm(mpg ~ wt + I(wt^2) + qsec, data = mtcars)) open3d() # Specify vars in the order: response, pred1, pred2. plot3d(lm(mpg ~ poly(wt, 3) + qsec, data = mtcars), vars = mtcars[,c("mpg", "wt", "qsec")]) open3d() # Clip parts of the plot with few (wt, qsec) points plot3d(lm(mpg ~ poly(wt, 3) + qsec, data = mtcars), vars = mtcars[,c("mpg", "wt", "qsec")], clip_to_density = 0.1) } rgl/man/rglMouse.Rd0000644000176200001440000000540614100762641013703 0ustar liggesusers\name{rglMouse} \alias{rglMouse} \title{ Generate HTML code to select mouse mode } \description{ This generates an HTML \code{select} element to choose among the mouse modes supported by \code{\link{rglwidget}}. } \usage{ rglMouse(sceneId, choices = c("trackball", "selecting", "xAxis", "yAxis", "zAxis", "polar", "zoom", "fov", "none"), labels = choices, button = 1, dev = cur3d(), subscene = currentSubscene3d(dev), default = par3d("mouseMode", dev = dev, subscene = subscene)[button], stayActive = FALSE, height = 40, ...) } \arguments{ \item{sceneId}{ Either an \code{\link{rglwidget}} or the \code{elementId} from one of them. } \item{choices}{ Which mouse modes to support? } \item{labels}{ How to label each mouse mode. } \item{button}{ Which mouse button is being controlled. } \item{dev}{ The RGL device used for defaults. } \item{subscene}{ Which subscene is being modified. } \item{default}{ What is the default entry to show in the control. } \item{stayActive}{ Whether a selection brush should stay active if the mouse mode is changed. } \item{height}{ The (relative) height of the item in the output display. } \item{...}{ Additional arguments to pass to \code{htmltools::tags$select()}, e.g. \code{id} or \code{class}. } } \details{ A result of an \code{\link{rglwidget}} call can be passed as the \code{sceneId} argument. This allows the widget to be \dQuote{piped} into the \code{rglMouse} call. The widget will appear first, the selector next in a \code{\link[htmltools:tag]{tagList}}. If the \code{sceneId} is a character string, it should be the \code{elementId} of a separately constructed \code{\link{rglwidget}} result. Finally, the \code{sceneId} can be omitted. In this case the \code{rglMouse} result needs to be passed into an \code{\link{rglwidget}} call as part of the \code{controllers} argument. This will place the selector before the widget on the resulting display. If the mouse mode is changed while brushing the scene, by default the brush will be removed (and so the selection will be cleared too). If this is not desired, set \code{stayActive = TRUE}. } \value{ A browsable value to put in a web page. } \author{ Duncan Murdoch } \examples{ if (interactive() || in_pkgdown_example()) { open3d() xyz <- matrix(rnorm(300), ncol = 3) id <- plot3d(xyz, col = "red", type = "s")["data"] par3d(mouseMode = "selecting") share <- rglShared(id) # This puts the selector below the widget. rglwidget(shared = share, width = 300, height = 300) \%>\% rglMouse() # This puts the selector above the widget. rglMouse() \%>\% rglwidget(shared = share, width = 300, height = 300, controllers = .) } } rgl/man/subsceneInfo.Rd0000644000176200001440000000274014100762641014527 0ustar liggesusers\name{subsceneInfo} \alias{subsceneInfo} \title{ Get information on subscenes } \description{ This function retrieves information about the tree of subscenes shown in the active window. } \usage{ subsceneInfo(id = NA, embeddings, recursive = FALSE) } \arguments{ \item{id}{ Which subscene to report on; \code{NA} is the current subscene. Set to \code{"root"} for the root. } \item{embeddings}{ Optional new setting for the embeddings for this subscene. } \item{recursive}{ Whether to report on children recursively. } } \details{ In RGL, each window contains a tree of \dQuote{subscenes}, each containing views of a subset of the objects defined in the window. Rendering in each subscene depends on the viewport, the projection, and the model transformation. Each of these characteristics may be inherited from the parent (\code{embedding[i] = "inherit"}), may modify the parent (\code{embedding[i] = "modify"}), or may replace the parent (\code{embedding[i] == "replace"}). All three must be specified if \code{embeddings} is used. } \value{ \item{id}{The object id of the subscene} \item{parent}{The object id of the parent subscene, if any} \item{children}{If \code{recursive}, a list of the information for the children, otherwise just their object ids.} \item{embedding}{A vector of 3 components describing how this subscene is embedded in its parent. } } \author{ Duncan Murdoch } \seealso{ \code{\link{newSubscene3d}} } \examples{ example(plot3d) subsceneInfo() } \keyword{ graphics } rgl/man/material.Rd0000644000176200001440000002214414145464133013706 0ustar liggesusers\name{rgl.material} \alias{rgl.material} \alias{material3d} \title{Set material properties} \description{ Set material properties for geometry appearance. } \usage{ rgl.material( color = "white", alpha = 1.0, lit = TRUE, ambient = "black", specular = "white", emission = "black", shininess = 50.0, smooth = TRUE, texture = NULL, textype = "rgb", texmipmap = FALSE, texminfilter = "linear", texmagfilter = "linear", texenvmap = FALSE, front = "fill", back = "fill", size = 3.0, lwd = 1.0, fog = TRUE, point_antialias = FALSE, line_antialias = FALSE, depth_mask = TRUE, depth_test = "less", polygon_offset = c(0.0, 0.0), margin = "", floating = FALSE, tag = "", ... ) material3d(...) } \arguments{ \item{color}{ vector of R color characters. Represents the diffuse component in case of lighting calculation (lit = TRUE), otherwise it describes the solid color characteristics. } \item{lit}{ logical, specifying if lighting calculation should take place on geometry } \item{ambient, specular, emission, shininess}{ properties for lighting calculation. ambient, specular, emission are R color character string values; shininess represents a numerical. } \item{alpha}{ vector of alpha values between 0.0 (fully transparent) .. 1.0 (opaque). } \item{smooth}{ logical, specifying whether Gouraud shading (smooth) or flat shading should be used. } \item{texture}{ path to a texture image file. Supported formats: png. } \item{textype}{ specifies what is defined with the pixmap \describe{ \item{"alpha"}{alpha values} \item{"luminance"}{luminance} \item{"luminance.alpha"}{luminance and alpha} \item{"rgb"}{color} \item{"rgba"}{color and alpha texture} } } \item{texmipmap}{ Logical, specifies if the texture should be mipmapped. } \item{texmagfilter}{ specifies the magnification filtering type (sorted by ascending quality): \describe{ \item{"nearest"}{texel nearest to the center of the pixel} \item{"linear"}{weighted linear average of a 2x2 array of texels} } } \item{texminfilter}{ specifies the minification filtering type (sorted by ascending quality): \describe{ \item{"nearest"}{texel nearest to the center of the pixel} \item{"linear"}{weighted linear average of a 2x2 array of texels} \item{"nearest.mipmap.nearest"}{low quality mipmapping} \item{"nearest.mipmap.linear"}{medium quality mipmapping} \item{"linear.mipmap.nearest"}{medium quality mipmapping} \item{"linear.mipmap.linear"}{high quality mipmapping} } } \item{texenvmap}{ logical, specifies if auto-generated texture coordinates for environment-mapping should be performed on geometry. } \item{front, back}{ Determines the polygon mode for the specified side: \describe{ \item{"filled"}{filled polygon} \item{"lines"}{wireframed polygon} \item{"points"}{point polygon} \item{"culled"}{culled (hidden) polygon} } } \item{size}{ numeric, specifying the size of points in pixels } \item{lwd}{ numeric, specifying the line width in pixels } \item{fog}{logical, specifying if fog effect should be applied on the corresponding shape. Fog type is set in \code{\link{bg3d}}.} \item{point_antialias, line_antialias}{logical, specifying if points should be round and lines should be antialiased, but see Note below.} \item{depth_mask}{logical, specifying whether the object's depth should be stored.} \item{depth_test}{Determines which depth test is used to see if this object is visible, depending on its apparent depth in the scene compared to the stored depth. Possible values are \code{"never"}, \code{"less"} (the default), \code{"equal"}, \code{"lequal"} (less than or equal), \code{"greater"}, \code{"notequal"}, \code{"gequal"} (greater than or equal), \code{"always"}.} \item{polygon_offset}{If non-zero, offsets are added to the recorded depth of filled polygons. See Details below.} \item{margin, floating}{Used mainly for text to draw annotations in the margins, but supported by most kinds of objects: see \code{\link{mtext3d}}.} \item{tag}{A length 1 string value. These may be used to identify objects, or encode other meta data about the object.} \item{...}{Any of the arguments above can be passed to \code{material3d}; see Details below. \code{rgl.material} will ignore others.} } \details{ Values can be queried by specifying their names in a character vector, e.g. \code{material3d("color")}. There is one read-only property that can be queried but not set: \describe{ \item{isTransparent}{Is the current color transparent?} } Only one side at a time can be culled. Object display colors are determined as follows: \itemize{ \item{If \code{lit = FALSE}, an element of the \code{color} vector property is displayed without modification. See documentation for individual objects for information on which element is chosen.} \item{If \code{lit = TRUE}, the color is determined as follows.} \enumerate{ \item{The color is set to the \code{emission} property of the object. } \item{For each defined light, the following are added: \itemize{ \item{the product of the \code{ambient} color of the light and the \code{ambient} color of the object is added.} \item{the \code{color} of the object is multiplied by the \code{diffuse} color of the light and by a constant depending on the angle between the surface and the direction to the light, and added.} \item{the \code{specular} color of the object is multiplied by the \code{specular} color of the light and a constant depending on the \code{shininess} of the object and the direction to the light, and added. The \code{shininess} property mainly determines the size of the shiny highlight; adjust one or both of the \code{specular} colors to change its brightness.} } } } } The \code{polygon_offset} property is a two element vector giving the \samp{factor} and \samp{units} values to use in a \code{glPolygonOffset()} call in OpenGL. If only one value is given, it is used for both elements. The \samp{units} value is added to the depth of all pixels in a filled polygon, and the \samp{factor} value is multiplied by an estimate of the slope of the polygon and then added to the depth. Positive values \dQuote{push} polygons back slightly for the purpose of depth testing, to allow points, lines or other polygons to be drawn on the surface without being obscured due to rounding error. Negative values pull the object forward. A typical value to use is \code{1} (which is automatically expanded to \code{c(1,1)}). If values are too large, objects which should be behind the polygon will show through, and if values are too small, the objects on the surface will be partially obscured. Experimentation may be needed to get it right. The first example in \code{?\link{persp3d}} uses this property to add grid lines to a surface. \code{material3d} is an alternate interface to the material properties, modelled after \code{\link{par3d}}: rather than setting defaults for parameters that are not specified, they will be left unchanged. \code{material3d} may also be used to query the material properties; see the examples below. The current implementation does not return parameters for textures. The \code{material} member of the \code{\link{r3dDefaults}} list may be used to set default values for material properties. The \code{...} parameter to \code{rgl.material} is ignored. } \value{ \code{rgl.material()} is called for the side effect of setting the material properties. It returns a value invisibly which is not intended for use by the user. Users should use \code{material3d()} to query material properties. It returns values similarly to \code{\link{par3d}} as follows: When setting properties, it returns the previous values in a named list. A named list is also returned when more than one value is queried. When a single value is queried it is returned directly. } \note{ If \code{point_antialias} is \code{TRUE}, points will be drawn as circles in WebGL; otherwise, they will be drawn as squares. Within R, the behaviour depends on your graphics hardware: for example, I see circles for both settings on my laptop. Within R, lines tend to appear heavier with \code{line_antialias == TRUE}. There's no difference at all in WebGL. } \seealso{ \code{\link{rgl.primitive}}, \code{\link{rgl.bbox}}, \code{\link{rgl.bg}}, \code{\link{rgl.light}} } \examples{ save <- material3d("color") material3d(color = "red") material3d("color") material3d(color = save) # this illustrates the effect of depth_test x <- c(1:3); xmid <- mean(x) y <- c(2, 1, 3); ymid <- mean(y) z <- 1 open3d() tests <- c("never", "less", "equal", "lequal", "greater", "notequal", "gequal", "always") for (i in 1:8) { triangles3d(x, y, z + i, col = heat.colors(8)[i]) texts3d(xmid, ymid, z + i, paste(i, tests[i], sep = ". "), depth_test = tests[i]) } highlevel() # To trigger display } \keyword{dynamic} rgl/man/tagged3d.Rd0000644000176200001440000000251014145464133013565 0ustar liggesusers\name{tagged3d} \alias{tagged3d} \title{ Find tags on rgl objects. } \description{ Objects with material properties may have an arbitrary string set as a tag. This function retrieves the id values associated with a given tag, or the tags set on given ids. } \usage{ tagged3d(tags = NULL, ids = NULL, full = FALSE, subscene = 0) } \arguments{ \item{tags}{ A vector of tags to use for selection. } \item{ids}{ A vector of ids to report the tags on. } \item{full}{logical; whether to return a dataframe containing \code{id}, \code{type}, \code{tag}, or a vector of ids or tags.} \item{subscene}{ Where to look: by default, the whole scene is searched. \code{NA} restricts the search to the current subscene, or a subscene id can be given. } } \details{ Exactly one of \code{tags} and \code{ids} must be specified. } \value{ A dataframe is constructed with columns \item{id}{item id} \item{type}{item type} \item{tag}{item tag} matching the specified \code{tags} or \code{ids} value. If \code{full = TRUE}, the full dataframe is returned, otherwise just the requested ids or tags. If \code{ids} is specified, the return value will be in the same order as \code{ids}). } \author{ Duncan Murdoch } \examples{ open3d() ids <- plot3d(rnorm(10), rnorm(10), rnorm(10), tag = "plot") unclass(ids) tagged3d("plot") tagged3d(ids = ids, full = TRUE) } rgl/man/as.mesh3d.rglId.Rd0000644000176200001440000000355414145464133014741 0ustar liggesusers\name{as.mesh3d.rglId} \alias{as.mesh3d.rglId} \title{ Convert object in plot to RGL mesh object } \description{ This method attempts to read the attributes of objects in the rgl display and construct a mesh3d object to approximate them. } \usage{ \method{as.mesh3d}{rglId}(x, type = NA, subscene = NA, ...) } \arguments{ \item{x}{ A vector of RGL identifiers of objects in the specified subscene. } \item{type}{ A vector of names of types of shapes to convert. Other shapes will be ignored. } \item{subscene}{ Which subscene to look in; the default \code{NA} specifies the current subscene. } \item{\dots}{ Ignored. } } \details{ This function attempts to construct a triangle mesh to approximate one or more objects from the current display. It can handle objects of types from \code{c("points", "lines", "linestrip", "triangles", "quads", "planes", "surface")}. Since this method only produces meshes containing points, segments and triangles, they won't necessarily be an exact match to the original object. If the generic \code{\link{as.mesh3d}} is called with no \code{x} argument, this method will be called with \code{x} set to the ids in the current scene. } \value{ A mesh object. } \author{ Duncan Murdoch } \seealso{ \code{\link{as.triangles3d.rglId}} for extracting the triangles, \code{\link{clipMesh3d}} to apply complex clipping to a mesh object. } \examples{ # volcano example taken from "persp" # data(volcano) z <- 2 * volcano # Exaggerate the relief x <- 10 * (1:nrow(z)) # 10 meter spacing (S to N) y <- 10 * (1:ncol(z)) # 10 meter spacing (E to W) zlim <- range(y) zlen <- zlim[2] - zlim[1] + 1 colorlut <- terrain.colors(zlen) # height color lookup table col <- colorlut[ z - zlim[1] + 1 ] # assign colors to heights for each point open3d(useNULL = TRUE) surface3d(x, y, z, color = col) m <- as.mesh3d() close3d() open3d() shade3d(m) } rgl/man/setUserCallbacks.Rd0000644000176200001440000001407614100762641015343 0ustar liggesusers\name{setUserCallbacks} \alias{setUserCallbacks} \title{ Set mouse callbacks in R or Javascript code } \description{ This function sets user mouse callbacks in R or \code{\link{rglwidget}} displays. } \usage{ setUserCallbacks(button, begin = NULL, update = NULL, end = NULL, rotate = NULL, javascript = NULL, subscene = scene$rootSubscene$id, scene = scene3d(minimal = FALSE), applyToScene = TRUE, applyToDev = missing(scene)) } \arguments{ \item{button}{ Which button should this callback apply to? Can be numeric from \code{0:4}, or character from \code{"none", "left", "right", "center", "wheel"}. } \item{begin, update, end, rotate}{ Functions to call when events occur. See Details. } \item{javascript}{ Optional block of Javascript code to be included (at the global level). } \item{subscene}{ Which subscene do these callbacks apply to? } \item{scene}{ Which scene? } \item{applyToScene}{ Should these changes apply to the scene object? } \item{applyToDev}{ Should these changes apply to the current device? } } \details{ If \code{applyToScene} is \code{TRUE}, this function adds Javascript callbacks to the \code{scene} object. If \code{applyToDev} is \code{TRUE}, it adds R callbacks to the current RGL device. For Javascript, the callbacks are specified as strings; these will be evaluated within the browser in the global context to define the functions, which will then be called with the Javascript \code{this} object set to the current \code{rglwidgetClass} object. For R, they may be strings or R functions. Both options may be \code{TRUE}, in which case the callbacks must be specified as strings which are both valid Javascript and valid R. The usual way to do this is to give just a function name, with the function defined elsewhere, as in the Example below. The \code{begin} and \code{update} functions should be of the form \code{function(x, y) { ... }}. The \code{end} function will be called with no arguments. The \code{rotate} callback can only be set on the mouse wheel. It is called when the mouse wheel is rotated. It should be of the form \code{function(away)}, where \code{away} will be 1 while rotating the wheel \dQuote{away} from you, and 2 while rotating it towards you. If \code{rotate} is not set but other callbacks are set on the wheel \dQuote{button}, then each click of the mouse wheel will trigger all \code{start}, \code{update}, then \code{end} calls in sequence. The \code{javascript} argument is an optional block of code which will be evaluated once during the initialization of the widget. It can define functions and assign them as members of the \code{window} object, and then the names of those functions can be given in the callback arguments; this allows the callbacks to share information. } \value{ Invisibly returns an \code{rglScene} object. This object will record the changes if \code{applyToScene} is \code{TRUE}. If \code{applyToDev} is \code{TRUE}, it will also have the side effect of attempting to install the callbacks using \code{\link{rgl.setMouseCallbacks}} and \code{\link{rgl.setWheelCallback}}. } \seealso{ \code{\link{setAxisCallbacks}} for user defined axes. } \author{ Duncan Murdoch } \examples{ verts <- cbind(rnorm(11), rnorm(11), rnorm(11)) idverts <- plot3d(verts, type = "s", col = "blue")["data"] # Plot some invisible text; the Javascript will move it idtext <- text3d(verts[1,,drop = FALSE], texts = 1, adj = c(0.5, -1.5), alpha = 0) # Define the R functions to use within R fns <- local({ idverts <- idverts idtext <- idtext closest <- -1 update <- function(x, y) { save <- par3d(skipRedraw = TRUE) on.exit(par3d(save)) rect <- par3d("windowRect") size <- rect[3:4] - rect[1:2] x <- x / size[1]; y <- 1 - y / size[2]; verts <- rgl.attrib(idverts, "vertices") # Put in window coordinates vw <- rgl.user2window(verts) dists <- sqrt((x - vw[,1])^2 + (y - vw[,2])^2) newclosest <- which.min(dists) if (newclosest != closest) { if (idtext > 0) pop3d(id = idtext) closest <<- newclosest idtext <<- text3d(verts[closest,,drop = FALSE], texts = closest, adj = c(0.5, -1.5)) } } end <- function() { if (idtext > 0) pop3d(id = idtext) closest <<- -1 idtext <<- -1 } list(rglupdate = update, rglend = end) }) rglupdate <- fns$rglupdate rglend <- fns$rglend # Define the Javascript functions with the same names to use in WebGL js <- ' var idverts = \%id\%, idtext = \%idtext\%, closest = -1, subid = \%subid\%; window.rglupdate = function(x, y) { var obj = this.getObj(idverts), i, newdist, dist = Infinity, pt, newclosest; x = x/this.canvas.width; y = y/this.canvas.height; for (i = 0; i < obj.vertices.length; i++) { pt = obj.vertices[i].concat(1); pt = this.user2window(pt, subid); pt[0] = x - pt[0]; pt[1] = y - pt[1]; pt[2] = 0; newdist = this.vlen(pt); if (newdist < dist) { dist = newdist; newclosest = i; } } if (newclosest !== closest) { closest = newclosest var text = this.getObj(idtext); text.vertices[0] = obj.vertices[closest]; text.colors[0][3] = 1; // alpha is here! text.texts[0] = (closest + 1).toString(); text.initialized = false; this.drawScene(); } }; window.rglend = function() { var text = this.getObj(idtext); text.colors[0][3] = 0; text.initialized = false; this.drawScene(); }' js <- sub("\%id\%", idverts, js) js <- sub("\%subid\%", subsceneInfo()$id, js) js <- sub("\%idtext\%", idtext, js) # Install both setUserCallbacks("left", begin = "rglupdate", update = "rglupdate", end = "rglend", javascript = js) rglwidget() } rgl/man/tkpar3dsave.Rd0000644000176200001440000000325114100762641014331 0ustar liggesusers\name{tkpar3dsave} \alias{tkpar3dsave} \alias{par3dsave} \title{ Modal dialog for saving par3d settings } \description{ This function opens a TCL/TK modal dialog to allow particular views of an RGL scene to be saved. } \usage{ tkpar3dsave(params = c("userMatrix", "scale", "zoom", "FOV"), times = FALSE, dev = cur3d(), ...) } \arguments{ \item{params}{ Which parameters to save } \item{times}{ Should times be saved as well? } \item{dev}{ Which RGL device to work with } \item{...}{ Additional parameters to pass to \code{\link[tcltk:TkWidgets]{tktoplevel}}} } \details{ This opens a TCL/TK modal dialog box with \code{Record} and \code{Quit} buttons. Each time \code{Record} is clicked, a snapshot is taken of current \code{\link[rgl]{par3d}} settings. When \code{Quit} is clicked, the dialog closes and the values are returned in a list. If \code{times == TRUE}, then the times at which the views are recorded will also be saved, so that the \code{\link[rgl]{play3d}} function will play back with the same timing. } \value{ A list of the requested components. Each one will consist of a list of values that were current when the \code{Record} button was clicked. These are suitable to be passed directly to the \code{\link[rgl]{par3dinterp}} function. } \author{ Duncan Murdoch } \seealso{ \code{\link{par3d}}, \code{\link{par3dinterp}}} \examples{ if (interactive() && !in_pkgdown_example()) { # Record a series of positions, and then play them back immediately # at evenly spaced times, in an oscillating loop example(plot3d) play3d( par3dinterp( tkpar3dsave() ) ) # As above, but preserve the click timings # play3d( par3dinterp( tkpar3dsave(times=TRUE) ) ) } } rgl/man/subscene3d.Rd0000644000176200001440000001567214145464133014156 0ustar liggesusers\name{subscene3d} \alias{subscene3d} \alias{newSubscene3d} \alias{currentSubscene3d} \alias{useSubscene3d} \alias{addToSubscene3d} \alias{delFromSubscene3d} \alias{gc3d} \title{ Create, select or modify a subscene } \description{ This creates a new subscene, or selects one by \code{id} value, or adds objects to one. } \usage{ newSubscene3d(viewport = "replace", projection = "replace", model = "replace", mouseMode = "inherit", parent = currentSubscene3d(), copyLights = TRUE, copyShapes = FALSE, copyBBoxDeco = copyShapes, copyBackground = FALSE, newviewport, ignoreExtent) currentSubscene3d(dev = cur3d()) useSubscene3d(subscene) addToSubscene3d(ids = tagged3d(tags), tags, subscene = currentSubscene3d()) delFromSubscene3d(ids = tagged3d(tags), tags, subscene = currentSubscene3d()) gc3d(protect = NULL) } \arguments{ \item{viewport, projection, model, mouseMode}{ How should the new subscene be embedded? Possible values are \code{c("inherit", "modify", "replace")}. See Details below. } \item{parent}{ The parent subscene (defaults to the current subscene). } \item{copyLights, copyShapes, copyBBoxDeco, copyBackground}{ Whether lights, shapes, bounding box decorations and background should be copied to the new subscene. } \item{newviewport}{ Optionally specify the new subscene's viewport (in pixels). } \item{ignoreExtent}{ Whether to ignore the subscene's bounding box when calculating the parent bounding box. Defaults to \code{TRUE} if \code{model} is not \code{"inherit"}. } \item{dev}{ Which RGL device to query for the current subscene. } \item{subscene}{ Which subscene to use or modify. } \item{ids}{ A vector of integer object ids to add to the subscene. } \item{tags}{ Alternate way to specify \code{ids}. Ignored if \code{ids} is given. } \item{protect}{ Object ids to protect from this garbage collection. } } \details{ The \pkg{rgl} package allows multiple windows to be open; each one corresponds to a \dQuote{scene}. Within each scene there are one or more \dQuote{subscenes}. Each subscene corresponds to a rectangular region in the window, and may have its own projection, transformation and behaviour in response to the mouse. There is always a current subscene: most graphic operations make changes there, e.g. by adding an object to it. The scene \dQuote{owns} objects; \code{addToSubscene3d} and \code{delFromSubscene3d} put their ids into or remove them from the list being displayed within a particular subscene. The \code{gc3d} function deletes objects from the scene if they are not visible in any subscene, unless they are protected by having their id included in \code{protect}. The \code{viewport}, \code{projection} and \code{model} parameters each have three possible settings: \code{c("inherit", "modify", "replace")}. \code{"inherit"} means that the corresponding value from the parent subscene will be used. \code{"replace"} means that the new subscene will have its own value of the value, independent of its parent. \code{"modify"} means that the child value will be applied first, and then the parent value will be applied. For viewport, this means that if the parent viewport is changed, the child will maintain its relative position. For the two matrices, \code{"modify"} is unlikely to give satisfactory results, but it is available for possible use. The \code{mouseMode} parameter can only be one of \code{c("inherit", "replace")}. If it is \code{"inherit"}, the subscene will use the mouse controls of the parent, and any change to them will affect the parent and all children that inherit from it. This is the behaviour that was present before \pkg{rgl} version 0.100.13. If it is \code{"replace"}, then it will receive a copy of the parent mouse controls, but modifications to them will affect only this subscene, not the parent. Note that this is orthogonal to the \code{\link{par3d}("listeners")} setting: if another subscene is listed as a listener, it will respond to mouse actions using the same mode as the one receiving them. The \code{viewport} parameter controls the rectangular region in which the subscene is displayed. It is specified using \code{newviewport} (in pixels relative to the whole window), or set to match the parent viewport. The \code{projection} parameter controls settings corresponding to the observer. These include the field of view and the zoom; they also include the position of the observer relative to the model. The \code{par3d("projMatrix")} matrix is determined by the projection. The \code{model} parameter controls settings corresponding to the model. Mouse rotations affect the model, as does scaling. The \code{par3d("modelMatrix")} matrix is determined by these as well as by the position of the observer (since OpenGL assumes that the observer is at (0, 0, 0) after the MODELVIEW transformation). Only those parts concerning the model are inherited when \code{model} specifies inheritance, the observer setting is controlled by \code{projection}. If \code{copyBackground} is \code{TRUE}, the background of the newly created child will overwrite anything displayed in the parent subscene, regardless of depth. } \value{ If successful, each function returns the object id of the subscene, with the exception of \code{gc3d}, which returns the count of objects which have been deleted, and \code{useSubscene3d}, which returns the previously active subscene id. } \author{ Duncan Murdoch and Fang He. } \seealso{ \code{\link{subsceneInfo}} for information about a subscene, \code{\link{mfrow3d}} and \code{\link{layout3d}} to set up multiple panes of subscenes. } \examples{ # Show the Earth with a cutout by using clipplanes in subscenes lat <- matrix(seq(90, -90, len = 50)*pi/180, 50, 50, byrow = TRUE) long <- matrix(seq(-180, 180, len = 50)*pi/180, 50, 50) r <- 6378.1 # radius of Earth in km x <- r*cos(lat)*cos(long) y <- r*cos(lat)*sin(long) z <- r*sin(lat) open3d() obj <- surface3d(x, y, z, col = "white", texture = system.file("textures/worldsmall.png", package = "rgl"), specular = "black", axes = FALSE, box = FALSE, xlab = "", ylab = "", zlab = "", normal_x = x, normal_y = y, normal_z = z) cols <- c(rep("chocolate4", 4), rep("burlywood1", 4), "darkgoldenrod1") rs <- c(6350, 5639, 4928.5, 4207, 3486, (3486 + 2351)/2, 2351, (2351 + 1216)/2, 1216) for (i in seq_along(rs)) obj <- c(obj, spheres3d(0, 0, col = cols[i], radius = rs[i])) root <- currentSubscene3d() newSubscene3d("inherit", "inherit", "inherit", copyShapes = TRUE, parent = root) clipplanes3d(1, 0, 0, 0) newSubscene3d("inherit", "inherit", "inherit", copyShapes = TRUE, parent = root) clipplanes3d(0, 1, 0, 0) newSubscene3d("inherit", "inherit", "inherit", copyShapes = TRUE, parent = root) clipplanes3d(0, 0, 1, 0) # Now delete the objects from the root subscene, to reveal the clipping planes useSubscene3d(root) delFromSubscene3d(obj) } \keyword{ graphics } rgl/man/rgl.user2window.Rd0000644000176200001440000000403414100762641015155 0ustar liggesusers\name{rgl.user2window} \alias{rgl.user2window} \alias{rgl.window2user} \alias{rgl.projection} \title{ Convert between RGL user and window coordinates } \description{ This function converts from 3-dimensional user coordinates to 3-dimensional window coordinates. } \usage{ rgl.user2window(x, y = NULL, z = NULL, projection = rgl.projection()) rgl.window2user(x, y = NULL, z = 0, projection = rgl.projection()) rgl.projection(dev = cur3d(), subscene = currentSubscene3d(dev)) } \arguments{ \item{x, y, z}{Input coordinates. Any reasonable way of defining the coordinates is acceptable. See the function \code{\link[grDevices]{xyz.coords}} for details.} \item{projection}{The RGL projection to use } \item{dev, subscene}{The RGL device and subscene to work with } } \details{ These functions convert between user coordinates and window coordinates. Window coordinates run from 0 to 1 in X, Y, and Z. X runs from 0 on the left to 1 on the right; Y runs from 0 at the bottom to 1 at the top; Z runs from 0 foremost to 1 in the background. RGL does not currently display vertices plotted outside of this range, but in normal circumstances will automatically resize the display to show them. In the example below this has been suppressed. } \value{ The coordinate conversion functions produce a matrix with columns corresponding to the X, Y, and Z coordinates. \code{rgl.projection()} returns a list containing the following components: \item{model}{the modelview matrix} \item{projection}{the projection matrix} \item{viewport}{the viewport vector} See \code{\link{par3d}} for more details. } \author{ Ming Chen / Duncan Murdoch} \seealso{\code{\link{select3d}} } \examples{ open3d() points3d(rnorm(100), rnorm(100), rnorm(100)) if (interactive() || !.Platform$OS == "unix") { # Calculate a square in the middle of the display and plot it square <- rgl.window2user(c(0.25, 0.25, 0.75, 0.75, 0.25), c(0.25, 0.75, 0.75, 0.25, 0.25), 0.5) par3d(ignoreExtent = TRUE) lines3d(square) par3d(ignoreExtent = FALSE) } } \keyword{ dynamic } rgl/man/getBoundary3d.Rd0000644000176200001440000000206214145464133014617 0ustar liggesusers\name{getBoundary3d} \alias{getBoundary3d} \title{ Extract the boundary of a mesh } \description{ Constructs a mesh of line segments corresponding to non-shared (i.e. boundary) edges of triangles or quads in the original mesh. } \usage{ getBoundary3d(mesh, sorted = FALSE, simplify = TRUE) } \arguments{ \item{mesh}{ A mesh object. } \item{sorted}{ Whether the result should have the segments sorted in sequential order. } \item{simplify}{ Whether to simplify the resulting mesh, dropping all unused vertices. If \code{FALSE}, the vertices of the result will be identical to the vertices of \code{mesh}; if \code{TRUE}, they will likely be different, even if no vertices were dropped. } } \value{ A \code{"mesh3d"} object containing 0 or more segments. } \author{ Duncan Murdoch } \seealso{ \code{\link{mesh3d}} } \examples{ x <- cube3d() x$ib <- x$ib[,-(1:2)] b <- getBoundary3d(x, sorted = TRUE) open3d() shade3d(x, alpha=0.2, col = "blue") shade3d(b) # Show edge vertices in sequence: text3d(t(b$vb), text = 1:ncol(b$vb), adj = 0) c(b$is[1,1], b$is[2,]) } rgl/man/decorate3d.Rd0000644000176200001440000000215614145464133014126 0ustar liggesusers\name{decorate3d} \alias{decorate3d} \title{ Add decorations to a 3D plot } \description{ \code{decorate3d} adds the usual decorations to a plot: labels, axes, etc. } \usage{ decorate3d(xlim = NULL, ylim = NULL, zlim = NULL, xlab = "x", ylab = "y", zlab = "z", box = TRUE, axes = TRUE, main = NULL, sub = NULL, top = TRUE, aspect = FALSE, expand = 1.03, tag = material3d("tag"), ...) } \arguments{ \item{xlim, ylim, zlim}{These are used for the labels.} \item{xlab, ylab, zlab}{labels for the coordinates.} \item{box, axes}{whether to draw a box and axes.} \item{main, sub}{main title and subtitle.} \item{top}{whether to bring the window to the top when done.} \item{aspect}{either a logical indicating whether to adjust the aspect ratio, or a new ratio.} \item{expand}{how much to expand the box around the data, if it is drawn.} \item{tag}{optional label for objects being produced.} \item{...}{ignored.} } \value{ The RGL id values for those items. } \examples{ open3d() shade3d(tetrahedron3d(), col = "red") decorate3d(main = "A Tetrahedron") }rgl/man/aspect3d.Rd0000644000176200001440000000237114100762640013611 0ustar liggesusers\name{aspect3d} \alias{aspect3d} \title{Set the aspect ratios of the current plot} \description{ This function sets the apparent ratios of the x, y, and z axes of the current bounding box. } \usage{ aspect3d(x, y = NULL, z = NULL) } \arguments{ \item{x}{The ratio for the x axis, or all three ratios, or \code{"iso"} } \item{y}{The ratio for the y axis } \item{z}{The ratio for the z axis } } \details{ If the ratios are all 1, the bounding box will be displayed as a cube approximately filling the display. Values may be set larger or smaller as desired. Aspect \code{"iso"} signifies that the coordinates should all be displayed at the same scale, i.e. the bounding box should not be rescaled. (This corresponds to the default display before \code{aspect3d} has been called.) Partial matches to \code{"iso"} are allowed. \code{aspect3d} works by modifying \code{par3d("scale")}. } \value{ The previous value of the scale is returned invisibly. } \author{Duncan Murdoch} \seealso{\code{\link{plot3d}}, \code{\link{par3d}}} \examples{ x <- rnorm(100) y <- rnorm(100)*2 z <- rnorm(100)*3 open3d() plot3d(x, y, z) aspect3d(1, 1, 0.5) highlevel() # To trigger display open3d() plot3d(x, y, z) aspect3d("iso") highlevel() } \keyword{dynamic} rgl/man/callbacks.Rd0000644000176200001440000000760314100762640014025 0ustar liggesusers\name{rgl.setMouseCallbacks} \alias{rgl.setMouseCallbacks} \alias{rgl.getMouseCallbacks} \alias{rgl.setWheelCallback} \alias{rgl.getWheelCallback} \title{ User callbacks on mouse events } \description{ Set and get user callbacks on mouse events. } \usage{ rgl.setMouseCallbacks(button, begin = NULL, update = NULL, end = NULL, dev = cur3d(), subscene = currentSubscene3d(dev)) rgl.getMouseCallbacks(button, dev = cur3d(), subscene = currentSubscene3d(dev)) rgl.setWheelCallback(rotate, dev = cur3d(), subscene = currentSubscene3d(dev)) rgl.getWheelCallback(dev = cur3d(), subscene = currentSubscene3d(dev)) } \arguments{ \item{button}{ Which button? Use 1 for left, 2 for right, 3 for middle, 4 for wheel. Use 0 to set an action when no button is pressed. } \item{begin}{ Called when mouse down event occurs } \item{update}{ Called when mouse moves } \item{end}{ Called when mouse is released } \item{rotate}{ Called when mouse wheel is rotated } \item{dev, subscene}{The RGL device and subscene to work with } } \details{ The set functions set event handlers on mouse events that occur within the current RGL window. The \code{begin} and \code{update} events should be functions taking two arguments; these will be the mouse coordinates when the event occurs. The \code{end} event handler takes no arguments. The \code{rotate} event takes a single argument, which will be equal to \code{1} if the user pushes the wheel away by one click, and \code{2} if the user pulls the wheel by one click. Alternatively, the handlers may be set to \code{NULL}, the default value, in which case no action will occur. If a subscene has multiple listeners, the user action will still only be called for the subscene that received the mouse event. It should consult \code{\link{par3d}("listeners")} if it makes sense to take action on the whole group of subscenes. The get function retrieves the callbacks that are currently set. The \dQuote{no button} mouse handler may be set by specifying \code{button = 0}. The \code{begin} function will be called the first time the mouse moves within the subscene, and the \code{update} function will be called repeatedly as it moves. The \code{end} function will never be called. } \value{ The set functions are called for the side effect of setting the mouse event handlers. The \code{rgl.getMouseCallbacks} function returns a list containing the callback functions or \code{NULL} if no user callback is set. The \code{rgl.getWheelCallback} returns the callback function or \code{NULL}. } \author{ Duncan Murdoch } \seealso{ \code{\link{par3d}} to set built-in handlers, \code{\link{setUserCallbacks}} to work with \code{\link{rglwidget}}.} \examples{ pan3d <- function(button, dev = cur3d(), subscene = currentSubscene3d(dev)) { start <- list() begin <- function(x, y) { activeSubscene <- par3d("activeSubscene", dev = dev) start$listeners <<- par3d("listeners", dev = dev, subscene = activeSubscene) for (sub in start$listeners) { init <- par3d(c("userProjection","viewport"), dev = dev, subscene = sub) init$pos <- c(x/init$viewport[3], 1 - y/init$viewport[4], 0.5) start[[as.character(sub)]] <<- init } } update <- function(x, y) { for (sub in start$listeners) { init <- start[[as.character(sub)]] xlat <- 2*(c(x/init$viewport[3], 1 - y/init$viewport[4], 0.5) - init$pos) mouseMatrix <- translationMatrix(xlat[1], xlat[2], xlat[3]) par3d(userProjection = mouseMatrix \%*\% init$userProjection, dev = dev, subscene = sub ) } } rgl.setMouseCallbacks(button, begin, update, dev = dev, subscene = subscene) cat("Callbacks set on button", button, "of RGL device", dev, "in subscene", subscene, "\n") } open3d() shade3d(icosahedron3d(), col = "yellow") # This only works in the internal display... pan3d(1) } \keyword{ dynamic } rgl/man/pch3d.Rd0000644000176200001440000000501614100762640013103 0ustar liggesusers\name{pch3d} \alias{pch3d} \title{ Plot symbols similar to base graphics } \description{ This function plots symbols similarly to what the base graphics function \code{\link{points}} does when \code{pch} is specified. } \usage{ pch3d(x, y = NULL, z = NULL, pch = 1, bg = material3d("color")[1], cex = 1, radius, color = "black", lit = FALSE, ...) } \arguments{ \item{x, y, z}{ The locations at which to plot in a form suitable for use in \code{\link{xyz.coords}}. } \item{pch}{ A vector of integers or single characters describing the symbols to plot. } \item{bg}{ The fill color(s) to use for \code{pch} from 21 to 25. } \item{cex}{ A relative size of the symbol to plot. } \item{radius}{ An absolute size of the symbol to plot in user coordinates. } \item{color}{ The color(s) to use for symbols. } \item{lit}{ Whether the object responds to lighting or just shows the displayed color directly. } \item{\dots}{ Other material properties. } } \details{ The list of symbols encoded by numerical \code{pch} values is given in the \code{\link{points}} help page. } \note{ This function is not a perfect match to how the \code{\link{points}} function works due to limitations in RGL and OpenGL. In particular: Symbols with numbers from 1 to 25 are drawn as 3D sprites (see \code{\link{sprites3d}}), so they will resize as the window is zoomed. Letters and numbers from 32 to 255 (which are mapped to letters) are drawn using \code{\link{text3d}}, so they maintain a fixed size. A calculation somewhat like the one in \code{\link{plot3d}} that sets the size of spheres is used to choose the size of sprites based on \code{cex} and the current scaling. This will likely need manual tweaking. Use the \code{radius} argument for a fixed size. No special handling is done for the case of \code{pch = "."}. Use \code{points3d} for small dots. As of \pkg{rgl} version 0.100.10, background and foreground colors can vary from symbol to symbol. } \value{ A vector of object id values is returned invisibly. Separate objects will be drawn for each different combination of \code{pch} value from 0 to 25, \code{color} and \code{bg}, and another holding all the character symbols. } \author{ Duncan Murdoch } \seealso{ \code{\link{points3d}}, \code{\link{text3d}}, \code{\link{plot3d}}, \code{\link{points}}. } \examples{ open3d() i <- 0:25; x <- i \%\% 5; y <- rep(0, 26); z <- i \%/\% 5 pch3d(x, y, z, pch = i, bg = "gray", color = rainbow(26)) text3d(x, y, z + 0.3, i) pch3d(x + 5, y, z, pch = i+65) text3d(x + 5, y, z + 0.3, i+65) } rgl/man/contourLines3d.Rd0000644000176200001440000001442514100762640015021 0ustar liggesusers\name{contourLines3d} \alias{contourLines3d} \alias{contourLines3d.rglId} \alias{contourLines3d.mesh3d} \alias{filledContour3d} \alias{filledContour3d.rglId} \alias{filledContour3d.mesh3d} \title{ Draw contours on a surface } \description{ \code{contourLines3d} draws contour lines on a surface; \code{filledContour3d} draws filled contours on it. } \usage{ contourLines3d(obj, ...) \method{contourLines3d}{rglId}(obj, ...) \method{contourLines3d}{mesh3d}(obj, fn = "z", nlevels = 10, levels = NULL, minVertices = 0, plot = TRUE, ... ) filledContour3d(obj, ...) \method{filledContour3d}{rglId}(obj, plot = TRUE, replace = plot, ...) \method{filledContour3d}{mesh3d}(obj, fn = "z", nlevels = 20, levels = pretty(range(values), nlevels), color.palette = function(n) hcl.colors(n, "YlOrRd", rev = TRUE), col = color.palette(length(levels) - 1), minVertices = 0, plot = TRUE, keepValues = FALSE, ... ) } \arguments{ \item{obj}{ The object(s) on which to draw contour lines. } \item{fn}{ The function(s) to be contoured. See Details. } \item{nlevels}{ Suggested number of contour levels if \code{levels} is not given. } \item{levels}{ Specified contour values. } \item{minVertices}{ See Details below. } \item{plot}{ Whether to draw the lines or return them in a dataframe. } \item{\dots}{ For the \code{"mesh3d"} methods, additional parameters to pass to \code{\link{segments3d}} when drawing the contour lines or to \code{\link{shade3d}} when drawing the filled contours. For the \code{"rglId"} methods, additional parameters to pass to the \code{"mesh3d"} methods. } \item{replace}{ Whether to delete the objects that are being contoured. } \item{color.palette}{a color palette function to assign colors in the plot} \item{col}{the actual colors to use in the plot.} \item{keepValues}{whether to save the function values at each vertex when \code{plot = FALSE}} } \details{ For \code{contourLines3d}, the \code{fn} argument can be any of the following: \itemize{ \item{ a character vector naming one or more functions} \item{a function} \item{a numeric vector with one value per vertex} \item{\code{NULL}, indicating that the numeric values are saved in \code{obj$values}} \item{a list containing any of the above.} } For \code{filledContour3d}, only one function can be specified. The special names \code{"x", "y", "z"} may be used in \code{fn} to specify functions returning one of those coordinates. (If you have existing functions \code{x()}, \code{y()} or \code{z()} they will be masked by this choice; specify such functions by value rather than name, e.g. \code{fn = x} instead of \code{fn = "x"}.) Functions in \code{fn} with formal arguments \code{x}, \code{y} and \code{z} will receive the coordinates of vertices in those arguments, otherwise they will receive the coordinates in a single n x 3 matrix. They should be vectorized and return one value per vertex. Each of the functions will be evaluated at each vertex of the surface specified by \code{obj}, and contours will be drawn assuming the function is linear between vertices. If contours of a nonlinear function are needed, you may want to increase \code{minVertices} as described below. If \code{levels} is not specified, values will be set separately for each entry in \code{fn}, using \code{pretty(range(values, na.rm = TRUE), nlevels)} where \code{values} are the values on the vertices. The \code{minVertices} argument is used to improve the approximation to the contour when the function is non-linear. In that case, the interpolation between vertices can be inaccurate. If \code{minVertices} is set to a positive number (e.g. \code{10000}), then the mesh is modified by subdivision to have at least that number of vertices, so that pieces are smaller and the linear interpolation is more accurate. } \note{ To draw contours on a surface, the surface should be drawn with material property \code{polygon_offset = 1} (or perhaps some larger positive value) so that the lines of the contour are not obscured by the surface. In R versions prior to 3.6.0, the default \code{color.palette} is \code{grDevices::cm.colors}. } \value{ For both \code{contourLines3d} and \code{filledContour3d} the \code{"rglId"} method converts the given id values to a mesh, and calls the \code{"mesh3d"} method. The \code{"mesh3d"} method returns an object of class \code{"rglId"} corresponding to what was drawn if \code{plot} is \code{TRUE}, If \code{plot} is \code{FALSE}, \code{contourLines3d} returns a dataframe containing columns \code{c("x", "y", "z", "fn", "level")} giving the coordinates of the endpoints of each line segment, the name (or index) of the function for this contour, and the level of the contour. If \code{plot} is \code{FALSE}, \code{filledContour3d} returns a \code{"\link{mesh3d}"} object holding the result. If \code{keepValues} is \code{TRUE}, the mesh will contain the values corresponding to each vertex (with linear approximations at the boundaries). } \author{ Duncan Murdoch } \seealso{ The \pkg{misc3d} package contains the function \code{\link[misc3d]{contour3d}} to draw contour surfaces in space instead of contour lines on surfaces. } \examples{ # Add contourlines in "z" to a persp plot z <- 2 * volcano # Exaggerate the relief x <- 10 * (1:nrow(z)) # 10 meter spacing (S to N) y <- 10 * (1:ncol(z)) # 10 meter spacing (E to W) open3d() id <- persp3d(x, y, z, aspect = "iso", axes = FALSE, box = FALSE, polygon_offset = 1) contourLines3d(id) # "z" is the default function filledContour3d(id, polygon_offset = 1, nlevels = 10, replace = TRUE) # Draw longitude and latitude lines on a globe lat <- matrix(seq(90, -90, len = 50)*pi/180, 50, 50, byrow = TRUE) long <- matrix(seq(-180, 180, len = 50)*pi/180, 50, 50) r <- 6378.1 # radius of Earth in km x <- r*cos(lat)*cos(long) y <- r*cos(lat)*sin(long) z <- r*sin(lat) open3d() ids <- persp3d(x, y, z, col = "white", texture = system.file("textures/worldsmall.png", package = "rgl"), specular = "black", axes = FALSE, box = FALSE, xlab = "", ylab = "", zlab = "", normal_x = x, normal_y = y, normal_z = z, polygon_offset = 1) contourLines3d(ids, list(latitude = function(x, y, z) asin(z/sqrt(x^2+y^2+z^2))*180/pi, longitude = function(x, y, z) atan2(y, x)*180/pi)) } rgl/man/propertySetter.Rd0000644000176200001440000000723114100762641015157 0ustar liggesusers\name{propertySetter} \alias{propertySlider} \alias{propertySetter} \alias{par3dinterpSetter} \alias{matrixSetter} \alias{vertexSetter} \title{ Obsolete functions to write HTML/Javascript code to control a WebGL display } \description{ These functions write out HTML code to control WebGL displays based using the obsolete \code{writeWebGL}. Use \code{\link{playwidget}} and related functions instead. } \usage{ propertySlider(setter = propertySetter, minS = NULL, maxS = NULL, step = 1, init = NULL, labels, id = basename(tempfile("input")), name = id, outputid = paste0(id, "text"), index = NULL, ...) propertySetter(values = NULL, entries, properties, objids, prefixes = "", param = seq_len(NROW(values)), interp = TRUE, digits = 7) par3dinterpSetter(fn, from, to, steps, subscene, omitConstant = TRUE, rename = character(), ...) matrixSetter(fns, from, to, steps, subscene = currentSubscene3d(), matrix = "userMatrix", omitConstant = TRUE, prefix = "", ...) vertexSetter(values, vertices = 1, attributes, objid, prefix = "", param = seq_len(NROW(values)), interp = TRUE, digits = 7) } \arguments{ \item{setter}{A function to write Javascript code, or its output, or a list containing several of these.} \item{minS, maxS, step, init}{Slider values to be displayed. Reasonable defaults are used if missing.} \item{labels}{Labels to display for each slider value. The defaults are calculated using internal variables. If \code{NULL}, no labels will be shown.} \item{id}{The \code{id} of the input control that will be generated.} \item{name}{The name of the input control that will be generated.} \item{outputid}{The \code{id} of the output control that will display the slider value, or \code{NULL} for none.} \item{index}{The 1-based index of this slider: it controls the corresponding entry in an indexed setter such as \code{matrixSetter}.} \item{...}{Other parameters.} \item{values}{An array of values; rows correspond to slider positions. Alternatively, \code{NULL}; the generated function takes a single value or array of values and applies them directly.} \item{entries, properties, objids, prefixes}{Vectors describing the columns of \code{values}.} \item{param}{Parameter values corresponding to each row of \code{values}.} \item{interp}{Whether to interpolate values. If \code{FALSE}, the Javascript function will expect non-negative integer values. Ignored if \code{values} is \code{NULL}.} \item{digits}{How many significant digits to emit in the Javascript code.} \item{fn}{A function returned from \code{\link{par3dinterp}}.} \item{from, to, steps}{Values where \code{fn} should be evaluated.} \item{subscene}{Which subscene's properties should be modified?} \item{omitConstant}{If \code{TRUE}, do not set values that are constant across the range.} \item{rename}{A named character vector of names of Javascript properties to modify.} \item{fns}{A list containing functions returned from \code{\link{par3dinterp}}.} \item{matrix}{A character string giving the Javascript property name of the matrix to modify.} \item{prefix}{The prefix of the scene containing \code{matrix}.} \item{vertices}{A vector of vertex numbers (1-based) within an object.} \item{attributes}{A vector of attributes of a vertex, from \code{c("x", "y", "z", "r", "g", "b", "a", "nx", "ny", "nz", "radius", "ox", "oy", "oz", "ts", "tt")}.} \item{objid}{The object containing the vertices to be modified.} } \author{ Duncan Murdoch } \seealso{ \code{\link{rglwidget}}, \code{\link{playwidget}} } rgl/man/writePLY.Rd0000644000176200001440000000567414145464133013640 0ustar liggesusers\name{writePLY} \alias{writePLY} \title{ Write Stanford PLY format files } \description{ This function writes PLY files. This is a simple file format that is commonly used in 3D printing. It does not represent text, only edges and polygons. The \code{writePLY} function does the necessary conversions. } \usage{ writePLY(con, format = c("little_endian", "big_endian", "ascii"), pointRadius = 0.005, pointShape = icosahedron3d(), lineRadius = pointRadius, lineSides = 20, pointsAsEdges = FALSE, linesAsEdges = pointsAsEdges, withColors = TRUE, withNormals = !(pointsAsEdges || linesAsEdges), ids = tagged3d(tags), tags = NULL) } \arguments{ \item{con}{ A connection or filename. } \item{format}{ Which output format. Defaults to little-endian binary. } \item{pointRadius, lineRadius}{ The radius of points and lines relative to the overall scale of the figure, if they are converted to polyhedra. } \item{pointShape}{ A mesh shape to use for points if they are converted. It is scaled by the \code{pointRadius}. } \item{lineSides}{ Lines are rendered as cylinders with this many sides. } \item{pointsAsEdges, linesAsEdges}{ Whether to convert points and lines to \dQuote{Edge} records in the PLY output. } \item{withColors}{ Whether to output vertex color information. } \item{withNormals}{ Whether to output vertex normals for smooth shading. } \item{ids}{ The identifiers (from \code{\link{ids3d}}) of the objects to write. If \code{NULL}, try to write everything. } \item{tags}{ Select objects with matching tags. Ignored if \code{ids} is specified. } } \details{ The current implementation only outputs triangles, quads, planes, spheres, points, line segments, line strips and surfaces. The defaults for \code{pointsAsEdges} and \code{linesAsEdges} have been chosen because Blender (\url{https://www.blender.org}) does not import lines, only polygons. If you are exporting to other software you may want to change them. Since the PLY format only allows one object per file, all RGL objects are combined into a single object when output. The output file is readable by Blender and Meshlab; the latter can write in a number of other formats, including U3D, suitable for import into a PDF document. } \value{ Invisibly returns the name of the connection to which the data was written. } \references{ The file format was found on \url{https://www.mathworks.com} on November 10, 2012 at a URL that no longer exists; currently the format is described at \url{https://www.mathworks.com/help/vision/ug/the-ply-format.html}. } \author{ Duncan Murdoch } \seealso{ \code{\link{scene3d}} saves a copy of a scene to an R variable; \code{\link{rglwidget}}, \code{\link{writeASY}}, \code{\link{writeOBJ}} and \code{\link{writeSTL}} write the scene to a file in various other formats. } \examples{ filename <- tempfile(fileext = ".ply") open3d() shade3d( icosahedron3d(col = "magenta") ) writePLY(filename) } \keyword{ graphics } rgl/man/rglShared.Rd0000644000176200001440000000633614137472630014032 0ustar liggesusers\name{rglShared} \alias{rglShared} \title{ Create shared data from an RGL object } \description{ The \pkg{crosstalk} package provides a way for different parts of an interactive display to communicate about datasets, using \dQuote{shared data} objects. When selection or filtering is performed in one view, the result is mirrored in all other views. This function allows vertices of RGL objects to be treated as shared data. } \usage{ rglShared(id, key = NULL, group = NULL, deselectedFade = 0.1, deselectedColor = NULL, selectedColor = NULL, selectedIgnoreNone = TRUE, filteredFade = 0, filteredColor = NULL) } \arguments{ \item{id}{ An existing RGL id. } \item{key}{ Optional unique labels to apply to each vertex. If missing, numerical keys will be used. } \item{group}{ Optional name of the shared group to which this data belongs. If missing, a random name will be generated. } \item{deselectedFade, deselectedColor}{ Appearance of points that are not selected. See Details. } \item{selectedColor}{ Appearance of points that are selected. } \item{selectedIgnoreNone}{ If no points are selected, should the points be shown in their original colors (\code{TRUE}), or in the deselected colors (\code{FALSE})? } \item{filteredFade, filteredColor}{ Appearance of points that have been filtered out. } } \details{ Some functions which normally work on dataframe-like datasets will accept shared data objects in their place. If a selection is in progress, the alpha value for unselected points is multiplied by \code{deselectedFade}. If \code{deselectedColor} is \code{NULL}, the color is left as originally specified; if not, the point is changed to the color given by \code{deselectedColor}. If no points have been selected, then by default points are shown in their original colors. However, if \code{selectedIgnoreNone = FALSE}, all points are displayed as if unselected. The \code{selectedColor} argument is similarly used to change the color (or not) of selected points, and \code{filteredFade} and \code{filteredColor} are used for points that have been filtered out of the display. } \value{ An object of class \code{"SharedData"} (from the optional \pkg{crosstalk} package) which contains the x, y and z coordinates of the RGL object with the given \code{id}. } \references{ \url{https://rstudio.github.io/crosstalk/index.html} } \author{ Duncan Murdoch } \examples{ save <- options(rgl.useNULL = TRUE) open3d() x <- sort(rnorm(100)) y <- rnorm(100) z <- rnorm(100) + atan2(x, y) ids <- plot3d(x, y, z, col = rainbow(100)) # The data will be selected and filtered, not the axes. sharedData <- rglShared(ids["data"]) # Also add some labels that are only displayed # when points are selected sharedLabel <- rglShared(text3d(x, y, z, text = 1:100, adj = -0.5), group = sharedData$groupName(), deselectedFade = 0, selectedIgnoreNone = FALSE) if (interactive() || in_pkgdown_example()) crosstalk::filter_slider("x", "x", sharedData, ~x) \%>\% rglwidget(shared = list(sharedData, sharedLabel), controller = .) \%>\% rglMouse() options(save) }rgl/man/surface3d.Rd0000644000176200001440000000475314100762641013771 0ustar liggesusers\name{surface3d} \title{Add surface} \alias{surface3d} \alias{terrain3d} \description{ Adds a surface to the current scene. The surface is defined by a matrix defining the height of each grid point and two vectors defining the grid. } \usage{ surface3d(x, y, z, ..., normal_x = NULL, normal_y = NULL, normal_z = NULL) terrain3d(x, y, z, ..., normal_x = NULL, normal_y = NULL, normal_z = NULL) } \arguments{ \item{ x }{ values corresponding to rows of \code{z}, or matrix of x coordinates } \item{ y }{ values corresponding to the columns of \code{z}, or matrix of y coordinates } \item{ z }{ matrix of heights } \item{ ... }{Material and texture properties. See \code{\link{rgl.material}} for details.} \item{normal_x, normal_y, normal_z}{ matrices of the same dimension as \code{z} giving the coordinates of normals at each grid point} } \details{ Adds a surface mesh to the current scene. The surface is defined by the matrix of height values in \code{z}, with rows corresponding to the values in \code{x} and columns corresponding to the values in \code{y}. This is the same parametrization as used in \code{\link{persp}}. If the \code{x} or \code{y} argument is a matrix, then it must be of the same dimension as \code{z}, and the values in the matrix will be used for the corresponding coordinates. This is used to plot shapes such as cylinders where z is not a function of x and y. If the normals are not supplied, they will be calculated automatically based on neighbouring points. \code{surface3d} always draws the surface with the `front' upwards (i.e. towards higher \code{z} values). This can be used to render the top and bottom differently; see \code{\link{rgl.material}} and the example below. For more flexibility in defining the surface, use \code{\link{rgl.surface}}. \code{surface3d} and \code{terrain3d} are synonyms. } \examples{ # # volcano example taken from "persp" # z <- 2 * volcano # Exaggerate the relief x <- 10 * (1:nrow(z)) # 10 meter spacing (S to N) y <- 10 * (1:ncol(z)) # 10 meter spacing (E to W) zlim <- range(z) zlen <- zlim[2] - zlim[1] + 1 colorlut <- terrain.colors(zlen) # height color lookup table col <- colorlut[ z - zlim[1] + 1 ] # assign colors to heights for each point open3d() surface3d(x, y, z, color = col, back = "lines") } \seealso{ \code{\link{rgl.material}}, \code{\link{rgl.surface}}. See \code{\link{persp3d}} for a higher level interface. } \keyword{dynamic} rgl/man/as.rglscene.Rd0000644000176200001440000000070114145464133014307 0ustar liggesusers\name{as.rglscene} \alias{as.rglscene} \title{ Convert an object to an rglscene object. } \description{ This is a placeholder generic function, to allow other packages to create \code{"rglscene"} objects compatible with the objects produced by \code{\link{scene3d}}. No methods are currently defined in \pkg{rgl}. } \usage{ as.rglscene(x, ...) } \arguments{ \item{x}{ Object to convert. } \item{\dots}{ Other parameters to pass to methods. } } rgl/man/thigmophobe3d.Rd0000644000176200001440000000442514100762641014642 0ustar liggesusers\name{thigmophobe3d} \alias{thigmophobe3d} \title{ Find the direction away from the closest point in a 3d projection } \description{ Jim Lemon's \code{\link[plotrix]{thigmophobe}} function in the \code{\link[plotrix:plotrix-package]{plotrix}} package computes good directions for labels in a 2D plot. This function does the same for a particular projection in a 3D plot by projecting down to 2D and calling his function. } \usage{ thigmophobe3d(x, y = NULL, z = NULL, P = par3d("projMatrix"), M = par3d("modelMatrix"), windowRect = par3d("windowRect")) } \arguments{ \item{x, y, z}{point coordinates. Any reasonable way of defining the coordinates is acceptable. See the function \code{\link[grDevices]{xyz.coords}} for details. } \item{P, M, windowRect}{ The projection and modelview matrices, and the size and position of the display in pixels. } } \details{ Since \code{thigmophobe3d} projects using fixed \code{P} and \code{M}, it will not necessarily choose good directions if the user rotates the display or makes any other change to the projection.} \note{ The example below shows how to update the directions during an animation; I find that the moving labels are distracting, and prefer to live with fixed ones. } \value{ A vector of values from 1 to 4 to be used as the \code{pos} argument in \code{\link{text3d}}. } \references{ \CRANpkg{plotrix} } \author{ Duncan Murdoch } \seealso{ \code{\link{text3d}} } \examples{ if (requireNamespace("plotrix", quietly = TRUE)) { # Simulate some data xyz <- matrix(rnorm(30), ncol = 3) # Plot the data first, to establish the projection plot3d(xyz) # Now thigmophobe3d can choose directions textid <- text3d(xyz, texts = 1:10, pos = thigmophobe3d(xyz)) # Update the label positions during an animation if (interactive() && !rgl.useNULL()) { spin <- spin3d(rpm = 5) f <- function(time) { par3d(skipRedraw = TRUE) on.exit(par3d(skipRedraw = FALSE)) pop3d(id = textid) # Need to rotate before thigmophobe3d is called result <- spin(time) par3d(userMatrix = result$userMatrix) textid <<- text3d(xyz, texts = 1:10, pos = thigmophobe3d(xyz)) result } play3d(f, duration = 5) } else textid # just print the static display } } rgl/man/clipMesh3d.Rd0000644000176200001440000001272214145464133014104 0ustar liggesusers\name{clipMesh3d} \alias{clipMesh3d} \alias{clipObj3d} \title{ Clip mesh or RGL object to general region } \description{ Modifies a mesh3d object so that values of a function are bounded. } \usage{ clipMesh3d(mesh, fn, bound = 0, greater = TRUE, minVertices = 0, plot = FALSE, keepValues = FALSE) clipObj3d(ids = tagged3d(tags), fn, bound = 0, greater = TRUE, minVertices = 0, replace = TRUE, tags) } \arguments{ \item{mesh}{ A \code{\link{mesh3d}} object. } \item{fn}{ A function used to determine clipping, or a vector of values from such a function, with one value per vertex. } \item{bound}{ The value(s) of \code{fn} on the clipping boundary. } \item{greater}{ Logical; whether to keep \code{fn >= bound} or not. } \item{minVertices}{ See Details below. } \item{plot}{Logical; whether or not to plot the mesh.} \item{keepValues}{Logical; whether to save the function values at each vertex when \code{plot = FALSE}.} \item{ids}{ The RGL id value(s) of objects to clip. } \item{tags}{ Alternate way to specify \code{ids}. Ignored if \code{ids} is given. } \item{replace}{ Should the \code{ids} objects be deleted after the clipped ones are drawn? } } \details{ These functions transform a mesh3d object or other RGL objects by removing parts where \code{fn} violates the bound. For \code{clipMesh3d} the \code{fn} argument can be any of the following: \itemize{ \item{a character vector naming a function (with special names \code{"x"}, \code{"y"}, and \code{"z"} corresponding to functions returning those coordinates)} \item{a function} \item{a numeric vector with one value per vertex} \item{\code{NULL}, indicating that the numeric values are saved in \code{mesh$values}} } For \code{clipObj3d} any of the above except \code{NULL} may be used. If \code{fn} is a numeric vector, with one value per vertex, those values will be used in the test. If it is a function with formal arguments \code{x}, \code{y} and \code{z}, it will receive the coordinates of vertices in those arguments, otherwise it will receive the coordinates in a single n x 3 matrix. The function should be vectorized and return one value per vertex, to check against the bound. These operations are performed on the mesh: First, all quads are converted to triangles. Next, each vertex is checked against the condition. Modifications to triangles depend on how many of the vertices satisfy the condition (\code{fn >= bound} or \code{fn <= bound}, depending on \code{greater}) for inclusion. \itemize{ \item If no vertices in a triangle satisfy the condition, the triangle is omitted. \item If one vertex satisfies the condition, the other two vertices in that triangle are shrunk towards it by assuming \code{fn} is locally linear. \item If two vertices satisfy the condition, the third vertex is shrunk along each edge towards each other vertex, forming a quadrilateral made of two new triangles. \item If all vertices satisfy the condition, they are included with no modifications. } Modifications to line segments are similar: the segment will be shortened if it crosses the boundary, or omitted if it is entirely out of bounds. Points, spheres, text and sprites will just be kept or rejected. The \code{minVertices} argument is used to improve the approximation to the boundary when \code{fn} is a non-linear function. In that case, the interpolation described above can be inaccurate. If \code{minVertices} is set to a positive number (e.g. \code{10000}), then each object is modified by subdivision to have at least that number of vertices, so that pieces are smaller and the linear interpolation is more accurate. In the \code{clipObj3d} function, \code{minVertices} can be a vector, with entries corresponding to each of the entries in \code{ids}. } \value{ If \code{plot = FALSE}, \code{clipMesh3d} returns new mesh3d object in which all vertices (approximately) satisfy the clipping condition. Note that the order of vertices will likely differ from the original order, and new vertices will be added near the boundary (and if \code{minVertices > 0}, in the interior). If in addition \code{keepValues = TRUE}, a component named \code{"values"} will be added to the mesh containing the values for each vertex. If \code{plot = TRUE}, the result will be plotted with \code{\link{shade3d}} and its result returned. \code{clipObj3d} is called for the side effect of modifying the scene. It returns a list of new RGL id values corresponding to the \code{ids} passed as arguments. } \author{ Duncan Murdoch } \references{ See \url{https://stackoverflow.com/q/56242470/2554330} for a motivating example. } \seealso{ See \code{\link{contourLines3d}} and \code{\link{filledContour3d}} for ways to display function values without clipping. } \examples{ # Show the problem that minVertices solves: cube <- cube3d(col = "red") # This function only has one argument, so it will # be passed x, y and z in columns of a matrix vecnorm <- function(vals) apply(vals, 1, function(row) sqrt(sum(row^2))) open3d() mfrow3d(2, 2, sharedMouse = TRUE) id1 <- shade3d(cube) # All vertices have norm sqrt(3), so this clips nothing: clipObj3d(id1, fn = vecnorm, bound = sqrt(2)) next3d() id2 <- wire3d(cube, lit = FALSE) clipObj3d(id2, fn = vecnorm, bound = sqrt(2)) # This subdivides the cube, and does proper clipping: next3d() id3 <- shade3d(cube) clipObj3d(id3, fn = vecnorm, bound = sqrt(2), minVertices = 200) next3d() id4 <- wire3d(cube, lit = FALSE) clipObj3d(id4, fn = vecnorm, bound = sqrt(2), minVertices = 200) } rgl/man/tkrgl.Rd0000644000176200001440000000222214100762641013222 0ustar liggesusers\name{tkrgl} \alias{tkrgl} \title{ The former tkrgl package } \description{ Functions from the former \pkg{tkrgl} package. } \details{ The \pkg{tkrgl} package contained functions to use TCL/TK to control an RGL scene on screen. These functions have now been merged into the \pkg{rgl} package, and the \pkg{tkrgl} package has been archived. To avoid conflicts with RGL names and to indicate the TCL/TK nature of these functions, they have all been prefixed with \code{tk}: \describe{ \item{\code{\link{tkpar3dsave}}}{Formerly \code{tkrgl::par3dsave}, allows interactive saving of scene parameters.} \item{\code{\link{tkspin3d}, \link{tkspinControl}}}{Formerly \code{tkrgl::spin3d} and \code{tkrgl::spinControl}, create buttons to spin the scene.} } History: \tabular{ll}{ 0.2-2 \tab First public release \cr 0.3 \tab Added possibility to control multiple windows \cr 0.4 \tab Compatibility with 2.0.0 tcltk package \cr 0.5 \tab Added continuous rotation \cr 0.6 \tab Added par3dsave \cr 0.7 \tab Added parameters to \code{\link{tkspinControl}}, fixed startup \cr 0.8 \tab Minor fixes to pass checks \cr 0.9 \tab Merge functions into \pkg{rgl} \cr } } rgl/man/writeASY.Rd0000644000176200001440000000706114145464133013620 0ustar liggesusers\name{writeASY} \alias{writeASY} \title{ Write Asymptote code for an RGL scene } \description{ Asymptote is a language for 3D graphics that is highly integrated with LaTeX. This is an experimental function to write an Asymptote program to approximate an RGL scene. } \usage{ writeASY(scene = scene3d(), title = "scene", outtype = c("pdf", "eps", "asy", "latex", "pdflatex"), prc = TRUE, runAsy = "asy \%filename\%", defaultFontsize = 12, width = 7, height = 7, ppi = 100, ids = tagged3d(tags), tags = NULL, version = "2.65") } \arguments{ \item{scene}{RGL scene object} \item{outtype}{ What type of file to write? See Details. } \item{prc}{ Whether to produce an interactive PRC scene. } \item{title}{ The base of the filename to produce. } \item{runAsy}{ Code to run the Asymptote program. } \item{defaultFontsize}{ The default fontsize for text. } \item{width, height}{ Width and height of the output image, in inches. } \item{ppi}{ \dQuote{Pixels per inch} to assume when converting line widths and point sizes (which RGL measures in pixels). } \item{ids}{ If not \code{NULL}, write out just these RGL objects. } \item{tags}{ Alternate way to specify \code{ids}. Ignored if \code{ids} is given. } \item{version}{ Asymptote version 2.44 had a definition for its \dQuote{light()} function that was incompatibly changed in versions 2.47 and 2.50. The current code has been tested with version 2.65. If you are using an older version, set \code{version} to your version number and it may work better. } } \details{ Asymptote is both a language describing a 2D or 3D graphic, and a program to interpret that language and produce output in a variety of formats including EPS, PDF (interactive or static), etc. The interactive scene produced with \code{prc = TRUE} requires \code{outtype = "pdf"}, and (as of this writing) has a number of limitations: \itemize{ \item{As far as we know, only Adobe Acrobat Reader of a sufficiently recent version can display these scenes.} \item{Current versions ignore lighting settings.} } } \value{ The filename of the output file is returned invisibly. } \references{ J. C. Bowman and A. Hammerlindl (2008). Asymptote: A vector graphics language, TUGBOAT: The Communications of the TeX Users Group, 29:2, 288-294. } \author{ Duncan Murdoch } \note{ This function is currently under development and limited in the quality of output it produces. Arguments will likely change. There are a number of differences between the interactive display in Asymptote and the display in RGL. In particular, many objects that are a fixed size in RGL will scale with the image in Asymptote. Defaults have been chosen somewhat arbitrarily; tweaking will likely be needed. Material properties of surfaces are not yet implemented. On some systems, the program \command{asy} used to process the output has bugs and may fail. Run the example at your own risk! } \seealso{ \code{\link{scene3d}} saves a copy of a scene to an R variable; \code{\link{rglwidget}}, \code{\link{writePLY}}, \code{\link{writeOBJ}} and \code{\link{writeSTL}} write the scene to a file in various other formats. } \examples{ \dontrun{ # On some systems, the program "asy" used # to process the output has bugs, so this may fail. x <- rnorm(20) y <- rnorm(20) z <- rnorm(20) plot3d(x, y, z, type = "s", col = "red") olddir <- setwd(tempdir()) writeASY(title = "interactive") # Produces interactive.pdf writeASY(title = "noninteractive", prc = FALSE) # Produces noninteractive.pdf setwd(olddir) } } rgl/man/cube3d.Rd0000644000176200001440000000265014100762640013250 0ustar liggesusers\name{cube3d} \alias{cube3d} \alias{oh3d} \alias{tetrahedron3d} \alias{octahedron3d} \alias{icosahedron3d} \alias{dodecahedron3d} \alias{cuboctahedron3d} \title{Sample 3D mesh objects} \description{ A collection of sample mesh objects. } \usage{ cube3d(trans = identityMatrix(), ...) tetrahedron3d(trans = identityMatrix(), ...) octahedron3d(trans = identityMatrix(), ...) icosahedron3d(trans = identityMatrix(), ...) dodecahedron3d(trans = identityMatrix(), ...) cuboctahedron3d(trans = identityMatrix(), ...) oh3d(trans = identityMatrix(), ...) # an 'o' object } \arguments{ \item{trans}{transformation to apply to objects} \item{...}{additional parameters to pass to \code{\link{mesh3d}}} } \details{ These sample objects optionally take a 4x4 matrix transformation \code{trans} as an argument. This transformation is applied to all vertices of the default shape. The default is an identity transformation. } \value{ Objects of class \code{c("mesh3d", "shape3d")}. } \examples{ # render all of the Platonic solids open3d() shade3d( translate3d( tetrahedron3d(col = "red"), 0, 0, 0) ) shade3d( translate3d( cube3d(col = "green"), 3, 0, 0) ) shade3d( translate3d( octahedron3d(col = "blue"), 6, 0, 0) ) shade3d( translate3d( dodecahedron3d(col = "cyan"), 9, 0, 0) ) shade3d( translate3d( icosahedron3d(col = "magenta"), 12, 0, 0) ) } \seealso{ \code{\link{mesh3d}} } \keyword{dynamic} rgl/man/rglIds.Rd0000644000176200001440000000344714100762641013335 0ustar liggesusers\name{rglIds} \alias{lowlevel} \alias{highlevel} \alias{rglId} \alias{rglLowlevel} \alias{rglHighlevel} \alias{print.rglId} \title{ RGL id values } \description{ All objects in an RGL scene have a numerical id. These ids are normally stored in vectors of class \code{c("rglIds", "numeric")}, which will also have class \code{"rglHighlevel"} or \code{"rglLowlevel"} depending on whether a high level function like \code{\link{plot3d}} or \code{\link{persp3d}}, or a low level function created the objects. } \usage{ rglId(ids = integer()) lowlevel(ids = integer()) highlevel(ids = integer()) \method{print}{rglId}(x, rglwidget = getOption("rgl.printRglwidget", FALSE), ...) } \arguments{ \item{ids}{ A vector of object ids. } \item{x}{ An \code{"rglId"} object to print. } \item{rglwidget}{ Whether to create and print an RGL widget. If false, nothing is printed. } \item{...}{ Other arguments which will be passed to \code{\link{rglwidget}} if it is used. } } \details{ These functions and classes are intended to allow RGL scenes to be automatically displayed in R Markdown documents. See \code{\link{setupKnitr}} for details on enabling auto-printing. Note that \emph{all} objects in the current scene will be printed by default, not just the ids in \code{x}. (One reason for this is that lights are also objects; printing objects without lights would rarely make sense.) } \value{ Objects of class \code{"rglId"}, \code{c("rglHighlevel", "rglId", "numeric")} or \code{c("rglLowlevel", "rglId", "numeric")} for \code{rglId}, \code{lowlevel} or \code{highlevel} respectively. } \author{ Duncan Murdoch } \examples{ x <- matrix(rnorm(30), ncol = 3, dimnames = list(NULL, c("x", "y", "z"))) p <- plot3d(x, type = "s") str(p) if (interactive() || in_pkgdown_example()) print(p, rglwidget = TRUE) } rgl/man/shadow3d.Rd0000644000176200001440000000426114100762641013620 0ustar liggesusers\name{shadow3d} \alias{shadow3d} \title{ Project shadows of mesh onto object. } \description{ Project a mesh onto a surface in a scene so that it appears to cast a shadow onto the surface. } \usage{ shadow3d(obj, mesh, plot = TRUE, up = c(0, 0, 1), P = projectDown(up), outside = FALSE, ...) } \arguments{ \item{obj}{ The target object which will show the shadow. } \item{mesh}{ The mesh which will cast the shadow. } \item{plot}{ Whether to plot the result. } \item{up}{ Which direction is \dQuote{up}? } \item{P}{ The projection to use for draping, a 4x4 matrix. See \code{\link{drape3d}} for details on how \code{P} is used. } \item{outside}{ Should the function compute and (possibly) plot the region outside of the shadow? } \item{\dots}{ Other arguments to pass to \code{\link{filledContour3d}}, which will do the boundary calculations and plotting. } } \details{ \code{shadow3d} internally constructs a function that is zero on the boundary of the shadow and positive inside, then draws filled contours of that function. Because the function is nonlinear, the boundaries will be approximate, with the best approximation resulting from a large value of \code{\link{filledContour3d}} parameter \code{minVertices}. If \code{outside = TRUE}, the first color used by \code{\link{filledContour3d}} will indicate the inside of the shadow, and the second color will indicate the exterior. } \value{ The returned value from \code{\link{filledContour3d}}. } \author{ Duncan Murdoch } \seealso{ \code{\link{drape3d}}, \code{\link{facing3d}} } \examples{ open3d() obj <- translate3d(scale3d(oh3d(), 0.3, 0.3, 0.3), 0,0,2) shade3d(obj, col = "red") target <- icosahedron3d() # We offset the target using polygon_offset = 1 so that the # shadow on its surface will appear clearly. shade3d(target, col = "white", polygon_offset = 1) # minVertices = 1000 leaves noticeable artifacts on the edges # of the shadow. A larger value gives a better result, but is # slower. # We use facing3d(target) so the shadow and outside part only # appear on the upper side of the target shadow3d(facing3d(target), obj, minVertices = 1000, plot=TRUE, col = c("yellow", "blue"), outside = TRUE) } rgl/man/par3dinterpControl.Rd0000644000176200001440000000274714100762640015706 0ustar liggesusers\name{par3dinterpControl} \alias{par3dinterpControl} \title{ Control RGL widget like par3dinterp() } \description{ This control works with \code{\link{playwidget}} to change settings in a WebGL display in the same way as \code{\link{par3dinterp}} does within R. } \usage{ par3dinterpControl(fn, from, to, steps, subscene = NULL, omitConstant = TRUE, ...) } \arguments{ \item{fn}{A function returned from \code{\link{par3dinterp}}.} \item{from, to, steps}{Values where \code{fn} should be evaluated.} \item{subscene}{Which subscene's properties should be modified?} \item{omitConstant}{If \code{TRUE}, do not set values that are constant across the range.} \item{...}{Additional parameters which will be passed to \code{\link{propertyControl}}.} } \details{ \code{par3dinterpSetter} sets parameters corresponding to values produced by the result of \code{par3dinterp}. } \value{ Returns controller data in a list of class "rglControl". } \author{ Duncan Murdoch } \examples{ example(plot3d) M <- r3dDefaults$userMatrix fn <- par3dinterp(times = (0:2)*0.75, userMatrix = list(M, rotate3d(M, pi/2, 1, 0, 0), rotate3d(M, pi/2, 0, 1, 0)), scale = c(0.5, 1, 2)) control <- par3dinterpControl(fn, 0, 3, steps = 15) control if (interactive() || in_pkgdown_example()) rglwidget(width = 500, height = 250) \%>\% playwidget(control, step = 0.01, loop = TRUE, rate = 0.5) } rgl/man/rglToLattice.Rd0000644000176200001440000000353414100762641014503 0ustar liggesusers\name{rglToLattice} \alias{rglToLattice} \alias{rglToBase} \title{ Convert RGL userMatrix to lattice or base angles } \description{ These functions take a user orientation matrix from an RGL scene and approximate the parameters to either \pkg{lattice} or base graphics functions. } \usage{ rglToLattice(rotm = par3d("userMatrix")) rglToBase(rotm = par3d("userMatrix")) } \arguments{ \item{rotm}{ A matrix in homogeneous coordinates to convert. } } \details{ The \pkg{lattice} package can use Euler angles in the ZYX scheme to describe the rotation of a scene in its \code{\link[lattice:cloud]{wireframe}} or \code{\link[lattice]{cloud}} functions. The \code{rglToLattice} function computes these angles based on \code{rotm}, which defaults to the current user matrix. This allows RGL to be used to interactively find a decent viewpoint and then reproduce it in \pkg{lattice}. The base graphics \code{\link{persp}} function does not use full Euler angles; it uses a viewpoint angle, and assume the z axis remains vertical. The \code{rglToBase} function computes the viewpoint angle accurately if the RGL scene is displayed with a vertical z axis, and does an approximation otherwise. } \value{ \code{rglToLattice} returns a list suitable to be used as the \code{screen} argument to \code{\link[lattice:cloud]{wireframe}}. \code{rglToBase} returns a list containing \code{theta} and \code{phi} components which can be used as corresponding arguments in \code{\link{persp}}. } \author{ Duncan Murdoch } \examples{ persp3d(volcano, col = "green") if ((hasorientlib <- requireNamespace("orientlib", quietly = TRUE)) && requireNamespace("lattice", quietly = TRUE)) lattice::wireframe(volcano, screen = rglToLattice()) if (hasorientlib) { angles <- rglToBase() persp(volcano, col = "green", border = NA, shade = 0.5, theta = angles$theta, phi = angles$phi) } } rgl/man/rglExtrafonts.Rd0000644000176200001440000000475314100762641014754 0ustar liggesusers\name{rglExtrafonts} \alias{rglExtrafonts} \title{ Register extra fonts } \description{ This function uses the \href{https://github.com/wch/extrafont}{\pkg{extrafont}} package to help register system fonts for use with FreeType in \pkg{rgl}. } \usage{ rglExtrafonts(..., quiet = TRUE) } \arguments{ \item{\dots}{ Vectors of fonts to try. See the Details. } \item{quiet}{ Whether to print information on progress. } } \details{ The \pkg{extrafont} package collects information on installed fonts from the system. When you first install \pkg{extrafont}, or after new fonts have been installed on your system, run \code{extrafont::font_import()} to build its database of system fonts. Fonts can be installed in \pkg{rgl} using \code{rglExtrafonts(rglname = familyname)} or \code{rglExtrafonts(familyname)}. In this call \code{familyname} is a vector of family names to look for in the \pkg{extrafont} database using \code{extrafont::choose_font(familyname)}; the first one found will be registered with \pkg{rgl}. The optional name \code{rglname} will also be usable to refer to the font family. If none of the given family names is found, no change will be made to the registered fonts in \pkg{rgl}. During startup, \pkg{rgl} detects whether \pkg{extrafont} is installed, and if so runs \verb{ rglExtrafonts(sans = c("Helvetica", "Arial"), serif = c("Times", "Times New Roman"), mono = c("Courier", "Courier New")) } to attempt to set up the default fonts. Fonts found by \pkg{extrafont} can also be used in some other graphics devices besides \pkg{rgl}; see \href{https://github.com/wch/extrafont}{the \pkg{extrafont} documentation} for details. } \note{ Each font in a display needs a unique \pkg{rgl} name; if the associated font for a given name is changed, all previously plotted text will also change. Currently \code{\link{rglwidget}} displays will not respect the new definitions. } \value{ Invisibly returns a vector giving the \pkg{rgl} name and the family name for the newly installed font. } \author{ Duncan Murdoch } \seealso{ \code{\link{text3d}}, \code{\link{rglFonts}} } \examples{ if (requireNamespace("extrafont") && !in_pkgdown_example()) { open3d() text3d(1,1,1, "Default", family = "sans", cex = 2) # Attempt to register new sans-serif font: newfamily <- rglExtrafonts(newsans = c("Comic Sans MS", "Impact", "Verdana", "Tahoma")) text3d(2,2,2, newfamily, family = "newsans", cex = 2) } } rgl/man/asRow.Rd0000644000176200001440000000460714137472630013211 0ustar liggesusers\name{asRow} \alias{asRow} \alias{getWidgetId} \title{ Convenience functions for RGL HTML layouts } \description{ The \code{asRow} function arranges objects in a row in the display; the \code{getWidgetId} function extracts the HTML element ID from an HTML widget. } \usage{ asRow(..., last = NA, height = NULL, colsize = 1) getWidgetId(widget) } \arguments{ \item{\dots}{ Either a single \code{"combineWidgets"} object produced by \code{asRow} or a \code{\%>\%} pipe of RGL objects, or several objects intended for rearrangement. } \item{last}{ If not \code{NA}, the number of objects from \code{...} that are to be arranged in a row. Earlier ones will remain in a column. } \item{height}{ An optional height for the resulting row. This is normally specified in pixels, but will be rescaled as necessary to fit the display. } \item{colsize}{ A vector of relative widths for the columns in the row. } \item{widget}{ A single HTML widget from which to extract the HTML element ID. } } \details{ Using \code{asRow} requires that the \pkg{manipulateWidget} package is installed. \code{asRow} produces a \code{"combineWidgets"} object which is a single column whose last element is another \code{"combineWidgets"} object which is a single row. If \code{n} objects are given as input and \code{last} is given a value less than \code{n}, the first \code{n - last} objects will be displayed in a column above the row containing the \code{last} objects. } \value{ \code{asRow} returns a single \code{"combineWidgets"} object suitable for display or nesting within a more complicated display. \code{getWidgetId} returns a character string containing the HTML element ID of the widget. } \author{ Duncan Murdoch } \seealso{ \link{pipe} for the \code{\%>\%} operator. } \examples{ if (requireNamespace("manipulateWidget", quietly = TRUE) && require("crosstalk", quietly = TRUE)) { sd <- SharedData$new(mtcars) ids <- plot3d(sd$origData(), col = mtcars$cyl, type = "s") # Copy the key and group from existing shared data rglsd <- rglShared(ids["data"], key = sd$key(), group = sd$groupName()) w <- rglwidget(shared = rglsd) \%>\% asRow("Mouse mode: ", rglMouse(getWidgetId(.)), "Subset: ", filter_checkbox("cylinderselector", "Cylinders", sd, ~ cyl, inline = TRUE), last = 4, colsize = c(1,2,1,2), height = 60) if (interactive() || in_pkgdown_example()) w } } rgl/man/spheres.Rd0000644000176200001440000000461714100762641013562 0ustar liggesusers\name{spheres3d} \alias{spheres3d} \title{Add spheres} \description{ Adds a sphere set shape node to the scene } \usage{ spheres3d(x, y = NULL, z = NULL, radius = 1, fastTransparency = TRUE, ...) } \arguments{ \item{x, y, z}{Numeric vector of point coordinates corresponding to the center of each sphere. Any reasonable way of defining the coordinates is acceptable. See the function \code{\link[grDevices]{xyz.coords}} for details.} \item{radius}{Vector or single value defining the sphere radius/radii} \item{fastTransparency}{logical value indicating whether fast sorting should be used for transparency. See the Details.} \item{ ... }{Material properties. See \code{\link{material3d}} for details.} } \details{ If a non-isometric aspect ratio is chosen, these functions will still draw objects that appear to the viewer to be spheres. Use \code{\link{ellipse3d}} to draw shapes that are spherical in the data scale. When the scale is not isometric, the radius is measured in an average scale. In this case the bounding box calculation is iterative, since rescaling the plot changes the shape of the spheres in user-coordinates, which changes the bounding box. Versions of \pkg{rgl} prior to 0.92.802 did not do this iterative adjustment. If any coordinate or radius is \code{NA}, the sphere is not plotted. If a texture is used, its bitmap is wrapped around the sphere, with the top edge at the maximum y coordinate, and the left-right edges joined at the maximum in the z coordinate, centred in x. If the \code{alpha} material value of the spheres is less than the default \code{1}, they need to be drawn in order from back to front. When \code{fastTransparency} is \code{TRUE}, this is approximated by sorting the centers and drawing complete spheres in that order. This produces acceptable results in most cases, but artifacts may be visible, especially if the \code{radius} values vary, or they intersect other transparent objects. Setting \code{fastTransparency = FALSE} will cause the sorting to apply to each of the 480 facets of individual spheres. This is much slower, but may produce better output. } \value{ A shape ID of the spheres object is returned. } \examples{ open3d() spheres3d(rnorm(10), rnorm(10), rnorm(10), radius = runif(10), color = rainbow(10)) } \seealso{ \code{\link{material3d}}, \code{\link{aspect3d}} for setting non-isometric scales } \keyword{dynamic} rgl/man/figures/0000755000176200001440000000000014146446052013263 5ustar liggesusersrgl/man/figures/READMEpolyhedra-1-rgl.png0000644000176200001440000002320714146473075017567 0ustar liggesusers‰PNG  IHDR ×ÙÙAsRGB®Îé IDATxœí{UÕï¿û`äa]щ¢ÈCåq0ªî̼œš D­ ‹Ö‰Ä‰‚øˆ¹×njtnÝI$&‘ ©äÎ#%êäLŒÑ˜Ð$£Í#ˆhb›`Cf®b¥níùãô>g?ÖÚ{­ýZûñýP›>g?×ÞÍéþðû­õ[–mÛ6!„Bɉ†éB!„zA%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹B%„B!¹rŠéB!qغ{úwo3ÝŒB±üSŸ3Ý„Â0xt;öíycϺ pá”[ ·ˆ¸¡€B)_þǯbõ?|Õt3 G×å³0ûòY¦›Q¶cp`ZÿIÙ·çk€±gÍ¢”˶mÛt#!„Æÿ÷ ¦›PXžøâ?QBì{ùá¶tFA)ÍŸÚ÷íßÒO,X„s¬óðàªÕ¦›C!$‚OÞõ¦›PhVÿ##ú lþ=_þ=_Ãs&â¹ ±só -‰}ùaÓÍ«$µ€öoéÇ—zWã…¾þÀ¶•½+pGÏ ­"EbÕê5èYñYÓÍ „¸`ê]‹?Wûþ :PU)MÚ h˜xúYÙ»sš]èšß•CËHQXµz zìü·÷Ž[)¢„ʧuOÅïÜ|C»ÿg–8R:ö¬«0öÌ«2¿^U¨€êˆ§Šh=ØÒ¿Í…7H·SD 1 û}êóëg^7Ýcä% "(¥ÑT^@“ˆ§Šh5‰O?Ñz³êÙï£çÿÄt3jÇ'ïú ô¿È’Kºt]1 ÿí?™n†žÛ0Ñt<\8õ¯€R:De4Mñô³²·Õ?”ýDËÍ–þè]ý0ú^ØëxŠhýX°öaôí} Í‹.Ææ[Øÿ+/˜zOF]ûƒM@EÔYJ+' YЧŸ9Í.ÌivQDKFRñtC ­Ž|:PBóaëîmXt'G½'¥ŽýAË  "ê"¥•Ð<ÅÓE´<,Xôieñ|ÿ9âÃû”ö¥ˆV¿|:PB³‡ý>Ó£nýAË* "ª(¥¥P“â)‚%œŠ‰–xž{þËŒÿÖЃß]§|Šhõɧ%4;˜zO—ºõ­’€Š(»”–V@ÓÏá“x7•sÑ¢à/©Å™3ÿgÎü£Àú£;€£; |Šh5ˆ’OJhúP>³¡NýA«. ")-CÒÒ hZâ9#0g´_÷¿Þ‡® MÀq¼íùšЍtG¶À¯¹ï?çBéöwïÃþMkµÎI-/ªòé@ M¦Þ³£ýAnÇÎ-6ÝŒBPT)-€&Ïáƒ3Ú¯Ýtß¶Ko[‚o|å[Xÿ•o¶§!¤Ñ|ˆ3Àèç^„^s‹òþ?}?}V«]Ñr¡+Ÿ”Ðt |fKRñÐpŠ ¥…Ð8â9#GŽ›€i·>„‘çM€Õh Ñh a5а,4, –ÂÒh/­ã­FgÏú“ÖyÇ©÷[ë{a;,útœÛ&¶|@ßÞ×°`­^dž´°ض Û¶[‘?Û»ÎYo£¥\þõíý…Ûlg—Àvÿß"X5t§}Á%xŽeH ãdÛ!ÚÞÞæ_/Ø?çï')Ž|.¼þîL¯c<Ú¿¥Þ\Ô~Ÿ$®C÷K°4D4¿±ú[Xÿ`p@RZÈ"¤Œˆªa›¤µÿ9³>Œ³g}8VCÀ‘mOãð¶§õŽ;ô‹lD”ÈB>Ý0ªÎ«ïìÃßhÕÝ•E0Ã×CšnWMß‹b¬©üà°/¢E0*.KËK£¡Þõë'ÿ﨔–›oÀàÀ6ÓÍ(Ž|È4ú PG<óÎÀõ÷EîÓuN3‡–´ð÷#¥ˆŠÑ-¯túyãœÙÁé*ÑI+ðÂ…íù† `×WþJ­Cô=ù÷œd€¬åÓªN÷Ëwµ^(¦ÛÃÄS5Õ¸R]F]évï«ð}Åéw]m­Y?åoUZZJ( ú¸åÈ^@sOÁÿlËÏ1Ýš…eÍÛÛétYy¤¬è^¹¤õ&byä;åÖ&§_«ÓÕàÉÞM˜d]Žo¬Ê. [6tåóÜÙÁÄ…·aÔyÓé «“†÷¤ã®4»/åny÷·ÖyiúÿzûÃ8wöG”ÛÚ\x¶ôïˆóXHLò’O€éx:éìð”z;¥íÛ_5ÕîΡ{Séiò´'Ý'åyšÞ—š¥Ùô;ljRðLÃ7»^zÇ#ŸY§ßº¾÷[¹G;ý,½sH@ý?Û‹LŸ; 3æN3ÖÎ18ý}[]¿H¬Z½FK>/]t;Æu}T.C¢©Òï3¼?¨\FÇu}—.R¯¨Ð\xV­^çñMò”OJ¨jâUá6IÐÀ>š}Aã,Ñ2êIHD3¸XD}Û$"ZeýTg×Kï`×KïxÖMž:7óëæ. '0˜÷%=<ò/uä3,:´½ûÎä’’æô eE§ÌÒ¨ñ—àª`ÔøK\â© CrˆŠz¢âˆ§PF‡Ö;í×õQ¥ö÷>ø0%4cLȧ%TW:Y.žaR©(ʲéÆX|ÎH)ÕQáviäÓîD>+. D ‘|ùè)™_ÁÇIœÌû’mºïZ‚éó4"š0}^+ ºëùde™âbòyùœ|í œ~ÞÅí÷–¬ößPé%n^²¾dí_•¶oß¡k;Q†óæ| –eá7/|7òZÎý²Vhú˜”OGBÙ'TL;• o¿OÿgÍÙf[®#ýŸÃíÞý:ïìÀÛó%UÚ–¨x‰¡ý¥û…m:–Ô™|æ‘~ D@»š³ñž!©Zz· ï§$ýî^Ölʯ/¨›DWs¶‘k‹>­$Ÿ£Æ_‚Ù+mG=ÛQK_„³¡š~o…4|C!u·å¼9Ãì•â¼9‹¼§Þf™¦”)‚|:0*çÒ\osGIeÛýÑÎ~Ñ‘QÕÔ|ì~ ÎE<LÈ£¢œÃ·íÒèÏGªÃS?(¡AüÂÁŒ’Vá~BÙÔL¡«F5ä2=•œ3°¯_6Åûø·_:’)øº±þÛ¿ •ϼÉ]@ç4»äÝ›1oZ¼è§`ÿéó¦a†Î &¢Œ§ÆçhbÄhàô³€±ã[ËÈ3‘gâÄÑ#t»_<…ÒHµ«OÁ)Ž~ZA)ɨ_D}iùo¿ Õº?ç^O?«uÿ#F·Ÿk…êQùtèÛû¬•·™nF!˜èô ¥‚p ÷‘ì§õ„Y…yëM‚0ª‚°B.‘ª²)Ú'¸]óCJËáßcý·«´ïÂëîʸ5ŒE@óJïyê!}é ‘ÑîÏ瓊wÝö*³¥š7® ˆ&†N9-°ÿ‰7ßh‹c@òü©wY4¬¨VT!ÒÆ†%‹Êi­û>ªó\ÆŽG󯕨²cwÆß‘òc­¼­4òé†ÚÂ/”zÂéß'Ù fàÚ>Y ‘Ö¸©øàE%r*”j ©{E` ÞÁ?»Qy¦ßƒ dŸ†ïþ¼Fê]QR§_= 3®Î6 jªJ€1N9M(šaüîÈPñŒŒ€Šú€6:b\‚£áÃú€ # ‚÷wFO xV$”²K\ÙÛŸœ¤Â)“MÈå4B,ƒQQýEMTE’‰H)íì«.¤Õ×P¢#Ÿ&0* Y§á—Þ›NßÏ@Y¦ïeÛ”Åç£9°}spä»`ð‘?åýÔœŠÓ ¤äeƒ‘\²zâЦe¥¨Š¼Uå>â0iä„È(€À>Jû D3,  ~j Fò> ‚úÖ¹û€:²:xh.Ï«TMÚªv?ªØ@¬¨l?YÐà1jÑÐÔYÔÓÓ0‰œÆ•R÷>I¾I¤ÐÈ Ì‡‘wú0²K7K£Ÿ¬‹!¦y¤âI8Çß|Ã+šH§(ú)Š|ªF >òJ¦H<½QOgûþí?2ý+CUe­ª÷Eò¨lß œÊS쮃ҽ)áõÄ‚*h‚LL5# U¦Î}@ãȧ)Œ hQÐîŒRïþ¥eM‘:–_ŠËþm? ЧgÆ£ix%*ýî•Ñ ˆZ²HD‹ªKZÕïÏϤ‘RH·GˆihÔ M+"êù‘¢KÏ+ˆ©Š”2_=’ÈgÞéw šn´ûÞ%XúAúÝùªãú:ýCéGAëZ|>oÿzoPxz"¾ùßå)ø°ñá#ße¢é—͆oûÞ­”ϤÔMÊêv¿ªÑÏÀ¾Pï±’(hÜHhà‚×FF@e³Fi÷:5»QyM½éǸ€éõíväG?ý’)#b’; š–„2ý®Ïë/ü 0úÝ/â|D´3bø°¾Ÿ~Ùô·ËjX°"ÿ’0ê*cu¹oõCÑÑOïþ # º'´Ú„PÏ¥uö'Õ ©|fÒï@A4­´óÒ°‘ïîõþmaQP…ó-M©/hÚÝêÀ±ƒ¯·DS&¡ IäSUDuÅSr}oT´_=ÿŒéGWZê"a2êrÿi Rø÷ÕŒ~¯'‰€êFA…6nÞãBû’R“†|šÄˆ€úg÷I# ßíN½j¯Ýïeâ©x¾G¾Ÿ¼,“ÿ9Ôa$‡æ•WÄ>vð7û"%´2^µ“"žÎva$Ô'Ÿ¯%Ï$Ï© ÔE¾¢¨üsP‘L…ȧ÷qô3³¾Ÿá ‰Ž„FEA;é|pô{,*/]šTùyLu± êi0ò§ïg}A= MeA…I£.Vú>â‘öìF¦Òï@4IÞ}”¥Î¯ªixÿ>¢óù^gQ–‰DóÛ¯ùJ1…IhC.¡ž¾ŸÑ³ ù#›áòÙ)ÁôËÏô#+U–­$ÔṄ§âÅR*¡”J£jd3O"¥²HÑQQï9ÝÇ“â“uäÓÔìGnN1qÑ9Í.<ˆ/ ·Ç þç„?ãêiÞ)7eˆ¢•²}ܯeŸPkh›±:óÄïúÉÏC.NꀦÁÀþW[QFË5Ïxfò¿wcµþmm}ÛmÀ¶„ÿžlg›à½ À²mì~î_´ïÉOÝë€ö hïß}½³òÀÁÖrÁùÀã µ,eNü®uOǃý¾zoº¹ýê‚-xg~[ž/Ñç‘lq½Ì¢`Zªh^(]cò¨KÒlE¡¨BÐ< Ì×V@ÃPIÃúÄ鵟ò^q¿î{—`Ù‡o—\¤Óïéqdï/ÚinË5ÚÜò<÷¿ïlhÿÕ~k»7!$hÛžOî÷­×¬ý™B :" ”WFCĨ‘|ºCu’Nð£(S×I4?†…ˆJ$S¼Fñ\…¸1""ù,Bú( €­4üi.Ü–Z­M•ÔzÂéô«“GA‰û_ÅÙMòJ¦å‹júß{¶µÿ‚÷UXô³ᔾ·müìÙï¨ß‰D*¡eŠŠFH§Cߣë0ÆÌœe[(”q£œvû‹üP+ômjÚê„×±«&W¸ýàÀ6ÓMˆMÙ§ÖÔŲmÛÈÿ…εΗnŽÒ4|ÿ¿÷ÉK'‰Þ‹¾ú_˰¯E_mÉû¡¥ëô¦ðô'0}Ó>¨ÐÈê`MýãÄç8gÂd|ô³ÿÓ—†/ B¢ŸÀPÇþà{çõSkþ‡_Eé°÷<›øUbË®h~æ/Õv.šŒ*Š'P?ù€On½Eº-ø áT!ÍSfòË6FþñÙk³hI!xnÃDÓMˆÅúoÿ6·k=¶ñXn× £pƒÂèþ|9Ë=ò=ñ€$¦ßÓçðë¯DNO©½| ž? ù$AæÏ˜‰¾Gãa½o$;å3¢F VJgp‘ ¦{I§¾{Ô D …3¯{^%ýT@Oâ]áhø¥%ÐéóZ©x’Göý2ÉTZ »žùgÓ¤ÒÌŸ1ööŸ¶Ê4©`b½`${Í™­ûª­|¦RFÉ5~\µ¶gž,ncìY“×q¤•ªM­©K!Fê¾'D>ã|ž¢ŽIùœÝw{ÛÏòKÙ±óé'"„q˜xý°Î¶a®¥}Ì0Íó9%™8)ÚµBuÈ2*#ÚéМ9³Òe–TnBûg´<2éÓ;å¢ôÉÕš¡ñnT%%æ1%Ÿ¦g?rSÈAHp'1zèu÷=K°ôž%­OŽÿw¹ê:Ñú°ýÂÞ‡­—¬›>ofÌ›†]ÿÖÄô{vúÕžVÍO«Ó/Ì[ŠIÒ4¢ Së— d›§hg?Û¶±ã© Ú÷@â±yí:¬ú»¯Ë'ÉHs½FßN”Ï ÁÝúœ6X—ɮU@léÉR$LÍnT¤ô;P’èRwô0꿆¶àuاQç¿›¢óÉÚ 8_h—¤Êá½¢¾ !ËPôs˜dû°È(¨xÙñ½ÇM?ŠÚÑsÓÍ‚õqpGEOüNí˜ÑN7U/0¯Ã”Ñáµ*â™Áˆ©/rZtCóÜ”à>¤ä£žk™wºï^Âô»„Þe‹S;×¶}Lš"K¦\>*\/Nɧ™~OóùTÄ ´DôÅ—ÂSô1úvʨMOUÈbTº].¨!šڢpÝ´Óòþ‡BŒ`Z>‹”~ ¦àç4»ðB_è>Ç1ˆs§ãgÿö¢ZÙ%¶Ã·-ì½›¨4¼;êˆÚ‚íCËŒ¹ÓqRaºÑ:΂Գl1zù‡TÎõ›W_›û^m½ñ¢—ÔûÓªÌeû×ûW´ÞoÝôm…³ªÑCÕ"²V¨cF'J±‹ |q4,4Õžyš=¸§Î%¸žì‡ªïŸEžÉ´|N¾lž±kË(lP À{xŸºæÓ±¦›“'0ˆ÷ðnuî+Iß7¿„æ+“ŸèÔØðÕû“Ÿ')ÃÞüÿä……û¾ù¥S?znºÍ™3Õk…Fqà p S9°ÌR8¢Ÿ“–³V&¦¾—Y·'wl雈µÀ” OÃYTŠP`¾Soú)d Þýsã8Þ®LʺUxþíö{Ž2ÿÊËÓI5Ÿ*žI+wRhGï²Å˜åå)4¦žhÕ Íʧœ0Q’§¥]ïŠTnI—¨´½§SAJ)z’ EO xéw `êϦ;ÇÛº eâ=œôȧƒìž»š³3oSQéY¶Í+¯ˆ‚SG¤×˜¤ ;¥MSïÉqj…‰Z×øÌˆðî—¾5Fú:KtÐN«å’IÑ,6E‘Ï¢bL@ý‚ <‚C¥•Ð÷pGp(tFC½$Š‚%úé =L½§‹VÁúŒp Ì“("˜üŒK”úé/Q‹2L¿øR[s¡HòY´òKÆ# ² ˆ2J¨Š|:è<‹ª;_¤è§CÌ((SïÙ«`}J°Æ§:SFOŒH«#EK““¦‚æ×PY4µõ\«J!9SkA>'_6÷=°©éwÀ°€Æ‘-U™+ qÚK m‘8_$bDA™zÏŽÍk×%/Ó¤ k|ÆC.r bZµ`_X*ßwÓL×çOQ¦Öœ|Ù<<¶ñî»c!9GÏrXìý²ö±oáMüÎM¿Q)s{cwGïr¬èYžrkÊIï²ÅhÞø¢úEK¿;8QPÅñL½gOªeš"`™¥t “)Ë¿U¸³ä¿ù&þ÷/½™he¤TzØfìÚEÏ…×ß]Øh§£Ð=ËqÈ>¨]óò$ÞÅ[x3£V¥CœöÍiváɾÇ)Ÿ.´RñEL¿»Q”c¦Þó#•‚õP>ã·\Z\²5ÇyàÅ‘Ëè(fÒˆ&Ë0¥iù¼ïMxlã±RÉ'X¶mÇýwœ*«W}Y;:#  } oz¦UQÏpÜx'úvDDBG– ^ì»ÿµ÷<›ScˆÃ–];Ó«ê‚e–’ñ‰ç‹'î…/DÁ?ÏÍ>âoŠç6äß¿ÕTùÉ—ÍÃÂëî*tŠ= ãƒâDCOâÝÂÕ=A-ùœÓìÂ!û å3‚È(hÑ£ŸQP¦ÞÍE­PÊg °_gaE!ë/JRÄ|:‹ŠÞ¿S…¨Û7àŽ^u+R¡z¡ù(žì{OlÞa‹ªCd*¾¨}?ý “w»fêÝ,iÖ ¥|¦,UŽŸ!¤¢É‡“%yËg•ÄÓ¡p t¢¡ª"Z Õ‘O'êÙ5¿¾Åæã _–è§ÃˆÓ«šW^ÁQïOXþ5IDAT!I­P§Æ'å3¢#‹a}8#.>ÒðjXÒðCIrò”Ï*ЧCaç‚ÐNK«ô uäÏļñ:òùdßãÏGÅ—%úé ˆ‚nþæ 4„ÈØ¼vÜò—èÛ¹SùÖøÌ0‘²¢ö ¬Öúži'P½(”æS4¯ó“/›‡ûîߘùuLRȨh¨‰);eSlúaÔ3©ø²E?\QÐD³>‘ÌЩJù̆©1Цë÷ËÔéÕ)É®=Â]­ui÷1ó¶ñXíä(™€:¬èYŽ'ûÝ'î,Dª„ß)(ÏîÙ1ÿÊËaïÚˆÞîE¦›‹æŒ)è[ÿ¿L7ƒ("’оG×Q>3fÊè‰A“×ó«ò<ðYàÌëž6UX¤Ca ÑÇ%¬€}V…êà ͳ ¼¶ìz}»^Aïú'L7EJsÆôv/Äü“M7…ÄÄ)XÏ2Kù°áà&l8°I°E0ÈÄ4šEAø[<¸òÚ ®Áµç_“ysL°ï凱oÏ×R;_³U¡x|š”^@ ËV,l~R¸-m •ÉçœfVô.gº½¬Zÿ$BF)„ÄG. a„˜h%5ô7´Þ¯ï* èÎÍ7¤6|ÚòIñSšAHatÍŸCöAa4Ô™7> •ÍrĨg±èé^Øþºjý“èÛõ úv½œÛõ)„¤ÃÔÑñ˜d›Ü%C¤¬½)†‰&‘×Xažø±¡ÒG• ’fÏ:”RJB%" ~-¸/ôõ{ÖÁ‰j„Šj}2êY.V­2³¨(¥“ôyùÄ«ø»õê•1ЩKœ_Ü÷_~geû¦1|Zò¹ðú»±ðº»Ÿ§êT"êç‰ÍÑÐ$…êEòɨgùèé^ØŽŽ¦%£OBЇªœQT+* iÈgK)%¡’P7þh¨n$Ô/Ÿsš]Ý^!âô¥t’q# DÌÿ½z½é&dF’hùdÿÎøT^@àHyÕBõþBó,(_mÂd”ÒIˆþì'ݦ›P( A☧x&§êàÑ( uË'£žõüDé$Ä,Ðô €z‰#ŸÏô¨dPîé<æìtË'£žõ¤§{!zL7‚BH&èÊ'Å3}J9RÜÓyʦÒ<‚CœF“BŠgBJF žßàQ½yàu¦Öœ|Ù<<¶ñXíg-Ê‚ZE@Ý8ÑÐ5½zj„À^F= !¤08æd…KT‡´çE¤\VØ>5Ð)0ÏRJÙS»¨›=˱×~Ÿê½paóF= !¤@LséÐ+;d‰Ø\Ö( Ö=Uå¦õˆŽ€ªÊç}lÂcQ>s ¶P7Ëz>ƒe=Ÿ1Ý B!±ˆ’,Wx´´>–¬á‘¯QòÉþf €B),î^ü,{RëL#¿oÆ|mß׺&ŸO³P@ !„”s]@‹­o*­›ZÑ)8اx (!„Â2uôDì9þËÈýÊ<ý¦ŒbkoqõÉ'ųXP@ !„ÔJ]õñËçäËæá¾û7lA%„BH%pË'ųØP@ !„–©c&L·‚™Ám:³Ý÷À&¦ÙK”B©8SÇT{Òþ·.ÃMŸ[Nñ,–mÛìC!¤°lݽÍtJÏìËg™nBf ÝŽ±g^eºD (!„BÉ•ZOÅI!„Bò‡J!„Br…J!„Br…J!„Br…J!„Br…J!„Br…J!„Br…J!„Br…J!„Br…J!„Br…J!„Br…J!„Br…J!„Br…J!„Br…J!„Br…J!„Br…J!„Br…J!„Brå?xï4·øtcIEND®B`‚rgl/man/play3d.Rd0000644000176200001440000001203114146472047013302 0ustar liggesusers\name{play3d} \alias{play3d} \alias{movie3d} \title{ Play animation of RGL scene } \description{ \code{play3d} calls a function repeatedly, passing it the elapsed time in seconds, and using the result of the function to reset the viewpoint. \code{movie3d} does the same, but records each frame to a file to make a movie. } \usage{ play3d(f, duration = Inf, dev = cur3d(), ..., startTime = 0) movie3d(f, duration, dev = cur3d(), ..., fps = 10, movie = "movie", frames = movie, dir = tempdir(), convert = NULL, clean = TRUE, verbose = TRUE, top = !rgl.useNULL(), type = "gif", startTime = 0, webshot = TRUE) } \arguments{ \item{f}{ A function returning a list that may be passed to \code{\link{par3d}} } \item{duration}{ The duration of the animation } \item{dev}{ Which RGL device to select } \item{\dots}{ Additional parameters to pass to \code{f}. } \item{startTime}{ Initial time at which to start the animation } \item{fps}{ Number of frames per second } \item{movie}{ The base of the output filename, not including .gif } \item{frames}{ The base of the name for each frame } \item{dir}{ A directory in which to create temporary files for each frame of the movie } \item{convert}{ How to convert to a GIF movie; see Details } \item{clean}{ If \code{convert} is \code{NULL} or \code{TRUE}, whether to delete the individual frames } \item{verbose}{ Whether to report the \code{convert} command and the output filename } \item{top}{ Whether to call \code{\link{rgl.bringtotop}} before each frame } \item{type}{ What type of movie to create. See Details. } \item{webshot}{ Whether to use the \pkg{webshot2} package for snapshots of frames. See \code{\link{snapshot3d}}.} } \details{ The function \code{f} will be called in a loop with the first argument being the \code{startTime} plus the time in seconds since the start (where the start is measured after all arguments have been evaluated). \code{play3d} is likely to place a high load on the CPU; if this is a problem, calls to \code{\link{Sys.sleep}} should be made within the function to release time to other processes. \code{play3d} will run for the specified \code{duration} (in seconds), but can be interrupted by pressing \code{ESC} while the RGL window has the focus. \code{movie3d} saves each frame to disk in a filename of the form \file{framesXXX.png}, where XXX is the frame number, starting from 0. If \code{convert} is \code{NULL} (the default) and the \pkg{\link[magick]{magick}} package is installed, it will be used to convert the frames to a GIF movie (or other format if supported). If \pkg{\link[magick]{magick}} is not installed or \code{convert} is \code{TRUE}, \code{movie3d} will attempt to use the external \command{ImageMagick} program to convert the frames to a movie. The newer \command{magick} executable is tried first, then \command{convert} if that fails. The \code{type} argument will be passed to \command{ImageMagick} to use as a file extension to choose the file type. Finally, \code{convert} can be a template for a command to execute in the standard shell (wildcards are allowed). The template is converted to a command using \cr \code{\link{sprintf}(convert, fps, frames, movie, type, duration, dir)} \cr For example, \code{convert = TRUE} uses the template \code{"magick -delay 1x\%d \%s*.png \%s.\%s"}. All work is done in the directory \code{dir}, so paths should not be needed in the command. (Note that \code{\link{sprintf}} does not require all arguments to be used, and supports formats that use them in an arbitrary order.) The \code{top = TRUE} default is designed to work around an OpenGL limitation: in some implementations, \code{\link{rgl.snapshot}} will fail if the window is not topmost. As of \pkg{rgl} version 0.94, the \code{dev} argument is not needed: the function \code{f} can specify its device, as \code{\link{spin3d}} does, for example. However, if \code{dev} is specified, it will be selected as the current device as each update is played. As of \pkg{rgl} version 0.95.1476, \code{f} can include multiple values in a \code{"subscene"} component, and \code{par3d()} will be called for each of them. } \value{ \code{play3d} is called for the side effect of its repeated calls to \code{f}. It returns \code{NULL} invisibly. \code{movie3d} is also normally called for the side effect of producing the output movie. It invisibly returns } \author{ Duncan Murdoch, based on code by Michael Friendly } \seealso{ \code{\link{spin3d}} and \code{\link{par3dinterp}} return functions suitable to use as \code{f}. See \code{demo(flag)} for an example that modifies the scene in \code{f}.} \examples{ open3d() plot3d( cube3d(col = "green") ) M <- par3d("userMatrix") if (!rgl.useNULL()) play3d( par3dinterp(time = (0:2)*0.5, userMatrix = list(M, rotate3d(M, pi/2, 1, 0, 0), rotate3d(M, pi/2, 0, 1, 0) ) ), duration = 2 ) \dontrun{ movie3d( spin3d(), duration = 5 ) } } \keyword{ dplot } rgl/man/spin3d.Rd0000644000176200001440000000412114100762641013277 0ustar liggesusers\name{spin3d} \alias{spin3d} \title{ Create a function to spin a scene at a fixed rate } \description{ This creates a function to use with \code{\link{play3d}} to spin an RGL scene at a fixed rate. } \usage{ spin3d(axis = c(0, 0, 1), rpm = 5, dev = cur3d(), subscene = par3d("listeners", dev = dev)) } \arguments{ \item{axis}{ The desired axis of rotation } \item{rpm}{ The rotation speed in rotations per minute } \item{dev}{ Which RGL device to use } \item{subscene}{ Which subscene to use } } \value{ A function with header \code{function(time, base = M)}, where \code{M} is the result of \code{par3d("userMatrix")} at the time the function is created. This function calculates and returns a list containing \code{userMatrix} updated by spinning the base matrix for \code{time} seconds at \code{rpm} revolutions per minute about the specified \code{axis}. } \note{ Prior to \pkg{rgl} version 0.95.1476, the \code{subscene} argument defaulted to the current subscene, and any additional entries would be ignored by \code{\link{play3d}}. The current default value of \code{par3d("listeners", dev = dev)} means that all subscenes that share mouse responses will also share modifications by this function. } \author{ Duncan Murdoch } \seealso{ \code{\link{play3d}} to play the animation } \examples{ # Spin one object open3d() plot3d(oh3d(col = "lightblue", alpha = 0.5)) if (!rgl.useNULL()) play3d(spin3d(axis = c(1, 0, 0), rpm = 30), duration = 2) # Show spinning sprites, and rotate the whole view open3d() spriteid <- NULL spin1 <- spin3d(rpm = 4.5 ) # the scene spinner spin2 <- spin3d(rpm = 9 ) # the sprite spinner f <- function(time) { par3d(skipRedraw = TRUE) # stops intermediate redraws on.exit(par3d(skipRedraw = FALSE)) # redraw at the end pop3d(id = spriteid) # delete the old sprite cubeid <- shade3d(cube3d(), col = "red") spriteid <<- sprites3d(0:1, 0:1, 0:1, shape = cubeid, userMatrix = spin2(time, base = spin1(time)$userMatrix)$userMatrix) spin1(time) } if (!rgl.useNULL()) play3d(f, duration = 2) } \keyword{ dplot } rgl/man/rgl.open.Rd0000644000176200001440000000651714100762641013636 0ustar liggesusers\name{rgl.open} \title{Low level window interface} \alias{rgl.open} \alias{rgl.close} \alias{rgl.cur} \alias{rgl.set} \alias{rgl.quit} \alias{rgl.antialias} \alias{rgl.dev.list} \description{ 3D real-time rendering system. } \usage{ rgl.open(useNULL = rgl.useNULL()) # open new device rgl.close() # close current device rgl.cur() # returns active device ID rgl.dev.list() # returns all device IDs rgl.set(which, silent = FALSE) # set device as active rgl.quit() # shutdown RGL device system } \arguments{ \item{useNULL}{whether to open the \dQuote{null} device} \item{which}{device ID} \item{silent}{whether to suppress update of window titles} } \details{ The RGL device design is oriented towards the R device metaphor. If you send scene management instructions, and there's no device open, it will be opened automatically. Opened devices automatically get the current device focus. The focus may be changed by using \code{rgl.set()}. \code{rgl.quit()} shuts down the RGL subsystem and all open devices, detaches the package including the shared library and additional system libraries. The \code{rgl.open()} function attempts to open a new RGL window. If the \code{"rgl.antialias"} option is set, it will be used to select the requested antialiasing. (See \code{\link{open3d}} for more description of antialiasing and an alternative way to set the value.) If \code{useNULL} is \code{TRUE}, RGL will use a \dQuote{null} device. This device records objects as they are plotted, but displays nothing. It is intended for use with \code{\link{rglwidget}} and similar functions. If \code{rgl.open()} fails (e.g. because X windows is not running, or its \code{DISPLAY} variable is not set properly), then you can retry the initialization by calling \code{\link{rgl.init}()}. Do not do this when windows have already been successfully opened: they will be orphaned, with no way to remove them other than closing R. In fact, it's probably a good idea not to do this at all: quitting R and restarting it is a better solution. This package also includes a higher level interface which is described in the \link{r3d} help topic. That interface is designed to act more like classic 2D R graphics. We recommend that you avoid mixing \code{rgl.*} and \code{*3d} calls. } \value{ \code{rgl.open}, \code{rgl.close} and \code{rgl.set} are called for their side effects and return no useful value. Similarly \code{rgl.quit} is not designed to return useful values; in fact, users shouldn't call it at all! \code{rgl.cur} returns the currently active devices, or \code{0} if none is active; \code{rgl.dev.list} returns a vector of all open devices. Both functions name the items according to the type of device: \code{null} for a hidden null device, \code{wgl} for a Windows device, and \code{glX} for an X windows device. } \seealso{ \link{r3d}, \code{\link{rgl.init}}, \code{\link{rgl.clear}}, \code{\link{rgl.pop}}, \code{\link{rgl.viewpoint}}, \code{\link{rgl.light}}, \code{\link{rgl.bg}}, \code{\link{rgl.bbox}}, \code{\link{rgl.points}}, \code{\link{rgl.lines}}, \code{\link{rgl.triangles}}, \code{\link{rgl.quads}}, \code{\link{rgl.texts}}, \code{\link{rgl.surface}}, \code{\link{rgl.spheres}}, \code{\link{rgl.sprites}}, \code{\link{rgl.snapshot}}, \code{\link{rgl.useNULL}} } \keyword{dynamic} rgl/man/writeWebGL.Rd0000644000176200001440000000522714100762641014122 0ustar liggesusers\name{writeWebGL} \alias{writeWebGL} \title{ Write scene to HTML (obsolete) } \description{ Obsolete function to write the current scene to a collection of files that contain WebGL code to reproduce it in a browser. Please use \code{\link{rglwidget}} instead. } \usage{ writeWebGL(dir = "webGL", filename = file.path(dir, "index.html"), template = system.file(file.path("WebGL", "template.html"), package = "rgl"), prefix = "", snapshot = TRUE, commonParts = TRUE, reuse = NULL, font = "Arial", width, height) } \arguments{ \item{dir}{ Where to write the files. } \item{filename}{ The filename to use for the main file. } \item{template}{ The template web page to which to write the Javascript for the scene. See Details below. } \item{prefix}{ An optional prefix to use on global identifiers in the scene; use different prefixes for different scenes displayed on the same web page. If not blank, it should be a legal identifier in Javascript and HTML. } \item{snapshot}{ Whether to include a snapshot of the scene, to be displayed in browsers that don't support WebGL, or a specification of the snapshot to use. See details below. } \item{commonParts}{ Whether to include parts that would be common to several figures on the same page. Currently this includes a reference to and copy of the \file{CanvasMatrix.js} file in the output. } \item{reuse}{ Ignored. } \item{font}{ The font to use for text. } \item{width, height}{ The (optional) width and height in pixels of the image to display. If omitted, the \code{par3d("windowRect")} dimensions will be used. } } \details{ This obsolete function writes out a web page containing Javascript that reconstructs the scene in WebGL. It will be formally deprecated in an upcoming release; you should use \code{\link{rglwidget}} instead in any new code, and start migrating old code there. The remaining documentation has been removed to discourage use of this function. } \value{ The \code{filename} is returned. } \author{ Duncan Murdoch. } \note{ If \code{commonParts} is \code{TRUE}, the output includes a binary copy of the CanvasMatrix Javascript library. Its source (including the copyright notice and license for free use) is included in the file named by \code{system.file("htmlwidgets/lib/CanvasMatrix.src.js", package = "rgl")}. } \seealso{ \code{\link{rglwidget}} should be used instead of \code{writeWebGL}. Other functions which are related: \code{\link{scene3d}} saves a copy of a scene to an R variable; \code{\link{writeASY}}, \code{\link{writePLY}}, \code{\link{writeOBJ}} and \code{\link{writeSTL}} write the scene to a file in various other formats. } rgl/man/facing3d.Rd0000644000176200001440000000422714100762640013563 0ustar liggesusers\name{facing3d} \alias{facing3d} \alias{projectDown} \title{ Subset an object to parts facing in a particular direction } \description{ \code{facing3d} subsets an object by converting it to a triangle mesh, then subsetting to those triangles that are counterclockwise (for \code{front = TRUE}) when projected into a plane. \code{projectDown} computes a projection that \dQuote{looks down} the specified direction. } \usage{ facing3d(obj, up = c(0, 0, 1), P = projectDown(up), front = TRUE, strict = TRUE) projectDown(up) } \arguments{ \item{obj}{ An object that can be converted to a triangular mesh object. } \item{up}{ The direction that is to be considered \dQuote{up}. It may be either a 3 vector in Euclidean coordinates or a 4 vector in homogeneous coordinates. } \item{P}{ The projection to use for draping, a 4x4 matrix. See \code{\link{drape3d}} for details on how \code{P} is used. } \item{front}{ If \code{front = TRUE}, retains triangles that are counterclockwise after projection by \code{P}, otherwise retains those that are clockwise. } \item{strict}{If \code{TRUE}, drops indeterminate triangles (those that are annihilated by \code{P}).} } \details{ By default the returned subset will be those triangles whose upper side matches \code{front}. Change \code{up} or use an arbitrary projection for different subsets. \code{\link{drape3d}} and \code{\link{shadow3d}} project objects onto meshes; these functions can be used to project only onto the top or front. } \value{ \code{facing3d} returns a mesh object made of those triangles which face in the desired direction. \code{projectDown} computes a 4x4 matrix. The first two coordinates of \code{asEuclidean(x \%*\% projectDown(up))} give a projection of \code{x} from above into a plane, where \code{up} determines which direction is taken to be \dQuote{up}. } \seealso{\code{\link{drape3d}}, \code{\link{shadow3d}}} \examples{ open3d() d <- rnorm(3) d <- d/sqrt(sum(d^2)) shade3d( facing3d( icosahedron3d(), up = d, strict = FALSE), col = "yellow") wire3d( facing3d( icosahedron3d(), up = d, front = FALSE), col = "black") # Show the direction: arrow3d(-2*d , -d) } rgl/man/setupKnitr.Rd0000644000176200001440000001133614100762641014255 0ustar liggesusers\name{setupKnitr} \alias{hook_rgl} \alias{hook_webgl} \alias{hook_rglchunk} \alias{setupKnitr} \title{ Displaying RGL scenes in \pkg{knitr} documents } \description{ These functions allow RGL graphics to be embedded in \pkg{knitr} documents. The simplest method is to run \code{setupKnitr(autoprint = TRUE)} early in the document. That way RGL commands act a lot like base graphics commands: plots will be automatically inserted where appropriate, according to the \code{fig.keep} chunk option. By default (\code{fig.keep = "high"}), only high-level plots are kept, after low-level changes have been merged into them. See the \pkg{knitr} documentation \url{https://yihui.org/knitr/options/#plots} for more details. To suppress auto-printing, the RGL calls can be wrapped in \code{\link{invisible}()}. Similarly to \pkg{grid} graphics (used by \pkg{lattice} and \pkg{ggplot2}), automatic inclusion requires the object to be printed: only the last statement in a code block in braces is automatically printed. Unlike those packages, auto-printing is the only way to get this to work: calling \code{\link{print}} explicitly doesn't work. Other functions allow embedding either as bitmaps (\code{hook_rgl} with format \code{"png"}), fixed vector graphics (\code{hook_rgl} with format \code{"eps"}, \code{"pdf"} or \code{"postscript"}), or interactive WebGL graphics (\code{hook_webgl}). \code{hook_rglchunk} is not normally invoked by the user; it is the hook that supports automatic creation and deletion of RGL scenes. } \note{The \code{setupKnitr(autoprint = TRUE)} method assumes \emph{all} printing of RGL objects happens through auto-printing of objects produced by the \code{\link{lowlevel}} or \code{\link{highlevel}} functions. All RGL functions that produce graphics do this, but functions in other packages that call them may not return values appropriately. If you have multiple calls to \code{setupKnitr()}, all should have the same arguments. If any differ, a warning will be issued, and the first set of arguments will be used. Mixing explicit calls to \code{\link{rglwidget}} with auto-printing is likely to lead to failure of some scenes to display. To avoid this, set \code{options(rgl.printRglwidget = FALSE)} before using such explicit calls. Similarly, use that option before calling the \code{\link{example}} function in a code chunk if the example prints RGL objects. } \usage{ setupKnitr(autoprint = FALSE, rgl.newwindow = autoprint, rgl.closewindows = autoprint) hook_rgl(before, options, envir) hook_webgl(before, options, envir) hook_rglchunk(before, options, envir) } \arguments{ \item{autoprint}{If true, RGL commands automatically plot (with low level plots suppressed by the default value of the \code{fig.keep} chunk option.)} \item{rgl.newwindow, rgl.closewindows}{Default values for the \pkg{knitr} chunk options.} \item{before, options, envir}{ Standard \pkg{knitr} hook function arguments. } } \details{ The \code{setupKnitr()} function needs to be called once at the start of the document to install the \pkg{knitr} hooks. If it is called twice in the same session the second call will override the first. The following chunk options are supported: \itemize{ \item \code{rgl.newwindow}: Whether to open a new window for the chunk. Default is set by \code{setupKnitr} argument. \item \code{rgl.closewindows}: Whether to close windows at the end of the chunk. Default is set by \code{setupKnitr} argument. \item \code{rgl.margin} (default 100): number of pixels by which to indent the WebGL window. \item \code{snapshot}: Logical value: when autoprinting in HTML, should a snapshot be used instead of the dynamic WebGL display? Corresponds to \code{rglwidget(snapshot = TRUE, webgl = FALSE)}. Ignored in LaTeX, where a snapshot will always be produced (unless \code{fig.keep} specifies no figure at all). \item \code{dpi}, \code{fig.retina}, \code{fig.width}, \code{fig.height}: standard \pkg{knitr} chunk options used to set the size of the output. \item \code{fig.keep}, \code{fig.hold}, \code{fig.beforecode}: standard \pkg{knitr} chunk options used to control the display of plots. \item \code{dev}: used by \code{hook_rgl} to set the output format. May be \code{"eps"}, \code{"postscript"}, \code{"pdf"} or \code{"png"} (default: \code{"png"}). \item \code{rgl.keepopen}: no longer used. Ignored with a warning. } } \value{ A string to be embedded into the output, or \code{NULL} if called when no output is available. } \author{ The \code{hook*} functions are originally by Yihui Xie in the \pkg{knitr} package; and have been modified by Duncan Murdoch. Some parts of the \code{setupKnitr} function duplicate source code from \pkg{knitr}. } \keyword{ utilities } rgl/man/as.tmesh3d.Rd0000644000176200001440000000255014137472630014062 0ustar liggesusers\name{as.tmesh3d} \alias{as.tmesh3d} \alias{as.tmesh3d.default} \alias{as.tmesh3d.mesh3d} \title{ Convert object to a triangular mesh } \description{ Converts the quads in a mesh version of an object to triangles by splitting them up. Optionally drops any point or segment components. } \usage{ as.tmesh3d(x, ...) \method{as.tmesh3d}{default}(x, drop = FALSE, ...) \method{as.tmesh3d}{mesh3d}(x, drop = FALSE, ...) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{x}{ An object from which to create a triangular mesh object. } \item{drop}{ If \code{TRUE}, drop any point or segment components. } \item{\dots}{ Ignored in the \code{mesh3d} method, passed to \code{as.mesh3d} in the default method. } } \details{ The default method simply calls \code{\link{as.mesh3d}(x, ...)} and passes the result to the \code{"mesh3d"} method. } \note{ Older versions of \pkg{rgl} had a \code{"tmesh3d"} class for meshes of triangles. That class is no longer used: \code{as.tmesh3d} and \code{\link{tmesh3d}} both produce \code{"mesh3d"} objects. } \value{ A \code{"mesh3d"} object containing no quads. If \code{drop = TRUE}, it will only contain triangles. } \author{ Duncan Murdoch } \seealso{ \code{as.triangles3d} to get just the coordinates. } \examples{ x <- cuboctahedron3d() x # has quads and triangles as.tmesh3d(x) # has only triangles }rgl/man/persp3d.tri.Rd0000644000176200001440000001012114100762641014251 0ustar liggesusers\name{persp3d.triSht} \alias{persp3d.triSht} \alias{plot3d.triSht} \alias{as.mesh3d.triSht} \alias{persp3d.tri} \alias{plot3d.tri} \alias{as.mesh3d.tri} \title{ Plot an interp or tripack Delaunay triangulation } \description{ The \code{\link[interp]{tri.mesh}()} functions in the \pkg{interp} and \pkg{tripack} packages compute a Delaunay triangulation of a set of points. These functions display it as a surface. } \usage{ \method{plot3d}{triSht}(x, z, ...) \method{persp3d}{triSht}(x, z, ..., add = FALSE) \method{as.mesh3d}{triSht}(x, z, col = "gray", coords = c("x", "y", "z"), smooth = TRUE, normals = NULL, texcoords = NULL, ...) \method{plot3d}{tri}(x, z, ...) \method{persp3d}{tri}(x, z, ..., add = FALSE) \method{as.mesh3d}{tri}(x, z, col = "gray", coords = c("x", "y", "z"), smooth = TRUE, normals = NULL, texcoords = NULL, ...) } \arguments{ \item{x}{ A \code{"triSht"} or \code{"tri"} object, produced by the \code{\link[interp]{tri.mesh}()} function in the \pkg{interp} or \pkg{tripack} packages respectively. } \item{z}{ z coordinate values corresponding to each of the nodes in \code{x}. } \item{add}{ Whether to add surface to existing plot (\code{add = TRUE}) or create a new plot (\code{add = FALSE}, the default). } \item{col}{ Colors to apply to each vertex in the triangulation. Will be recycled as needed. } \item{coords}{ See Details below. } \item{smooth}{ Whether to average normals at vertices for a smooth appearance. } \item{normals}{ User-specified normals at each vertex. Requires \code{smooth = FALSE}. } \item{texcoords}{ Texture coordinates at each vertex. } \item{...}{ See Details below. } } \details{ These functions construct a \code{\link{mesh3d}} object corresponding to the triangulation in \code{x}. The \code{plot3d} and \code{persp3d} methods plot it. The \code{coords} parameter allows surfaces to be plotted over any coordinate plane. It should be a permutation of the column names \code{c("x", "y", "z")}. The first will be used as the x coordinate, the second as the y coordinate, and the third as the z coordinate. The \code{...} parameters in \code{plot3d.triSht} and \code{plot3d.tri} are passed to \code{persp3d}; in \code{persp3d.triSht} and \code{persp3d.tri} they are passed to both \code{as.mesh3d} and \code{persp3d.mesh3d}; in \code{as.mesh3d.triSht} and \code{as.mesh3d.tri} they are used as material parameters in a \code{\link{tmesh3d}} call. \code{"tri"} objects may contain constraints. These appear internally as extra nodes, representing either the inside or outside of boundaries on the region being triangulated. Each of these nodes should also have a \code{z} value, but triangles corresponding entirely to constraint nodes will not be drawn. In this way complex, non-convex regions can be triangulated. See the second example below. } \note{ If there are duplicate points, the \code{tri.mesh()} functions will optionally delete some of them. If you choose this option, the \code{z} values must correspond to the nodes \emph{after} deletion, not before. } \examples{ x <- rnorm(200, sd = 5) y <- rnorm(200, sd = 5) r <- sqrt(x^2 + y^2) z <- 10 * sin(r)/r col <- cm.colors(20)[1 + round(19*(z - min(z))/diff(range(z)))] save <- NULL if ((haveinterp <- requireNamespace("interp", quietly = TRUE))) { save <- options(rgl.meshColorWarning = FALSE) dxy <- interp::tri.mesh(x, y) open3d() persp3d(dxy, z, col = col, meshColor = "vertices") } if (haveinterp) { open3d() # Do it without smoothing and with a different orientation. persp3d(dxy, z, col = col, coords = c("z", "x", "y"), smooth = FALSE) } if (requireNamespace("tripack", quietly = TRUE)) { if (is.null(save)) save <- options(rgl.meshColorWarning = FALSE) # Leave a circular hole around (3, 0) theta <- seq(0, 2*pi, len = 30)[-1] cx <- 2*cos(theta) + 3 cy <- 2*sin(theta) keep <- (x - 3)^2 + y^2 > 4 dxy2 <- tripack::tri.mesh(x[keep], y[keep]) dxy2 <- tripack::add.constraint(dxy2, cx, cy) z <- dxy2$x^2 - dxy2$y^2 col <- terrain.colors(20)[1 + round(19*(z - min(z))/diff(range(z)))] open3d() persp3d(dxy2, z, col = col) } options(save) } \keyword{graphics} rgl/man/elementId2Prefix.Rd0000644000176200001440000000146414100762640015253 0ustar liggesusers\name{elementId2Prefix} \alias{elementId2Prefix} \title{ Use widget with old-style controls } \description{ The \code{\link{rglwidget}} control is designed to work in the \pkg{htmlwidgets} framework. Older RGL web pages that used \code{\link{writeWebGL}} or \pkg{knitr} used a different method of linking the controls to the scene. This is a partial bridge between the two systems. You should adopt the new system, not use this function. } \usage{ elementId2Prefix(elementId, prefix = elementId) } \arguments{ \item{elementId}{ An element identifier from a \code{\link{rglwidget}} call. } \item{prefix}{ The prefix to use in the old-style control. } } \value{ This function generates Javascript code, so it should be used in an \code{results = "asis"} block in a \pkg{knitr} document. } \author{ Duncan Murdoch } rgl/man/writeOBJ.Rd0000644000176200001440000001113314145464133013571 0ustar liggesusers\name{writeOBJ} \alias{writeOBJ} \alias{readOBJ} \title{ Read and write Wavefront OBJ format files } \description{ \code{writeOBJ} writes OBJ files. This is a file format that is commonly used in 3D graphics applications. It does not represent text, but does represent points, lines, polygons (and many other types that RGL doesn't support). \code{readOBJ} reads only some parts of OBJ files. } \usage{ writeOBJ(con, pointRadius = 0.005, pointShape = icosahedron3d(), lineRadius = pointRadius, lineSides = 20, pointsAsPoints = FALSE, linesAsLines = FALSE, withNormals = TRUE, withTextures = TRUE, separateObjects = TRUE, ids = tagged3d(tags), tags = NULL) readOBJ(con, ...) } \arguments{ \item{con}{ A connection or filename. } \item{pointRadius, lineRadius}{ The radius of points and lines relative to the overall scale of the figure, if they are converted to polyhedra. } \item{pointShape}{ A mesh shape to use for points if they are converted. It is scaled by the \code{pointRadius}. } \item{lineSides}{ Lines are rendered as cylinders with this many sides. } \item{pointsAsPoints, linesAsLines}{ Whether to convert points and lines to \dQuote{point} and \dQuote{line} records in the OBJ output. } \item{withNormals}{ Whether to output vertex normals for smooth shading. } \item{separateObjects}{ Whether to mark each RGL object as a separate object in the file. } \item{withTextures}{ Whether to output texture coordinates. } \item{ids}{ The identifiers (from \code{\link{ids3d}}) of the objects to write. If \code{NULL}, try to write everything. } \item{tags}{ Alternate way to specify \code{ids}. Ignored if \code{ids} is given. } \item{...}{ Additional arguments (typically just \code{material}) to pass to \code{\link{tmesh3d}}. } } \details{ The current \code{writeOBJ} implementation only outputs triangles, quads, planes, spheres, points, line segments, line strips and surfaces. It does not output material properties such as colors, since the OBJ format does not support the per-vertex colors that RGL uses. The \code{readOBJ} implementation can read faces, normals, and textures coordinates, but ignores material properties (including the specification of the texture file to use). To read a file that uses a single texture, specify it in the \code{material} argument, e.g. \code{readOBJ("model.OBJ", material = list(color = "white", texture = "texture.png"))}. There is no support for files that use multiple textures. The defaults for \code{pointsAsPoints} and \code{linesAsLines} have been chosen because Blender (\url{https://www.blender.org}) does not import points or lines, only polygons. If you are exporting to other software you may want to change them. If present, texture coordinates are output by default, but the textures themselves are not. Individual RGL objects are output as separate objects in the file when \code{separateObjects = TRUE}, the default. The output file should be readable by Blender and Meshlab; the latter can write in a number of other formats, including U3D, suitable for import into a PDF document. } \value{ \code{writeObj} invisibly returns the name of the connection to which the data was written. \code{readObj} returns a mesh object constructed from the input file. } \references{ The file format was found at \url{http://www.martinreddy.net/gfx/3d/OBJ.spec} on November 11, 2012. } \author{ Duncan Murdoch } \seealso{ \code{\link{scene3d}} saves a copy of a scene to an R variable; \code{\link{rglwidget}}, \code{\link{writeASY}}, \code{\link{writePLY}} and \code{\link{writeSTL}} write the scene to a file in various other formats. } \examples{ filename <- tempfile(fileext = ".obj") open3d() shade3d( icosahedron3d() ) writeOBJ(filename) # The motivation for writing readObj() was to read a shape # file of Comet 67P/Churyumov-Gerasimenko, from the ESA. # The file no longer appears to be online, but may still be # available on archive.org. Here was the original URL: # cometurl <- "http://sci.esa.int/science-e/www/object/doc.cfm?fobjectid=54726" # This code would read and display it: # open3d() # shade3d(readOBJ(url(cometurl), # material = list(col = "gray"))) # Textures are used in a realistic hand image available from # https://free3d.com/3d-model/freerealsichand-85561.html # Thanks to Monte Shaffer for pointing this out. # Decompress the files into the current directory, convert # hand_mapNew.jpg to hand_mapNew.png, then use \dontrun{ open3d() shade3d(readOBJ("hand.OBJ", material = list(color = "white", shininess = 1, texture = "hand_mapNew.png"))) } } \keyword{ graphics } rgl/man/sprites.Rd0000644000176200001440000000760114142256754013607 0ustar liggesusers\name{sprites} \alias{sprites3d} \alias{particles3d} \title{Add sprites} \description{ Adds a sprite set shape node to the scene. } \usage{ sprites3d(x, y = NULL, z = NULL, radius = 1, shapes = NULL, userMatrix, fixedSize = FALSE, adj = 0.5, pos = NULL, offset = 0.25, ...) particles3d(x, y = NULL, z = NULL, radius = 1, ...) } \arguments{ \item{ x, y, z }{point coordinates. Any reasonable way of defining the coordinates is acceptable. See the function \code{\link[grDevices]{xyz.coords}} for details.} \item{ radius }{vector or single value defining the sprite radius} \item{ shapes }{\code{NULL} for a simple square, or a vector of identifiers of shapes in the scene} \item{ userMatrix }{if \code{shape} is not \code{NULL}, the transformation matrix for the shapes} \item{ fixedSize }{should sprites remain at a fixed size, or resize with the scene?} \item{ adj, pos, offset }{positioning arguments; see Details} \item{ ... }{material properties when \code{shapes = NULL}, texture mapping is supported} } \details{ Simple sprites (used when \code{shapes} is \code{NULL}) are 1 by 1 squares that are directed towards the viewpoint. Their primary use is for fast (and faked) atmospherical effects, e.g. particles and clouds using alpha blended textures. Particles are sprites using an alpha-blended particle texture giving the illusion of clouds and gases. The centre of each square will by default be at the coordinates given by \code{x, y, z}. This may be adjusted using the \code{adj} or \code{pos} parameters. \code{adj} and \code{pos} are treated similarly to the same parameters for \code{\link{text3d}}. \code{adj} has 3 entries, for adjustment to the \code{x}, \code{y} and \code{z} coordinates respectively. For \code{x}, a value of 0 puts the sprite to the right of the specified point, 0.5 centers it there, and 1 puts it to the left. The other coordinates are similar. By default, each value is 0.5 and the sprites are centered at the points given by \code{(x, y, z)}. The \code{pos} parameter overrides \code{adj}. It should be an integer or vector of integers (one per point), interpreted as in \code{\link{text3d}} to position the sprite relative to the \code{(x, y, z)} point: 0 is centered on it, 1 is below, 2 is to the left, 3 is above, 4 is to the right, 5 is in front, and 6 is behind. \code{offset} is the fraction of the sprite size to separate it from the point. When \code{shapes} is not \code{NULL}, it should be a vector of identifiers of objects to plot in the scene (e.g. as returned by plotting functions or by \code{\link{ids3d}}). These objects will be removed from the scene and duplicated as a sprite image in a constant orientation, as specified by \code{userMatrix}. By default the origin \code{(0, 0, 0)} will be plotted at the coordinates given by \code{(x, y, z)}, perhaps modified by \code{adj} or \code{pos}. The \code{userMatrix} argument is ignored for \code{shapes = NULL}. For shapes, \code{sprites3d} defaults the matrix to \code{r3dDefaults$userMatrix}. If any coordinate is \code{NA}, the sprite is not plotted. The id values of the shapes may be retrieved after plotting using \code{rgl.attrib(id, "ids")}; the user matrix is retrieved using \code{rgl.attrib(id, "usermatrix")}. } \value{ These functions are called for the side effect of displaying the sprites. The shape ID of the displayed object is returned. } \examples{ open3d() particles3d( rnorm(100), rnorm(100), rnorm(100), color = rainbow(100) ) # is the same as sprites3d( rnorm(100), rnorm(100), rnorm(100), color = rainbow(100), lit = FALSE, alpha = .2, textype = "alpha", texture = system.file("textures/particle.png", package = "rgl") ) sprites3d( rnorm(10) + 6, rnorm(10), rnorm(10), shape = shade3d(tetrahedron3d(), col = "red") ) } \seealso{ \code{\link{material3d}}, \code{\link{text3d}} } \keyword{dynamic} rgl/man/bbox.Rd0000644000176200001440000000562714100762640013044 0ustar liggesusers\name{rgl.bbox} \alias{rgl.bbox} \alias{bbox3d} \title{Set up bounding box decoration} \description{ Set up the bounding box decoration. } \usage{ rgl.bbox( xat = NULL, xlab = NULL, xunit = 0, xlen = 5, yat = NULL, ylab = NULL, yunit = 0, ylen = 5, zat = NULL, zlab = NULL, zunit = 0, zlen = 5, marklen = 15.0, marklen.rel = TRUE, expand = 1, draw_front = FALSE, ...) bbox3d(xat = NULL, yat = NULL, zat = NULL, xunit = "pretty", yunit = "pretty", zunit = "pretty", expand = 1.03, draw_front = FALSE, ...) } \arguments{ \item{xat, yat, zat}{vector specifying the tickmark positions} \item{xlab, ylab, zlab}{character vector specifying the tickmark labeling} \item{xunit, yunit, zunit}{value specifying the tick mark base for uniform tick mark layout} \item{xlen, ylen, zlen}{value specifying the number of tickmarks} \item{marklen}{value specifying the length of the tickmarks} \item{marklen.rel}{logical, if TRUE tick mark length is calculated using 1/\code{marklen} * axis length, otherwise tick mark length is \code{marklen} in coordinate space} \item{expand}{value specifying how much to expand the bounding box around the data} \item{draw_front}{draw the front faces of the bounding box} \item{ ... }{Material properties (or other \code{rgl.bbox} parameters in the case of \code{bbox3d}). See \code{\link{rgl.material}} for details.} } \details{ Four different types of tick mark layouts are possible. This description applies to the X axis; other axes are similar: If \code{xat} is not \code{NULL}, the ticks are set up at custom positions. If \code{xunit} is numeric but not zero, it defines the tick mark base. If it is \code{"pretty"} (the default in \code{bbox3d}), ticks are set at \code{\link{pretty}} locations. If \code{xlen} is not zero, it specifies the number of ticks (a suggestion if \code{xunit} is \code{"pretty"}). The first color specifies the bounding box, while the second one specifies the tick mark and font color. \code{bbox3d} defaults to \code{\link{pretty}} locations for the axis labels and a slightly larger box, whereas \code{rgl.bbox} covers the exact range. \code{\link{axes3d}} offers more flexibility in the specification of the axes, but they are static, unlike those drawn by \code{\link{rgl.bbox}} and \code{\link{bbox3d}}. } \value{ This function is called for the side effect of setting the bounding box decoration. A shape ID is returned to allow \code{\link{pop3d}} to delete it. } \examples{ rgl.open() rgl.points(rnorm(100), rnorm(100), rnorm(100)) rgl.bbox(color = c("#333377", "white"), emission = "#333377", specular = "#3333FF", shininess = 5, alpha = 0.8 ) open3d() points3d(rnorm(100), rnorm(100), rnorm(100)) bbox3d(color = c("#333377", "black"), emission = "#333377", specular = "#3333FF", shininess = 5, alpha = 0.8) } \seealso{ \code{\link{rgl.material}}, \code{\link{axes3d}} } \keyword{dynamic} rgl/man/rgl.bringtotop.Rd0000644000176200001440000000162414100762641015056 0ustar liggesusers\name{rgl.bringtotop} \alias{rgl.bringtotop} \title{Assign focus to an RGL window } \description{ 'rgl.bringtotop' brings the current RGL window to the front of the window stack (and gives it focus).} \usage{ rgl.bringtotop(stay = FALSE) } \arguments{ \item{stay}{whether to make the window stay on top.} } \details{ If \code{stay} is \code{TRUE}, then the window will stay on top of normal windows. } \author{ Ming Chen/Duncan Murdoch } \note{not completely implemented for X11 graphics (stay not implemented; window managers such as KDE may block this action (set "Focus stealing prevention level" to None in Control Center/Window Behavior/Advanced)). Not currently implemented under OS/X.} #ifdef windows \seealso{\code{\link[grDevices]{bringToTop}}} #endif \examples{ rgl.open() rgl.points(rnorm(1000), rnorm(1000), rnorm(1000), color = heat.colors(1000)) rgl.bringtotop(stay = TRUE) } \keyword{ dynamic } rgl/man/as.triangles3d.Rd0000644000176200001440000000247614100762640014732 0ustar liggesusers\name{as.triangles3d} \alias{as.triangles3d} \alias{as.triangles3d.rglId} \title{ Convert an object to triangles } \description{ This generic and its methods extract or creates a matrix of coordinates of triangles from an object, suitable for passing to \code{\link{triangles3d}}. } \usage{ as.triangles3d(obj, ...) \method{as.triangles3d}{rglId}(obj, attribute = c("vertices", "normals", "texcoords", "colors"), subscene = NA, ...) } \arguments{ \item{obj}{ The object to convert. } \item{attribute}{Which attribute of an RGL object to extract?} \item{subscene}{Which subscene is this object in?} \item{\dots}{ Additional arguments used by the methods. } } \details{ The method for \code{"rglId"} objects can extract several different attributes, organizing them as it would organize the vertices for the triangles. } \value{ An \code{n x 3} matrix containing the vertices of triangles making up the object. Each successive 3 rows of the matrix corresponds to a triangle. If the attribute doesn't exist, \code{NULL} will be returned. } \author{ Duncan Murdoch } \seealso{ \code{\link{as.mesh3d}} to also capture material properties. } \examples{ open3d() x <- surface3d(x = 1:10, y = 1:10, z = rnorm(100), col = "red") tri <- as.triangles3d(x) open3d() triangles3d(tri, col = "blue") } rgl/man/scene3d.Rd0000644000176200001440000001043414100762641013427 0ustar liggesusers\name{scene3d} \alias{scene3d} \alias{rglscene-class} \alias{rglobject-class} \alias{plot3d.rglscene} \alias{plot3d.rglobject} \alias{print.rglscene} \alias{print.rglobject} \title{ Saves the current scene to a variable, and displays such variables } \description{ This function saves a large part of the RGL state associated with the current window to a variable. } \usage{ scene3d(minimal = TRUE) \S3method{plot3d}{rglscene}(x, add = FALSE, ...) \S3method{plot3d}{rglobject}(x, ...) \S3method{print}{rglscene}(x, ...) \S3method{print}{rglobject}(x, ...) } \arguments{ \item{minimal}{Should attributes be skipped if they currently have no effect? See Details.} \item{x}{An object of class \code{"rglscene"}} \item{add}{Whether to open a new window, or add to the existing one.} \item{...}{Additional parameters, currently ignored.} } \details{ The components saved are: the \code{\link{par3d}} settings, the \code{\link{material3d}} settings, the \code{\link{bg3d}} settings, the lights and the objects in the scene. In most cases, calling \code{\link{plot3d}} on that variable will duplicate the scene. (There are likely to be small differences, mostly internal, but some aspects of the scene are not currently available.) If textures are used, the name of the texture will be saved, rather than the contents of the texture file. Other than saving the code to recreate a scene, saving the result of \code{scene3d} to a file will allow it to be reproduced later most accurately. In roughly decreasing order of fidelity, \code{\link{writeWebGL}} (now obsolete), \code{\link{writePLY}}, \code{\link{writeOBJ}} and \code{\link{writeSTL}} write the scene to a file in formats readable by other software. If \code{minimal = TRUE} (the default), then attributes of objects will not be saved if they currently have no effect on the display, thereby reducing the file size. Set \code{minimal = FALSE} if the scene is intended to be used in a context where the appearance could be changed. Currently this only affects the inclusion of normals; with \code{minimal = TRUE} they are omitted for objects when the material is not lit. } \value{ The \code{scene3d} function returns an object of class \code{"rglscene"}. This is a list with some or all of the components: \item{material}{The results returned from a \code{\link{material3d}} call.} \item{rootSubscene}{A list containing information about the main ("root") subscene. This may include: \describe{ \item{id}{The scene id.} \item{type}{"subscene"} \item{par3d}{The \code{\link{par3d}} settings for the subscene.} \item{embeddings}{The \code{\link{subsceneInfo}()$embeddings} for the main subscene.} \item{objects}{The ids for objects in the subscene.} \item{subscenes}{A recursive list of child subscenes.}}} \item{objects}{A list containing the RGL lights, background and objects in the scene.} The objects in the \code{objects} component are of class \code{"rglobject"}. They are lists containing some or all of the components \item{id}{The RGL identifier of the object in the original scene.} \item{type}{A character variable identifying the type of object.} \item{material}{Components of the material that differ from the scene material.} \item{vertices, normals, etc.}{Any of the attributes of the object retrievable by \code{\link{rgl.attrib}}.} \item{ignoreExtent}{A logical value indicating whether this object contributes to the bounding box. Currently this may differ from the object in the original scene.} \item{objects}{Sprites may contain other objects; they will be stored here as a list of \code{"rglobject"}s.} Lights in the scene are stored similarly, mixed into the \code{objects} list. The \code{plot3d} methods invisibly return a vector of RGL object ids that were plotted. The \code{print} methods invisibly return the object that was printed. } \author{ Duncan Murdoch } \seealso{ \code{\link{rglwidget}}, \code{\link{writePLY}}, \code{\link{writeOBJ}} and \code{\link{writeSTL}} write the scene to a file in various formats. } \examples{ open3d() z <- 2 * volcano # Exaggerate the relief x <- 10 * (1:nrow(z)) # 10 meter spacing (S to N) y <- 10 * (1:ncol(z)) # 10 meter spacing (E to W) persp3d(x, y, z, col = "green3", aspect = "iso") s <- scene3d() # Make it bigger s$par3d$windowRect <- 1.5*s$par3d$windowRect # and draw it again plot3d(s) } \keyword{ graphics } rgl/man/drape3d.Rd0000644000176200001440000000565514100762640013435 0ustar liggesusers\name{drape3d} \alias{drape3d} \alias{drape3d.default} \alias{drape3d.mesh3d} \title{ Drape lines over a scene. } \description{ Project a line onto the surface in a scene so that it appears to drape itself onto the surface. } \usage{ drape3d(obj, ...) \method{drape3d}{mesh3d}(obj, x, y = NULL, z = NULL, plot = TRUE, up = c(0, 0, 1), P = projectDown(up), ...) \method{drape3d}{default}(obj, ...) } \arguments{ \item{obj}{ The object(s) upon which to drape lines. } \item{x,y,z}{Coordinates of the line segments to be draped. Any reasonable way of defining the coordinates is acceptable. See the function \code{\link[grDevices]{xyz.coords}} for details. } \item{plot}{ Should the result be plotted, or returned as a data frame? } \item{up}{ The direction to consider as \dQuote{up}. } \item{P}{ The projection to use for draping, a 4x4 matrix. } \item{\dots}{ For the \code{"mesh3d"} method, additional parameters to pass to \code{\link{segments3d}} when drawing the draped lines. For the \code{"default"} method, additional parameters to pass to the \code{"mesh3d"} method. } } \details{ The default method converts \code{obj} to a mesh using \code{\link{as.mesh3d}}, then uses the \code{"mesh3d"} method. The current implementation constructs the segments to drape across the surface using the same method as \code{\link{lines3d}} uses: each successive point is joined to the previous one. Use \code{NA} coordinates to indicate breaks in the line. The \code{P} matrix is used to project points to a plane as follows: They are transformed by \code{P} in homogeneous coordinates, then only first two (Euclidean) coordinates are kept. } \value{ If \code{plot = TRUE}, plots the result and invisibly returns the object ID of the collection of segments. If \code{plot = FALSE}, returns a matrix containing "x", "y" and "z" values for the line(s) (for use with \code{\link{segments3d}}), } \author{ George Helffrich and Duncan Murdoch } \seealso{\code{\link{shadow3d}}, \code{\link{facing3d}}} \examples{ # # volcano example taken from "persp" # z <- 2 * volcano # Exaggerate the relief x <- 10 * (1:nrow(z)) # 10 meter spacing (S to N) y <- 10 * (1:ncol(z)) # 10 meter spacing (E to W) zlim <- range(z) zlen <- zlim[2] - zlim[1] + 1 colorlut <- terrain.colors(zlen) # height color lookup table col <- colorlut[ z - zlim[1] + 1 ] # assign colors to heights for each point open3d() id <- surface3d(x, y, z, color = col, polygon_offset = 1) segs <- data.frame(x = range(x) + c(100, -100), y = range(y) + c(150, -100), z = 325) drape3d(id, segs, col = 'yellow', lwd = 3) lines3d(segs, col='red', lwd=3) p <- c(350, 205) # (x,y) of strike & dip reading off <- 20*c(-1, +1) # X-marks-the-spot offset segs <- data.frame( x = c(p[1] + off, NA, p[1] + off), y = c(p[2] + off, NA, p[2] - off), z = rep(350, 5) ) drape3d(id, segs, col = "yellow", lwd = 3) } rgl/man/as.mesh3d.ashape3d.Rd0000644000176200001440000000671314100762640015363 0ustar liggesusers\name{as.mesh3d.ashape3d} \alias{as.mesh3d.ashape3d} \title{ Convert alpha-shape surface of a cloud of points to RGL mesh object } \description{ The \code{\link[alphashape3d:ashape3d]{alphashape3d::ashape3d}} function computes the 3D \eqn{\alpha}-shape of a cloud of points. This is an approximation to the visual outline of the cloud. It may include isolated points, line segments, and triangular faces: this function converts the triangular faces to an RGL \code{\link{tmesh3d}} object. } \usage{ \method{as.mesh3d}{ashape3d}(x, alpha = x$alpha[1], tri_to_keep = 2L, col = "gray", smooth = FALSE, normals = NULL, texcoords = NULL, ...) } \arguments{ \item{x}{ An object of class \code{"ashape3d"}. } \item{alpha}{ Which \code{alpha} value stored in \code{x} should be converted? } \item{tri_to_keep}{ Which triangles to keep. Expert use only: see \code{triang} entry in \bold{Value} section of \link[alphashape3d]{ashape3d} for details. } \item{col}{ The surface colour. } \item{smooth}{ Whether to attempt to add normals to make the surface look smooth. See the Details below. } \item{normals, texcoords}{ Normals and texture coordinates at each vertex can be specified. } \item{\dots}{ Additional arguments to pass to use as \code{\link{material3d}} properties on the resulting mesh. } } \details{ Edelsbrunner and Mucke's (1994) \eqn{\alpha}-shape algorithm is intended to compute a surface of a general cloud of points. Unlike the convex hull, the cloud may have voids, isolated points, and other oddities. This function is designed to work in the case where the surface is made up of simple polygons. If \code{smooth = TRUE}, this method attempts to orient all of the triangles in the surface consistently and add normals at each vertex by averaging the triangle normals. However, for some point clouds, the \eqn{\alpha}-shape will contain sheets of polygons with a few solid polyhedra embedded. This does not allow a consistent definition of "inside" and outside. If this is detected, a warning is issued and the resulting mesh will likely contain boundaries where the assumed orientation of triangles changes, resulting in ugly dark lines through the shape. Larger values of \code{alpha} in the call to \code{\link[alphashape3d:ashape3d]{alphashape3d::ashape3d}} may help. Methods for \code{\link{plot3d}} and \code{\link{persp3d}} are also defined: they call the \code{\link{as.mesh3d}} method and then plot the result. } \value{ A \code{"mesh3d"} object, suitable for plotting. } \references{ Edelsbrunner, H., Mucke, E. P. (1994). Three-Dimensional Alpha Shapes. ACM Transactions on Graphics, 13(1), pp.43-72. Lafarge, T. and Pateiro-Lopez, B. (2017). alphashape3d: Implementation of the 3D Alpha-Shape for the Reconstruction of 3D Sets from a Point Cloud. R package version 1.3. } \author{ Duncan Murdoch } \examples{ if (requireNamespace("alphashape3d", quietly = TRUE)) { set.seed(123) n <- 400 # 1000 gives a nicer result, but takes longer xyz <- rbind(cbind(runif(n), runif(n), runif(n)), cbind(runif(n/8, 1, 1.5), runif(n/8, 0.25, 0.75), runif(n/8, 0.25, 0.75))) ash <- suppressMessages(alphashape3d::ashape3d(xyz, alpha = 0.2)) m <- as.mesh3d(ash, smooth = TRUE) open3d() mfrow3d(1, 2, sharedMouse = TRUE) plot3d(xyz, size = 1) plot3d(m, col = "red", alpha = 0.5) points3d(xyz, size = 1) } }rgl/man/webGLcontrols.Rd0000644000176200001440000000476514100762641014701 0ustar liggesusers\name{webGLcontrols} \alias{subsetSlider} \alias{subsetSetter} \alias{clipplaneSlider} \alias{toggleButton} \title{ Obsolete functions to write HTML/Javascript code to control a WebGL display } \description{ These functions write out HTML code to control WebGL displays on the same page. They are deprecated; most documentation has now been removed. } \usage{ subsetSlider(subsets, labels = names(subsets), fullset = Reduce(union, subsets), subscenes = currentSubscene3d(), prefixes = "", accumulate = FALSE, ...) subsetSetter(subsets, subscenes = currentSubscene3d(), prefixes = "", fullset = Reduce(union, subsets), accumulate = FALSE) clipplaneSlider(a=NULL, b=NULL, c=NULL, d=NULL, plane = 1, clipplaneids, prefixes = "", labels = signif(values[,1],3), ...) toggleButton(subset, subscenes = currentSubscene3d(), prefixes = "", label = deparse(substitute(subset)), id = paste0(basename(tempfile("input"))), name = id) } \arguments{ \item{subsets}{A list of vectors of object identifiers; the slider or setter will choose among them.} \item{labels}{Labels to display corresponding to each subset. If \code{NULL}, numeric labels will be shown.} \item{fullset}{Objects in the subscene which are not in \code{fullset} will not be touched.} \item{subscenes}{The subscenes to be controlled.} \item{prefixes}{The prefixes of the WebGL scenes to be controlled.} \item{accumulate}{If \code{TRUE}, the subsets will accumulate (by union) as the value increases.} \item{id}{The \code{id} of the input control that will be generated.} \item{name}{The name of the input control that will be generated.} \item{...}{Arguments to pass to \code{\link{propertySlider}}.} \item{a,b,c,d}{The parameter values to change. Leave as \code{NULL} to hold the parameter constant.} \item{plane, clipplaneids}{The identifier of the particular clipplane to modify.} \item{subset}{The subset that the button should toggle.} \item{label}{The button label.} } \value{ \code{subsetSetter} returns a length-one character vector of class \code{"propertySetter"}. The other functions use \code{\link{cat}} to write their output and invisibly return the \code{id} of the control that was generated. } \author{ Duncan Murdoch } \seealso{ \code{\link{playwidget}} and \code{\link{toggleWidget}} for a newer, preferred method of inserting controls into a scene. } rgl/man/Buffer.Rd0000644000176200001440000003023414145464133013320 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/buffer.R \name{Buffer} \alias{Buffer} \title{R6 Class for binary buffers in glTF files.} \description{ These files typically have one buffer holding all the binary data for a scene. } \section{Methods}{ \subsection{Public methods}{ \itemize{ \item \href{#method-new}{\code{Buffer$new()}} \item \href{#method-load}{\code{Buffer$load()}} \item \href{#method-saveOpenBuffer}{\code{Buffer$saveOpenBuffer()}} \item \href{#method-getBuffer}{\code{Buffer$getBuffer()}} \item \href{#method-setBuffer}{\code{Buffer$setBuffer()}} \item \href{#method-openBuffer}{\code{Buffer$openBuffer()}} \item \href{#method-writeBuffer}{\code{Buffer$writeBuffer()}} \item \href{#method-closeBuffer}{\code{Buffer$closeBuffer()}} \item \href{#method-closeBuffers}{\code{Buffer$closeBuffers()}} \item \href{#method-getBufferview}{\code{Buffer$getBufferview()}} \item \href{#method-addBufferView}{\code{Buffer$addBufferView()}} \item \href{#method-openBufferview}{\code{Buffer$openBufferview()}} \item \href{#method-setBufferview}{\code{Buffer$setBufferview()}} \item \href{#method-getAccessor}{\code{Buffer$getAccessor()}} \item \href{#method-setAccessor}{\code{Buffer$setAccessor()}} \item \href{#method-readAccessor}{\code{Buffer$readAccessor()}} \item \href{#method-addAccessor}{\code{Buffer$addAccessor()}} \item \href{#method-dataURI}{\code{Buffer$dataURI()}} \item \href{#method-as.list}{\code{Buffer$as.list()}} \item \href{#method-clone}{\code{Buffer$clone()}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-new}{}}} \subsection{Method \code{new()}}{ \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$new(json = NULL, binfile = NULL)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{json}}{list read from glTF file.} \item{\code{binfile}}{optional External binary filename, or raw vector} } \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-load}{}}} \subsection{Method \code{load()}}{ Load from file. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$load(uri, buf = 0)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{uri}}{Which file to load.} \item{\code{buf}}{Which buffer number to load.} } \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-saveOpenBuffer}{}}} \subsection{Method \code{saveOpenBuffer()}}{ Write open buffer to connection. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$saveOpenBuffer(con, buf = 0)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{con}}{Output connection.} \item{\code{buf}}{Buffer number.} } \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-getBuffer}{}}} \subsection{Method \code{getBuffer()}}{ Get buffer object. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$getBuffer(buf, default = list(byteLength = 0))}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{buf}}{Buffer number.} \item{\code{default}}{Default buffer object if `buf` not found.} } \if{html}{\out{
}} } \subsection{Returns}{ A list containing components described here: \url{https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-buffer}. } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-setBuffer}{}}} \subsection{Method \code{setBuffer()}}{ Set buffer object. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$setBuffer(buf, buffer)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{buf}}{Buffer number.} \item{\code{buffer}}{New value to insert.} } \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-openBuffer}{}}} \subsection{Method \code{openBuffer()}}{ Open a connection for the data in a buffer. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$openBuffer(buf)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{buf}}{Buffer number.} } \if{html}{\out{
}} } \subsection{Returns}{ An open binary connection. } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-writeBuffer}{}}} \subsection{Method \code{writeBuffer()}}{ Write data to buffer. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$writeBuffer(values, type, size, buf = 0)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{values}}{Values to write.} \item{\code{type}}{Type to write.} \item{\code{size}}{Byte size of each value.} \item{\code{buf}}{Which buffer to write to.} } \if{html}{\out{
}} } \subsection{Returns}{ Byte offset of start of bytes written. } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-closeBuffer}{}}} \subsection{Method \code{closeBuffer()}}{ Close the connection in a buffer. If there was a connection open, this will save the contents in the raw vector `bytes` within the buffer object. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$closeBuffer(buf)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{buf}}{The buffer number.} } \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-closeBuffers}{}}} \subsection{Method \code{closeBuffers()}}{ Close any open buffers. Call this after working with a GLTF file to avoid warnings from R about closing unused connections. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$closeBuffers()}\if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-getBufferview}{}}} \subsection{Method \code{getBufferview()}}{ Get bufferView object. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$getBufferview(bufv)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{bufv}}{bufferView number.} } \if{html}{\out{
}} } \subsection{Returns}{ A list containing components described here: \url{https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-bufferview}. } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-addBufferView}{}}} \subsection{Method \code{addBufferView()}}{ Add a new buffer view. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$addBufferView(values, type, size, target = NULL, buf = 0)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{values}}{Values to put in the view.} \item{\code{type}}{Type of values.} \item{\code{size}}{Size of values in bytes.} \item{\code{target}}{Optional target use for values.} \item{\code{buf}}{Which buffer to write to.} } \if{html}{\out{
}} } \subsection{Returns}{ New bufferView number. } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-openBufferview}{}}} \subsection{Method \code{openBufferview()}}{ Open a connecton to a buffer view. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$openBufferview(bufv)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{bufv}}{Which bufferView.} } \if{html}{\out{
}} } \subsection{Returns}{ A connection. } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-setBufferview}{}}} \subsection{Method \code{setBufferview()}}{ Set bufferView object. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$setBufferview(bufv, bufferView)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{bufv}}{bufferView number.} \item{\code{bufferView}}{New value to insert.} } \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-getAccessor}{}}} \subsection{Method \code{getAccessor()}}{ Get accessor object \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$getAccessor(acc)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{acc}}{Accessor number} } \if{html}{\out{
}} } \subsection{Returns}{ A list containing components described here: \url{https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-accessor} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-setAccessor}{}}} \subsection{Method \code{setAccessor()}}{ Set accessor object. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$setAccessor(acc, accessor)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{acc}}{Accessor number.} \item{\code{accessor}}{New value to insert.} } \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-readAccessor}{}}} \subsection{Method \code{readAccessor()}}{ Read data given by accessor object. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$readAccessor(acc)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{acc}}{Accessor number.} } \if{html}{\out{
}} } \subsection{Returns}{ A vector or array as specified in the accessor. } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-addAccessor}{}}} \subsection{Method \code{addAccessor()}}{ Write values to accessor, not including `min` and `max`. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$addAccessor(values, target = NULL, useDouble = FALSE)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{values}}{Values to write.} \item{\code{target}}{Optional target use for values.} \item{\code{useDouble}}{Whether to write doubles or singles.} \item{\code{glTF}}{Whether this is for glTF use.} } \if{html}{\out{
}} } \subsection{Returns}{ New accessor number } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-dataURI}{}}} \subsection{Method \code{dataURI()}}{ Convert buffer to data URI. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$dataURI(buf = 0)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{buf}}{Buffer to convert.} } \if{html}{\out{
}} } \subsection{Returns}{ String containing data URI. } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-as.list}{}}} \subsection{Method \code{as.list()}}{ Convert to list. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$as.list()}\if{html}{\out{
}} } \subsection{Returns}{ List suitable for writing using JSON. } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-clone}{}}} \subsection{Method \code{clone()}}{ The objects of this class are cloneable with this method. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Buffer$clone(deep = FALSE)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{deep}}{Whether to make a deep clone.} } \if{html}{\out{
}} } } } rgl/man/checkDeldir.Rd0000644000176200001440000000065714145464133014316 0ustar liggesusers\name{checkDeldir} \alias{checkDeldir} \title{ Check for a compatible version of deldir } \description{ Version 1.0-2 of \pkg{deldir} is not compatible with \pkg{rgl}. This allows code to avoid trying to call it. } \usage{ checkDeldir(error = FALSE) } \arguments{ \item{error}{ If \code{TRUE}, stop with an error. } } \value{ Returns \code{TRUE} if \pkg{deldir} is available in a compatible version. } \examples{ checkDeldir() } rgl/man/all.equal.mesh3d.Rd0000644000176200001440000000343414137472630015153 0ustar liggesusers\name{all.equal.mesh3d} \alias{all.equal.mesh3d} \alias{compare_proxy.mesh3d} \title{ Compare mesh3d objects in a meaningful way. } \description{ These functions allow comparison of mesh3d objects, ignoring irrelevant differences. \code{compare_proxy.mesh3d} can function as a \code{compare_proxy} method for the \pkg{waldo} package, by stripping out \code{NULL} components and ordering other components alphabetically by name. \code{all.equal.mesh3d} compares mesh3d objects by using \code{compare_proxy.mesh3d} to standardize them, then using the regular \code{\link{all.equal}} function to compare them. } \usage{ \method{all.equal}{mesh3d}(target, current, ...) compare_proxy.mesh3d(x, path = "x") } %- maybe also 'usage' for other objects documented here. \arguments{ \item{target, current}{ Two mesh3d objects to compare. } \item{x}{ A single mesh3d object to standardize. } \item{path}{ The string to use in a \pkg{waldo} display of this object. } \item{\dots}{ Additional parameters to pass to \code{\link{all.equal}}. } } \value{ \code{all.equal.mesh3d} returns \code{TRUE}, or a character vector describing (some of) the differences. \code{compare_proxy.mesh3d} returns a list containing two components: \describe{ \item{object}{a copy of \code{x} with relevant components in alphabetical order.} \item{path}{a modification of the path label for \code{x}} } } \note{ \pkg{waldo} is not an installation requirement for \pkg{rgl} and \pkg{rgl} will never cause it to be loaded. The \code{compare_proxy.mesh3d} function will only be registered as a method for \code{waldo::compare_proxy} if you load \pkg{waldo} before \pkg{rgl}, as would normally happen during testing using \pkg{testthat}, or if you load it before calling \code{\link{mesh3d}}, as might happen if you are doing manual tests. } rgl/man/rgl.useNULL.Rd0000644000176200001440000000175014100762641014156 0ustar liggesusers\name{rgl.useNULL} \alias{rgl.useNULL} \title{ Report default use of null device } \description{ This function checks the \code{"rgl.useNULL"} option if present, or the \env{RGL_USE_NULL} environment variable if it is not. If the value is \code{TRUE} or a string which matches \dQuote{yes} or \dQuote{true} in a case-insensitive test, \code{TRUE} is returned. } \usage{ rgl.useNULL() } \note{ This function is checked by the initialization code when the \pkg{rgl} package is loaded. Thus if you want to run RGL on a system where there is no graphics support, you should run \code{options(rgl.useNULL = TRUE)} or set the environment variable \code{RGL_USE_NULL=TRUE} *before* calling \code{library(rgl)} (or other code that loads \pkg{rgl}), and it will not fail in its attempt at initialization. } \value{ A logical value indicating the current default for use of the null device. } \author{ Duncan Murdoch } \seealso{ \code{\link{open3d}} and \code{\link{rgl.open}}. } \examples{ rgl.useNULL() } rgl/man/attributes.Rd0000644000176200001440000000523014100762640014266 0ustar liggesusers\name{rgl.attrib} \alias{rgl.attrib} \title{ Get information about shapes } \description{ Retrieves information about the shapes in a scene. } \usage{ rgl.attrib(id, attrib, first = 1, last = rgl.attrib.count(id, attrib)) } \arguments{ \item{id}{ A shape identifier, as returned by \code{\link{ids3d}}. } \item{attrib}{ An attribute of a shape. Currently supported: one of \cr \code{"vertices"}, \code{"normals"}, \code{"colors"}, \code{"texcoords"}, \code{"dim"}, \code{"texts"}, \code{"cex"}, \code{"adj"}, \code{"radii"}, \code{"centers"}, \code{"ids"}, \code{"usermatrix"}, \code{"types"}, \code{"flags"}, \code{"offsets"}, \code{"family"}, \code{"font"}, \code{"pos"}\cr or unique prefixes to one of those. } \item{first, last}{ Specify these to retrieve only those rows of the result. } } \details{ If the identifier is not found or is not a shape that has the given attribute, zero will be returned by \code{rgl.attrib.count}, and an empty matrix will be returned by \code{rgl.attrib}. The first four \code{attrib} names correspond to the usual OpenGL properties; \code{"dim"} is used just for surfaces, defining the rows and columns in the rectangular grid; \code{"cex"}, \code{"adj"}, \code{"family"}, \code{"font"} and \code{"pos"} apply only to text objects. } \value{ \code{rgl.attrib} returns the values of the attribute. Attributes are mostly real-valued, with the following sizes: \tabular{lll}{ \code{"vertices"} \tab 3 values \tab x, y, z \cr \code{"normals"} \tab 3 values \tab x, y, z \cr \code{"centers"} \tab 3 values \tab x, y, z \cr \code{"colors"} \tab 4 values \tab r, g, b, a \cr \code{"texcoords"} \tab 2 values \tab s, t \cr \code{"dim"} \tab 2 values \tab r, c \cr \code{"cex"} \tab 1 value \tab cex \cr \code{"adj"} \tab 2 values \tab x, y \cr \code{"radii"} \tab 1 value \tab r \cr \code{"ids"} \tab 1 value \tab id \cr \code{"usermatrix"} \tab 4 values \tab x, y, z, w \cr \code{"texts"} \tab 1 value \tab text \cr \code{"types"} \tab 1 value \tab type \cr \code{"flags"} \tab 1 value \tab flag \cr \code{"family"} \tab 1 value \tab family \cr \code{"font"} \tab 1 value \tab font \cr \code{"pos"} \tab 1 value \tab pos \cr } The \code{"texts"}, \code{"types"} and \code{"family"} attributes are character-valued; the \code{"flags"} attribute is logical valued, with named rows. These are returned as matrices with the row count equal to the count for the attribute, and the columns as listed above. } \author{ Duncan Murdoch } \seealso{ \code{\link{ids3d}}, \code{\link{rgl.attrib.info}} } \examples{ p <- plot3d(rnorm(100), rnorm(100), rnorm(100), type = "s", col = "red") rgl.attrib(p["data"], "vertices", last = 10) } \keyword{ graphics } rgl/man/propertyControl.Rd0000644000176200001440000000471114145464133015335 0ustar liggesusers\name{propertyControl} \alias{subsetControl} \alias{propertyControl} \title{ Controls to use with playwidget() } \description{ These are setter functions to produce actions in a Shiny app, or in an animation. } \usage{ subsetControl(value = 1, subsets, subscenes = NULL, fullset = Reduce(union, subsets), accumulate = FALSE) propertyControl(value = 0, entries, properties, objids = tagged3d(tags), tags, values = NULL, param = seq_len(NROW(values)) - 1, interp = TRUE) } \arguments{ \item{value}{The value to use for input (typically \code{input$value} in a Shiny app.)} \item{subsets}{A list of vectors of object identifiers; the value will choose among them.} \item{fullset}{Objects in the subscene which are not in \code{fullset} will not be touched.} \item{subscenes}{The subscenes to be controlled. If \code{NULL}, the root subscene.} \item{accumulate}{If \code{TRUE}, the subsets will accumulate (by union) as the value increases.} \item{entries, properties, objids}{Which properties to set.} \item{tags}{ Select objects with matching tags. Ignored if \code{objids} is specified. } \item{values}{Values to set.} \item{param}{Parameter values corresponding to the rows of \code{value}} \item{interp}{Whether to use linear interpolation between \code{param} values} } \details{ \code{subsetControl} produces data for \code{\link{playwidget}} to display subsets of the object in one or more subscenes. This code will not touch objects in the subscenes if they are not in \code{fullset}. \code{fullset} defaults to the union of all the object ids mentioned in \code{subsets}, so by default if an id is not mentioned in one of the subsets, it will not be controlled by the slider. If \code{value} is specified in R code, it will be a 1-based index into the \code{subsets} list; when specified internally in Javascript, 0-based indexing into the corresponding array will be used. \code{propertyControl} sets individual properties. Here the row of \code{values} is determined by the position of \code{value} in \code{param}. } \value{ These functions return controller data in a list of class \code{"rglControl"}. } \author{ Duncan Murdoch } \seealso{ \code{\link{subsetSetter}} for a way to embed a pure Javascript control, and \code{\link{playwidget}} for a way to use these in animations (including Shiny), \code{\link{rglShared}} for linking using the \pkg{crosstalk} package. } rgl/man/rgl.pixels.Rd0000644000176200001440000000275314100762641014177 0ustar liggesusers\name{rgl.pixels} \alias{rgl.pixels} \title{ Extract pixel information from window } \description{ This function extracts single components of the pixel information from the topmost window. } \usage{ rgl.pixels(component = c("red", "green", "blue"), viewport = par3d("viewport"), top = TRUE) } \arguments{ \item{component}{ Which component(s)? } \item{viewport}{ Lower left corner and size of desired region. } \item{top}{ Whether to bring window to top before reading. } } \details{ The possible components are \code{"red"}, \code{"green"}, \code{"blue"}, \code{"alpha"}, \code{"depth"}, and \code{"luminance"} (the sum of the three colors). All are scaled from 0 to 1. Note that the luminance is kept below 1 by truncating the sum; this is the definition used for the \code{GL_LUMINANCE} component in OpenGL. } \value{ A vector, matrix or array containing the desired components. If one component is requested, a vector or matrix will be returned depending on the size of block requested (length 1 dimensions are dropped); if more, an array, whose last dimension is the list of components. } \author{ Duncan Murdoch } \seealso{ \code{\link{rgl.snapshot}} to write a copy to a file, \code{demo("stereo")} for functions that make use of this to draw a random dot stereogram and an anaglyph. } \examples{ example(surface3d) depth <- rgl.pixels(component = "depth") if (length(depth) && is.matrix(depth)) # Protect against empty or single pixel windows contour(depth) } \keyword{ dynamic } rgl/man/as.mesh3d.default.Rd0000644000176200001440000001023614137472630015321 0ustar liggesusers\name{as.mesh3d} \alias{as.mesh3d} \alias{as.mesh3d.default} \title{ Convert object to mesh object } \description{ The \code{as.mesh3d} generic function converts various objects to \code{\link{mesh3d}} objects. The default method takes takes a matrix of vertices as input and (optionally) merges repeated vertices, producing a \code{\link{mesh3d}} object as output. It will contain either triangles or quads or segments or points according to the \code{type} argument. If the generic is called without any argument, it will pass all RGL ids from the current scene to the \code{\link{as.mesh3d.rglId}} method. } \usage{ as.mesh3d(x, ...) \method{as.mesh3d}{default}(x, y = NULL, z = NULL, type = c("triangles", "quads", "segments", "points"), smooth = FALSE, tolerance = sqrt(.Machine$double.eps), notEqual = NULL, merge = TRUE, ..., triangles) } \arguments{ \item{x, y, z}{ For the generic, \code{x} is the object to convert. For the default method, \code{x}, \code{y} and \code{z} are coordinates. Any reasonable way of defining the coordinates is acceptable. See the function \code{\link{xyz.coords}} for details. } \item{type}{ What type of things should be in the mesh? Tries this list in order until it finds one that works. } \item{smooth}{ If \code{TRUE}, \code{\link{addNormals}} will be called on the mesh object to make it render smoothly. } \item{tolerance}{ The numerical tolerance to be used in \code{\link{all.equal}} to determine whether two vertices should be merged. } \item{notEqual}{ If not \code{NULL}, an n by n matrix of logical values, where n is the number of vertices as input. \code{TRUE} entries indicate that the corresponding pair of vertices should not be merged even if they appear equal. } \item{merge}{ Should apparently equal vertices be merged? } \item{\dots}{ Material properties to pass to \code{\link{tmesh3d}} or \code{\link{qmesh3d}}. } \item{triangles}{ Deprecated. If present, \code{TRUE} indicates \code{type = "triangles"} and \code{FALSE} indicates \code{type = "quads"}. } } \details{ The motivation for this function is the following problem: I was asked whether RGL could render a surface made up of triangles or quadrilaterals to look smooth. It can do that, but needs normals at each vertex; they should be the average of the normals for each polygon sharing that vertex. Then OpenGL will interpolate the normals across the polygons and give the illusion of smoothness. To do this, it needs to know which polygons share each vertex. If the surface is described as a list of triangles or quadrilaterals, that means identifying vertices that are in multiple polygons, and converting the representation to a \code{"\link{mesh3d}"} object (which is a matrix of vertices and a matrix of vertex numbers making up triangles or quads). Then the \code{\link{addNormals}} function will add the normals. Sometimes two polygons will share vertices (within numerical tolerance) without the user wanting them to be considered internal to the surface, or might want one sharp edge in an otherwise smooth surface. This means I needed a way to declare that two vertices from the original list of vertices in the triangles or quads are "not equal", even when they test numerically equal. That's what the \code{notEqual} matrix specifies. } \value{ A \code{"\link{mesh3d}"} object with the same faces as in the input, but (if \code{merge=TRUE}) with vertices that test equal to within \code{tolerance} merged. } \author{ Duncan Murdoch } \examples{ xyz <- matrix(c(-1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1), byrow = TRUE, ncol = 3) mesh <- as.mesh3d(xyz, type = "quads", col = "red") mesh$vb mesh$ib open3d() shade3d(mesh) # Stop vertices 2 and 5 from being merged notEQ <- matrix(FALSE, 12, 12) notEQ[2, 5] <- TRUE mesh <- as.mesh3d(xyz, type = "quads", notEqual = notEQ) mesh$vb mesh$ib } rgl/man/clipplaneControl.Rd0000644000176200001440000000261114145464133015415 0ustar liggesusers\name{clipplaneControl} \alias{clipplaneControl} \title{ Sets attributes of a clipping plane } \description{ This is a function to produce actions in a web display. A \code{\link{playwidget}} or Shiny input control (e.g. a \code{\link[shiny]{sliderInput}} control) sets a value which controls attributes of one or more clipping planes. } \usage{ clipplaneControl(a = NULL, b = NULL, c = NULL, d = NULL, plane = 1, clipplaneids = tagged3d(tag), tag, ...) } \arguments{ \item{a, b, c, d}{ Parameter values for the clipping planes. } \item{plane}{ Which plane in the clipplane object? } \item{clipplaneids}{ The id of the clipplane object. } \item{tag}{ Select clipplane with matching tag. Ignored if \code{clipplaneid} is specified. } \item{\dots}{ Other parameters passed to \code{\link{propertyControl}}. } } \value{ A list of class \code{"rglControl"} of cleaned up parameter values, to be used in an RGL widget. } \author{ Duncan Murdoch } \examples{ open3d() saveopts <- options(rgl.useNULL = TRUE) xyz <- matrix(rnorm(300), ncol = 3) id <- plot3d(xyz, type="s", col = "blue", zlim = c(-3,3))["clipplanes"] dvals <- c(3, -3) widget <- rglwidget() \%>\% playwidget(clipplaneControl(d = dvals, clipplaneids = id), start = 0, stop = 1, step = 0.01, rate = 0.5) if (interactive() || in_pkgdown_example()) widget options(saveopts) } rgl/man/open3d.Rd0000644000176200001440000000657614145464133013313 0ustar liggesusers\name{open3d} \alias{open3d} \alias{close3d} \alias{cur3d} \alias{set3d} \alias{getr3dDefaults} \alias{r3dDefaults} \title{Work with RGL windows} \description{ \code{open3d} opens a new RGL window; \code{cur3d} returns the device number of the current window; \code{close3d} closes one or more windows. } \usage{ open3d(\dots, params = getr3dDefaults(), useNULL = rgl.useNULL(), silent = FALSE) close3d(dev = cur3d(), silent = TRUE) cur3d() set3d(dev, silent = FALSE) getr3dDefaults(class = NULL, value = NULL) r3dDefaults } \arguments{ \item{\dots}{arguments in \code{name = value} form, or a list of named values. The names must come from the graphical parameters described in \code{\link{par3d}}.} \item{params}{a list of graphical parameters} \item{useNULL}{whether to use the null graphics device} \item{dev}{which device to close or use} \item{silent}{whether report on what was done} \item{class, value}{names of components to retrieve} } \details{ \code{open3d} opens a new RGL device, and sets the parameters as requested. The \code{r3dDefaults} list returned by the \code{getr3dDefaults} function will be used as default values for parameters. As installed this sets the point of view to 'world coordinates' (i.e. x running from left to right, y from front to back, z from bottom to top), the \code{mouseMode} to \code{(zAxis, zoom, fov)}, and the field of view to 30 degrees. \code{useFreeType} defaults to \code{FALSE} on Windows; on other systems it indicates the availability of FreeType. Users may create their own variable named \code{r3dDefaults} in the global environment and it will override the installed one. If there is a \code{bg} element in the list or the arguments, it should be a list of arguments to pass to the \code{\link{bg3d}} function to set the background. The arguments to \code{open3d} may include \code{material}, a list of material properties as in \code{\link{r3dDefaults}}, but note that high level functions such as \code{\link{plot3d}} normally use the \code{r3dDefaults} values in preference to this setting. If \code{useNULL} is \code{TRUE}, RGL will use a \dQuote{null} device. This device records objects as they are plotted, but displays nothing. It is intended for use with \code{\link{rglwidget}}. } \value{ The \code{open3d} function returns the device that was opened. If \code{silent = TRUE}, it is returned invisibly. The \code{cur3d} function returns the current device, or the value 0 if there isn't one. \code{set3d} returns the device number of the previously active device. The \code{close3d} function returns the new current device, invisibly. The \code{r3dDefaults} variable is a list containing default settings. The \code{getr3dDefaults} function searches the user's global environment for \code{r3dDefaults} and returns the one in the RGL namespace if it was not found there. The components of the list may include any settable \code{par3d} parameter, or \code{"material"}, which should include a list of default \code{\link{material3d}} properties, or \code{"bg"}, which is a list of defaults to pass to the \code{\link{bg3d}} function. } \seealso{ \code{\link{rgl.useNULL}} for default usage of null device. } \examples{ r3dDefaults open3d() shade3d(cube3d(color = rainbow(6), meshColor = "faces")) cur3d() } \keyword{dynamic} rgl/man/extrude3d.Rd0000644000176200001440000000263714100762640014017 0ustar liggesusers\name{extrude3d} \alias{extrude3d} \title{ Generate extrusion mesh } \description{ Given a two-dimensional polygon, this generates a three-dimensional extrusion of the shape by triangulating the polygon and creating a cylinder with that shape as the end faces. } \usage{ extrude3d(x, y = NULL, thickness = 1, smooth = FALSE, ...) } \arguments{ \item{x, y}{ A polygon description in one of the forms supported by \code{\link{triangulate}}. } \item{thickness}{ The extrusion will have this thickness. } \item{smooth}{ logical; should normals be added so that the edges of the extrusion appear smooth? } \item{\dots}{ Other parameters to pass to \code{\link{tmesh3d}} when constructing the mesh. } } \details{ The extrusion is always constructed with the polygon in the xy plane at \code{z = 0} and another copy at \code{z = thickness}. Use the transformation functions (e.g. \code{\link{rotate3d}}) to obtain other orientations and placements. } \value{ A mesh object containing a triangulation of the polygon for each face, and quadrilaterals for the sides. } \author{ Duncan Murdoch } \seealso{ \code{\link{polygon3d}} for a simple polygon, \code{\link{triangulate}} for the triangulation, \code{\link{turn3d}} for a solid of rotation. } \examples{ x <- c(1:10, 10:1) y <- rev(c(rep(c(0, 2), 5), rep(c(1.5, -0.5), 5))) plot(x, y, type = "n") polygon(x, y) open3d() shade3d( extrude3d(x, y), col = "red" ) } \keyword{ graphics } rgl/man/shiny.Rd0000644000176200001440000000366514100762641013245 0ustar liggesusers\name{shiny} \alias{rglwidgetOutput} \alias{renderRglwidget} \alias{playwidgetOutput} \alias{renderPlaywidget} \title{ Functions for integration of RGL widgets into Shiny app } \description{ These functions allow an RGL scene to be embedded in a Shiny app. } \usage{ rglwidgetOutput(outputId, width = "512px", height = "512px") renderRglwidget(expr, env = parent.frame(), quoted = FALSE, outputArgs = list()) playwidgetOutput(outputId, width = "0px", height = "0px") renderPlaywidget(expr, env = parent.frame(), quoted = FALSE, outputArgs = list()) } \arguments{ \item{outputId}{ The name for the control. } \item{width, height}{ Width and height to display the control. } \item{expr}{An R expression returning a \code{\link{rglwidget}} (for \code{renderRglwidget}) or a \code{\link{playwidget}} (for \code{renderPlaywidget}) as output.} \item{env}{The environment in which to evaluate \code{expr}.} \item{quoted}{Is the expression already quoted?} \item{outputArgs}{A list containing arguments; see details below.} } \details{ Use \code{rglwidgetOutput} or \code{playwidgetOutput} as an output object in a Shiny user interface section; use \code{renderRglwidget} or \code{renderPlaywidget} as the render function in the server section. In a dynamic R Markdown document with \code{runtime: shiny}, you only call the render function, and may optionally pass \code{width} and \code{height} to the output function by putting them in a list in \code{outputArgs}. See the example below. } \value{ Used internally by Shiny. } \author{ Duncan Murdoch } \examples{ \dontrun{ # This could be used in a dynamic R Markdown document. See # demo("shinyDemo") and demo("simpleShinyRgl") for Shiny apps. inputPanel( sliderInput("n", label = "n", min = 10, max = 100, value = 10, step = 10) ) renderRglwidget({ n <- input$n try(close3d()) plot3d(rnorm(n), rnorm(n), rnorm(n)) rglwidget() }, outputArgs = list(width = "auto", height = "300px")) } } rgl/man/arrow3d.Rd0000644000176200001440000000665014100762640013470 0ustar liggesusers\name{arrow3d} \alias{arrow3d} \title{ Draw an arrow } \description{ Draws various types of arrows in a scene. } \usage{ arrow3d(p0 = c(1, 1, 1), p1 = c(0, 0, 0), barblen, s = 1/3, theta = pi/12, type = c("extrusion", "lines", "flat", "rotation"), n = 3, width = 1/3, thickness = 0.618 * width, spriteOrigin = NULL, plot = TRUE, ...) } \arguments{ \item{p0}{ The base of the arrow. } \item{p1}{ The head of the arrow. } \item{barblen}{ The length of the barbs (in display coordinates). Default given by \code{s}. } \item{s}{ The length of the barbs as a fraction of line length. Ignored if \code{barblen} is present. } \item{theta}{ Opening angle of barbs } \item{type}{ Type of arrow to draw. Choose one from the list of defaults. Can be abbreviated. See below. } \item{n}{ Number of barbs. } \item{width}{ Width of shaft as fraction of barb width. } \item{thickness}{ Thickness of shaft as fraction of barb width. } \item{spriteOrigin}{ If arrow is to be replicated as sprites, the origins relative to which the sprites are drawn. } \item{plot}{ If \code{TRUE} (the default), plot the object; otherwise return the computed data that would be used to plot it. } \item{\dots}{ Material properties passed to \code{\link{polygon3d}}, \code{\link{shade3d}} or \code{\link{segments3d}}. } } \details{ Four types of arrows can be drawn. The shapes of all of them are affected by \code{p0}, \code{p1}, \code{barblen}, \code{s}, \code{theta}, material properties in \code{...}, and \code{spriteOrigin}. Other parameters only affect some of the types, as shown. \describe{ \item{\code{"extrusion"}}{(default) A 3-dimensional flat arrow, drawn with \code{\link{shade3d}}. Affected by \code{width}, \code{thickness} and \code{smooth}.} \item{\code{"lines"}}{Drawn with lines, similar to \code{\link{arrows}}, drawn with \code{\link{segments3d}}. Affected by \code{n}.} \item{\code{"flat"}}{A flat arrow, drawn with \code{\link{polygon3d}}. Affected by \code{width} and \code{smooth}.} \item{\code{"rotation"}}{A solid of rotation, drawn with \code{\link{shade3d}}. Affected by \code{n} and \code{width}.} } Normally this function draws just one arrow from \code{p0} to \code{p1}, but if \code{spriteOrigin} is given (in any form that \code{\link{xyz.coords}(spriteOrigin)} can handle), arrows will be drawn for each point specified, with \code{p0} and \code{p1} interpreted relative to those origins. The arrows will be drawn as 3D sprites which will maintain their orientation as the scene is rotated, so this is a good way to indicate particular locations of interest in the scene. } \value{ If \code{plot = TRUE} (the default), this is called mainly for the side effect of drawing the arrow; invisibly returns the id(s) of the objects drawn. If \code{plot = FALSE}, the data that would be used in the plot (not including material properties) is returned. } \author{ Design based on \code{heplots::arrow3d}, which contains modifications by Michael Friendly to a function posted by Barry Rowlingson to R-help on 1/10/2010. Additions by Duncan Murdoch. } \examples{ xyz <- matrix(rnorm(300), ncol = 3) plot3d(xyz) arrow3d(xyz[1,], xyz[2,], type = "extrusion", col = "red") arrow3d(xyz[3,], xyz[4,], type = "flat", col = "blue") arrow3d(xyz[5,], xyz[6,], type = "rotation", col = "green") arrow3d(xyz[7,], xyz[8,], type = "lines", col = "black") arrow3d(spriteOrigin = xyz[9:12,], col = "purple") }rgl/man/texts.Rd0000644000176200001440000000623314142256754013265 0ustar liggesusers\name{text3d} \alias{text3d} \alias{texts3d} \title{Add text to plot} \description{ Adds text to the scene. The text is positioned in 3D space. Text is always oriented towards the camera. } \usage{ text3d(x, y = NULL, z = NULL, texts, adj = 0.5, pos = NULL, offset = 0.5, usePlotmath = is.language(texts), ...) texts3d(x, y = NULL, z = NULL, texts, adj = 0.5, pos = NULL, offset = 0.5, usePlotmath = is.language(texts), ...) } \arguments{ \item{x, y, z}{point coordinates. Any reasonable way of defining the coordinates is acceptable. See the function \code{\link[grDevices]{xyz.coords}} for details.} \item{texts}{text character vector to draw} \item{adj}{ one value specifying the horizontal adjustment, or two, specifying horizontal and vertical adjustment respectively, or three, specifying adjustment in all three directions.} \item{pos}{ a position specifier for the text. If specified, this overrides any \code{adj} value given. Values of 0, 1, 2, 3, 4, 5, 6 respectively indicate positions at, below, to the left of, above, to the right of, in front of, and behind the specified coordinates.} \item{offset}{ when \code{pos} is specified, this value gives the offset of the label from the specified coordinate in fractions of a character width.} \item{ usePlotmath }{logical. Should \code{\link{plotmath3d}} be used for the text?} \item{ ... }{In the other functions, additional parameters to pass to \code{rgl.texts}.} } \details{ The \code{adj} parameter determines the position of the text relative to the specified coordinate. Use \code{adj = c(0, 0)} to place the left bottom corner at \code{(x, y, z)}, \code{adj = c(0.5, 0.5)} to center the text there, and \code{adj = c(1, 1)} to put the right top corner there. The optional second coordinate for vertical adjustment defaults to \code{0.5}. Placement is done using the "advance" of the string and the "ascent" of the font relative to the baseline, when these metrics are known. \code{text3d} and \code{texts3d} draw text using the \link{r3d} conventions. These are synonyms; the former is singular to be consistent with the classic 2-D graphics functions, and the latter is plural to be consistent with all the other graphics primitives. Take your choice! If any coordinate or text is \code{NA}, that text is not plotted. If \code{usePlotmath} is \code{TRUE}, the work will be done by the \code{\link{plotmath3d}} function instead of \code{rgl.texts}. This is the default if the \code{texts} parameter is \dQuote{language}, e.g. the result of a call to \code{\link{expression}} or \code{\link{quote}}. } \value{ The text drawing functions return the object ID of the text object (or sprites, in case of \code{usePlotmath = TRUE}) invisibly. } \examples{ open3d() famnum <- rep(1:3, 8) family <- c("serif", "sans", "mono")[famnum] font <- rep(rep(1:4, each = 3), 2) cex <- rep(1:2, each = 12) text3d(font, cex, famnum, text = paste(family, font), adj = 0.5, color = "blue", family = family, font = font, cex = cex) } \seealso{ \code{\link{r3d}}, \code{\link{rgl.texts}}, \code{\link{plotmath3d}}, \code{\link{rglExtrafonts}} for adding fonts } \keyword{dynamic} rgl/man/par3d.Rd0000644000176200001440000003155514145464133013127 0ustar liggesusers\name{par3d} \alias{par3d} \concept{activeSubscene} \concept{antialias} \concept{bbox} \concept{cex} \concept{family} \concept{font} \concept{fontname} \concept{FOV} \concept{ignoreExtent} \concept{maxClipPlanes} \concept{modelMatrix} \concept{listeners} \concept{mouseMode} \concept{projMatrix} \concept{scale} \concept{skipRedraw} \concept{useFreeType} \concept{userMatrix} \concept{userProjection} \concept{viewport} \concept{windowRect} \concept{zoom} \title{Set or query RGL parameters} \description{ \code{par3d} can be used to set or query graphical parameters in RGL. Parameters can be set by specifying them as arguments to \code{par3d} in \code{name = value} form, or by passing them as a list of named values. } \usage{ par3d(\dots, no.readonly = FALSE, dev = cur3d(), subscene = currentSubscene3d(dev)) } \arguments{ \item{\dots}{arguments in \code{name = value} form, or a list of tagged values. The names must come from the graphical parameters described below.} \item{no.readonly}{logical; if \code{TRUE} and there are no other arguments, only those parameters which can be set by a subsequent \code{par3d()} call are returned.} \item{dev}{integer; the RGL device.} \item{subscene}{integer; the subscene.} } \details{ Parameters are queried by giving one or more character vectors to \code{par3d}. \code{par3d()} (no arguments) or \code{par3d(no.readonly = TRUE)} is used to get \emph{all} the graphical parameters (as a named list). By default, queries and modifications apply to the current subscene on the current device; specify \code{dev} and/or \code{subscene} to change this. Some parameters apply to the device as a whole; these are marked in the list below. } \value{ When parameters are set, their former values are returned in an invisible named list. Such a list can be passed as an argument to \code{par3d} to restore the parameter values. Use \code{par3d(no.readonly = TRUE)} for the full list of parameters that can be restored. When just one parameter is queried, its value is returned directly. When two or more parameters are queried, the result is a list of values, with the list names giving the parameters. Note the inconsistency: setting one parameter returns a list, but querying one parameter returns an object. } \section{Parameters}{ \emph{\bold{R.O.}} indicates \emph{\bold{read-only arguments}}: These may only be used in queries, i.e., they do \emph{not} set anything. \describe{ \item{\code{activeSubscene}}{\emph{\bold{R.O.}} integer. Used with \code{\link{rgl.setMouseCallbacks}}: during a callback, indicates the id of the subscene that was clicked.} \item{\code{antialias}}{\emph{\bold{R.O.}} in \code{par3d}, may be set in \code{open3d}. The (requested) number of hardware antialiasing planes to use (with multisample antialiasing). The OpenGL driver may not support the requested number, in which case \code{par3d("antialias")} will report what was actually set. Applies to the whole device.} \item{\code{cex}}{real. The default size for text.} \item{\code{family}}{character. The default device independent family name; see \code{\link{rgl.texts}}. Applies to the whole device.} \item{\code{font}}{integer. The default font number (from 1 to 4; see \code{\link{rgl.texts}}). Applies to the whole device.} \item{\code{useFreeType}}{logical. Should FreeType fonts be used? Applies to the whole device.} \item{\code{fontname}}{\emph{\bold{R.O.}}; the system-dependent name of the current font. Applies to the whole device.} \item{\code{FOV}}{real. The field of view, from 0 to 179 degrees. This controls the degree of parallax in the perspective view. Isometric perspective corresponds to \code{FOV = 0}.} \item{\code{ignoreExtent}}{logical. Set to \code{TRUE} so that subsequently plotted objects will be ignored in calculating the bounding box of the scene. Applies to the whole device.} \item{\code{maxClipPlanes}}{\emph{\bold{R.O.}}; an integer giving the maximum number of clip planes that can be defined in the current system. Applies to the whole device.} \item{\code{modelMatrix}}{\emph{\bold{R.O.}}; a 4 by 4 matrix describing the position of the user data. See the Note below.} \item{\code{listeners}}{integer. A vector of subscene id values. If a subscene receives a mouse event (see \code{mouseMode} just below), the same action will be carried out on all subscenes in this list. (The subscene itself is normally listed as a listener. If it is not listed, it will not respond to its own mouse events.)} \item{\code{mouseMode}}{character. A vector of 5 strings describing mouse actions. The 5 entries are named \code{c("none", "left", "right", "middle", "wheel")}, corresponding to actions for no button, the left, right or middle button, and the mouse wheel. Partial matching to action names is used. Possible values for the actions are: \describe{ \item{\code{"none"}}{No action for this button.} \item{\code{"trackball"}}{Mouse acts as a virtual trackball, rotating the scene.} \item{\code{"xAxis"}}{Similar to \code{"trackball"}, but restricted to X axis rotation.} \item{\code{"yAxis"}}{Y axis rotation.} \item{\code{"zAxis"}}{Z axis rotation.} \item{\code{"polar"}}{Mouse rotates the scene by moving in polar coordinates.} \item{\code{"selecting"}}{Mouse is used for selection. This is not normally set by the user, but is used internally by the \code{\link{select3d}} function.} \item{\code{"zoom"}}{Mouse is used to zoom the display.} \item{\code{"fov"}}{Mouse changes the field of view of the display.} \item{\code{"user"}}{Used when a user handler is set by \code{\link{rgl.setMouseCallbacks}}.} } Possible values for the last entry corresponding to the mouse wheel also include \describe{ \item{\code{"pull"}}{Pulling on the mouse wheel increases magnification, i.e. \dQuote{pulls the scene closer}.} \item{\code{"push"}}{Pulling on the mouse wheel decreases magnification, i.e. \dQuote{pushes the scene away}.} \item{\code{"user2"}}{Used when a user handler is set by \code{\link{rgl.setWheelCallback}}.} } A common default on Mac OSX is to convert a two finger drag on a trackpad to a mouse wheel rotation. The first entry is for actions to take when no mouse button is pressed. Legal values are the same as for the mouse buttons. The first entry was added after \pkg{rgl} version 0.106.8. For back compatibility, if the vector of actions is less than 5 entries, \code{"none"} will be added at the start of it. } \item{\code{observer}}{\emph{\bold{R.O.}}; the position of the observer relative to the model. Set by \code{\link{observer3d}}. See the Note below.} \item{\code{projMatrix}}{\emph{\bold{R.O.}}; a 4 by 4 matrix describing the current projection of the scene.} \item{\code{scale}}{real. A vector of 3 values indicating the amount by which to rescale each axis before display. Set by \code{\link{aspect3d}}.} \item{\code{skipRedraw}}{whether to update the display. Set to \code{TRUE} to suspend updating while making multiple changes to the scene. See \code{demo(hist3d)} for an example. Applies to the whole device.} \item{\code{userMatrix}}{a 4 by 4 matrix describing user actions to display the scene.} \item{\code{userProjection}}{a 4 by 4 matrix describing changes to the projection.} \item{\code{viewport}}{real. A vector giving the dimensions of the window in pixels. The entries are taken to be \code{c(x, y, width, height)} where \code{c(x, y)} are the coordinates in pixels of the lower left corner within the window.} \item{\code{zoom}}{real. A positive value indicating the current magnification of the scene.} \item{\code{bbox}}{\emph{\bold{R.O.}}; real. A vector of six values indicating the current values of the bounding box of the scene (xmin, xmax, ymin, ymax, zmin, zmax)} \item{\code{windowRect}}{integer. A vector of four values indicating the left, top, right and bottom of the displayed window (in pixels). Applies to the whole device.} } } \note{ The \code{"xAxis"}, \code{"yAxis"} and \code{"zAxis"} mouse modes rotate relative to the coordinate system of the data, regardless of the current orientation of the scene. When multiple parameters are set, they are set in the order given. In some cases this may lead to warnings and ignored values; for example, some font families only support \code{cex = 1}, so changing both \code{cex} and \code{family} needs to be done in the right order. For example, when using the \code{"bitmap"} family on Windows, \code{par3d(family = "sans", cex = 2)} will work, but \code{par3d(cex = 2, family = "sans")} will leave \code{cex} at 1 (with a warning that the \code{"bitmap"} family only supports that size). Although \code{par3d("viewport")} names the entries of the reported vector, names are ignored when setting the viewport and entries must be specified in the standard order. In \pkg{rgl} versions 0.94.x the \code{modelMatrix} entry had a changed meaning; before and after that it contains a copy of the OpenGL MODELVIEW matrix. As of version 0.100.32, when changing the \code{"windowRect"} parameter, the \code{"viewport"} for the root (or specified) subscene is changed immediately. This fixes a bug where in earlier versions it would only be changed when the window was redrawn, potentially after another command making use of the value. Default values are not described here, as several of them are changed by the \code{\link{r3dDefaults}} variable when the window is opened by \code{\link{open3d}}. } \section{Rendering}{ The parameters returned by \code{par3d} are sufficient to determine where RGL would render a point on the screen. Given a column vector \code{(x, y, z)} in a subscene \code{s}, it performs the equivalent of the following operations: \enumerate{ \item It converts the point to homogeneous coordinates by appending \code{w = 1}, giving the vector \code{v = (x, y, z, 1)}. \item It calculates the \code{M = par3d("modelMatrix")} as a product from right to left of the following matrices: \itemize{ \item A matrix to translate the centre of the bounding box to the origin. \item A matrix to rescale according to \code{par3d("scale")}. \item The \code{par3d("userMatrix")} as set by the user. \item A matrix which may be set by mouse movements. \item If \code{s} has the \code{"model"} set to \code{"modify"}, a similar collection of matrices using parameters from the parent subscene. } \item It multiplies the point by \code{M} giving \code{u = M \%*\% v}. \item It multiplies that point by a matrix based on the observer position to translate the origin to the centre of the viewing region. \item Using this location and information on the normals (which have been similarly transformed), it performs lighting calculations. \item It obtains the projection matrix \code{P = par3d("projMatrix")} based on the bounding box and field of view or observer location, multiplies that by the \code{userProjection} matrix to give \code{P}. It multiplies the point by it giving \code{P \%*\% u = (x2, y2, z2, w2)}. \item It converts back to Euclidean coordinates by dividing the first 3 coordinates by \code{w2}. \item The new value \code{z2/w2} represents the depth into the scene of the point. Depending on what has already been plotted, this depth might be obscured, in which case nothing more is plotted. \item If the point is not culled due to depth, the \code{x2} and \code{y2} values are used to determine the point in the image. The \code{par3d("viewport")} values are used to translate from the range \code{(-1, 1)} to pixel locations, and the point is plotted. \item If hardware antialiasing is enabled, then the whole process is repeated multiple times (at least conceptually) with different locations in each pixel sampled to determine what is plotted there, and then the images are combined into what is displayed. } See ?\link{matrices} for more information on homogeneous and Euclidean coordinates. Note that many of these calculations are done on the graphics card using single precision; you will likely see signs of rounding error if your scene requires more than 4 or 5 digit precision to distinguish values in any coordinate. } \seealso{ \code{\link{rgl.viewpoint}} to set \code{FOV} and \code{zoom}. \code{\link{open3d}} for how to open a new window with default settings for these parameters. } \references{ OpenGL Architecture Review Board (1997). OpenGL Programming Guide. Addison-Wesley. } \examples{ open3d() shade3d(cube3d(color = rainbow(6), meshColor = "faces")) save <- par3d(userMatrix = rotationMatrix(90*pi/180, 1, 0, 0)) highlevel() # To trigger display save par3d("userMatrix") par3d(save) highlevel() par3d("userMatrix") } \keyword{dynamic} rgl/man/tkspin3d.Rd0000644000176200001440000000137014100762641013641 0ustar liggesusers\name{tkspin3d} \alias{tkspin3d} \title{Create TCL/TK controller for RGL window} \description{ This function creates a TCL/TK window containing buttons to spin and resize one or more RGL windows. } \usage{ tkspin3d(dev = cur3d(), ...) } \arguments{ \item{dev}{A vector of one or more RGL device numbers to control } \item{...}{Named parameters in that match named formal arguments to \code{\link{tkspinControl}} are passed there, while others are passed to \code{\link[tcltk:TkWidgets]{tktoplevel}}}} \author{ Ming Chen and Duncan Murdoch } \seealso{ \code{\link{tkspinControl}}} \examples{ if (interactive() && !in_pkgdown_example()) { open3d() points3d(rnorm(100), rnorm(100), rnorm(100), size=3) axes3d() box3d() tkspin3d() } } rgl/man/ellipse3d.Rd0000644000176200001440000000633214100762640013770 0ustar liggesusers\name{ellipse3d} \alias{ellipse3d} \alias{ellipse3d.default} \alias{ellipse3d.lm} \alias{ellipse3d.glm} \alias{ellipse3d.nls} \title{ Make an ellipsoid } \description{ A generic function and several methods returning an ellipsoid or other outline of a confidence region for three parameters. } \usage{ ellipse3d(x, \dots) \method{ellipse3d}{default}(x, scale = c(1, 1, 1), centre = c(0, 0, 0), level = 0.95, t = sqrt(qchisq(level, 3)), which = 1:3, subdivide = 3, smooth = TRUE, ...) \method{ellipse3d}{lm}(x, which = 1:3, level = 0.95, t = sqrt(3 * qf(level, 3, x$df.residual)), ...) \method{ellipse3d}{glm}(x, which = 1:3, level = 0.95, t, dispersion, ...) \method{ellipse3d}{nls}(x, which = 1:3, level = 0.95, t = sqrt(3 * qf(level, 3, s$df[2])), ...) } \arguments{ \item{x}{ An object. In the default method the parameter \code{x} should be a square positive definite matrix at least 3x3 in size. It will be treated as the correlation or covariance of a multivariate normal distribution. } \item{\dots}{ Additional parameters to pass to the default method or to \code{\link{qmesh3d}}. } \item{scale}{ If \code{x} is a correlation matrix, then the standard deviations of each parameter can be given in the scale parameter. This defaults to \code{c(1, 1, 1)}, so no rescaling will be done. } \item{centre}{ The centre of the ellipse will be at this position. } \item{level}{ The confidence level of a simultaneous confidence region. The default is 0.95, for a 95\% region. This is used to control the size of the ellipsoid. } \item{t}{ The size of the ellipse may also be controlled by specifying the value of a t-statistic on its boundary. This defaults to the appropriate value for the confidence region. } \item{which}{ This parameter selects which variables from the object will be plotted. The default is the first 3. } \item{subdivide}{ This controls the number of subdivisions (see \code{\link{subdivision3d}}) used in constructing the ellipsoid. Higher numbers give a smoother shape. } \item{smooth}{ If \code{TRUE}, smooth interpolation of normals is used; if \code{FALSE}, a faceted ellipsoid will be displayed. } \item{dispersion}{ The value of dispersion to use. If specified, it is treated as fixed, and chi-square limits for \code{t} are used. If missing, it is taken from \code{summary(x)}. } } \value{ A \code{\link{mesh3d}} object representing the ellipsoid. } \examples{ # Plot a random sample and an ellipsoid of concentration corresponding to a 95\% # probability region for a # trivariate normal distribution with mean 0, unit variances and # correlation 0.8. if (requireNamespace("MASS", quietly = TRUE)) { Sigma <- matrix(c(10, 3, 0, 3, 2, 0, 0, 0, 1), 3, 3) Mean <- 1:3 x <- MASS::mvrnorm(1000, Mean, Sigma) open3d() plot3d(x, box = FALSE) plot3d( ellipse3d(Sigma, centre = Mean), col = "green", alpha = 0.5, add = TRUE) } # Plot the estimate and joint 90\% confidence region for the displacement and cylinder # count linear coefficients in the mtcars dataset data(mtcars) fit <- lm(mpg ~ disp + cyl , mtcars) open3d() plot3d(ellipse3d(fit, level = 0.90), col = "blue", alpha = 0.5, aspect = TRUE) } \keyword{dplot} rgl/man/readSTL.Rd0000644000176200001440000000554714145464133013416 0ustar liggesusers\name{readSTL} \alias{readSTL} \alias{writeSTL} \title{ Read and write STL (stereolithography) format files } \description{ These functions read and write STL files. This is a simple file format that is commonly used in 3D printing. It does not represent text, only triangles. The \code{writeSTL} function converts some RGL object types to triangles. } \usage{ readSTL(con, ascii = FALSE, plot = TRUE, ...) writeSTL(con, ascii = FALSE, pointRadius = 0.005, pointShape = icosahedron3d(), lineRadius = pointRadius, lineSides = 20, ids = tagged3d(tags), tags = NULL) } \arguments{ \item{con}{ A connection or filename. } \item{ascii}{ Whether to use the ASCII format or the binary format. } \item{plot}{ On reading, should the object be plotted? } \item{\dots}{ If plotting, other parameters to pass to \code{\link{triangles3d}} } \item{pointRadius, lineRadius}{ The radius of points and lines relative to the overall scale of the figure. } \item{pointShape}{ A mesh shape to use for points. It is scaled by the \code{pointRadius}. } \item{lineSides}{ Lines are rendered as cylinders with this many sides. } \item{ids}{ The identifiers (from \code{\link{ids3d}}) of the objects to write. If \code{NULL}, try to write everything. } \item{tags}{ Alternate way to specify \code{ids}. Ignored if \code{ids} is given. } } \details{ The current implementation is limited. For reading, it ignores normals and color information. For writing, it only outputs triangles, quads, planes, spheres, points, line segments, line strips and surfaces, and does not write color information. Lines and points are rendered in an isometric scale: if your data scales vary, they will look strange. Since the STL format only allows one object per file, all RGL objects are combined into a single object when output. The output file is readable by Blender and Meshlab; the latter can write in a number of other formats, including U3D, suitable for import into a PDF document. } \value{ \code{readSTL} invisibly returns the object id if \code{plot = TRUE}, or (visibly) a matrix of vertices of the triangles if not. \code{writeSTL} invisibly returns the name of the connection to which the data was written. } \references{ The file format was found on Wikipedia on October 25, 2012. I learned about the STL file format from David Smith's blog reporting on Ian Walker's \code{r2stl} function. } \author{ Duncan Murdoch } \seealso{ \code{\link{scene3d}} saves a copy of a scene to an R variable; \code{\link{rglwidget}}, \code{\link{writeASY}}, \code{\link{writePLY}}, \code{\link{writeOBJ}} and \code{\link{writeSTL}} write the scene to a file in various other formats. } \examples{ filename <- tempfile(fileext = ".stl") open3d() shade3d( icosahedron3d(col = "magenta") ) writeSTL(filename) open3d() readSTL(filename, col = "red") } \keyword{ graphics } rgl/man/plot3d.Rd0000644000176200001440000001003514145464133013311 0ustar liggesusers\name{plot3d} \alias{plot3d} \alias{plot3d.default} \alias{plot3d.mesh3d} \title{3D scatterplot} \description{ Draws a 3D scatterplot. } \usage{ plot3d(x, ...) \method{plot3d}{default}(x, y, z, xlab, ylab, zlab, type = "p", col, size, lwd, radius, add = FALSE, aspect = !add, xlim = NULL, ylim = NULL, zlim = NULL, forceClipregion = FALSE, decorate = !add, ...) \method{plot3d}{mesh3d}(x, xlab = "x", ylab = "y", zlab = "z", type = c("shade", "wire", "dots"), add = FALSE, aspect = !add, ...) } \arguments{ \item{x, y, z}{vectors of points to be plotted. Any reasonable way of defining the coordinates is acceptable. See the function \code{\link[grDevices]{xyz.coords}} for details.} \item{xlab, ylab, zlab}{labels for the coordinates.} \item{type}{For the default method, a single character indicating the type of item to plot. Supported types are: 'p' for points, 's' for spheres, 'l' for lines, 'h' for line segments from \code{z = 0}, and 'n' for nothing. For the \code{mesh3d} method, one of 'shade', 'wire', or 'dots'. Partial matching is used. } \item{col}{the color to be used for plotted items.} \item{size}{the size for plotted points.} \item{lwd}{the line width for plotted items.} \item{radius}{the radius of spheres: see Details below.} \item{add}{whether to add the points to an existing plot.} \item{aspect}{either a logical indicating whether to adjust the aspect ratio, or a new ratio.} \item{xlim, ylim, zlim}{If not \code{NULL}, set clipping limits for the plot.} \item{forceClipregion}{Force a clipping region to be used, whether or not limits are given.} \item{decorate}{Whether to add bounding axes and other decorations.} \item{\dots}{additional parameters which will be passed to \code{\link{par3d}}, \code{\link{material3d}} or \code{\link{decorate3d}}.} } \value{ \code{plot3d} is called for the side effect of drawing the plot; a vector of object IDs is returned. } \details{ \code{plot3d} is a partial 3D analogue of plot.default. Missing values in the data are skipped, as in standard graphics. If \code{aspect} is \code{TRUE}, aspect ratios of \code{c(1, 1, 1)} are passed to \code{\link{aspect3d}}. If \code{FALSE}, no aspect adjustment is done. In other cases, the value is passed to \code{\link{aspect3d}}. With \code{type = "s"}, spheres are drawn centered at the specified locations. The radius may be controlled by \code{size} (specifying the size relative to the plot display, with the default \code{size = 3} giving a radius about 1/20 of the plot region) or \code{radius} (specifying it on the data scale if an isometric aspect ratio is chosen, or on an average scale if not). } \section{Clipping}{ If any of \code{xlim}, \code{ylim} or \code{zlim} are specified, they should be length two vectors giving lower and upper clipping limits for the corresponding coordinate. \code{NA} limits will be ignored. If any clipping limits are given, then the data will be plotted in a newly created subscene within the current one; otherwise plotting will take place directly in the current subscene. This subscene is named \code{"clipregion"} in the results. This may affect the appearance of transparent objects if some are drawn in the \code{plot3d} call and others after, as RGL will not attempt to depth-sort objects if they are in different subscenes. It is best to draw all overlapping transparent objects in the same subscene. See the example in \code{\link{planes3d}}. It will also affect the use of \code{\link{clipplanes3d}}; clipping planes need to be in the same subscene as the objects being clipped. Use \code{forceClipregion = TRUE} to force creation of this subscene even without specifying limits. } \author{ Duncan Murdoch } \seealso{ \code{\link{plot.default}}, \code{\link{open3d}}, \code{\link{par3d}}. There are \code{\link{plot3d.function}} and \code{\link{plot3d.deldir}} methods for plotting surfaces. } \examples{ open3d() x <- sort(rnorm(1000)) y <- rnorm(1000) z <- rnorm(1000) + atan2(x, y) plot3d(x, y, z, col = rainbow(1000)) } \keyword{dynamic} rgl/man/mesh3d.Rd0000644000176200001440000000627214100762640013272 0ustar liggesusers\name{mesh3d} \alias{shape3d} \alias{mesh3d} \alias{qmesh3d} \alias{tmesh3d} \title{Construct 3D mesh objects} \description{ Creates meshes containing points, segments, triangles and quads. } \usage{ mesh3d( x, y = NULL, z = NULL, vertices, material = NULL, normals = NULL, texcoords = NULL, points = NULL, segments = NULL, triangles = NULL, quads = NULL, meshColor = c("vertices", "edges", "faces", "legacy")) qmesh3d(vertices, indices, homogeneous = TRUE, material = NULL, normals = NULL, texcoords = NULL, meshColor = c("vertices", "edges", "faces", "legacy")) tmesh3d(vertices, indices, homogeneous = TRUE, material = NULL, normals = NULL, texcoords = NULL, meshColor = c("vertices", "edges", "faces", "legacy")) } \arguments{ \item{x, y, z}{coordinates. Any reasonable way of defining the coordinates is acceptable. See the function \code{\link[grDevices]{xyz.coords}} for details.} \item{vertices}{A 4 row matrix of homogeneous coordinates; takes precedence over \code{x, y, z}.} \item{material}{material properties for later rendering} \item{normals}{normals at each vertex} \item{texcoords}{texture coordinates at each vertex} \item{points}{vector of indices of vertices to draw as points} \item{segments}{2 x n matrix of indices of vertices to draw as segments} \item{triangles}{3 x n matrix of indices of vertices to draw as triangles} \item{quads}{4 x n matrix of indices of vertices to draw as quads} \item{indices}{(obsolete) 3 or 4 x n matrix of vertex indices} \item{homogeneous}{(obsolete) should \code{tmesh3d} and \code{qmesh3d} vertices be assumed to be homogeneous?} \item{meshColor}{how should colours be interpreted? See details in \code{\link{shade3d}}.} } \details{ These functions create \code{mesh3d} objects, which consist of a matrix of vertex coordinates together with a matrices of indices indicating how the vertices should be displayed, and material properties. The \code{"shape3d"} class is a general class for shapes that can be plotted by \code{dot3d}, \code{wire3d} or \code{shade3d}. The \code{"mesh3d"} class is a class of objects that form meshes: the vertices are in member \code{vb}, as a 4 by \code{n} matrix using homogeneous coordinates. Indices of these vertices are contained in optional components \code{ip} for points, \code{is} for line segments, \code{it} for triangles, and \code{ib} for quads. Individual meshes may have any combination of these. The functions \code{tmesh3d} and \code{qmesh3d} are included for back-compatibility; they produce meshes of triangles and quads respectively. } \value{ Objects of class \code{c("mesh3d", "shape3d")}. See \code{\link{rgl.primitive}} for a discussion of texture coordinates. } \examples{ # generate a quad mesh object vertices <- c( -1.0, -1.0, 0, 1.0, -1.0, 0, 1.0, 1.0, 0, -1.0, 1.0, 0 ) indices <- c( 1, 2, 3, 4 ) open3d() wire3d( mesh3d(vertices = vertices, quads = indices) ) } \seealso{ \code{\link{shade3d}}, \code{\link{shapelist3d}} for multiple shapes } \keyword{dynamic} rgl/man/merge.mesh3d.Rd0000644000176200001440000000243314100762640014363 0ustar liggesusers\name{merge.mesh3d} \alias{merge.mesh3d} \title{ Merge RGL mesh objects } \description{ Attempts to merge \code{"mesh3d"} objects. Objects need to be similar enough; see Details. } \usage{ \method{merge}{mesh3d}(x, y, ..., attributesMustMatch = FALSE) } \arguments{ \item{x, y}{ \code{"mesh3d"} objects to merge. } \item{\dots}{ Optional additional objects. } \item{attributesMustMatch}{ See Details.} } \details{ To allow objects to be merged, they need to be similar enough in terms of having the same list of material properties, normals, texture coordinates, etc. If \code{attributesMustMatch} is \code{TRUE}, it is an error to have attributes in one mesh but not in another, and those attributes that only specify a single value must have equal values in all meshes. If \code{attributesMustMatch} is \code{FALSE}, any non-matching attributes will be dropped from the final result. } \value{ A single \code{"mesh3d"} object merging the contents of the arguments. } \author{ Duncan Murdoch } \examples{ open3d() # Notice that the alpha setting for the cube is dropped, because # the other shapes don't specify alpha. shade3d(merge(cube3d(col="red", alpha = 0.5), translate3d(tetrahedron3d(col="green"), 2, 0, 0), translate3d(octahedron3d(col="blue"), 4, 0, 0))) } rgl/man/postscript.Rd0000644000176200001440000000362614100762641014322 0ustar liggesusers\name{rgl.postscript} \alias{rgl.postscript} \title{Export vector graphics} \description{ Saves the screenshot to a file in PostScript or other vector graphics format. } \usage{ rgl.postscript( filename, fmt = "eps", drawText = TRUE ) } \arguments{ \item{filename}{full path to filename.} \item{fmt}{export format, currently supported: ps, eps, tex, pdf, svg, pgf } \item{drawText}{logical, whether to draw text} } \details{ Animations can be created in a loop modifying the scene and saving a screenshot to a file. (See example below) This function is a wrapper for the GL2PS library by Christophe Geuzaine, and has the same limitations as that library: not all OpenGL features are supported, and some are only supported in some formats. See the reference for full details. } \references{ GL2PS: an OpenGL to PostScript printing library by Christophe Geuzaine, \url{http://www.geuz.org/gl2ps/}, version 1.4.0. } \author{ Christophe Geuzaine / Albrecht Gebhardt } \examples{ # Create new files in tempdir savedir <- setwd(tempdir()) x <- y <- seq(-10, 10, length = 20) z <- outer(x, y, function(x, y) x^2 + y^2) persp3d(x, y, z, col = 'lightblue') title3d("Using LaTeX text", col = 'red', line = 3) rgl.postscript("persp3da.ps", "ps", drawText = FALSE) rgl.postscript("persp3da.pdf", "pdf", drawText = FALSE) rgl.postscript("persp3da.tex", "tex") pop3d() title3d("Using ps/pdf text", col = 'red', line = 3) rgl.postscript("persp3db.ps", "ps") rgl.postscript("persp3db.pdf", "pdf") rgl.postscript("persp3db.tex", "tex", drawText = FALSE) setwd(savedir) \dontrun{ # # create a series of frames for an animation # rgl.open() shade3d(oh3d(), color = "red") rgl.viewpoint(0, 20) for (i in 1:45) { rgl.viewpoint(i, 20) filename <- paste("pic", formatC(i, digits = 1, flag = "0"), ".eps", sep = "") rgl.postscript(filename, fmt = "eps") } } } \seealso{ \code{\link{view3d}}, \code{\link{snapshot3d}} } \keyword{dynamic} rgl/man/shade3d.Rd0000644000176200001440000001166514145464133013431 0ustar liggesusers\name{shade3d} \alias{dot3d} \alias{dot3d.mesh3d} \alias{wire3d} \alias{wire3d.mesh3d} \alias{shade3d} \alias{shade3d.mesh3d} \title{Draw 3D mesh objects} \description{ Draws 3D mesh objects in full, or just the edges, or just the vertices. } \usage{ dot3d(x, ...) # draw dots at the vertices of an object \method{dot3d}{mesh3d}(x, ..., front = "points", back = "points") wire3d(x, ...) # draw a wireframe object \method{wire3d}{mesh3d}(x, ..., front = "lines", back = "lines") shade3d(x, ...) # draw a shaded object \method{shade3d}{mesh3d}(x, override = TRUE, meshColor = c("vertices", "edges", "faces", "legacy"), texcoords = NULL, ..., front = "filled", back = "filled") } \arguments{ \item{x}{a \code{mesh3d} object.} \item{...}{additional rendering parameters, or for \code{dots3d} and \code{wire3d}, parameters to pass to \code{shade3d}} \item{override}{should the parameters specified here override those stored in the object?} \item{meshColor}{how should colours be interpreted? See details below} \item{texcoords}{texture coordinates at each vertex.} \item{front, back}{Material properties for rendering.} } \details{ The \code{meshColor} argument controls how material colours and textures are interpreted. This parameter was added in \pkg{rgl} version 0.100.1 (0.100.27 for \code{dot3d}). Possible values are: \describe{ \item{\code{"vertices"}}{Colours and texture coordinates are applied by vertex, in the order they appear in the \code{x$vb} matrix.} \item{\code{"edges"}}{Colours are applied to each edge: first to the segments in the \code{x$is} matrix, then the 3 edges of each triangle in the \code{x$it} matrix, then the 4 edges of each quad in the \code{x$ib} matrix. This mode is only supported if both front and back materials are \code{"lines"}, and the mesh contains no points.} \item{\code{"faces"}}{Colours are applied to each face: first to the triangles in the \code{it} matrix, then to the quads in the \code{ib} matrix. Not compatible with meshes containing points or segments.} \item{\code{"legacy"}}{Colours and textures are applied in the same way as in \pkg{rgl} versions earlier than 0.100.1.} } Unique partial matches of these values will be recognized. If colours are specified but \code{meshColor} is not and \code{options(rgl.meshColorWarning = TRUE)}, a warning will be given that their interpretation may have changed. In versions 0.100.1 to 0.100.26 of \pkg{rgl}, the default was to give the warning; now the default is for no warning. Note that since version 0.102.10, \code{meshColor = "edges"} is only allowed when drawing lines (the \code{wire3d} default), and it may draw edges more than once. In general, if any rendering draws twice at the same location, which copy is visible depends on the order of drawing and the \code{\link{material3d}("depth_test")} setting. Whether points, lines or solid faces are drawn is determined in 3 steps: \enumerate{ \item{If arguments \code{"front"} or \code{"back"} are specified in the call, those are used.} \item{If one or both of those arguments are not specified, but the material properties are present in the object, those are used.} \item{If values are not specified in either of those places, \code{shade3d} draws filled surfaces, \code{wire3d} draws lines, and \code{dot3d} draws points. } } Note: For some versions of rgl up to version 0.107.15, rule 2 above was not respected. } \value{ \code{dot3d}, \code{wire3d}, and \code{shade3d} are called for their side effect of drawing an object into the scene; they return an object ID (or vector of IDs) invisibly. See \code{\link{rgl.primitive}} for a discussion of texture coordinates. } \examples{ # generate a quad mesh object vertices <- c( -1.0, -1.0, 0, 1.0, -1.0, 0, 1.0, 1.0, 0, -1.0, 1.0, 0 ) indices <- c( 1, 2, 3, 4 ) open3d() wire3d( mesh3d(vertices = vertices, quads = indices) ) # render 4 meshes vertically in the current view open3d() bg3d("gray") l0 <- oh3d(tran = par3d("userMatrix"), color = "green" ) shade3d( translate3d( l0, -6, 0, 0 )) l1 <- subdivision3d( l0 ) shade3d( translate3d( l1 , -2, 0, 0 ), color = "red", override = FALSE ) l2 <- subdivision3d( l1 ) shade3d( translate3d( l2 , 2, 0, 0 ), color = "red", override = TRUE ) l3 <- subdivision3d( l2 ) shade3d( translate3d( l3 , 6, 0, 0 ), color = "red" ) # render all of the Platonic solids open3d() shade3d( translate3d( tetrahedron3d(col = "red"), 0, 0, 0) ) shade3d( translate3d( cube3d(col = "green"), 3, 0, 0) ) shade3d( translate3d( octahedron3d(col = "blue"), 6, 0, 0) ) shade3d( translate3d( dodecahedron3d(col = "cyan"), 9, 0, 0) ) shade3d( translate3d( icosahedron3d(col = "magenta"), 12, 0, 0) ) } \seealso{ \code{\link{mesh3d}}, \code{\link{par3d}}, \code{\link{shapelist3d}} for multiple shapes } \keyword{dynamic} rgl/man/setUserShaders.Rd0000644000176200001440000001036314100762641015050 0ustar liggesusers\name{setUserShaders} \alias{setUserShaders} \title{ Set user-defined shaders for RGL objects. } \description{ Sets user-defined shaders (programs written in GLSL) for customized display of RGL objects. Currently only supported in WebGL displays, as the regular displays do not support GLSL. } \usage{ setUserShaders(ids, vertexShader = NULL, fragmentShader = NULL, attributes = NULL, uniforms = NULL, scene = scene3d(minimal), minimal = TRUE) } \arguments{ \item{ids}{ Which objects should receive the shaders. } \item{vertexShader, fragmentShader}{ The vertex and fragment shader source code. If \code{NULL}, the automatically generated shader will be used instead. } \item{attributes}{ A named list of \dQuote{attributes} to attach to each vertex. } \item{uniforms}{ A named list of \dQuote{uniforms}. } \item{scene}{ A \code{\link{scene3d}} object to modify. } \item{minimal}{ See \code{\link{scene3d}}. } } \details{ Modern versions of OpenGL work with \dQuote{shaders}, programs written to run on the graphics processor. The vertex shader does the calculations to move vertices and set their intrinsic colours. The fragment shader computes how each pixel in the display will be shown, taking into account lighting, material properties, etc. (More precisely, it does the computation for each \dQuote{fragment}; a fragment is a pixel within an object to display. There may be many objects at a particular location, and each will result in a fragment calculation unless culled by z-buffering or being discarded in some other way.) Normally the WebGL code automatically generates shaders for each object. This function allows them to be written by hand, for testing new features, hand optimization, etc. Currently it is not easy to get copies of the default shaders; they need to be obtained from a Javascript debugger while displaying the scene. } \value{ A modified version of the \code{scene}. } \author{ Duncan Murdoch } \seealso{ \code{\link{rglwidget}} for display of the scene in WebGL. } \examples{ open3d() id <- shade3d(octahedron3d(), col = "red") # For each triangle, set weights on the 3 vertices. # This will be replicated to the appropriate size in Javascript. wts <- diag(3) # This leaves out the centres of each face vs <- " attribute vec3 aPos; attribute vec4 aCol; uniform mat4 mvMatrix; uniform mat4 prMatrix; varying vec4 vCol; varying vec4 vPosition; attribute vec3 aNorm; uniform mat4 normMatrix; varying vec3 vNormal; attribute vec3 wts; varying vec3 vwts; void main(void) { vPosition = mvMatrix * vec4(aPos, 1.); gl_Position = prMatrix * vPosition; vCol = aCol; vNormal = normalize((normMatrix * vec4(aNorm, 1.)).xyz); vwts = wts; } " fs <- " #ifdef GL_ES precision highp float; #endif varying vec4 vCol; // carries alpha varying vec4 vPosition; varying vec3 vNormal; uniform mat4 mvMatrix; uniform vec3 emission; uniform float shininess; uniform vec3 ambient0; uniform vec3 specular0; // light*material uniform vec3 diffuse0; uniform vec3 lightDir0; uniform bool viewpoint0; uniform bool finite0; varying vec3 vwts; uniform vec2 wtrange; void main(void) { float minwt = min(vwts.x, min(vwts.y, vwts.z)); if (minwt < wtrange.x || minwt > wtrange.y) discard; vec3 eye = normalize(-vPosition.xyz); vec3 lightdir; vec4 colDiff; vec3 halfVec; vec4 lighteffect = vec4(emission, 0.); vec3 col; float nDotL; vec3 n = normalize(vNormal); n = -faceforward(n, n, eye); colDiff = vec4(vCol.rgb * diffuse0, vCol.a); lightdir = lightDir0; if (!viewpoint0) lightdir = (mvMatrix * vec4(lightdir, 1.)).xyz; if (!finite0) { halfVec = normalize(lightdir + eye); } else { lightdir = normalize(lightdir - vPosition.xyz); halfVec = normalize(lightdir + eye); } col = ambient0; nDotL = dot(n, lightdir); col = col + max(nDotL, 0.) * colDiff.rgb; col = col + pow(max(dot(halfVec, n), 0.), shininess) * specular0; lighteffect = lighteffect + vec4(col, colDiff.a); gl_FragColor = lighteffect; } " x <- setUserShaders(id, vs, fs, attributes = list(wts=wts), uniforms = list(wtrange = c(-0.01, 0.15))) if (interactive() || in_pkgdown_example()) rglwidget(x) } rgl/man/rgl.init.Rd0000644000176200001440000000550614137472630013643 0ustar liggesusers\name{rgl.init} \title{Initializing RGL} \alias{rgl.init} \description{ Initializing the RGL system. } \usage{ rgl.init(initValue = 0, onlyNULL = FALSE, debug = getOption("rgl.debug", FALSE)) } \arguments{ \item{initValue}{value for internal use only} \item{onlyNULL}{only initialize the null (no display) device} \item{debug}{enable some debugging messages} } \value{ Normally the user doesn't call \code{rgl.init} at all: it is called when the package is loaded. It returns no useful value. } \details{ If \code{useNULL} is \code{TRUE}, RGL will use a \dQuote{null} device. This device records objects as they are plotted, but displays nothing. It is intended for use with \code{\link{rglwidget}} and similar functions. Currently \code{debug} only controls messages printed by the OpenGL library during initialization. In future \code{debug = TRUE} may become more verbose. For display within an OpenGL window in R, RGL requires the OpenGL system to be installed and available. If there is a problem initializing it, you may see the message \verb{'rgl.init' failed, running with 'rgl.useNULL = TRUE'.} There are several causes and remedies: \itemize{ \item{On any system, the OpenGL libraries need to be present for RGL to be able to start an OpenGL device.} \itemize{ \item{On macOS, you need to install XQuartz. It is available from \url{https://www.xquartz.org}.} \item{On Linux, you need to install Mesa 3D. One of these commands may work, depending on your system: \verb{ zypper source-install --build-deps-only Mesa # openSUSE/SLED/SLES yum-builddep mesa # yum Fedora, OpenSuse(?) dnf builddep mesa # dnf Fedora apt-get build-dep mesa # Debian, Ubuntu and related } } \item{Windows should have OpenGL installed by default.} } \item{On Unix-alike systems (macOS and Linux, for example), RGL normally uses the GLX system for creating displays. If the graphic is created on a remote machine, it may need to use \dQuote{Indirect GLX} (IGLX). Due to security concerns, this is often disabled by default. See \url{https://www.x.org/wiki/Development/Security/Advisory-2014-12-09/} for a discussion of the security issues, and \url{https://unix.stackexchange.com/q/317954} for ways to re-enable IGLX.} \item{The \url{https://www.virtualgl.org} project is intended to be a way to avoid IGLX, by rendering remotely and sending bitmaps to the local machine. It's not a simple install...} \item{If you don't need to see RGL displays on screen, you can use the \dQuote{NULL device}. See \code{\link{rgl.useNULL}}.} \item{If you can't build the \pkg{rgl} package with OpenGL support, you can disable it and use the NULL device. (This may happen automatically during configuration, but you'll get a tested result if you specify it explicitly.) See the instructions in the \file{README} file in the source tarball.} } } rgl/man/in_pkgdown_example.Rd0000644000176200001440000000053214100762640015752 0ustar liggesusers\name{in_pkgdown_example} \alias{in_pkgdown_example} \title{ Are we running in a \pkg{pkgdown} example? } \description{ This is mainly for internal use to decide whether results should be automatically included in a \pkg{pkgdown} web page. } \usage{ in_pkgdown_example() } \value{ \code{TRUE} or \code{FALSE} } \examples{ in_pkgdown_example() } rgl/man/addNormals.Rd0000644000176200001440000000305414100762640014166 0ustar liggesusers\name{addNormals} \alias{addNormals} \alias{addNormals.mesh3d} \alias{addNormals.shapelist3d} \title{ Add normal vectors to objects so they render more smoothly } \description{ This generic function adds normals at each of the vertices of a polyhedron by averaging the normals of each incident face. This has the effect of making the surface of the object appear smooth rather than faceted when rendered. } \usage{ addNormals(x, ...) \method{addNormals}{mesh3d}(x, angleWeighted = TRUE, ...) } \arguments{ \item{x}{An object to which to add normals.} \item{\dots}{Additional parameters which will be passed to the methods.} \item{angleWeighted}{See Details below.} } \details{ Currently methods are supplied for \code{\link[=mesh3d]{"mesh3d"}} and \code{\link[=shapelist3d]{"shapelist3d"}} classes. These methods work by averaging the normals on the faces incident at each vertex. By default these are weighted according to the angle in the polygon at that vertex. If \code{angleWeighted = FALSE}, a slightly faster but less accurate weighting by the triangle area is used. Prior to \pkg{rgl} version 0.104.12 an incorrect weighting was used; it can be partially reproduced by using \code{angleWeighted = NA}, but not all the bugs in that scheme will be kept. } \value{ A new object of the same class as \code{x}, with normals added. } \author{ Duncan Murdoch } \examples{ open3d() y <- subdivision3d(tetrahedron3d(col = "red"), depth = 3) shade3d(y) # No normals y <- addNormals(y) shade3d(translate3d(y, x = 1, y = 0, z = 0)) # With normals } \keyword{dynamic} rgl/man/3dobjects.Rd0000644000176200001440000000651014100762640013762 0ustar liggesusers\name{points3d} \alias{points3d} \alias{lines3d} \alias{segments3d} \alias{triangles3d} \alias{quads3d} \title{Add primitive shape} \description{ Adds a shape node to the current scene. } \usage{ points3d(x, y = NULL, z = NULL, ...) lines3d(x, y = NULL, z = NULL, ...) segments3d(x, y = NULL, z = NULL, ...) triangles3d(x, y = NULL, z = NULL, ...) quads3d(x, y = NULL, z = NULL, ...) } \arguments{ \item{x, y, z}{coordinates. Any reasonable way of defining the coordinates is acceptable. See the function \code{\link[grDevices]{xyz.coords}} for details.} \item{ ... }{Material properties (see \code{\link{material3d}}). For normals use \code{normals} and for texture coordinates use \code{texcoords}; see \code{\link{rgl.primitive}} for details.} } \details{ The functions \code{points3d}, \code{lines3d}, \code{segments3d}, \code{triangles3d} and \code{quads3d} add points, joined lines, line segments, filled triangles or quadrilaterals to the plots. They correspond to the OpenGL types \code{GL_POINTS, GL_LINE_STRIP, GL_LINES, GL_TRIANGLES} and \code{GL_QUADS} respectively. Points are taken in pairs by \code{segments3d}, triplets as the vertices of the triangles, and quadruplets for the quadrilaterals. Colors are applied vertex by vertex; if different at each end of a line segment, or each vertex of a polygon, the colors are blended over the extent of the object. Polygons must be non-degenerate and quadrilaterals must be entirely in one plane and convex, or the results are undefined. These functions call the lower level functions \code{\link{rgl.points}}, \code{\link{rgl.linestrips}}. The appearance of the new objects are defined by the material properties. See \code{\link{rgl.material}} for details. The two principal differences between the \code{rgl.*} functions and the \code{*3d} functions are that the former set all unspecified material properties to defaults, whereas the latter use current values as defaults; the former make persistent changes to material properties with each call, whereas the latter make temporary changes only for the duration of the call. } \value{ Each function returns the integer object ID of the shape that was added to the scene. These can be passed to \code{\link{pop3d}} to remove the object from the scene. } \author{ Ming Chen and Duncan Murdoch } \examples{ # Show 12 random vertices in various ways. M <- matrix(rnorm(36), 3, 12, dimnames = list(c('x', 'y', 'z'), rep(LETTERS[1:4], 3))) # Force 4-tuples to be convex in planes so that quads3d works. for (i in c(1, 5, 9)) { quad <- as.data.frame(M[, i + 0:3]) coeffs <- runif(2, 0, 3) if (mean(coeffs) < 1) coeffs <- coeffs + 1 - mean(coeffs) quad$C <- with(quad, coeffs[1]*(B - A) + coeffs[2]*(D - A) + A) M[, i + 0:3] <- as.matrix(quad) } open3d() # Rows of M are x, y, z coords; transpose to plot M <- t(M) shift <- matrix(c(-3, 3, 0), 12, 3, byrow = TRUE) points3d(M) lines3d(M + shift) segments3d(M + 2*shift) triangles3d(M + 3*shift, col = 'red') quads3d(M + 4*shift, col = 'green') text3d(M + 5*shift, texts = 1:12) # Add labels shift <- outer(0:5, shift[1, ]) shift[, 1] <- shift[, 1] + 3 text3d(shift, texts = c('points3d', 'lines3d', 'segments3d', 'triangles3d', 'quads3d', 'text3d'), adj = 0) rgl.bringtotop() } \keyword{dynamic} rgl/man/cylinder3d.Rd0000644000176200001440000001120614100762640014140 0ustar liggesusers\name{cylinder3d} \alias{cylinder3d} \encoding{UTF-8} \title{ Create cylindrical or "tube" plots } \description{ This function converts a description of a space curve into a \code{\link[=mesh3d]{"mesh3d"}} object forming a cylindrical tube around the curve. } \usage{ cylinder3d(center, radius = 1, twist = 0, e1 = NULL, e2 = NULL, e3 = NULL, sides = 8, section = NULL, closed = 0, rotationMinimizing = is.null(e2) && is.null(e3), debug = FALSE, keepVars = FALSE) } \arguments{ \item{center}{An n by 3 matrix whose columns are the x, y and z coordinates of the space curve.} \item{radius}{The radius of the cross-section of the tube at each point in the center.} \item{twist}{The amount by which the polygon forming the tube is twisted at each point.} \item{e1, e2, e3}{The local coordinates to use at each point on the space curve. These default to a rotation minimizing frame or Frenet coordinates.} \item{sides}{The number of sides in the polygon cross section.} \item{section}{The polygon cross section as a two-column matrix, or \code{NULL}.} \item{closed}{Whether to treat the first and last points of the space curve as identical, and close the curve, or put caps on the ends. See the Details.} \item{rotationMinimizing}{Use a rotation minimizing local frame if \code{TRUE}, or a Frenet or user-specified frame if \code{FALSE}.} \item{debug}{If \code{TRUE}, plot the local Frenet coordinates at each point.} \item{keepVars}{If \code{TRUE}, return the local variables in attribute \code{"vars"}.} } \details{ The number of points in the space curve is determined by the vector lengths in \code{center}, after using \code{\link{xyz.coords}} to convert it to a list. The other arguments \code{radius}, \code{twist}, \code{e1}, \code{e2}, and \code{e3} are extended to the same length. The \code{closed} argument controls how the ends of the cylinder are handled. If \code{closed > 0}, it represents the number of points of overlap in the coordinates. \code{closed == TRUE} is the same as \code{closed = 1}. If \code{closed > 0} but the ends don't actually match, a warning will be given and results will be somewhat unpredictable. Negative values of \code{closed} indicate that caps should be put on the ends of the cylinder. If \code{closed == -1}, a cap will be put on the end corresponding to \code{center[1, ]}. If \code{closed == -2}, caps will be put on both ends. If \code{section} is \code{NULL} (the default), a regular \code{sides}-sided polygon is used, and \code{radius} measures the distance from the center of the cylinder to each vertex. If not \code{NULL}, \code{sides} is ignored (and set internally to \code{nrow(section)}), and \code{radius} is used as a multiplier to the vertex coordinates. \code{twist} specifies the rotation of the polygon. Both \code{radius} and \code{twist} may be vectors, with values recycled to the number of rows in \code{center}, while \code{sides} and \code{section} are the same at every point along the curve. The three optional arguments \code{e1}, \code{e2}, and \code{e3} determine the local coordinate system used to create the vertices at each point in \code{center}. If missing, they are computed by simple numerical approximations. \code{e1} should be the tangent coordinate, giving the direction of the curve at the point. The cross-section of the polygon will be orthogonal to \code{e1}. When \code{rotationMinimizing} is \code{TRUE}, \code{e2} and \code{e3} are chosen to give a rotation minimizing frame (see Wang et al., 2008). When it is \code{FALSE}, \code{e2} defaults to an approximation to the normal or curvature vector; it is used as the image of the \code{y} axis of the polygon cross-section. \code{e3} defaults to an approximation to the binormal vector, to which the \code{x} axis of the polygon maps. The vectors are orthogonalized and normalized at each point. } \value{ A \code{\link[=mesh3d]{"mesh3d"}} object holding the cylinder, possibly with attribute \code{"vars"} containing the local environment of the function. } \author{ Duncan Murdoch } \references{ Wang, W., Jüttler, B., Zheng, D. and Liu, Y. (2008). Computation of rotation minimizing frames. ACM Transactions on Graphics, Vol. 27, No. 1, Article 2. } \examples{ # A trefoil knot open3d() theta <- seq(0, 2*pi, len = 25) knot <- cylinder3d( center = cbind( sin(theta) + 2*sin(2*theta), 2*sin(3*theta), cos(theta) - 2*cos(2*theta)), e1 = cbind( cos(theta) + 4*cos(2*theta), 6*cos(3*theta), sin(theta) + 4*sin(2*theta)), radius = 0.8, closed = TRUE) shade3d(addNormals(subdivision3d(knot, depth = 2)), col = "green") } \keyword{ dynamic } rgl/man/toggleWidget.Rd0000644000176200001440000000371414145464133014537 0ustar liggesusers\name{toggleWidget} \alias{toggleWidget} \title{ An HTML widget to toggle display of elements of a scene } \description{ This function produces a button in an HTML scene that will toggle the display of items in the scene. } \usage{ toggleWidget(sceneId, ids = tagged3d(tags), tags = NULL, hidden = integer(), subscenes = NULL, label, ...) } \arguments{ \item{sceneId}{ The HTML id of the RGL scene being controlled, or an object as in \code{\link{playwidget}}. } \item{ids, hidden}{ The RGL id numbers of the objects to toggle. Those in \code{ids} are initially shown; those in \code{hidden} are initially hidden. } \item{tags}{ Alternate way to specify \code{ids}. Ignored if \code{ids} is given. } \item{subscenes}{ The subscenes in which to toggle the objects. } \item{label}{ The label to put on the button. The default is set from the expression passed to \code{ids} or the value of \code{tags}. } \item{\dots}{ Additional arguments to pass to \code{\link{playwidget}}. } } \details{ Like \code{\link{playwidget}}, this function is designed to work within the \pkg{htmlwidgets} framework. If the value is printed, the button will be inserted into the output. It is also designed to work with \pkg{magrittr}-style pipes: the result of \code{\link{rglwidget}} or other widgets can be piped into it to add it to a display. It can also appear first in the pipeline, if \code{sceneId} is set to \code{NA}. } \value{ A widget suitable for use in an \pkg{Rmarkdown}-generated web page, or elsewhere. } \author{ Duncan Murdoch } \seealso{ \code{\link{toggleButton}} for the older style of HTML control. } \examples{ theplot <- plot3d(rnorm(100), rnorm(100), rnorm(100), col = "red") widget <- rglwidget(height = 300, width = 300) \%>\% toggleWidget(theplot["data"], hidden = theplot[c("xlab", "ylab", "zlab")], label = "Points") if (interactive() || in_pkgdown_example()) widget } rgl/man/figWidth.Rd0000644000176200001440000000124214100762640013644 0ustar liggesusers\name{figWidth} \alias{figWidth} \alias{figHeight} \title{ Get R Markdown figure dimensions in pixels } \description{ In an R Markdown document, figure dimensions are normally specified in inches; these are translated into pixel dimensions when HTML output is requested and \code{\link{rglwidget}} is used. These functions reproduce that translation. } \usage{ figWidth() figHeight() } \value{ When used in an R Markdown document, these functions return the requested current dimensions of figures in pixels. Outside such a document, \code{NULL} is returned. } \author{ Duncan Murdoch } \examples{ # No useful return value outside of R Markdown: figWidth() figHeight() } rgl/man/shinyGetPar3d.Rd0000644000176200001440000000730114100762641014566 0ustar liggesusers\name{shinyGetPar3d} \alias{shinyGetPar3d} \alias{shinySetPar3d} \alias{shinyResetBrush} \title{ Communicate RGL parameters between R and Javascript in Shiny } \description{ These functions allow Shiny apps to read and write the \code{par3d} settings that may have been modified by user interaction in the browser. } \usage{ shinyGetPar3d(parameters, session, subscene = currentSubscene3d(cur3d()), tag = "") shinySetPar3d(..., session, subscene = currentSubscene3d(cur3d())) shinyResetBrush(session, brush) } \arguments{ \item{parameters}{ A character vector naming the parameters to get. } \item{session}{ The Shiny session object. } \item{subscene}{ The subscene to which the parameters apply. Defaults to the currently active subscene in the R session. } \item{tag}{ An arbitrary string or value which will be sent as part of the response. } \item{...}{ A number of \code{name = value} pairs to be modified, or a single named list of parameters. Entries named \code{tag} or \code{subscene} will be ignored. } \item{brush}{The name of a Shiny input element corresponding to the \code{shinyBrush} argument to \code{\link{rglwidget}}.} } \details{ Requesting information from the browser is a complicated process. The \code{shinyGetPar3d} function doesn't return the requested value, it just submits a request for the value to be returned later in \code{input$par3d}, a reactive input. No action will result except when a reactive observer depends on \code{input$par3d}. See the example code below. The \code{shinySetPar3d} function sends a message to the browser asking it to change a particular parameter. The change will be made immediately, without sending the full scene to the browser, so should be reasonably fast. } \value{ These functions are called for their side effects, and don't return useful values. The side effect of \code{shinyGetPar3d} is to cause \code{input$par3d} to be updated sometime later. Besides the requested parameter values, \code{input$par3d} will contain a copy of the \code{subscene} and \code{tag} arguments. The side effect of \code{shinySetPar3d} is to send a message to the browser to update its copy of the \code{par3d} parameters immediately. } \note{ R and the browser don't maintain a perfect match between the way parameters are stored internally. The browser version of parameters will be returned by \code{shinyGetPar3d} and should be supplied to \code{shinySetPar3d}. } \references{ \url{https://shiny.rstudio.com/articles/communicating-with-js.html} describes the underlying mechanisms used by these two functions. } \seealso{The \code{\link{rglwidget}} argument \code{shinySelectionInput} allows information about mouse selections to be returned to R.} \author{ Duncan Murdoch } \examples{ if (interactive() && !in_pkgdown_example() && requireNamespace("shiny")) { save <- options(rgl.useNULL = TRUE) xyz <- matrix(rnorm(300), ncol = 3) app = shiny::shinyApp( ui = shiny::bootstrapPage( shiny::actionButton("redraw", "Redraw"), rglwidgetOutput("rglPlot") ), server = function(input, output, session) { # This waits until the user to click on the "redraw" # button, then sends a request for the current userMatrix shiny::observeEvent(input$redraw, { shinyGetPar3d("userMatrix", session) }) # This draws the plot whenever input$par3d changes, # i.e. whenever a response to the request above is # received. output$rglPlot <- renderRglwidget({ if (length(rgl.dev.list())) close3d() col <- sample(colors(), 1) plot3d(xyz, col = col, type = "s", main = col) par3d(userMatrix = input$par3d$userMatrix) rglwidget() }) }) shiny::runApp(app) options(save) } } rgl/man/ageControl.Rd0000644000176200001440000000517714145464133014214 0ustar liggesusers\name{ageControl} \alias{ageControl} \title{ Set attributes of vertices based on their age } \description{ This is a function to produce actions in response to a \code{\link{playwidget}} or Shiny input control. The mental model is that each of the vertices of some object has a certain birth time; a control sets the current time, so that vertices have ages depending on the control setting. Attributes of those vertices can then be changed. } \usage{ ageControl(births, ages, objids = tagged3d(tags), tags, value = 0, colors = NULL, alpha = NULL, radii = NULL, vertices = NULL, normals = NULL, origins = NULL, texcoords = NULL, x = NULL, y = NULL, z = NULL, red = NULL, green = NULL, blue = NULL) } \arguments{ \item{births}{Numeric birth times of vertices.} \item{ages}{Chosen ages at which the following attributes will apply.} \item{objids}{Object ids to which the changes apply.} \item{tags}{ Alternate way to specify \code{objids}. Ignored if \code{objids} is given. } \item{value}{Initial value; typically overridden by input.} \item{colors, alpha, radii, vertices, normals, origins, texcoords}{ Attributes of the vertices that can be changed. There should be one entry or row for each entry in \code{ages}.} \item{x, y, z, red, green, blue}{These one-dimensional components of vertices and colors are provided for convenience.} } \details{ All attributes must have the same number of entries (rows for the matrices) as the ages vector. The births vector must have the same number of entries as the number of vertices in the object. Not all objects contain all attributes; if one is chosen that is not a property of the corresponding object, a Javascript \code{alert()} will be generated. (This restriction may be removed in the future by attempting to add the attribute when it makes sense.) If a \code{births} entry is \code{NA}, no change will be made to that vertex. } \value{ A list of class \code{"rglControl"} of cleaned up parameter values, to be used in an RGL widget. } \author{ Duncan Murdoch } \examples{ saveopts <- options(rgl.useNULL = TRUE) theta <- seq(0, 4*pi, len=100) xyz <- cbind(sin(theta), cos(theta), sin(theta/2)) lineid <- plot3d(xyz, type="l", alpha = 0, lwd = 5, col = "blue")["data"] widget <- rglwidget() \%>\% playwidget(ageControl(births = theta, ages = c(-4*pi, -4*pi, 1-4*pi, 0, 0, 1), objids = lineid, alpha = c(0, 1, 0, 0, 1, 0)), start = 0, stop = 4*pi, step = 0.1, rate = 4) if (interactive() || in_pkgdown_example()) widget options(saveopts) } rgl/man/surface.Rd0000644000176200001440000000703514100762641013536 0ustar liggesusers\name{rgl.surface} \title{Add surface (obsolete)} \alias{rgl.surface} \description{ Adds a surface to the current scene. The surface is defined by a matrix defining the height of each grid point and two vectors defining the grid. } \usage{ rgl.surface(x, z, y, coords = 1:3, ..., normal_x = NULL, normal_y = NULL, normal_z = NULL, texture_s = NULL, texture_t = NULL) } \arguments{ \item{ x }{ values corresponding to rows of \code{y}, or matrix of x coordinates } \item{ y }{ matrix of height values } \item{ z }{ values corresponding to columns of \code{y}, or matrix of z coordinates } \item{ coords }{ See details } \item{ ... }{Material and texture properties. See \code{\link{rgl.material}} for details.} \item{normal_x, normal_y, normal_z}{ matrices of the same dimension as \code{y} giving the coordinates of normals at each grid point} \item{texture_s, texture_t}{ matrices of the same dimension as \code{z} giving the coordinates within the current texture of each grid point} } \details{ Adds a surface mesh to the current scene. The surface is defined by the matrix of height values in \code{y}, with rows corresponding to the values in \code{x} and columns corresponding to the values in \code{z}. The \code{coords} parameter can be used to change the geometric interpretation of \code{x}, \code{y}, and \code{z}. The first entry of \code{coords} indicates which coordinate (\code{1 = X}, \code{2 = Y}, \code{3 = Z}) corresponds to the \code{x} parameter. Similarly the second entry corresponds to the \code{y} parameter, and the third entry to the \code{z} parameter. In this way surfaces may be defined over any coordinate plane. If the normals are not supplied, they will be calculated automatically based on neighbouring points. Texture coordinates run from 0 to 1 over each dimension of the texture bitmap. If texture coordinates are not supplied, they will be calculated to render the texture exactly once over the grid. Values greater than 1 can be used to repeat the texture over the surface. \code{rgl.surface} always draws the surface with the `front' upwards (i.e. towards higher \code{y} values). This can be used to render the top and bottom differently; see \code{\link{rgl.material}} and the example below. If the \code{x} or \code{z} argument is a matrix, then it must be of the same dimension as \code{y}, and the values in the matrix will be used for the corresponding coordinates. This is used to plot shapes such as cylinders where y is not a function of x and z. \code{NA} values in the height matrix are not drawn. } \note{ It is recommended to use \code{\link{surface3d}} instead of \code{rgl.surface}; use of the \code{rgl.*} functions is discouraged due to their side effects. } \value{ The object ID of the displayed surface is returned invisibly. } \examples{ # # volcano example taken from "persp" # data(volcano) y <- 2 * volcano # Exaggerate the relief x <- 10 * (1:nrow(y)) # 10 meter spacing (S to N) z <- 10 * (1:ncol(y)) # 10 meter spacing (E to W) ylim <- range(y) ylen <- ylim[2] - ylim[1] + 1 colorlut <- terrain.colors(ylen) # height color lookup table col <- colorlut[ y - ylim[1] + 1 ] # assign colors to heights for each point rgl.open() rgl.surface(x, z, y, color = col, back = "lines") } \seealso{ \code{\link{rgl.material}}, \code{\link{surface3d}}, \code{\link{terrain3d}}. See \code{\link{persp3d}} for a higher level interface. } \keyword{dynamic} rgl/man/show2d.Rd0000644000176200001440000001137414100762641013315 0ustar liggesusers\name{show2d} \alias{show2d} \title{ Draw a 2D plot on a rectangle in a 3D scene } \description{ This function uses a bitmap of a standard 2D graphics plot as a texture on a quadrilateral. Default arguments are set up so that it will appear on the face of the bounding box of the current 3D plot, but optional arguments allow it to be placed anywhere in the scene. } \usage{ show2d(expression, face = "z-", line = 0, reverse = FALSE, rotate = 0, x = NULL, y = NULL, z = NULL, width = 480, height = 480, filename = NULL, ignoreExtent = TRUE, color = "white", specular = "black", lit = FALSE, texmipmap = TRUE, texminfilter = "linear.mipmap.linear", expand = 1.03, texcoords = matrix(c(0, 1, 1, 0, 0, 0, 1, 1), ncol = 2), ...) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{expression}{ Any plotting commands to produce a plot in standard graphics. Ignored if \code{filename} is not \code{NULL}. } \item{face}{ A character string defining which face of the bounding box to use. See Details below. } \item{line}{ How far out from the bounding box should the quadrilateral be placed? Uses same convention as \code{\link{mtext3d}}: not lines of text, but fraction of the bounding box size. } \item{reverse, rotate}{ Should the image be reversed or rotated? See Details below. } \item{x, y, z}{ Specific values to use to override \code{face}. } \item{width,height}{ Parameters to pass to \code{\link{png}} when creating the bitmap. See Details below. } \item{filename}{ A \file{.png} file image to use as the texture. } \item{ignoreExtent}{ Whether the quadrilateral should be ignored when computing the bounding box of the scene. } \item{color, specular, lit, texmipmap, texminfilter, \dots}{ Material properties to use for the quadrilateral. } \item{expand}{Amount by which the quadrilateral is expanded outside the bounding box of the data. } \item{texcoords}{Coordinates on the image. Lower left of the bitmap is \code{c(0,0)}, upper right is \code{c(1,1)}.} } \details{ The default arguments are chosen to make it easy to place a 2D image on the face of the bounding box. If \code{x}, \code{y} and \code{z} are \code{NULL} (the defaults), \code{face} will be used as a code for one of the six faces of the bounding box. The first letter should be \code{"x"}, \code{"y"} or \code{"z"}; this defines the axis perpendicular to the desired face. If the second letter is \code{"-"} or is missing, the face will be chosen to be the face with the lower value on that axis. Any other letter will use the opposite face. If any of \code{x}, \code{y} or \code{z} is given, the specified value will be used to replace the value calculated above. Usually four values should be given, corresponding to the coordinates of the lower left, lower right, upper right and upper left of the destination for the image before \code{reverse} and \code{rotate} are used. Fewer values can be used for one or two coordinates; \code{\link{cbind}} will be used to put together all 3 coordinates into a 4 by 3 matrix (which will be returned as an attribute of the result). The bitmap plot will by default be oriented so that it is properly oriented when viewed from the direction of the higher values of the perpendicular coordinate, and its lower left corner is at the lower value of the two remaining coordinates. The argument \code{reverse} causes the orientation to be mirrored, and \code{rotate} causes it to be rotated by multiples of 90 degrees. \code{rotate} should be an integer, with \code{0} for no rotation, \code{1} for a 90 degree counter-clockwise rotation, etc. The \code{width} and \code{height} arguments control the shape and resolution of the bitmap. The defaults give a square bitmap, which is appropriate with the usual \code{c(1,1,1)} aspect ratios (see \code{aspect3d}). Some tuning may be needed to choose the resolution. The plot will look best when displayed at its original size; shrinking it smaller tends to make it look faded, while expanding it bigger will make it look blurry. If \code{filename} is given, the width and height will be taken from the file, and \code{width} and \code{height} arguments will be ignored. } \value{ Invisibly returns the id value of the quadrilateral, with the following attributes: \item{value}{The value returned by \code{expression}.} \item{xyz}{A 4 by 3 matrix giving the coordinates of the corners as used in plotting.} \item{texcoords}{A 4 by 2 matrix giving the texture coordinates of the image.} \item{filename}{The filename for the temporary file holding the bitmap image.} } \author{ Duncan Murdoch } \seealso{ \code{\link{bgplot3d}} uses a plot as the background for the window. } \examples{ example(plot3d, ask = FALSE) show2d({ par(mar=c(0,0,0,0)) plot(x, y, col = rainbow(1000), axes=FALSE) }) }rgl/man/tkspinControl.Rd0000644000176200001440000000266014100762641014756 0ustar liggesusers\name{tkspinControl} \alias{tkspinControl} \title{Create a spin control in a TCL/TK window} \description{ This function may be used to embed a spin control in a TCL/TK window. } \usage{ tkspinControl(base, dev = cur3d(), continue=FALSE, speed=30, scale=100, ... ) } \arguments{ \item{base}{The TCL/TK frame in which to insert this control. } \item{dev}{A vector of one or more RGL device numbers to control. } \item{continue}{Initial setting for continuous rotation checkbox. } \item{speed}{Initial setting for speed slider. } \item{scale}{Initial setting for scale slider. } \item{...}{Additional parameters to pass to \code{\link[tcltk:TkWidgets]{tkframe}}} } \author{ Ming Chen and Duncan Murdoch } \seealso{\code{\link{spin3d}}} \examples{ if (interactive() && !in_pkgdown_example()) { library(tcltk) open3d() win1 <- cur3d() plot3d(rexp(100), rexp(100), rexp(100), size=3, col='green') open3d() win2 <- cur3d() plot3d(rt(100,2), rt(100,2), rt(100, 2), size=3, col='yellow') open3d() win3 <- cur3d() plot3d(rexp(100), rexp(100), rexp(100), size=3, col='red') open3d() win4 <- cur3d() plot3d(rbinom(100,10,0.5), rbinom(100,10,0.5), rbinom(100,10,0.5), size=3, col='cyan') base <- tktoplevel() tkwm.title(base, "Spinners") con1 <- tkspinControl(base, dev=c(win1,win2)) con2 <- tkspinControl(base, dev=c(win3,win4)) tkpack(con1, con2) } } rgl/man/rgl.attrib.info.Rd0000644000176200001440000000256614100762641015114 0ustar liggesusers\name{rgl.attrib.info} \alias{rgl.attrib.info} \alias{rgl.attrib.count} \title{ Get information about attributes of objects } \description{ These functions give information about the attributes of RGL objects. \code{rgl.attrib.info} is the more \dQuote{user-friendly} function; \code{rgl.attrib.count} is a lower-level function more likely to be used in programming. } \usage{ rgl.attrib.info(id = ids3d("all", 0)$id, attribs = NULL, showAll = FALSE) rgl.attrib.count(id, attrib) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{id}{ One or more RGL object ids. } \item{attribs}{ A character vector of one or more attribute names. } \item{showAll}{ Should attributes with zero entries be shown? } \item{attrib}{ A single attribute name. } } \details{ See the first example below to get the full list of attribute names. } \value{ A dataframe containing the following columns: \item{id}{The id of the object.} \item{attrib}{The full name of the attribute.} \item{nrow, ncol}{The size of matrix that would be returned by \code{\link{rgl.attrib}} for this attribute.} } \author{ Duncan Murdoch } \seealso{ \code{\link{rgl.attrib}} to obtain the attribute values. } \examples{ open3d() id <- points3d(rnorm(100), rnorm(100), rnorm(100), col = "green") rgl.attrib.info(id, showAll = TRUE) rgl.attrib.count(id, "vertices") merge(rgl.attrib.info(), ids3d("all")) } rgl/man/plot3d.formula.Rd0000644000176200001440000000314614145464133014762 0ustar liggesusers\name{plot3d.formula} \alias{plot3d.formula} \alias{persp3d.formula} \title{ Methods for formulas } \description{ These functions provide a simple formula-based interface to \code{\link{plot3d}} and \code{\link{persp3d}}. } \usage{ \method{plot3d}{formula}(x, data = NULL, xlab, ylab, zlab, ...) \method{persp3d}{formula}(x, data = NULL, xlab, ylab, zlab, ...) } \arguments{ \item{x}{ A formula like \code{z ~ x + y}. } \item{data}{ An optional dataframe or list in which to find the components of the formula. } \item{xlab, ylab, zlab}{ Optional axis labels to override the ones automatically obtained from the formula. } \item{\dots}{ Additional arguments to pass to the default \code{plot3d} method, or the \code{persp3d} method for \code{"deldir"} objects. } } \details{ Only simple formulas (the ones handled by the \code{\link{xyz.coords}} function) are supported: a single variable on the left hand side (which will be plotted on the Z axis), and a sum of two variables on the right hand side (which will be the X and Y axis variables in the plot.) } \note{ The \code{persp3d} method requires that the suggested package \pkg{deldir} is installed. } \value{ These functions are called for the side effect of drawing the plots. The \code{plot3d} method draws a scatterplot. The \code{persp3d} method draws a surface plot. Return values are as given by the \code{\link{plot3d.default}} method or the \code{\link{persp3d.deldir}} methods. } \author{ Duncan Murdoch } \examples{ open3d() mfrow3d(1, 2, sharedMouse = TRUE) plot3d(mpg ~ wt + qsec, data = mtcars) if (checkDeldir()) persp3d(mpg ~ wt + qsec, data = mtcars) } rgl/man/rgl-package.Rd0000644000176200001440000000354114100762641014261 0ustar liggesusers\name{rgl-package} \title{3D visualization device system} \alias{rgl-package} \alias{rgl} \alias{RGL} \description{ 3D real-time rendering system. } \details{ RGL is a 3D real-time rendering system for R. Multiple windows are managed at a time. Windows may be divided into \dQuote{subscenes}, where one has the current focus that receives instructions from the R command-line. The device design is oriented towards the R device metaphor. If you send scene management instructions, and there's no device open, it will be opened automatically. Opened devices automatically get the current device focus. The focus may be changed by using \code{\link{set3d}()} or \code{\link{useSubscene3d}()}. RGL provides medium to high level functions for 3D interactive graphics, including functions modelled on base graphics (\code{\link{plot3d}()}, etc.) as well as functions for constructing geometric objects (\code{\link{cube3d}()}, etc.). Output may be on screen using OpenGL, or to various standard 3D file formats including WebGL, PLY, OBJ, STL as well as 2D image formats, including PNG, Postscript, SVG, PGF. The \code{\link{open3d}()} function attempts to open a new RGL window, using default settings specified by the user. RGL also includes a lower level interface which is described in the \link{rgl.open} help topic. We recommend that you avoid mixing \code{rgl.*} and \code{*3d} calls. See the first example below to display the ChangeLog. } \seealso{\link{r3d} for a description of the \code{*3d} interface; \code{\link{par3d}} for a description of scene properties and the rendering pipeline; \code{\link{rgl.useNULL}} for a description of how to use RGL on a system with no graphics support.} \examples{ if (!in_pkgdown_example()) file.show(system.file("NEWS", package = "rgl")) example(surface3d) example(plot3d) } \keyword{dynamic} rgl/man/grid3d.Rd0000644000176200001440000000456614100762640013267 0ustar liggesusers\name{grid3d} \alias{grid3d} \title{Add a grid to a 3D plot } \description{ This function adds a reference grid to an RGL plot. } \usage{ grid3d(side, at = NULL, col = "gray", lwd = 1, lty = 1, n = 5) } \arguments{ \item{side}{ Where to put the grid; see the Details section. } \item{at}{ How to draw the grid; see the Details section. } \item{col}{ The color of the grid lines. } \item{lwd}{ The line width of the grid lines. (Currently only \code{lty = 1} is supported.)} \item{lty}{ The line type of the grid lines. } \item{n}{ Suggested number of grid lines; see the Details section. } } \details{ This function is similar to \code{\link{grid}} in classic graphics, except that it draws a 3D grid in the plot. The grid is drawn in a plane perpendicular to the coordinate axes. The first letter of the \code{side} argument specifies the direction of the plane: \code{"x"}, \code{"y"} or \code{"z"} (or uppercase versions) to specify the coordinate which is constant on the plane. If \code{at = NULL} (the default), the grid is drawn at the limit of the box around the data. If the second letter of the \code{side} argument is \code{"-"} or is not present, it is the lower limit; if \code{"+"} then at the upper limit. The grid lines are drawn at values chosen by \code{\link{pretty}} with \code{n} suggested locations. The default locations should match those chosen by \code{\link{axis3d}} with \code{nticks = n}. If \code{at} is a numeric vector, the grid lines are drawn at those values. If \code{at} is a list, then the \code{"x"} component is used to specify the x location, the \code{"y"} component specifies the y location, and the \code{"z"} component specifies the z location. Missing components are handled using the default as for \code{at = NULL}. Multiple grids may be drawn by specifying multiple values for \code{side} or for the component of \code{at} that specifies the grid location. } \note{ If the scene is resized, the grid will not be resized; use \code{\link{abclines3d}} to draw grid lines that will automatically resize. } \value{ A vector or matrix of object ids is returned invisibly. } \author{ Ben Bolker and Duncan Murdoch } \seealso{ \code{\link{axis3d}} } \examples{ x <- 1:10 y <- 1:10 z <- matrix(outer(x - 5, y - 5) + rnorm(100), 10, 10) open3d() persp3d(x, y, z, col = "red", alpha = 0.7, aspect = c(1, 1, 0.5)) grid3d(c("x", "y+", "z")) } \keyword{ dynamic } rgl/DESCRIPTION0000644000176200001440000000663114146502162012553 0ustar liggesusersPackage: rgl Version: 0.108.3 Title: 3D Visualization Using OpenGL Authors@R: c(person("Duncan", "Murdoch", role = c("aut", "cre"), email = "murdoch.duncan@gmail.com"), person("Daniel", "Adler", role = "aut", email = "dadler@dyncall.org"), person("Oleg", "Nenadic", role = "ctb"), person("Simon", "Urbanek", role = "ctb"), person("Ming", "Chen", role = "ctb"), person("Albrecht", "Gebhardt", role = "ctb"), person("Ben", "Bolker", role = "ctb"), person("Gabor", "Csardi", role = "ctb"), person("Adam", "Strzelecki", role = "ctb"), person("Alexander", "Senger", role = "ctb"), person("The R Core Team", role = c("ctb", "cph")), person("Dirk","Eddelbuettel", role = "ctb"), person("The authors of Shiny", role = "cph"), person("The authors of knitr", role = "cph"), person("Jeroen", "Ooms", role = "ctb"), person("Yohann", "Demont", role = "ctb"), person("Joshua", "Ulrich", role = "ctb"), person("Xavier", "Fernandez i Marin", role = "ctb"), person("George", "Helffrich", role = "ctb"), person("Ivan", "Krylov", role = "ctb"), person("Michael", "Sumner", role = "ctb")) Depends: R (>= 3.3.0) Suggests: MASS, rmarkdown, deldir (>= 1.0-4), orientlib, lattice, misc3d, magick, plotrix (>= 3.7-3), tripack, interp, alphashape3d, tcltk, js (>= 1.2), akima, webshot2, downlit (>= 0.4.0), pkgdown, extrafont, shiny, manipulateWidget (>= 0.9.0), testthat, markdown, crosstalk Imports: graphics, grDevices, stats, utils, htmlwidgets, htmltools, knitr (>= 1.33), jsonlite (>= 0.9.20), magrittr, R6 Enhances: waldo Description: Provides medium to high level functions for 3D interactive graphics, including functions modelled on base graphics (plot3d(), etc.) as well as functions for constructing representations of geometric objects (cube3d(), etc.). Output may be on screen using OpenGL, or to various standard 3D file formats including WebGL, PLY, OBJ, STL as well as 2D image formats, including PNG, Postscript, SVG, PGF. License: GPL URL: https://github.com/dmurdoch/rgl, https://dmurdoch.github.io/rgl/ SystemRequirements: OpenGL, GLU Library, XQuartz (on OSX), zlib (optional), libpng (>=1.2.9, optional), FreeType (optional), pandoc (>=1.14, needed for vignettes; if not present, markdown package will be used) BugReports: https://github.com/dmurdoch/rgl/issues VignetteBuilder: knitr Biarch: true Additional_repositories: https://dmurdoch.github.io/drat RoxygenNote: 7.1.2 NeedsCompilation: yes Packaged: 2021-11-21 16:42:37 UTC; murdoch Author: Duncan Murdoch [aut, cre], Daniel Adler [aut], Oleg Nenadic [ctb], Simon Urbanek [ctb], Ming Chen [ctb], Albrecht Gebhardt [ctb], Ben Bolker [ctb], Gabor Csardi [ctb], Adam Strzelecki [ctb], Alexander Senger [ctb], The R Core Team [ctb, cph], Dirk Eddelbuettel [ctb], The authors of Shiny [cph], The authors of knitr [cph], Jeroen Ooms [ctb], Yohann Demont [ctb], Joshua Ulrich [ctb], Xavier Fernandez i Marin [ctb], George Helffrich [ctb], Ivan Krylov [ctb], Michael Sumner [ctb] Maintainer: Duncan Murdoch Repository: CRAN Date/Publication: 2021-11-21 17:40:02 UTC rgl/build/0000755000176200001440000000000014146473374012152 5ustar liggesusersrgl/build/vignette.rds0000644000176200001440000000050414146473374014510 0ustar liggesusers‹R]KÃ0m׺®õƒÉÀG ø¢/ý˜ˆ¢26ô5k¯5ئ%‰+{ó‡ë]šŒv"%79'·çÞ{È[ä8ÎÀñ]Œ½ †!®1.¿÷ðVwñ¼H q\}fiYóˆ,ïÀ±”ËŠ àÉFó}É«¥Aî¹AÅJN'º ¹þªRª ½1©—KÉxFæx…9¦2©aE$S MÖ Ö'Ïkkµá.nÉS©€ ú¢ÓÎA+Q;݇*r«eÇëp£Ý||ÞP_ôecšõpo™!Ž´aœõíBf¢¥ZIçýŸyþƒkKsZ qíåÐþŒå`Lí÷2™£kû ¦PO­ù£ØÔ¥@Ü/вŽm±ÓÝKûÆÐ4Íö°£$§ÒvdÉŸßþèçþóÏ«rgl/tests/0000755000176200001440000000000014145464133012205 5ustar liggesusersrgl/tests/testthat/0000755000176200001440000000000014146502162014041 5ustar liggesusersrgl/tests/testthat/test-obj.R0000644000176200001440000000126514127571265015730 0ustar liggesusersset.seed(123) test_that("readOBJ works", { # textured rectangular prism obj_file <- "# geometric vertices v 1 1 -0.125 v 1 -1 -0.125 v -1 -1 -0.125 v -1 1 -0.125 v 1 1 0.125 v 1 -1 0.125 v -1 -1 0.125 v -1 1 0.125 # texture coordinates vt 0.025 1 vt 0.025 0 vt 0.425 0 vt 0.425 1 vt 0.575 1 vt 0.575 0 vt 0.975 0 vt 0.975 1 vt 0.52 0 vt 0.48 0 vt 0.48 1 vt 0.52 1 # Textured polygonal face element f 1/1 2/2 3/3 4/4 f 5/5 8/8 7/7 6/6 f 6/9 7/10 3/11 2/12 f 7/9 8/10 4/11 3/12 f 8/9 5/10 1/11 4/12 f 5/9 6/10 2/11 1/12" filename <- tempfile(fileext = ".obj") writeLines(obj_file, filename) mesh <- readOBJ(filename) unlink(filename) open3d() shade3d(mesh) expect_known_scene("obj") }) rgl/tests/testthat/conversions.R0000644000176200001440000000244614145464133016546 0ustar liggesuserstest_that("asEuclidean works", { expect_equal(asEuclidean(c(1,2,3)), asEuclidean(matrix(c(1,2,3), ncol = 3))) expect_equal(asEuclidean(c(1,2,3)), asEuclidean(matrix(c(1,2,3,1), ncol = 4))) expect_equal(asEuclidean(c(1,2,3)), asEuclidean(c(2,4,6,2))) expect_equal(dim(asEuclidean(1:24)), c(6,3)) }) test_that("asEuclidean2 works", { expect_equal(asEuclidean2(c(1,2,3)), asEuclidean2(matrix(c(1,2,3), nrow = 3))) expect_equal(asEuclidean2(c(1,2,3)), asEuclidean2(matrix(c(1,2,3,1), nrow = 4))) expect_equal(asEuclidean2(c(1,2,3)), asEuclidean2(c(2,4,6,2))) expect_equal(dim(asEuclidean2(1:24)), c(3,6)) }) test_that("asHomogeneous works", { expect_equal(asHomogeneous(c(1,2,3)), asHomogeneous(matrix(c(1,2,3), ncol = 3))) expect_equal(asHomogeneous(c(1,2,3)), asHomogeneous(matrix(c(1,2,3,1), ncol = 4))) expect_equal(asHomogeneous(c(1,2,3)), asHomogeneous(c(1,2,3,1))) expect_equal(dim(asHomogeneous(1:24)), c(8,4)) }) test_that("asHomogeneous2 works", { expect_equal(asHomogeneous2(c(1,2,3)), asHomogeneous2(matrix(c(1,2,3), nrow = 3))) expect_equal(asHomogeneous2(c(1,2,3)), asHomogeneous2(matrix(c(1,2,3,1), nrow = 4))) expect_equal(asHomogeneous2(c(1,2,3)), asHomogeneous2(c(1,2,3,1))) expect_equal(dim(asHomogeneous2(1:24)), c(4,8)) }) rgl/tests/testthat/test-tags.R0000644000176200001440000000104114146424752016103 0ustar liggesuserslibrary(rgl) test_that("tags work", { material3d(tag = "hello") expect_equal(material3d("tag"), "hello") file <- normalizePath(system.file("textures/worldsmall.png", package = "rgl")) material3d(texture = file) expect_equal(material3d("texture"), file) expect_equal(material3d("tag"), "hello") open3d() x <- points3d(1,2,3, tag = "hello2") expect_equal(unclass(x), tagged3d("hello2")) expect_equal(unclass(x), tagged3d("hello2", full = TRUE)$id) expect_equal(tagged3d(ids = x), "hello2") }) rgl/tests/testthat/test-subscenes.R0000644000176200001440000000257714127571323017152 0ustar liggesuserslibrary(rgl) test_that("subscenes work", { # Show the Earth with a cutout by using clipplanes in subscenes lat <- matrix(seq(90, -90, len = 50)*pi/180, 50, 50, byrow = TRUE) long <- matrix(seq(-180, 180, len = 50)*pi/180, 50, 50) r <- 6378.1 # radius of Earth in km x <- r*cos(lat)*cos(long) y <- r*cos(lat)*sin(long) z <- r*sin(lat) open3d() obj <- surface3d(x, y, z, col = "white", texture = system.file("textures/worldsmall.png", package = "rgl"), specular = "black", axes = FALSE, box = FALSE, xlab = "", ylab = "", zlab = "", normal_x = x, normal_y = y, normal_z = z) cols <- c(rep("chocolate4", 4), rep("burlywood1", 4), "darkgoldenrod1") rs <- c(6350, 5639, 4928.5, 4207, 3486, (3486 + 2351)/2, 2351, (2351 + 1216)/2, 1216) for (i in seq_along(rs)) obj <- c(obj, spheres3d(0, 0, col = cols[i], radius = rs[i])) root <- currentSubscene3d() newSubscene3d("inherit", "inherit", "inherit", copyShapes = TRUE, parent = root) clipplanes3d(1, 0, 0, 0) newSubscene3d("inherit", "inherit", "inherit", copyShapes = TRUE, parent = root) clipplanes3d(0, 1, 0, 0) newSubscene3d("inherit", "inherit", "inherit", copyShapes = TRUE, parent = root) clipplanes3d(0, 0, 1, 0) # Now delete the objects from the root subscene, to reveal the clipping planes useSubscene3d(root) delFromSubscene3d(obj) expect_known_scene("subscenes") }) rgl/tests/testthat/testdata/0000755000176200001440000000000014145464133015656 5ustar liggesusersrgl/tests/testthat/testdata/qmesh3d.rds0000644000176200001440000000264214145464133017740 0ustar liggesusers‹íXAo5žÝÙÝ̦ɒv‹è¡H•àH›•€d¡ ‰Šª©*nÅ»ã5õŒ{6›äÔ3?ñ¸´?NˆâqâØbÏøy<Þ™MÒ¦$ml¿yö{~~ï{oæ‹uÏóÚ^§%ÿûrèÕ?9QýeùÛ’¿–×ñú²_{ízÞäp È;{ÐÖs¶â×°¤JÞÍÛ1FŸ+ 7%”â°‘Zì˜}V)cÏ?qv÷y4vX*Â)I0âÔ:1î±: áðò«Znö:WuçY§mÍ» бÐL—8a”q˜ šÎœš’ î Åc‚˜"Å“9E°,À1‚°DÏûbFyzy"m 3–Í@Ê”3³WgŒ&`,È6Ò! §,Ò×RF’ì>J2‚(A°ÿ@Ùz‰º–áƒlα==LaÚ—Ó˜¤1J5a#'$Ò“2ÌmŠ*4µ'ûåÂõ§Ùì~ŒÄƒ*%Ã޹IÄ]Ž‘"^Úq2z±ä>›Nj/F<"`Ë`JÊHð3.š‡nWí­ïàÜ æc1Á Öá}Éâ <•Œ_Ù~díÙÞÊåè+JXRZË»#Jáácqyiû@Nç’%÷ÅÖS­cÝ~2¦`„.'Ѭ´ C lÝÅ cZØ ?ƒïÈè•kߣvn+üW¶Ÿûî¡ìýuþŸQÝsM>hôþƒ_ÏûáËß?V|Fn%ýÄÚÄŠÜÑ¿' îhó—÷íí›ÚIùþøõKKÍ¥ç7~O®T(JÝöÓzm79½y³oÎý©ÌûÑ«¯.=×tà;v?#w•¾§Ôñ…ñ­´iîÆÀëö’}Sóê¤Rí^­šˆ!¡AßÞ ç¡U ¶Ó£š÷\F^µ7ô-³ÎVðªVðªçä8!Ð+±0ë$uÅÛ{‡"ÃñögdÌ?ÜÞ•)DlïÍÓ”âXB*¢Ûr ÿײljÉ茑÷ƒj?ZÏ\^\s‰¿ûù=H$JÇŸd%Œ÷)‘ª%˜?fso± +`cù¾I!çbùŒÞB'pYë)g_U)âIïà£P䮼Â3P”Ûr%ždeþíŠ 2pì¼H7 ×éÎxÌŒ¸IB¶¸#w2EŠ 'êLˤíO0,;'5Øåß-3k 8U­¹/F7)IoS$k°QDïI‹•J<Â>Þ39+^Û±×8N)šàÓMëƒÄµJnþªó;*'òœ…N¹ÿ¨œ£rêEù»ÐÛÚ*˜ŽUwte ð6h1È,B©> ó@ìye ^ðœ@¤Ezn×–¶ÇxæYxÇqñý¼}êê˜gTM/ø—é­v™•.Ò/2IÊ4)_v3¼Â¨õ.Së60Ÿ÷ªþ°®^#ÎæI¨Ñyù›Ë›êÏ9d™:ò7| öv~¯¨qûæ:sØóÛ pìÆO$ÅëçRúø²Oz"áòƒÄ”EY¥lŠŠÂ­Þ“6¥çX¾pBwëNþ’;™ouMfëªï-±“_õ7])–‘Š/=¶j{Ÿ(þwÃÿ†ÖÖÜí·®ÃèÍwÍè3z¯f­ßp¾ ÎX¶W­}«¥³ïâ Bbójñ//à¢örgl/tests/testthat/testdata/shade3detc.rds0000644000176200001440000000371014145464133020400 0ustar liggesusers‹íËŽEpì±½ãÍf Y!mÞ‘8’ð:À"VA""Ê&·¤m·í&óbf¼œÂ•#?Ê/ ´{à'”BB HÊ8p t§æÑãž×g厼Ý]]S]]]]USvç“yEQÊJ¥Dÿª´©.±?´Ãê“ôs„~JJE©ÓzîÅó~¡ÍE^}¬@™÷ÑÁ#Iðš_$4>”NPë]Çm!t@G éd1m…kÿÇQWn“CIL®#G6 ¿¬ŠŽ]—Ã]ô·*]âÏñ¬sc•r¬_5‘Ýé$[–n9ÐAºÝC°jx°OÈhlBWsmÜêëÓ°A\—XfЯ»=bÒÕÓ²p Ëòz0KDZBZ•&jÝ…¶KîápöÍ64;V7h>g[Äôn#Ó#H'è/2Y§ sÞòúŽw·mèÖi× ¶ì°àLªIvâ0ÔMÀ؃ØÜˆœocÛëÝ6{7 ñ° Ë­wþ|þŸÆ°ñxPvú;}þˆï¾ôå7» /œ7qÕ613p%øüì6ÿôNœ¼¨äÅÛ]üýç;16SãWÎ<ÜM@»å'ÃyŒ«Éèâõ¾8ôïû×ÏJpÀ“Ò çÍâwD'†—)S_—¯)úá7(àAGª¨Wi Ûá‰!íÐúÖzØ?ZÑÄq÷Èú5Pp£²~°(`ð\Àà9…óq.5€Jd[JCæùÇWVÖ·]+‘¦ƒœí•5êBÜ•õ¾mëØ &é+ï9Ôü¿êyØ5˜£¡|Ïʱ1^€Ë`×xG¢®}| éš–ƒ?Øò"3^× eÍÄà× «ïâ«VL–f5]ìl„.äAÇô«ÈslÖ¼íXŸ&!î]b_Çmm„Ru8‹ r>‰[^ä«n …æRÛ xÓ¶œÐáÆŒt¥Ù´Âé6‰Ù¶6¯SJaP… ¢ƒU:‘ÓV[;D9Xs0¾yVa²X|Ÿ¶.뾦#€Œºú-*±ˆéED—°×CŸåÞ¸bÏ9ØÖQ Ö~Hx©øâO Ñߣ¨Cל¦?LóÓÏ e63cvš~ÎÐÏYú9&ðweQM%‹TiXpæ±ÑÄí6uùa c5o.ϵtäB£®—>/¿ÓƒŸr£,ªU¹“¡Ñ ^v–_‹Æ%t ó3"ý¼òy½¾eüN þÁŽ–WÿÞÜu£š]ËðóŽíÏ2 S— ˜ef™†B™†³Êø™†}Ž&F G‚h`TúyÇ…ë“¿¼|å–Ó>??®|v4qT˜2©Ç£ OVótf¹†Âe–kÈ®g¹† çjJSR_ø÷ÊCï J,Þœþ…¢ÉÐüIÓël™{d¬E7¦*SËV™L©®â3ºwDLâá }Ðc—C¥‘â²’Ô‡y§u«o¶…¿^½t™ýËûëÕÊêKKgÙŽðµx‡öÚ¦;*PláóÁ}ÞÔ½¾1ìK¦=©¹vG7¼;V×KÜCën פÃTsbºSŽKÕiØÛGðŸˆÄ–ÿëÍØ­|þ…£RÀPÌÔðÙPÃçuàü›aë­°õ6´.ž[¯…­ !ÞëaëRØzcÈlª@" ŽeyëÉ«†É›Š*o9™íowþPæ‹Drgl/tests/testthat/testdata/obj.rds0000644000176200001440000000310014145464133017134 0ustar liggesusers‹í=5tvgwovïƒÀ )Eh —pPÂ-Dœ‚DDÈE]ðîxwM<ãÁž½T©ùéhø t¹Š *„("P "¡¡$Ø3~žï|Ü&!$ÞiÎöó³ßóóó{ÏÞŽã´NKþweÕÝTÿdC•çäwF~-§ãôe¹òÊ…duC¡w9ƒ„,ý*†Ñ» 40¾ßÈ 7!”b¿›Îã™yꇺcÕÿ¶fwùtd‘˜SbÄ+±elìeu(¢ÝH¶jòãlÑ­¾N;×î†(ÀBä˜QÆ¡h4C°jJbØ'Œ¡é‰çÁ0DÂBÝî‹ åê労.DÀX<.ÎÌ\ß‚º ·±á~àCu¦ºú\ÄHßDaL%æßPº^À®Äø0žsœoEÐìËf@¢E±– BiI1æyšpj ÷³Gñìf€Ä­"&Æ–¹NÄuŽB!žéq#bôhÊ›l2°½ñ)]zÊPLBЀ£ij¢ÉÑíª¹õþ¯Xûï‰ùHŒqˆõñ>›£õ8*o»ÊÛQnÎö™„Þ¢…™¹Ü»¢:o3d›¶èh.I[l=Ö2–Í'ÏÀ”Ðåd:Ë4B|ŸY÷`†1Mu¬ÁµÈðÅ?×$µ¶ê?“;þµ°óï_Ý‘å½?žÿkXÖ¯ñ@WǚƷp]ŸNªb…îèïow¸~ÿ­ºéNJw¼ñÛOŠîÞ£ŠþíoÞ0JÜöãróf²¼zãÏWWê}÷Úù—ú5èç3|ëä]RÆgFW«ÓÄŒÖ.%ùº¦Õ¤p¤:Ú¼Z‡P92'†øÆûöf89Zã|xTí àÚǺ}lÆå<¯<ïX1NHèd¾¥U¿*>¾ºµw$bl}@Fñ£­]BÄÖÞ<Š(¤KEtë.Ýÿkq<Éñè¡ó­‚ïr}¶Ï‚_³‰»ûá d2Žß;Œ37Þ§DŠbôý€Í¾Â|pY Ì÷MY d½‚bN`³gŸ1≮aŸ£ÀÈYyfCa®Ê‘xgñ·+ÆÈ¸KoŸàƒˆqpsNº31Ã>;¸&g2I #êL² íŽ1 [•ìrŒ¯g‘ÕS”*׀ؠÃK”DW)’9èhJoHeBo ¹„}¼gbVrxó†½ÂqDÑ/×,?$¶Võ•˜ìQÖëLeJìGÅœ5]_­ˆmmL'—wte ° Œ°ïËðn’6Rr;wS$ wkƒîù”š¯Õ*Qé Z›éÁL’…~Îø×­ÖýlŽ|¡Ø'Ãq2WzÙvO÷¬² ¿ì¸ª²j¾*7zRþMtÿ¶|à}«Ê%˦ñ§Ý_ UfêZïÉ, .,›š.fne¨kÝv2SÍEÌ"ÔDåV:Ná;KX›( ¾¼™yk”“áÂÎÝ»w¿P<¡¼¿½=Ì—¿L&Ÿ¨ò¡n?´ð¾ü1‘ùç¯?z/ÿ¬û®Êu¸˜­ÔCýé÷—š[»fÁ¿¶À)·À›ª}¡jev~]%a]IzÕ +Ti[³Â ËMŒï4”MÐäC› É‡>-4ÉwÇ©/›äk¿lŒYvýMüŸê|ýšfþZHSúµ‰— «+‚I1ÉØd¤½ä%Ìä§1>3Æ}“˜É,+Îrüy …fñ^ˆå‚XàN<™›¥YVy®–äh='ËÑV+G£éÍ­]úêÑÔNÁ¬4uyÒ²DtµÌSŠÇUo¿êÕÛP½Í¤— f7(’רÍ=s•Úƒçdö0pŠö0Po§SÎæ¡¯÷Åçø7.©?k‘Ù­"yüÍeL;ßon¾¬vÄ.«wè´3¦ÃÎàvåëyú2¹ðBQУ·”Ã)‹åOz"šáì­z¦qáF=Mïôå–´.-'g '4§µFsrÌÉüŒS¥¶®zŠ–žÜ¢½éG„ì÷…ôG€¼j}/á(þ7Ãÿ†–>Ç´/n›ÚES»`j¯—Œu+Ö·Æ‹÷ŠÏ"ÅW×öƒÊ›W§¼ú¡ #rgl/tests/testthat/testdata/tmesh3d.rds0000644000176200001440000000263114145464133017741 0ustar liggesusers‹íXOoä4ÏL2ÓÌ´ŠzÙÃ"!q„Ò]–ëÒ•X±jW«½gâɘ:qdg:mOË•O·Ø~€å„8­8!$qâ¸ÅNü'“L·Ð= ájûùÙïùù÷þ$O‡Žãt¯#ÿ»²ën«r ž·åoKþ:Žç äsí½;y“Ý‘"ïýé@ælůeI•¼Ÿ·+Œ¿¸R@J(Åa+µØÇ7û¬RúN­ÿª¶»Ë£ ÆRNI‚o¥6‰©Ë£Xˆï(¿ªåf¯««^›óºÖ¸—  ÍtˆF‡¢é Á©)ÉàžPœÀÐ)žÌ)‚e>މ„%z<3’ÈÓËi[ˆ˜±lR¦œ™½¼MŽ¡/È96Ò!t§,ÒÝ·RF’ì%A” ؤl½D]Ëði6çØž¥0ÈaLÒ¥š°‘‰¤ s›†¢ M-ÄÉI¹pâ4›ÅHW)pÌM"s”ˆñÒŽ£”ѳˆ%Gl:¨ýñˆ€-ý)e(# XÀÍPT@4wÝžÚ[ßÿZíþ}1Ä'X»÷-‹×wÀU>1¸²qdíÙÝÊåè+JXRZË» ¥0yÎX\^Ú Ó¹dɱعÔ:6í'}` FèqÍJ‹0¤ÀÖ[Ì0¦… ò3¸u~ûyœ÷ºj~Ërÿ•mï§_¾&ŸÏÿxû¯qÓ¼¦´çzÿ ïÛ_ÕüEï鋜ÏÈ­ø¡’X›X‘=ý{êŽ7_Þ··ok¯Ëw¡Íj.Í¿ÿòþ׊R·{Ù¬£ “ë›7ûnýweÞÏvÞYš×tà»r?#w•¾×Ôññ­´icà­?%û¦æÕ 2HÅ¥< ¯Î)tÎŒÇÐDßþ ç®U ¶Ó£÷ë ŒêÓÐË4k+¸£Üqj9NÈè”±¥Ó ¿-?~°{x&2ï~IŽøÙî¾L!b÷pž¦Ç2¤"ºû)—áÿÃ,›Z2ú cì¼Pík®nÀ[×ê‰ÄÝÿê $%ŒãÏO³2Œ(‘ª%˜ÿ fs²B–Ïù‰I!뱜£QÆ \Ö0åì›*E“ô‡-€"wåž‘¢<’+ñ$+óoOL —þ Á‹”q“p­ í3â$ Ùâ@îdŠ* ò¦eÒv'–­K ö9ÆËÌê+NUk@î‹ÑéJÒGÉšlÑ'Òb¥Ò#$p‚MÎÊ×öÇ)E|½a³“Ô­’›¿jÄüŽÊ~ þj‡,SBþæn…¸½··ßU7R¶ßЇ8§µ½`·~ú(^+—ÊËcVÆ”¾Hg¸üÐ0eQV)‡¢¢ kFÒ¦DŽ……ׄӯ•pr—àd¾Áµ™­§¾£ˆšÜ*ÞtX~*¾àØ0Ôö¾F ø†ÿ 6ÖÒÝ»÷Lï®éÝ1½Öº-çÛàŒe‡Õš¶Z»õ8¨"±yeø$Pd4àrgl/tests/testthat/testdata/transformations.rds0000644000176200001440000000515414145464133021626 0ustar liggesusers‹í[MŒGîÝùñìÚ;lìËJÄÒòc'1ëe-ÒǬ‰Ë›Xää险™é¸†îÞ?+BË…¤€¸ !9 ˆB>å€z‚ 9Jdc"d,²²¼Æ±¶D„bªjêUw×tMï[8¶Ûêýê½zõ^uÕ«z¯§]ßVePÉà¿\Ìl#0AðA|â{@É*C7}~7½p±HØê5®a*Ö½%M¢ìiz%(=—h _× դܮž×Ó¯ãPV„ò'‚öŒÓ¨"ã†n!Í‘rã̈•5ë ²E:U½W¸Øu¡.;¢s–f"— =̪mØšÑjjðÔ†îÁCF\ ¥É³Z™–Iýhhù÷½ÔS~±„Ñ¿úÀÍR\=ãƒ\þÉâNŠ¿ó!©oOþ Ó!rÜndfjºÉ†˜°³ìþº[9ýÕ°zÙµZ¹vñÒ™qÒ½k’úŸ5;éîà­ø>†ÝdíÃë}oó2¼{îÚÞSÏø —¨Ûí×ß5ö15¹¾cJÝdEÄâ#L–]A"K*ËÜk` ‹|Åè5¾û曈.­Àp8<:ïß\XYÂ…c¶BXm3,òváîbÜ¥1ÎÅ ì-1öeññɉ™E×CæÄ×õŠ£9‹Ó8„¸3³­–L¼¥jÆÄ3Þþ¿àyõ<Ø()&×_BuâŽÁ¾&’Ìô7A@Ð–í ¯-xÁ6>dè¸kr@~È´g]ô¼]ƒ-«`W\äÌñ²ÙÄuÆóšçè0YÃ-Ç~9Êqè­ƒ¨æhóÀÁZˆL‘pà–¨êñ7çV5¾]æt4ß²pC›t¶R±¹¹yݪÙó±&žTi¦n€eëAÐÎT4ÛŒ{0í ôBY D’äûLmáYCo04œÀ5ŒCxÄ‚N5üsh†Ç,ºxÃŽ½ÉA-C«¢µ‘ñ‹D:üÑA¤sø9Ùš!þCVÀ£ø~ ß;ðMöÿÇñýñU|?"‰wƒ:d5ÙP.’ÃiÁT #³‚j5òy"cWHß\1Ÿ«š ùÜ Ì‡Ó0xÜgCY] lPI20ĈBhA<&,:àuÍj$i¤z³ýéénþyØ ƒ4· ¶áýŠp‰Û¨l[MÚn¡¾$¡E”Õ'é‘Ñ"r½E¾@ËôHi™ÞÕÚù£Þaò1a”dµaep†/;Û˜¼Ôe¤arਸj6Ù{ºBCr—Ÿ½cšGhˆÕT  …ú0¦žzñÅ2±)Ãßx£Ýo09†¥\“êKƒ]=¥‘õÑ1cT¦+vŒV9=ûýó‹?/áBZ¨¦Œi÷çÿ¥ÿÓ"ß'Y§k†ß"±Ð7üLÍC$yåÉ r<½Ês¥<£<À¡Ý ’ÍM855Èh‚J{‘^@ް'AhOz’ƒŠÜ¿5«ÕRK d—,&Õ-Ãê—~‰\O;Yà™þ$»2ºÇÞ¨D¿Œå×Û^|Gûc*ËùŽI¶Š6Wë†Ò™bÿüØd‡ÐÀ_þå3DzßÕåý?¢rÀgí€Ïå˜äfõœÏÛwõùÌn ås½Ðß÷_:GfÝ¿ñÀ$mwêÌOÂ|õÚÇoQümñz›ð?šú!mÏø¼ボÊô¨ z¡äY{núö>× v¯û7©üÙéTþßÇÛaþ…ï¾Iõÿ~d™¶¿4¼›Úg|hÇù zŸëeõÀWÁ.Ø» Gàƒ^hwwö1õí½µùÑ+j™àOgNÐÇ¿Ò:K¦Ñd|ËÑiaíü‹/o¦Ãw2™Ê]?·LåÞ}iªCø€Àgr*kç_ýö´]çoUªçúÜ8ÁåÓ9Ò#•>ȱv)¾á«¿»ø_jJÄ•}åN¾öã×—âðÒkGÚ1èË·+ÇáÊ>M‰Cܯ¥8<÷«óTß?zh<ý«ÿÙQŽÃ?<ÕŒCU†¬ˆ>ØPÅýjÇ ¹y¥‡gv¾WŠAõ½ÌŽÇá…?=Ô‰Ac;q;%U°#"ë—ˆ÷r"°®7üÇ•4ßðyÀ=ð˜…ÀΠ¡ä!€CÀ‡Àõ :ȃ$$¼_¬Ú=°b ‡@ Yì¸yõ ôAö@? èƒ~€>hú q€Ä¬èybY ì ! C€}(€<è‡zЉÈC¢ú€{ ÏêïîD`«zéÕíô±ïSé0ß÷tw^Ý^&x±ü†þ…ßì¥òä_§ÃÉPÅüqB/;ã”Æ¸DèwVæŽüç‹”ü¿¾òkJ3Lñ Ÿ<*é’ñ”û Ÿ„Lñvú š€> ±aJdè' L¡ ÉÔ–û š€Üdˆ]£ªIÈôȸZ¹ª x/ö5¿á?¡¤ý†/ûNF'ñÅzÙOð²Æ’ø"ÝŽ²9-"\%E¾HËôÈh™™]Þ^øßY¼½ð[î'7ö1ÿÃî·pª è߈¢øÍ>©¾ ÃÎp­tšßðWÌ7‰´PMýÓkCu˜ºþÏ=|,U Þiò÷r"°®7ü'•4ßð“¾Ü$öõ~ÀêoGÉž@ÛNÀR&éO²+£EyY –Ñ¢üzÛ‹_ĤÌww"°Uö;éÃn›a©¿Xâ%NÃýoøë¾îÃï÷¿á§ü†ŸW‚ þˆ"f£{¾g0öl\ÂŽwVÿ–¤ÙÝ(Æt<æmÚ¬e'„#.“ïï2}]d¨{ôD·‚s6º¥{¨?¡Ã‰IÞÃJÔ†É Û†cÏZ5i¦·çYòoµ™^V=¹mÛ8™å3t»ÃicW Ž-=cÝ=¿ÚsŽmûKßý$ï¶š(8Ñ\·^äÜU£{ò+Þ“F°ç„|a•îôh¢;ez܉ö— [ŽØv…qÊDý­K„N¡wŠÇdukØ(î»á§Ã #=‚žO}J{vóÒ$/}‘—¦xioûe^ú/=c-#‘-Žm{3Ñ£uÑ“yqç${7?Íø?|ˆï{Crgl/tests/testthat/testdata/subscenes.rds0000644000176200001440000007712714145464133020400 0ustar liggesusers‹í}|Õöõ¥*ŠˆbW4ö.öš8GTì ,  $tˆÒ{¯7!¤1xD¥÷z/ö.ßÜuöšL „ "óþßð~¾•ÓvY{fN¹¯žáóùÊúÊ—±þ¿œõg¹jÁÿ³A¼Ìú¯ªõ__y_% O»úvü³þ¬Ì6ùøï TÓÿ£IÑìZøwê©ã*¨Ø$*::²ñ1sµœÓm9%ο}Güý×ÒËÅ6mxD•"Ê££ZFFÄ3·85GºU>:2.Uª£ÿ9ÛiúeåË:ÒZF´ˆŒ“J—1³QLtL,Ñ­šEÐëè¨6ŒSD‹†Q‘-™<=®Ud£¶Ñlvzd‹¨¸¸¨˜–’®×,ª¥å½å‘p×"&¦M3jicË*ß0¢ÑÛü;.ªS¤­½}cþÙ$¦©üyv«˜¨–mÞŠhÙ&*":*‚ò«¹>*÷´6‘Ú´t&;¶b²’•lÕªED+ɨŒŒ–Ö•Ô&2֙ѴH^°adËv… ÏhÙªM³·ZDĽ]4§MdÝ<+*îåØˆ–q­"b y¬Ò*&ºcÓ˜–oÅ4iÉÜŠ-"b›F‘ËÓ›DÇD´‰jIʵ‰hª/Qܺƒ²%þ§ÿÓãÚ6ŒkÙ2Rnï‹uO÷ñVyؾ®œ×‘CfÙ Ì Q˘–… ÆZ±kÍÂN11- ƒÖŽÙ­ÚZUp-–9,6'Ϻš„ ±QM›2Õ¸q4«Uhß,22ZsÊyƒ¨mK—˜ø«l°¼ªãö/ñŸ±bkJ¼…çü¤Š+—|Ö³õ]rg‘ê¦è/Ô[ä>,×8ª…OSÌ./ÿýEsÕYëÂÂKanië™Uvm ºu¨øòÙeç!Er‚æ–=\¼ÎËäÄémÓëÌ}AzkÖ¾µúQå’ÏzÇ•gë-ÉÞ´ñ¤Õ+‘S\Ƭ{$ZÕÏ’ºò=H‘[ª¼\^e:ðŽöÕØ~úVl‰[«P±³{ ¦+šy;–šÖ*oÍÇ~ ͼ­}Òͼ=û‘Ö(NÑÀ[ÅÀ[}GôqqÖÐWøl)SŒþcõ·Ô¨Ó1®Md‹ÏF5ŒˆíX£–Õ…ÄÕ¨Ó¶U«èÈÖ#5"ºÆ#±Öãÿ¶6mš8tT¤åû*øo‘£ìH/âsíÈŽ¤\­ê²CˆjÚ2&6òñm ã•¢£,ÓZFƲ~¥1mã"Ÿ‹iÌGÖé1 ã"cÛÙ]È™-¬²èç"ÚÄF1Xg´Ši^4'îí¨Vµ#ÇF´gŽ%5¶H*Áœ­–‘Úö¿âEØËÓÛEE¶okw¸Ž‡tù† cluí£Z6Ži_Û’dª"ZDEó"*ߤ°Ó.×(’Íδ,¨ùraÏzz°fp¬Á¾¯ED‡G££Z½a ÈQÓèºc…FW‰°\hYÇî³pó:/ìÓb#[EG4Š<±dñ7É‘¬€þ¢$"F… ËO¹gxWºoý'ChôÇ××…¾¿?¾Ðëåÿ¨?.¹Ãð:a¯.Úö?î„ã%áuÂ^'ì¦N8ªe³ÈØÂ•Ò%ON'\Y0xm-²Ï±þ;×§;åó¬ÿηþ»À§;Û3Ñé•âRCyÇAk®~ ΈlÑ0²qckn¯.Ä4 Úwä"K£èˆ8.²”e|b›FÛ¿Poei ¾ÂÙ¼sôp±ïß=\ìåÞèÁçN¤ÞÿÐèáÈ)|¼z£oôàNxôp‰ï¤ŽÊQæ?0\êû÷ —zG¹7`ðy†©÷?<`8r¹!^*{oÀà Ž;`¥qÙ€¡ˆ-ÿ[Dÿã0B©*£š37ìYG<N‹kÛû:eeßå9³ï«ñŠu/ÅÕhÑ6¶qL£f5âÚµ¬ñ\ÇÚ5,ãjDµŒkSCNÄÕhÝ8®…5ع­U˦GYŽ´9ÏÒyHÆ>b÷PÕŸÕà¸x+cVƒGÒýA¬?´Að5뵎Oë}w¹ĺŸbY»/]ÕCñÙÎ X˘ŒzÆ—Cν[±rÝA »ö²îÁò°ûÛ]”Vó÷‘À§¢_Fþ ±wÛ…ÕîxøòþêÀz§×AûWçäëŸ_ íêÿšÄч}Nd>ë±åP.õP/í ]´S즶_ô“~“òBžÈy$¯ä™¼KÌŽ½ê…_NvÈŽ¶3Û§½”k¶S¿å™mÚïA:öÕÅA9fÌš[‘ß¼ÓÚ <³ñÔÿÆ9õQïÅçÏ ÚmÞtçYÁ´ztÜÄ`}U÷“)Áú*"éÁ ~ÕÔß>¨Wµx Q°½j}ó'¨;¤J>ë±åP.õP/í ]´S즶_ô“~“òBžÈy$¯ä™¼3ƒ+ïAzж”jÑ80¥3Ú ùìè×c-êõ~3%ó£ÙÍ‘ßÍ|õ;¯GyÛií÷fµq]šö* ?ßxlxhõÃøÛé¥G‘ße|wÍûW/+ð9¶+xê[®xì` ê ¼ñ;¤×Ncæïh7¸ìö"È|Öc;Ê¡\ê¡^ÚA»h§ØM?l¿è'ý&ä…<‘7òH^É3ygFJ|Fž{ôŽˆË@»á-#=¬âÄuHÍû Ð Óоw?Ê{ÝÓå´û zÞýü"ØÑêêgOí×÷E£·oíâO×þ·ýù5|Øg_òü5éÁÆ ÔZ£/x6¯#øþg òG,ö!=òÁ3âÈ|Öc;Ê¡\ê¡^ÚA»h§ØM?l¿è'ý&ä…<‘7òH^É3ygÆ7½ õÇ_{Òã†ü±—N€¾Ñ¯OÕõoÊDþ°~<¤.Òžhö=£Ã ¯ËÆ™H·©|ä½xI:xhvEÿ`}õÎ÷=ÀO÷ôíÈï[yu°žøs=àÐËf‡á»a·õÒGAyjÌ3g þØEã?né^¤ÇרœÈ|Öc;Ê¡\ê¡^ÚA»h§ØM?l¿è'ý&ä…<‘7òH^É3ygõým&öž}‰D^¹ èúÔûK6êÚ‡üá/=¹ƒ‹ü~µæ@^÷'/ƒ}í Ê¡][?‡Ñ3ã“Ãïž+*ÂßÏÖAþÐÈhä¼f(xÓ©Šæ»ÞÒ <å_½|&.C\ëëþ91õZU%ŸõØŽr(—z¨—vÐ.Ú)vÓÛ/úI¿Éy!Oä<’Wòló.qH—£±õcˆWÒî ÈO:ã^¤Wêç]Bá¨7þl]Ô“aϰæÏAÿÀøÛcô¥hÿΨ”×½e*ül5: |t{¸>øê»á7àßiàeDþaàØs0QþvšïË× F"ôAò’ïOB~ò຾"(ù¬Çv”C¹ÔC½´ƒvÑN±›~Ø~ÑOúMÈ y"o䑼’gòÎ8¤Ès,E=‹üINœ|/ä'?_é #Fiù’ãÞÓíG¾öê ^8!èÙ{ùýÈÿþ7ƒþš¯÷üŽ?|tÿL?Wlø —üÑ¿õ _­"Q?q\sÍkç[Pâi ÀϤ»ýP)¾GÐ>¥Éòø"(ù¬Çv”C¹ÔC½´ƒvÑN±›~Ø~ÑOúMÈ y"o䑼’gòÎ8L¹í{ÄiòK4>ÓñM½óMŸéíµ¼ù‡Q>áÃ!ÏÿÝJ´sÛ!Ø3¬L>ììw¨ Ò]êGû›ãà_›ÍÚÏwVš7'Ø^¼vxÉdÍW­®š¿Ì šÏù÷¯”÷¾_©_Å Ýäi㑞2)Þ‰Ìg=¶£Ê¥ê¥´‹vŠÝôÃö‹~Òoò@^Èy#ä•<“wÆaªî÷Ì©ýpŸšiË/ÔqòW€üÔŸ—£|Ò–N¨ŸÜ줇ü ·£pDÈtà€Ó`_·ŠŸBï›kƒ‡vÛ¾/½>< 2¬ pôÀßáÂYx£I%Ujœ˜Ñ å)¿= œ¼¶2xK{òøœªt¿0uÖ·!EPòYí(‡r©‡zií¢b7ý°ý¢Ÿô›<òDÞÈ#y%ÏäqH¿NÇ-½|wäOX?ç¦}i×lBS·¬@ù¤»~‡¼¤«G ÿÓ¾¨7ê:¬˜ƒ":!ýÁ¸Íh>àðÑañÙÁ´êcêqé°ôs}ìæHðØi!øLžqŽÃˆW‘žrî…š÷K*#Ú¤©7=»5ä¥Wÿ%Þ‰Ìg=¶£Ê¥ê¥´‹vŠÝôÃö‹~Òoò@^Èy#ä•<“wÆ!CúûŒÛ³Ñ>}.æ«fzU=™v÷‹À)_üˆú)z“ÁL[ò~A¿gŽ©úê þø;à‡Wb½ÈŒ˜÷üꔀñ‡ê·vüþíÇ@ÿééÀ +ª£Þ¤ço“#q½©©géçýô‡b4ÿq ?£Ü h—ñlù"(ù¬Çv”C¹ÔC½´ƒvÑN±›~Ø~ÑOúMÈ y"o䑼’gòÎ8d¶ˆú™O/‚œŒU×BNÆEïCoú9¢ýÔþëÐnòûPâa=®žp…BzìúÕh7äÏÉHÔ§3°áž©ð÷ݺçÀ¿͇GvJ gž’/Œü”¯üH§]”§¦í¹éô±h¾»œ†üÌK°n¡2›êþÀFÉg=¶£Ê¥ê¥´‹vŠÝôÃö‹~Òoò@^Èy#ä•<“wÆ!Kͬ—0Ÿ53WuÓqª¢×_ÒÙƒüé÷ÃNsÊa:þOߎzIwbkŽïù ä »ùYÔï±q ô5ú­+øxoÿ#ðo`Ý÷ÀǨ] ‚õTbù?¯‰O­“oÿé©“õ:dzý\Éèó¹æÿ]=¯Ìº< é¬VõýEPòYí(‡r©‡zií¢b7ý°ý¢Ÿô›<òDÞÈ#y%ÏäqÈŽÁº²™ý؈_Ö\=nÈ<´ù‹þÔq vLm€q¼™úNìH®1i¯Qø#c!·×…ÕQ¿ñµÁÇûƒn¿þypŒŽÇλ‘?)"ùS:.Bü¦_ÞéŒÎŒº鬯Ih—]% üe7n\%ŸõØŽr(—z¨—vÐ.Ú)vÓÛ/úI¿Éy!Oä<’WòLÞ‡ç\ÙL—þZÇ%0X·ð 0£ÚÙÐ3mL¤'¬‰ú/X‚t‚ñä0Ú#¿÷];`oäÚ àgüK´Ÿ?MCzlËYA;Õ„œ^à%%|=xLKÎAüÒ8˜±N·Ï’uûìûë ½{4Ò95+p"óYí(‡r©‡zií¢b7ý°ý¢Ÿô›<òDÞÈ#y%ÏäqÈ99»k|£@×ïØvdס~FÖ´Ÿžÿ8pJïÖ¨7qÇ èKØüìyõ×h×çîs`w“IágüÏßÂÿÁ©‚ŸqÝv!¤¯ •Z«%üŸšÕ ¼¦/Y ^2»…‚¯¬‹5ß?ÍBýœiš¿Ü3±žd#óYí(‡r©‡zií¢b7ý°ý¢Ÿô›<òDÞÈ#y%ÏäqÈÕó$3wÄ++u0Q¯ºÞ?ÉZ3í3k–‡¼ô7"?­Ù$¤'› {¥?¹?å}/ˆò¦o,]âõ|lÈ7€‡ñ~E:¹ÚÃHO>ëÏjZbð•ñêð”uánð”ý¡~þ䌿˜ûúdäçæ?_%ŸõØŽr(—z¨—vÐ.Ú)vÓÛ/úI¿Éy!Oä<’Wòló.q˜¡ŸŸæŒÛãQ?wìÔÏI»éì·š"n™ùZNúÂùÈŸzýoh—¶\Çcÿ°wÔ˜:Èï»¶=Ú5ýý6ø×å§óÀÇo>~=ÞVÉ º|²ù+xšÞêð“±èSÍãˆ÷ÁsNÕÍáàûvìǪÜïEùŒW^-‚Ìg=¶£Ê¥ê¥´‹vŠÝôÃö‹~Òoò@^Èy#ä•<“w;2œ‘þêϸ¤‹Ž×Õc!?û›T`Ö5"?ãÏ©óP?å³&h?¡îyÈ-óþ~‚¾fï¿»¾v&xZ³‰öûý6àgâE¯£|ÊËz<½ÊçÀÌ«Qž]¾#â˜óÁ¨—;ùwð;£õǨ7c…¾Þm”|Öc;Ê¡\ê¡^ÚA»h§ØM?l¿è'ý&ä…<‘7òH^ɳͻÄ!OÆgy^­ëu^ªãÑíS¤snª¨ãÑ^ïïfÄ.G»iOéçfêmû´]“+Aîè¤ßaÿráñðc÷tÄ¡kŠÞÿª×1•ÿ‹ ?±Ã³&xYX˜þrgÞ:ëõîìÐ.gKc”Ï8«™ŽÃªÐ>/,*܉Ìg=¶£Ê¥ê¥´‹vŠÝôÃö‹~Òoò@^Èy#ä•<“w;zýÀÌk<íg|ù6ôä~U˜ÓòŠpÈÍùéŒÉ¿ÂžiS¢´ïÿ ã±ûmçŸì–ý•¨ÖÀï®ÛÌxø¹Mï§ûÿ¬'š#ÁCÚ5ôž•4o3ëèxŒÙ†z¹7|£ù®7DÇášPÈÉëÝ,¼J>ë±åP.õP/í ]´S즶_ô“~“òBžÈy$¯ä™¼ÛqÐóT+ÝõgüñÒ¹`½ÙÌ­ç¥Y› Pž±çYÌiûFC^j®žß$U›ych¥íN݇tTŒ~NtÓûÃjعšŸ„+o×ñ8ô3â”þ‚ŽGšÎÏÜ‚ëFeÏÏAyn=Ý~FÏ»P/¯^_ð—^%ŸõØŽr(—z¨—vÐ.Ú)vÓÛ/úI¿Éy!Oä<’WòLÞí8È:K^æ»:ÿ‚Wt\ÎÓû9™ñ¨—õÃFÔËØúÒÓϪ¹©Kô<)é†ÕÚÎz zû/ÔûQú‹êve¥øySˆŽÇ]OÛ«I•îÒ¼t~Jó4K¯gþt>ʳ7¦¢]nÌ:‰UQ/¯õch'‡u QòYí(‡r©‡zií¢b7ý°ý¢Ÿô›<òDÞÈ#y%Ï6wÅÃ{^ùvœòç•ןûvœòþÜïšN;Nõx×›ºk>è­—¸k½Ä[Ot×z¢·Þî®õvo?Ê]ûQÞ~­»ök½ó î:Ïà÷q×yï<œ»ÎÃyçEÝu^Ô;Oí®óÔÞûîzßÀ{Ç]ïãx﫹ë}5ï}Nw½Ïé½ïì®÷½ï¸ë{Þ÷2Üõ½ ï{2îúžŒ÷½%W}oÉû™»¾G6³Ê‹}—[ª7B»‡¶< yù_Eúé_°Ÿ6ëŘߴžË[!ýÊ»=Çzñ/BÞkW>9õ_MÕq¾ò1ØÝ ýJ®éúú<Ǭ׾ìƒö¯¾á‡Üº½žD½—_ŃfÖK‹‡ ÿ¹?n†ÝO¬¹ íyi캧œnÙ-wƒg¢ä‡I½0i&rÂDn˜è ½abG˜Ø&v†‰ÝaâG˜ø&~†‰ßaÂC˜ð&<… oaÂc˜ð&<‡ ïÚqÐ~˜O‡¬¾¶{oPžÙèf|M׌ªúò[öÕëý­çŽ úeÆýŒsfÛU÷"¿}ýYA{Ìï^Ôkv¼÷#êquÇè]¾# éö¿TDº]ÒVÈióÝÔÝžÌVýêßÞ°õ›Ü8õÂ/B¿lÖù¨ô>x›Þ$J¾’zJÚ)‘£D®=Jô*±C‰]JìTb·?”ø¥ÄO%~+áA /JxR›•ðª„g%¼‡If…êø˜õ«]~¢Ö?­À÷•7iË}ÿ;¿÷âÐå“GÁS·ýá¨ß}áLäô|[`˜ûÀSÏÓØ±¯Æ7g£]52Ùû6ðÃú<Æ;±navݨÇåñÝÿÎ7!hßîòK ¿UÕK §Ñ{7£\ü¡_Jò•ÔSÒN‰%r•èQ¢W‰JìRb§»•ø¡Ä/%~*ñ[ JxQ“Þ”ð¨„W%<+á=Lâ0ëq}ÛþŽ|ðÝ8ßgvÍ ×¼-؈z½º D~ßkÁ߀§Û"àÛÝ×AÖCzÐ×MPoðÍ€ƒ~Š€œAƒ’Ðn`>/6`ëFðßßXŠò>wëýþ™9(ÿ`AÔïqäw(WõZ\…~€÷‰}_H¾’zJÚ)‘£D®=Jô*±C‰]JìTb·?”ø¥ÄO%~+áA /JxR›•ðª„g^?a‡YÏèç˜}_tL>äC~ùþ÷øæNðÛ/ì:¤= ~Ö| »8¼º>ß:â¡õàsÄz~4ò±r¨?òÆàˆä gøÇXß0‡E½^‡|2FÇ1wÒîDº÷=¯ê~p,ô¼¿~:ÊyÝð¾'ÒO©§¤9Jä*Ñ£D¯;”Ø¥ÄN%v+ñC‰_JüTâ·”ð¢„'%¼)áQ ¯Jxæ}&q˜õ’î÷ìçýýhàðÛoÉ^¤Í×çT‡®Î#úêõþQkQ>f†¾^Ç]‚s²æxßå¨?¾Q%È_³<â3nìhð:¶ƒ>Ÿ7zUw¯Ùñ:N†~Þ ipÒ¯LöVºÿéö¥žGñ>a?Aä}!õ”´S"G‰\%z”èUb‡»”Ø©Än%~(ñK‰ŸJüVƒ^”ð¤„7%<*áÕ¾^„÷0‰Ã¬—uo÷¼/úœ3|ªpØ›OQåõ¹î±ah¾¿ü&\\ å ˜ùÌĶãÀkbºÞÿJ³rü zú´„ÿ«€ãÒô}:z:ÎÛš#®ŽzCšèu à¼}ðyÊþ‘Èçý–vJä(‘«D½JìPb—;•Ø­Ä%~)ñS‰ßJxP‹ž”ð¦„G%¼Ú÷‰ð&q˜UOíþ’Ïú?ô>=¾¹þà¸ó°¿cúwÞ£y~÷gð5ásœ÷3“>þ¼&×ûLãè »_‰öÉÕ0~4“ž¾ú&ÜŒóPfÂ'QÈ÷—¹8æ4¬g˜Ã‡™Ð7hÎJäó>aÂñ‘ýï i§D޹Jô(Ñ«Ä%v)±S‰ÝJüPâ—?•ø­„%¼(áI oJx´¯>G…÷0‰Ã¬úz\l£Ø_ð¾~øð=ÖÐççÊÎÑ<^®Ïk'í:œØ@ó<©ÕÏH§\ÝFc«Žà/¥î\È™´2'~‡y–™øKúäKà¤çª¡]ê»Qšo5íÒéyÇÔ·õ¾ðÔzýêä×5V©ƒü)¿\¯ã­ŸS)­ñ>Œ9±*ÖõÌ /åƒo^|^r\Áñ7ç[DŽ/ÙòyA^D®=Jô*±C‰]JìTb·?”ø¥ÄO%~+áA /JxR›}Ÿ°?á¸Kx“8ÌŠÐëöü‹ãLö§|nŸ‰0¯7SÕnà”ñÕ5ÿ=ïoÓ~¾í§o9„òôk°ßc¦W{8ý½1ˆË´¯D½´ X¿3'¿÷ò'íÖç+“]¹¼OØŸpÜÅù çÛDÎ/8ŽbaßZ®=Jô*±C‰]JìTb·?”ø¥ÄO%~+áA /Jx²ãÏç$Çw ïa‡Yô:‹=ïæü‚ã(ö¼/Rª§!=åý>ÄÔ¤ÏÀ×ôL½^’>6˜qÙ#¨ŸQ[¯ÿg¨Ÿí[ 'ý±KÁ÷´O°Ÿg¦µl}©©ÑñθóùÈqÇÛœ—r]‚ÈyÇ›ìWùü O¢G‰^%v(±K‰JìV⇿”ø©Äo%<(áE O…÷‰ô'wq~"¼‡If5Öëjö:çcw²ås„|¥­<œÞûA”§oh ~2¦5™÷œ‰ò̘ktºA@Çç÷ÛÁÆ gèøÕ¿í§)}Ly¾7Òö}"ý Ç]œŸpÏu("çÝœ_pÅþ‚÷…èQ¢W‰JìRb§»•ø¡Ä/%~*ñ[ Jx±ãÍç"Çgs>*¼‡IfEêõH{=ŠónÎ/8ŽbÁûbZ[ýüIOyéŒo¾Ayfš>ßšõà4*ANV£~:>ÖñyB·2×óÈéßëû‹qæóãޝ9åz ×ïˆ\¯à¼ŒãOö³|ž7Ñ«Ä%v)±S‰ÝJüPâ—?•ø­„%¼Ø÷ ûŽ»8?á<^x“8Ìj¢×›íõ<®[p~Æq(û[>WÈ_FÇ·t¦¿ò¬azŸ,û– Ÿ­Ç½Ùu.@ùÞ?tœn­‰ö™Õ÷£<}Î9Û÷ ûŽ»8?á<žë]\Ÿ%r=ŠónÎ/8ŽbaßZ¯;”Ø¥ÄN%v+ñC‰_JüTâ·ìøò9ÈñÇÕœrFx“8Ìjª×ííuZ®GqÞÍùÇQì/x_dÞ)ÒYïè}äìhírN×û“9Ï4o9wÿŽzÙŸ·ÒñøKϯ3·êsãŒ+Ÿ'p<Íy'×g¸ŽÉun"×õ¸~ÁyÇ£ìwù|!b‡»”Ø©Än%~(ñK‰ŸJüVƒ}Ÿ°?ḋóÎã¹Þ%¼‡If5Óû0öº7×÷¸ŽÁùÇ¥ìùœ!ŸÙwêz9·^¨ãðµ~(·Únþ#<çôרÿsœÌù$×]¸>Éu|îw ïa‡Yo_)ûܲßÍ}=î_p–ëQœws~Áqû ÞyO$"7ô2´Ï{Ç(pƉÏ3öûsÉõ®Krýžû\Üæù"÷S¹oÄõq®r½ƒó:Ž_ÙOóyDÞÅn%~(ñ«ð>a"ã.ÎO8çz×…¹Â}Fá=Lâ0ëm}žÅ>oÀ}Uîqœë\÷àüŽãXö×|.‘ÿ¼oèôô§Qß¾O¤?ḋóÎã¹ÞÅuaîŸpŸ‘ûñöùAîws_û\§åzçÝœ_pÅþ¾/´ÝJü°ãÃçû{Ž‹9ä: ×#¹nÏý-î ïa‡YoësEö9îws_û\§åzçÝœ_pÅþ¾/ô+ÆEž_ìç9漑ë+\‡äz=÷µ¸ÿËsö9Až;àþ*÷‘¸^ÎuA®pžÇñ,ûm>Ÿì8ðÇ¢å>aÂqç'œÇs½‹ëÂÜ?á>#÷ã…÷0‰ƒ·ÅÃ{^¡Ü5Ï+¯?G¾[úso¼ë®ñ®7t×|Ð[/q×z‰·žè®õDo½Ý]ëíÞ~”»ö£¼ýZwí×zçÜužÁ;ïã®ó>Þy8w‡ó΋ºë¼¨wžÚ]穽÷ Üõ¾÷>Ž»ÞÇñÞWs×ûjÞûœîzŸÓ{ßÙ]ï;{ßp×÷¼ïe¸ë{Þ÷dÜõ=ï{K®úÞ’÷=2w}Låí¹Øï¡‹pý_ºsòÃ=t¶ÑßeöÐ%x1~ÒC—àŒä[B݃™¿ ñÐ=˜±¿×é¡K0Ýôù=tN?GŸ¿óИÖõô݃©ËóBˆK¥Ý²á]Ë¥ýÊ»FûU"gõâ߀kEÞº¹Àõ"wãq»IäÔù¢gsÂÀ-¢oË¡:À­¢wÛÃEÿö¾gwˆ;Öµî{vݸP£Øµ»ÃÀ=bßžy÷ŠûÎÛ®QìÝß?ƒf»d$Šýv̽xxñðâáŎ/^<¼xxñðâáŎ/^<¼xxñðâáŎ/^<¼xxñðâáŎ/^<¼xxñðâáŎ/^<¼xxñðâáŎ/^<¼xxñðâáŎ/^<¼xxñðâáŎ/^<¼xxñðâáŎ/^<¼xxñðâñÿk<ºyßxèäóÌCW ûÝìÿ=t r\æ¡+ãeÝœÇxè¼âUÓC÷ çýº¹ã¡Këdº¹~é¡;ëʺ¹Þï¡+p{ß³=trÌC— ÷-=tr?ÙCwà–Cuâ=t>u‡.Bž‹ñÐÈóJºyŽÌCW Ï÷yèä¹KÝëóÏ÷ÐE¸®E®é¡{p­ìÛzèä¹~Ý|ßÂCw ߃ñи|{‡.ÂeûÆ{è\*늺ùž¥‡î@¾ÿê¡;ð+™§{èüòŠ×Èù²øSÂg~-¾Ãü÷Oýrú_£óû]¶òû ShßkxgÄ«Ç ? ~÷—×ë¸]±ÖWÿ—=ýP?:lÊ鯫ÆtÆVyþvœ¾Tó›^ºÍoüðËíÈïÙb$âÕ;9 é¾Qå‘î—þ°û5ÎL.’f9ë³=åQ>õQ?í¡}´×²_‰?>§ô—þ“òC¾ÈùìwÙª"|÷Oýr‡»ñš[õ‡üyéÁûsÔ3ò¬JEû¾³>Cºç 5 çƒv÷¡~ç~‘ŽK?íäºQÖ}´GYökþoé†ü.»®Õ¼øLó5äwä÷ÿ¢&ê üø7´üøb䉟¾†FÖBùЃúúvyû"i–‰O,p¶§<ʧ>K¸ÓÚG{Å~û> –¿ñNÿ->”“òEþÈ'ù%ßäÌ=gêZõpä;uÀëðìʈ×ОWžÁåÒµžÛj£}¯7!Ý­gê‰&Ÿ?Öó~ò:‹¿èðùáö^à©oíiš÷Ä'‘?䥋Ã&wŽHšußàgtƒ>À1•w"Ì“¯*gšå¬Ïö”Gù–¾§~ÚÑõboØïôÇö¯[Ï+ œþ“òC¾Èù$¿äÛâr®¼òükîB;ÿÓo¡|Ü«Q>æónˆÓ¨«¿ƒ¼áç½ôà¤ÓP¯ÿœ²¨÷Qn;”[× äÈóSI¦ä>Vb¿êýåZÄgàBœñPC›v×¼¥Þz£»Ý»»?Ú_zÒþQÝÑ.¡â ¨ŸpS¨’´ßYnÕq¶§<Ê·ôùúií³ì wØo÷¼è¯å¿ÏɇÅÏÉ—ÅŸròI~É7ùOª–‚ô„Àch7á H'†H|Ö7@þ¸ 5¡ôY?¼B5È4æM”[~@ÜߦÕïÁkäó—×Ý€§Ú‡!ë2ÀçÈ Fþ˜¯‚?ÿ ŃÄäÕàoBÛEÈŸðýÀ¤ËÃüÎ4ËYŸí)ò-}¦S?í¡}´Wì·ü™âsúGé?ù ?ä‹ü‘O‹ßxá;ÄÉÿÄC¢|â€~H'/y˜”[K·{ì>`B—[t\w_}£žÛyC»zx]ðy)ã(eëà—ôgJîc%ö«á+ÇLôwë >£¢^ÒióÁSòóúy>1t øøÕ\ž_4-å¬Ïö”gÉ7ú¨ŸöÐ>Ú+öÛã"úgùâôŸ|òEþÈ'ù%ßä?5÷v´K}ú2ÈI‰› ù“îí§Û _¬å{ù µk£þØwÎA}Ëä[÷7äJ¿krÛûò(Ÿú¨ŸöÐ>ËÞ‡ýöü€ã"úKÿÉù!_ä|’_òMþ§íKÒØ|"ò§6[9Sö¾¢ÛÿÒEÇsD”'­¨rË”ËýmJ¿gÊxÐä<‰óVŽ×9.âó™×å„Ú—j¾jŽ×ü­¾¦ø.Gû´oEzê¯Q>í“Å3ío}Î4Ë­ú!ÒÞtÊ£|ê£~ÚCûh¯ØoÊ<ÓöOƶÿW‹Ÿ:>áËïä|ZüšN¾ÉzÚÝH§7¹qžž{/äL»¤rÓ|¡<µu”Ol‡q…wëyä8Šãg™W*kžÿe~£d\§¤?Sr+‰¯Jñ™¨?ù =®œZÝ@ù´_0ÎVé7VG~úÀͳõ¼ÍNK9ë³=åQ>õQ?í¡}´—ëœ'Ó?úKÿɇÅO¼ðâäÏ⳿ä›üg,î‹tFw=HÿöJ燧zSj|?Lëþ†é÷Lk<ˆ´Ì“L®p=ÇšÇÂ/Žß­q Ïkë:EyjrÒic–¡ÝôKM¤Ó{ÿ€tÆcï ‘­qÍ·EÓRÎúVû§¼ÔdSõÓÚG{-ûýlÿdükÊ¸Âæƒü¯©º¿²ù$¿Ý1ž´ùÏÜrƒÆA_èüõzJFåÆÀé3ôzTÚ’*áÎ8óùÇqÇËœG¾wnÝ`}%ë]JæùÊšßÛ)k\‡´ÕŸÁo¹•د¦½ü8xK÷3ͯ ‚zTæsºÍœ[í2÷]R$-å¬Ïö”gÉ/}ñNý´‡öÑ^®×‰?¶ô—þ“û>XRE9ù³ø wòK¾ÉÖ¦¨—ÕGs3w$évßv„Üôô-@ñôîo”K¿gÊxдæIÐ/ë&×Õ·¸|ôl1q6¹+xàxžã>¿íû`ï7šÏúÏkÞÛÎE~Ö£ “e~€vY{ÞŠ/’–rÖ·Ú8åQ>õ%%ï)bçÝ´WÖiéíý¥ÿäƒü/‹¿'Ÿä7«Oý'ÿÙó?A<²[¿vYsÏA:ó³iº}›h‰ë¤ù¼³Æˆ¯5>FšóF®§¼8~D¾ ¿{ ï ÿdž¯d~£d\§¤?Sr+‰¿Ê¼v¤æ÷ùÓ 'ûÚ‘Ξ´åÙ˦›EÒ×¾â¬oµyZ~ŧ>ê§=–}!boˆÃ~{Ý”þÑ_úÏq‘Åß缄?òiñîäÛâéœÑYH稨—Ý' r²º^§ã§ý0åþ6¥ß3eçwÍó·‹ÀoNG\*gÒ…!Î4ËYŸí)ò©úi×£h¯ØôG9ý£¿ôŸ|ò%×QÏ"ü’oòŸ[ïÎÿ­<Úç3tý[.Ñqœ®ã*Ï7öû[óDà¸W£œëв¡šü”eÝWÉz—’y¾št¯^ÿ‘qJ?ÿ-äË}¬Ä~•m.C½œ”š¨—{w ÊsÍw¦YÎúlOyÒ_õ)§~ÚCûh¯ØoïÐ?Ëßx§ÿäƒü°å}@>s ¬³Û|“ÿÜ?Ò4Ž© sÖGèvæR Üߦô{¦ŒMkž„vÉÏÿŽv²gÊú´É}˜¦þ3ÁKߨòHs41y5Òœ÷r~ÀqŸï¼®s^[òÜ'j\Ž8Ï8ýË"i–[õÃí)ò9¿ ~ÚCûh¯ØOlÿè/ý—y£Íù"r]Øü’o‹”Ïèù äϸîÔËmXÙïsÜì/¬~ùÓsïA>ç…ÉKtÄuD®¯Ë¾“’}@%ûKJÖ}•¬'*™ç+™ß(×)éÏ”ÜÇJìW¹‹oÖü7®Šv3†&˜Î4ËYŸí)ò©úií£½ÜÇä>ý£¿ôßâCøÑóòEþȧÅo¼“o‹V@\fŒ¨rË Üߦô‹¦ŒMkž¹²~`N ƒö²ÞlÊ>ŒÉýÉf“ºÂOî“q`BÛEHs=ÈšÛÛãŽ{ø¼çu>C5CþŒU8«ò*Mö9Ó,g}¶§<Êç¼›ú¹NKû,{CöÓÛ?ú+ëŠ6ä‡|‘?òI~É7ùÏ«7D§¿­ésÆÉz~!~V¿Ž¸r¼Ëy ×G¸nÈõtî3Éþ«Š*?ñ}@%ûJÖÙUêÓ—!_æùJæ7JÆu*GmB=¹•دòî¸ÆlܬÀ™f9ë³=åQ>õÉz›’uhÛ>Ú+öÛûÉ–Êé¯å¿éäƒü/òG>íû@ø&ÿy#z øaZ÷7ÒÒï™24eždÊú)ëj¦¬7›²/cÊþ¤ÙõÀZøÃsýÛãhö¾÷ ¸NÊõ!΋9à8Èzþ£½}´ÎÐü'wÖØ:Ó'å~Ÿ£¿`{Ê£üiŸ|SàÔO{hŸeo¸Ã~SÎ!ØþÑ_úO>Èù"äSžŸ6ß6ÿý\±ï é/Øs~Áy×CÒÂë¡|â¡?µ]WÞ½ÜoíVù ŽCŒÊ~¸’}X•TModÝWÉz—’y¾ÊÚ„ÃaÊ×i^õxBÉ}¬,û!'ï«IñÎ4ËYŸíe¾d˧>ê§=´öŠýö¹ úÇ}4îpÝ”ü/ÎÈ'ùµïƒ€~®Y~è¸èûÛ”~Ï”ñ )ó$3sße:ÙXÏ7ÓbžÊ>Œ)û“¦ìÛ›<Ïõî.9W1æÉWáÒåa:²ÀuS®qžÌùÇEììû`ÍÇþ"iöRŸí)ò-}!Ný´‡öÑ^±Ÿþý+púKÿeýÝæ‡|‘?òI~É·\G…ñ¨7$Üçè¿÷C¸3¾Žûí ï}}”â~@úÜ:ú~vÞÊWüýï”Wúûç‰Js?ᣄû!ÞWÒýPØ? }1ýô•¢€ŽþAûQØ?€Gÿ<þAÇAžÿG÷:ý7úåû{ýƒßéÚ]= œü8ú‡'Ÿä—|ÛüÛã¥GPß1^Òq(/!]Šñ’¶»p¼­ñüuŒ—æxÅ¿ ^ ã%ÔwŒ— Ç1^2å¬/ëŽñÒŸè3úO`¼âô÷ÆK¦“_òmó_8þù°˜ùü.aþ€|Çüùÿáü!Ü©¿˜ùƒrØOJ3qòUÂü!\øG;ëy¥œq:þ|ZÏóiä>ó„Îù4ÊOá|ºÀ©ŸöΧµ½¥˜Oû|”b>íwòMþ¹¾!÷±c}I¯‡œÀúRì<öúü/f})(·4ëKá>_±ëK!’Žw–—b}I9õ³¾äsØôG9ýûëK¦“o›ÿc¯·¢½QúõV”½ó %çI‚ëŸÈçzèÑë­Xw,n½µHºp½U×?z½õ­"ú¨ß±Þï´×±ÞêÿBœþ–°Þ®ùÓëÕ…ë­šß#×[ ÷6éúGï? ÿoì?h?ŽÞÏ%ì? íØ@úèýì³8ötº„ýÊqêsì?„kû’ œöžÀþƒ)üø|9öL'¿ä›üs|{ô~œì;Øûq²O-ûMÅìÇÁ^Ç~üsìÇÁÿáÙzãØ¦þÒ(çJÚƒœ¿±g:åS_1ûqÊi¯e¸ÃŸ’öãÂü½§ù$¿GîÇîOëýÒbö§‘?íåÇQ_Ο”´?ôߨŸFy1ûÓ¨ÿ/îOûEŸÒú»?­ÄŸ§%ìO‡_ñNþŽ·?í8¯z%œ×@½ÔÖM.Åy ðPÂy ”ËùÃâÎk€‡Rœ×PEÒÇ?¯a:õQ?í)ἆrúç8¯âäƒüs^#ÞÉï‘ç5Ž}~ ý™)ûêÅ_òüÏóœÀù%øï8¿„zÅœ_B½cŸ_:TP$}ÜóK Ôçwê§=C^º¨Àio)Î/™N>Ž>¿¤ù;úü’æ›üÿó|ˆ§ã<ÊOÂy> ô{ç<_¸´7E^ˆSþ œçSœçù|Úÿ‹|N>J8Ïîä÷Èó|Óö%¡Üq¾(ã:Sú3û¼¦ã|+Êç[¡¿÷=žþç[¼Nç[‘ÿ7η²}SåS_1ç[Cœö¾5¿…OûSÚó­šž&%œoE»bÎ{ƒïbÎ{Cþ„êøÆ…ó¼7ÊKqÞ|sÞéÎ{ƒ7™7wÞ;Ü™vœ÷ö;ÛŸÄóÞñN>Èωž÷v¼ÿþŠyÿéÞ€^¾PÂûàé¼ÿ œò,ù!N}Ô_Âû!Ly¯ÑùþCˆ“c¿ÿ çŽ÷Âüsýœë†Ž÷´¼£ßBú$¼¤ù‘÷uþ…÷ÂíïùEŸrê?þû@Ë‹øG‹y¨_Ž÷Èo¼ðíwò/ûöûZ%¼‡üÞC|ÿÁûq(·Æ-àÇñ~ÒżÞïÇùœåŽ÷ãŠÈ£|¾WÂûqNûMyÏ=è_¸ø«œþó~œßÉŸãý8¿“oò_Âû¢ÐWø¾è·š'8ÞE¹ã}QÄû¼/ ¾Jñ¾(xK¸)4Ä™v¼/Z¤ýI|_4ÄÉGáû¢š/òG>õ¾è ¼?üc¿?}ðøïOë÷“ÿÅ÷§ÃéxÚ'úýN{ïO›ûÿÎûÓ¦ðâ䳘÷§QîøžøòçaÔw|Oq+æ{°Ëñ=à¿ð=ð ë%}Orßð;ËYßñ=Ó)ßñ=å´§˜ï Ä;üq~OÀïôÿo|OÀ'üCŽãû(ç÷ú ShWÂ÷5Pï_ø¾ê9¾¯>‹ù¾ê9¾¯yýg&‡8ÓŽïk„8Û—ð}§=Žïk(‡ýÎïkñ÷¾¯¢ùÕß/)ü¾†æßñ½ä;¾7ä:£ã{3¨ÿïoFÏûß›Ašëç¥øÞŒé,w|oF‰Úù│ûÿø}87gvÙƒëÎì:&én¾HÔïv^{¤»®~|v}ö`—6ú{:ñuôyÏ÷Ö E~§þ‘ßnÅN`l¾~®FOš9ÞlŽü:µSÎ8HZI¹’úJÚ+‘§,ùàIô)K?Ú‹=JìS–½H[ö‡µ?JüSâ¯ÿ•ÅPøQ—²øCZøT¿/|+òÿ⣠Àk³šëÀcÜáŠà÷zÝªË 5ÀÏ_Fú£÷ôý׫ÂψWŸ+õ9¨¾óV£^¿A^ÿ¡ú»ýs; ^ÿÚ¡]¿æ{!§o¹8¤{_Uõz|Ý r><ó_³ëoa¨÷þÕkn¿¸6Ê[]¤÷½ÂÄz™I+«|XõÁŸ´W–< %ù¢O‰~eÙÞ,ûoÙ‹tÿÜŽ/þ(Ë?´•ø¯„%ü(áK JøT¿¨/|+ò_7m&økµ[¿/ôÎæáo·;²ýàç*}n§ÏT=OðÖ"ÔtÍ]ÀÁcê!È}þ`è€÷ÑnXùçÀ×°KõºÊÐú½Ó¡w·ÐõX9{îGùÀg.‚=ýæõöj;õºç༩?²õÚµ~é&~ìCÛq´’r%õ•Õþ‹<%ò•èS¢_Yö-ûÀ¿Ø«Ä~eùƒú⟕ø¯„%ü(‹/èþ”ð©„_%|+òÿú_z_»­_ï³vYúüíÑK÷ãýÖå!ƒ^‰DùƒÁïð;u¿5²¾áhŽê¥Ÿs£-F»1×mEù˜Çüà{ôÞžH®~ê\Ÿ y#j|¤ãuÙL´œ¦×ÍìÁ{ÎfïÙûÝq,Ôz.fÞŒ>pØtÆÁJÃÏw3kÀo«>ø´ÚƒO‘§D¾}Jô+±G‰}JìUb¿”åPüUâ¿>”ÅŽ‹æK JøT¿'|+ò1"1ØÎìdü ^º'N}¿| ùƒf6ÃÎ ›#£v£|Ì g£|\ÌZðâ¿t êùó«"pþðŸp½îÇýßî‚>üöŸ9¾ñS¨?¶A$â3jÕ%¨7|óÀ!=:A΀Õ)Ósî™h×¥y`ëþáÎ8HZI¹’úJÚ+‘§D¾}ÊÒ~Ä%ö)Ë^ Ø¯Ä%þ)ñW‰ÿJøP?@‹/Èþ”ð©„_%|+òßx|"üí<÷ðÔ³Að2°í½ðè÷ÃïQçWEùØ÷#þøó‘NX‰u3qs]¤'ŒÕç “*¶F~Ò¥#€Ö?€vžzü'FÆêxÝ};ÒãÛâÜ»9úO½6¢*ö1ÍÁŸúýîÔó£¢ôýÓfÈG¬þpÈð$åʪl§¤½²äK>Ò¢O‰~%ö(±O‰½JìWâÿ”ø«Äeñy¾”ð§„O%ü*á[‘ÿ¦‚‡.ƒ!ÝçWSûÿÝð7òüJð{ì"=M(¯Ïã$®¯ùŽÈE:yÐÏÀ‰QxÄœ¸Y?—&þv¶Ngèõ‘‰•Véú"R†éxüªßÿdzÀÑ﯇þaý—!>ö›Íêè}âöô2q´’r%õ•´W"OYò‘/ú”èWb²ì_–½¨'ö+ñG‰JüUâ¿>”ð£„/eñ½Â§²ø…^á[‘ÿæQ2ÎÌzþ Õûà BzÌeÍQîÏÒó… çêó³ÉW&kÞWés)·nG¼R/Ç935ùQð™jÖ×é˜;!'%+8©ÿƒh7ñt½_’tÍä'ìÃz›9nÉÏH|JŸ\÷e¤{]£Ç`ŸÊŽC§º?•reÕ/Ò^‰<%ò•èS¢_Yö ^bŸ{•د,4jÿ”ø«,ÿÑNøP¾”ð§„O%ü*‹o”“ÿ×Ý?»êo÷êçÒˆ´YÈ_ñ~ð’ØR¯W%WÎÖ<Ö~ü¥Þ£ß+ž<½1ò§ä}‰öiÏ¥"ö¶Þ×K;çOäO©Ùr'ûžÔqyq%äN|H¯“M˜ìH(³ rGï’÷*꽎8÷Y“ƒô{¬ qÆÁJ¥\I}%í•ÈS–|ð ú”èWbû”e/Ú‰ýJüQ⟕ø¯,>~”ð¥„?5"MŸ/~•ð­ÈÌ\=?þ(CGÔþŽÚúøóïÌD:é‚ðâ!=OmœÒQ[§ž§ÇIÓîÕýé´ÕOjüeƒÆá@ÎÔýÝš´Wä|îû_œä~ß{̃¼qQúû8Ãùõû·Òû^ïgõ wÆAÒJÊ•ÔWã¢ôû"O‰|eé¢_‰=JìS–½#ö+ñG‰Êò(þ«Ôæzœ ü(áKYü¡\øT¯¾ùo¢Ï öì£Ï­²üŽùk“æãA=HN9„ü”ü—5ÿM?SÇã=Pszð(ú•Ø£Ä>%ö*Ë~´KOÐë"–È·üŠÿJøP?@áK JøT¯¾ù}v6üëýìø;,þø?îwý\žÐ)8éýÞèä–g¡|ê“ú¹4}R”æÙü•Å/âbñä_‘ÿ¸Èo‚ùfŸƒßákÒÀÿíþÈOJ~õRzÜŠü´r¿§ŸQõÓçÍ×üÎ9qÍŒMѸâcägîö™ÓÊëü«·3žë9é·5NÖq˜\gÒý¨—8H??Ç4ÕãâÁwîC»5À9;VþK¹’úJÚ+‘§D¾}Jô+±G‰}JìUb¿”ø§,¡Çò_Ç㌲È~TJ­WøS§¾f*Ò·"ÿmš·ƒ¿ýÚh>G^¢Ï[&¨—µTŸOÏک㕪ßÿʺP?¿2ïÕqÉ8m%äL¿æjÄaJN&옴t>ÚMèý1pìö2¨?äî¨÷Á[‡;ã`¥Á‹U´ê¥½yJä+ѧD¿{”اÄ^%ö+ñGe5ï­ã•žŠ´ø¯,>Pßâò,¾€È·ø„^áW ߊü·}M¿ßÒÍPø7J=žÏÅ{gæÄÃÀó¾ŸfN[¡Çõçíï™íõ~TVïqh—ý|YŸèïyd/þNcÿz“õóK:.g¾ŽüŒoêë¸>Ù åi¿ÕF~ ^³´îÇVz|6þQô«æÐ+õ}ÒýùfÊI+)WV}¤¥½²äw‘¯ÒŸ”s²Z¿{TÖÏ/‚W±W‰ýÊòÇÔþ)ñW‰ÿJøP?Ð#|)áO ŸJøU·"ÿíî¬ÿôký´^ÏLüRÏ—&×çÂÓÎÅ{Ofúi-4sžÖ|ÞÌ®]<æ\¦Ûåôí¨ÓICnN¸Þ§Êž­Ï%f}•†z™\žÓ÷ëógÓBôõ‘ºcÚ'«¨çWº?ú ÎIš^75ÜI+)WR_I{%ò”%_ÇAëS¢_‰=JìSb¯û•ø£Ä?%þ*ñ_ JøQ—þ”ð©„_%|+òßîûàgàåúüñ˜ûõþ„2žl‘ü©õs9}°~ÿ7óuý¾EÖš|ð–S®’æyY3ˆ¹O=„ö¹áŸC^î%†.o§ûçìŽ×£]Öµ1:®]BÓ¯Ûz“ç7Ayò¯x/Èô/Òýø°] ÿÃxß¿0;õ>µU”úJÚ+‘§D¾}Jô+±Gå´[Œr±W‰ýJüQ⟕ø¯,>/ü(áK Êâ(ü*á[‘ÿöcÁ¿cô:ÄØÓ»‚‡ ž¾R¯Ôãù©ë"?ã,½_–¹­!ÚeG_¨ùû½æ»>·“»¿äϨ€qž™;ënÔË=_ïûäT½XÇ!sêg–}õÒ+>}SúnN­Ÿc OÍB<†¿©Ï¿}4à¿3VþI¹’úJÚ+Kx´äEŸýJìQ–}šm¯û•ø£Ä?%þ*ñ_ JøQ—þ”ð©„_eñ yä¿Ã­/¿A§ëùÙØ™§¤öúœê'À×´Á¡^FÛQžUO¾³¸ëGÍûU!:aþcÎèø‰ŽÃ 4>¦Ëṵ̈̀UÇñæJ:®­¢NoV é´{ëAÿ¤kõx !+VÇa¿oõ⌃•J¹’úJÚ+KüùJô)ѯÄ%ö)Ë^Èû•åòÅ?%þ*ñ_ JøQ—þ”ð©,~·"ÿ’ôï Šx|Ž{V÷2iÝ÷àeòƒÕàÿôf,ŒF~Ö ýû9/èóO¹ý+ ÝŒ=Ïž±ÿAäçUŒ×q™¹@çŸùôäüö§Žc?œ'23ê}ðô¼Ãà=m6ÞK7' Çû%fâ= D£qÀß/‡áÏ¥\I}%í•ÈS"_‰>%ú•Ø£fœY[£¶W‰ýJüQ⟕ø¯„%ü(áKYüA¾ð©Æ=ûÒß('ÿË< MÌ@zܧú¼eòM™:cõ{ÀÓÇF½Ì*xoÌÌ.óžæÓÿ4êån»Móý…ÞÇÌ{BÏò"ôùÁ¼óô9Ð _D:÷¹ŸQ/{֧ͬs«ÓÑ÷ÕÔ[3`ǤCï ø|ìÐãˆ?\í/‡®R®¤¾’öJä)‘¯DŸ²ôûÁ«¶GYöÅ^%ö+ñG‰JüU⿲ø€|‹è¾”ð§„O%ü*á[‘ÿŽ•ƒƒV·ޝŠïI™ÉnÏ“·] Þ¦¯¯ß̇å»÷nBûœ5º¿žq壚÷Óôûíy=êétâ#h—÷²×Îðç }nOÍoNµî¨—õØOПq­ÌëÞÑï+¥Üþ:0ñ}9ïYæÈëyïÇ!Î8Xi ”+©¯¤½y*ãÚf(·ô!^¢_‰=ʲí,{Q.ö+ñG‰JüU–ÿ:žš%ü(áK JøT¯¾ùï}=üôSð2¾æYÀäî8çiN©² õÒ«á}3³Á\‡ºzý4ç}žgF­ršï[ßÑ8]?÷òè÷¹óÞ©¥ã5¹Sõù—œ{Ê ^V£Á›¡’u&7¦ÔÕïs$ŽÙŒz#ol‡¸õ|ç ã ÓJÊ•ÔWV{ø?u²Þ_ùJô)ѯÄ%ö)±WYö£\üQ⟕ø¯„%ü(‹/ ð§„O%ü*á[‘ÿŽr¾h°OïËŒ—sÉÞ‡ßSª_¿Óeß3SöѲ#亖ýƒzÝ×Ì“uÓ×qìþAŸÃ8vÿ ×õDŸýÅõš÷£û”‹¿Jüwö(/¡@;á»°øûã%Ô³Æ hgPÏOèx<ÑOóqÚ9ÆKH;ÆKˆc ã%”[ãèµÆC_Âx ~J}%íOd¼„´c¼¤ã¡ýQ⟕øï/Ao ã%ÄcÐÄt ù?zþ€ñmIóÔwÌÀS1óä[ão`áüãóâæ_Šùê—0€%ÌÀ‡è+aþ ×³Åþ’æã˜? ß13’ÿŖQþ7æÓÿýù4Ò%̧ƒåÿd>¾µ½Îù4°óièu̧Gϧõ÷òÈ¿c} |{}éÒÇ__Òß8õ%ð›Yö c} õþÅõ%ÄCä+ѧDÿ ¬/Á¿âÖ— ·p} |•z}©˜õV¤e}ð﬷jÞ ×[uúﯷ¢¾c½(ë«vJXo…ÿ¥_oÕû£ŽõVÍáz+ÒŬ·"ÿèõÖ,Ès¬·¢Þ‘ë­Åì?€ãï?ès‘…ûúxáþƒ>™“$ó„Þø åÉê6{ÿá ä{ÿåÅì?@žù'²ÿ€|ñ§„ý}.³ûÈ?rÿáøûqšGÇ~êeœ·Ã'¼÷¢Æ£öãô¼£„ý8ÔsìljC)öãP¯ôûqú÷³ûq½”ýÊ’öãüA¯ó¥9¯¡ã¡Ï+8Ïkhž>¯3¯Þ†òŒçðý°bÎkà}µày Ôwœ×€<Çy Ó‡bÎk í8¯üRœ×¿boqç54ÿÚßҜ׀žÂó8<¯úäÿ?8¿¤qüë{~I¯G}~I¯÷•þü’^ßûç—tÚ>¿¤o¨˜óKç—P~äù¥pžåŽó|¨WÌy>GŸçC:mÐf¤å|ó<Úù#ñ™¿qžõKsž|ˆ=Îó|:>öy>Ý^ü+é<äsžåÇ:Ïç8ß ÿŠ9ß ¾“.h€z…ç[±Žå<ߊrÇùV”OûE¿Ï çEƒç[i¯èqÓä÷ñ]PçùVÈ/æ|+ÊOà|+â"íç[Q_ô)ѯÄ%ö)9«ÄþRœoÕólÇùV”s¾é#Ï·:Î{#]xÞ[?¶„óÞÀÎ{#žioë÷ã Ï{·€œÉ>ý]GÇyo¤KqÞrJ8ï K8ï´è+æ¼7ìSboIç½ÑÞòzÿéyïÿðý”Ÿ¼÷4_V9ø9öû½‘.áýÄOìu¾ÿÞŠyÿzKñþÒŽ÷PŸüŸ„÷4¾9G¿¤÷Û&¤ ƒœSø>ø{”اÄ^%ö;ßBù ¼„x9ÞBþ‘ï9ÞƒŸ=ôïÛÞ †~¯¿O6ê|½¾úÞÓøÔ›àµ„÷ã §ïÇ…8ãPÌûqàÑñ~Ðñ~œŽÇÝwhÿ½÷ã.æý8ä ¿Jø¶ß+æ}Qøíx_ùŽ÷E‘ÿ7ÞE{Çû¢@y_3ø¾(ø¾ùà‰¿/ªûIÇû¢àÁj|Çû¢àAô)y_U‰=¥y_Tãß_úŽ|_ôo¼?vG¿?½XŠ÷§Ñ¾ôïO€Üîê~Åñþt¼3ÿâûÓhWÂûÓÐóÞŸFý#ߟ.á{È/Å÷À³ã{à[Þ¿/î{H~O@÷¤„ï .Å|OÀ¤ÿÆ÷ôwMßÐXø=ÄÁñ=Íwá÷P^Ì÷PÞãªë>Þ÷Šù¾ü§Ç@à?ø¾†Xø} Ô“ïW÷} ÄåÃs磼˜ïk -ßÏ~_£HþÆ÷5ÀŸãûsô÷5`¿”ø÷w¾¯zÇú¾F1ß›Ÿ%|oFóSø½`1ß›AZ¾×bÊ÷[‚ß›A\ŠùÞ Òò=˜Ò|o&܇b¾7¬öÈ/á{3àÛñ½ðYÌ÷f Çñ½´s|oõ„ç÷f>Þ÷f¼ï/¹âûK*okå¡ p~ßÌÃSC/-ðÐXKgÓÃS‹36éßñðã›ú;(žZÌýü~Ý€Õp ÄÃSŒ9Ïèó€žZÌŽnãóðÔcV}ÞÙÃS‹™1×(O=fÔÖ¿Çâá©Åôkêy蜺 Óïá©Ç)7ësúžZLi…ßòðcòhýÞ˜‡§Óõïçyxjq|#ýpO-Ž|¬\ˆ‡§ŸÑ¬ÀÃS=;ö5=<õØñÃß•‡§½îøgZññðÔcO9÷èá©Eé¯=<Åh_}žz´æsážz”õ O1&ÖßýòðÔ¢¬{xŠQöƒ<<Å(û£žb”óžb̨½6ÞÃS™1ׄxxêQÎWzxŠQÎ{xŠQÎß{xŠ1·ÚŸ‡.@ý~–‡§g¼9°ÀC ~×ÃSŒyµþ ñÐ8ô2Ÿ‡.@ý½O5êïÿxxjÑç+_Öç+{Øúã,ë?ëïJÁïo–ÓùåƒùÕt¾ï/뿪(+ï þ&K™ü£#ÿ褫•­âóU6àÄëB¬Œü]ªh<7¢ ˆ|¼òûÍîŒtŸ§ð©ùüž 0„Ëÿ°ìAÓò»>ûZ|ßü.°Í×£¼IüT^~ÍKÎÊ mP?ÝóöÙÁüÐIHÇ×I Ê ýàŽ%Aý¡}rYPNh¯‚IA9¡}‡Þ‹zýE£Þ€À¯H¬½\㘠f”|Öc;Ê¡\ê¡^ÚA»h§ØM?l¿è'ý&ä…<‘7òH^ɳͻŽC ½ÉÎàc-ƒþ¦rÒӚĴ¡ø´|`òÓøIûÀ¤‚zIqßõÊà'£ú ê š¼í>øöÈ _:&Xßèx×9À¾wΖÃRðÓ Æ¸Wñ“­Fâ\|úИxÖ:`Êo‚í)/E½©ýnBzú•ø©'#ýâŽh—þæEQòYí(‡r©‡zií¢b7ý°ý¢Ÿô›<òDÞÈ#y%Ïäq0ß|õ̇ €É ÿÓWÏC:ÿë!wfè3ˆßŒnfGݽé¿à“xÉñø‰¸@b‚õ‡ì¸ØjÁgð¯çµ¸NŒ±W7Azâ˜lð0íÉø9Ÿæ5rË>¾òöã'ÍŒOb’Q>«óø #pÎXÈ1Ï)ƒzæ+øÉ†B”|Öc;Ê¡\ê¡^ÚA»h§ØM?l¿è'ý&ä…<‘7òH^É3ygæ·Ç§Qók‹ôSð)ÍÀ¼i#ÿó—V!ýÙèŸÐ~öàÔû´ë!ÈÿøMü´d ë›Ó‘?e5>%ö1°ãEýà÷ …¸žŒä/ÂÏô“âÁKâ ðöÉáW5¿q÷¿9 c€s»¤ƒŸyg@½/îÇOEóË¿…ôü·ËûŠ ä³ÛQåRõÒÚE;ÅnúaûE?é7y /䉼‘GòJžÉ;ã°ø¡è[|ñl¤¿iºå__„Ÿx|õt à—®+€œÚŸBß܇uÜÍå&äÎ|r/Ò™W£~ÒÌû‘ŽŸˆOI#ý>ÒvÜ€tn‹[á÷§•Ê"=gðÓàãóeø$²1?? g,¼G±E*ñüzñKóÍÆNÈ_|¦`62ŸõØŽr(—z¨—vÐ.Ú)vÓÛ/úI¿Éy!Oä<’WòLÞ‡å7á§ Ë}¸N˺lA½¥ÑÀ%ƒêú7¾ ù_ýú4ê/¸v)ÊçîÂ'ÿfÁÈÏý~òSŸÃަãykŒû?…bd|ÿ(ÒŸ¬¿ |Í™´|}Qí-”/¬¾ü|û$ê-Þ± <.½¹ê/»:<.[¨ŸûËCBŠ óYí(‡r©‡zií¢b7ý°ý¢Ÿô›<òDÞÈ#y%ÏäqX­ïïÀª%øi…Àª‡ž®|ôtÈY¾ÿÝÞÀO`–(üU`ÑwÛ!gþŽÞÈÿ¬õóÉ+øtw`Úä0Ô둈Ÿ¬4ãÎÊ1rÂ"mÛæÝ‡ŸÔ3¾s‹æÿZý|[úÔ$¿æy3øY1¡3Ú¯\xÚ¯„ç…±êçYEPòYí(‡r©‡zií¢b7ý°ý¢Ÿô›<òDÞÈ#y%ÏäqX7×Dýu½!íúšH¯™u¿®w>9XùHeèYöÝ@ïBú«/ è÷î÷@`To`ÆÌßç‹à_òˇy3°`|vÛƒðwA:~º×øfÞ9àséü”€±â|òÝXõø”¯)ÿpmý‘àoÝ#)¨¿.÷Ú"(ù¬Çv”C¹ÔC½´ƒvÑN±›~Ø~ÑOúMÈ y"o䑼’gòÎ8l’çØ¦kwAïÆð_ wÃe¯×½ŸH ¬¹ùY´[Ù¿=ä.ò5ò?±¸ z pö&üw »òTà€K1¾3RB0¾0>ùáNøÿyFü_tVOð¶äçÏÁçŠêWíþ ¸¶ö ¨·þ™\´Ûð5~‚ÅØ¸løÚT?©`#óYí(‡r©‡zií¢b7ý°ý¢Ÿô›<òDÞÈ#y%ÏäqØÜ¶‚Æ_F ¶à'6·EévooÑò~?åkΛ€üs¿@»¥7GùW~‹ø~¶Ÿpä>}&ÒwêñÊä¥U—@µÑÀùÕç!ñu·#NË~¥ùêXéµCñ„Ɔš5ïmv€·‚¯·ÍWéyÍæ·WAÉg=¶£Ê¥ê¥´‹vŠÝôÃö‹~Òoò@^Èy#ä•<“wÆa«î÷[~בּ[G]oV¢n7óÌÀƩ͠wÝûÑ»jÃZ”/[õ#Ò_ÿùðóùºSžÖ?APޱøõðwÅnüô´±îÒ3¿i­'m©4 ¸um{àöz_¡|Ç;Q¨¿S}ˆö;'`|Yˆ’ÏzlG9”K=ÔK;hí»é‡íý¤ßä¼'òFÉ+y&ïŒÃn= ìZ|ôìºëŸÛ§AÞö¯†Cþ¶ÊøÄK`ó/ëPÓ£!Í¡7 où#ç£ü«ŽÚŽÀ·# gd*~úØÈº¿R°¾1ï1½Ž±ä‰Ÿ¿êšíÀõ~¯‚%û‘ÞZy3pÛϳ5¿½:£|ç§zþ½«ß¤pàÏ£üEPòYí(‡r©‡zií¢b7ý°ý¢Ÿô›<òDÞÈ#y%ÏäqØóð”ï9M?Çv7Âü4°«ÎbäïØXú·Ÿ>ù[Ö¾ƒzo\…öëî-ƒü~2&°hãB¤ÍÙ/ ý¨½w€—ì_„_¼^/h·±4d7ø[ýDüßxÚÄksòÀ­œúÛÿúSÇ!¹£æ{×ð½{Î÷³çŽ3M'2ŸõØŽr(—z¨—vÐ.Ú)vÓÛ/úI¿Éy!Oä<’WòLÞ‡½2.Þ{µ®·§ƒì~CëÙ¹jâ½ýÀM·5?­Ø|¶ 9ëßÂOPV^¯Ÿ“ß\³ífw¸ é1甇¿9ôüj~ƒ—µß;ðÓÀÆšÛ#Ó Ÿ€¯-‘°Ïض?eiì8ˆëÏØ5i¨ŽÃ/±àkÏzý¼Ùû<~bËFæ³ÛQåRõÒÚE;ÅnúaûE?é7y /䉼‘GòJžÉ;ã°ï-ýÛwucÈÙÛú´ßóì}HïÊÓãµùÓÛ"Bîæô·Q¾¡ù:?ï.¾?˜sYôŒ½¸6üÍYˆŸö3¨Lø¹lĤ×êëÂ(x褷ž{åÛGéõî_œžv÷×Ï›=ûËé8¬ÁOû^¼X9‘ù¬Çv”C¹ÔC½´ƒvÑN±›~Ø~ÑOúMÈ y"o䑼’gòÎ8ì×ó¤Àþ oêø,S~ßÐýîÞÏU8øÏûéýwé~‚È|Öc;Ê¡\ê¡^ÚA»h§ØM?l¿è'ý&ä…<‘7òH^É3ygèçg`ÿ|}ß쯌Ÿˆì]Y í÷Ü4ù»ÎÁOÞ¶ÂþN`Ëǯ¡|ÓUùÀÕ/l.¹`Úvó¯!ðcÑ•àaÆ9™ø©.c¹oë¾Øÿ7߆Ÿà2¶Ý®ûå¾Cþî›oB½½U°gì‹BÇ¡Ó:¿\]%ŸõØŽr(—z¨—vÐ.Ú)vÓÛ/úI¿Éy!Oä<’WòLÞ‡2<}@Ç)­¿Ž_LÄ}ÏLü¤s`×Ðeh·£Ò{Èߢ×57}ýŒ¶kÅ:m§Ìû?ŠŸÆ Œo§Ÿ3¬G\>;ü\q;~¢ÍXáCùæ¾UÛÆ¯;|‹ú»sV÷NHCùþêúùwಡñÀ±EÉg=¶£Ê¥ê¥´‹vŠÝôÃö‹~Òoò@^Èy#ä•<“wÆáàz_øÀ·gè¸ÜÚ é}{ö!½÷¶Í¿Û7ù;¢nAzkŽD nÑýÛšG2`ßs)ä¶g"òÇÆO3~®Ξ±¢~*ÞX¿þø½yÍã:¿6EþÎÙz_bϵxÎû.Ü??em¯ûÛƒWÝ¥œÈ|Öc;Ê¡\ê¡^ÚA»h§ØM?l¿è'ý&ä…<‘7òH^É3ygêõƒÀÁ—Gê8õëýûŸøEÇãÃ×€»_ªˆüO!½5óÔ/õîAz]gɯxæÊþŠÿ.ܯFÞcÏÂï¯.Ç~¥±b‰^÷ÞðÀð˹ÙHoÝÄ]g}z{:âz4öµ»åû×ûãË`=Î8øaxQ”|Öc;Ê¡\ê¡^ÚA»h§ØM?l¿è'ý&ä…<‘7òH^É3y·ã ç©ƒÃïÒõ¾i‡xïÿPëßk®Óqþp5â·có‡áл¾"ò ºUFzÍ‚:(_‚Ÿ„Ì}eòý¯LÔ~µß‚¸|õÚ¦ ^c¥ïEð±¡ý=:\üíÍq½»Ô!Ôß“± åû2Àóg¡üà£z¾vpAcU%ŸõØŽr(—z¨—vÐ.Ú)vÓÛ/úI¿Éy!Oä<’WòLÞí8È:ËÁ<=o?pHï¯ìOn‚ü½å¾Køå;~Í€][¿-£í¢Ÿ“k¶ Ðñ¸ëyàÜ·Ïúõ9#oà'ÚÏöK}ðûB|*ÎØ0ìäoyö-ð³=>ù»ê÷Gþž¯/Ô¼.þVó\ x;Øx‘ŽËžŸÍ"(ù¬Çv”C¹ÔC½´ƒvÑN±›~Ø~ÑOúMÈ y"o䑼’gònÇÁ‹‡»âá=¯”ÓŽSþ¼òúó"vœòþÜïšN;Nõx×›ºk>è­—¸k½Ä[Ot×z¢·Þî®õvo?Ê]ûQÞ~­»ök½ó î:Ïà÷q×yï<œ»ÎÃyçEÝu^Ô;Oí®óÔÞûîzßÀ{Ç]ïãx﫹ë}5ï}Nw½Ïé½ïì®÷½ï¸ë{Þ÷2Üõ½ ï{2îúžŒ÷½%W}oÉû™»¾Göñ£í¿†œ†Upæ·Þug0~ù:c}9¿KíÇQ¿ûeÙH÷è‡ýæüÞ#Ö›ÐS£Ê\§õíŹüÑ¡¨7pÂ2­wàã;ðî°gÀ€«‘ßÿ¬¿å÷ùûoù½®| é7…ünŒEýÎ MQ¿ÝÃKÍÿÄzm~í SÁ#QòC¥^¨´ 9¡"7Tô„ŠÞP±#Tì ;CÅîPñ#Tü ?CÅïPá!Tx žB…·Pá1Tx žC…÷ì8h?ñ_ô ê HÒëZ#Æ­ Ê ø/ú!('0aœ^'›¸ôÞ`û@jrê¥U'hO`êáªAyé±¹—~‡ÞHo€Üô:ñh?ý÷š¨?mÁyHO=óƒÀä¸n)OÎ&?š½ ÛŸEû1íõù¥!i­ ·çùxþZ-Öór¢äRÏv†È1D®!z Ñkˆ†Øeˆ†Ømˆ†øeˆŸ†øm†ðbO†ðf†ðjφð*qÈ­¢ÏÅ øt&øõî?SnoéUßYCâÁSî¼{ÀÇÇ#j Ý' BýYŸÞ‚zæ QÏ|=DãÓ{ '°§ðÓ¼­ÀYqf®‰G½¼‡¾æÜÿäg¬Û yiÍ‘NJ=#O×ëJ–?¦ø”|CêÒÎ9†È5D!z ±Ã» ±Ó» ñÿ ñÓ¿ áÁ^ áÉÞ áÑ^ áÙÞC%ùôýô<¤,kƒtæ5áo^¹ˆË¬Çþ/³+L~v¥GÏÝ÷ÚÍ{ ãËÀmþ@zþõ#Po~›Éh?¿>Îi¾X‹õ¼À¼Ÿô8ïó ½ž=÷mÇœêåÑ>·NÇ)³.òsùÓVa}<˜3õx?%ßz†´3DŽ!r Ñcˆ^Cì0Ä.Cì4ÄnCü0Ä/Cü4ÄoCx0„Cx2„7Cx4„WCx6„÷P‰C~ý Þà7½ƒ¼å½©à`C,üÿìíW‘?oX=ð· a#¤~–^¥¿ü&ää/®8ñXüÀ,ÈY|ƒÞùfö'_wx øÕ‚;Pþe‚^¯çeÏÏÄOfçÖæß‚ñl »ÝÝHóºá}O¤ŸRÏv†È1D®!z Ñkˆ†Øeˆ†Ømˆ†øeˆŸ†øm†ðbO†ðf†ðjφð*qÈÿP÷{Áç€ßéï§Aþg_n…ßó¯À:h૳ ”Ócø\òð&´[ÚJŸZöÊ«H/ÛÕéå7œ‡ôòsõüsY*æÃ¥û1~ ,Ù\ ñ]Ü ç9‹ÖéþãËkõþÿ<ßÔ›ó:ß~vð>a?Aä}!õ igˆCä¢Ç½†Øaˆ]†ØiˆÝ†øaˆ_†øiˆß†ð`/†ðdo†ðh¯öõ"¼‡Jò{éþ>Ø_ãfßs*â|Fà‹AŸ¯f.?‹s°X:Ÿ,,ï‰s²?]‡v«*s€¿ÕeîC½U;õOÙ?ù< ßÒÎ9†È5D!z ±Ã» ±Ó» ñÿ ñÓ¿ áÁ^ áÉÞ áÑ^íûDx•8ä÷ÓãÁ` ù\ ÿ Õàcñè%àiÙK1šÇœÕˆãªOƒ÷5_†œµãôyÔuQ ¨·nöÅ:=A_çëÎí¹kÏÖçÌVÓû–+ç5Þåýâ¿ÔwÚýì5ˆßü‹>Eš÷ ûŽŸˆì/x_H;Cä"×=†è5ÄCì2ÄNCì6ÄCü2ÄOCü6„Cx1„'Cx3„GûúàsTx•8äÔãb{Åþ‚÷Å×KS€KçÏÑqXó æ±¯^÷\»®Òëg,Bzã¥ú¼Ë&ß:ðµ©Îi6Õü éãt6t¼ùëVëqÚš9Õ‘¿ÊÐë§Ëd¡þ’«°g_|~rœÁq$‘ý&ŸäAä"×=†è5ÄCì2ÄNCì6ÄCü2ÄOCü6„Cx1„'Cx3„Gû>a"¼‡Jòëy’5®Ôï°ÿäs‚|,ß|éÕOŸŸ=S×uÏ!½iÿÙÁ@ òŸ‡¼ÍåkŒý¼nǺv`sù_u½†• oãú½”õ‰z\°fõÔ[™ ÇÛË*—C{Þ'ìO8î⼂Èqû Þ"ǹ†è1D¯!vb—!vb·!~â—!~â·!<‹!<›}=ð¹Éñ…ð*qȪçÖüâ}øÉqû Þ+·_¾Ö&<‡ô†ýÝ.xûŸÍño‚Ç-¯Ý y[¶íï[¯¼õ¶ž¥×Ѷ`ûΪÿÓCÐSð Î 6E>9ëëêó«×B>¯>/9®àø›ó-"Ç—ìGù¼ /"×=†è5ÄCì2ÄNCì6ÄCü2ÄOCü6„Cx1„'Cx³ïö'w üazý 8ÿ‚g²?åsƒü¬_ßGÇá¾Ò›gž¶ü¼õ·nÁû{mîCù¶Oú#[²>·¿íkQkûžˆ×–Æ!s9¬ÿ6æÞ ùk·õC=Þ'ìO8îâü„óm"çG±¿à}!r Ñcˆ^Cì0Ä.Cì4ÄnCü0Ä/Cü4ÄoCx0„Cx²ãÏç$Çw üz%8œ_pÅþ‚÷ÅÆ_[ê84¦y­ô.øÛÖà1”o¯× ‘þ„ã.ÎO8çz×g‰\â¼›ó Ž£Ø_Ø÷…Ökˆ†Øeˆ†Ømˆ†øeˆŸ†ømv|ùäxãjÎ?¹N#¼‡JòÇéuûà:-xåzçÝœ_XãÄýï‹Môzàî s 4ÿóÁïÞr=¿÷µ™ÈߪÏS9»§=z»jîõ;ãÊçÇ OsÞÉõ®cr›Èu=®_pžÆñ(û]>_È£Øaˆ]†ØiˆÝ†øaˆ_†øiˆß†ðPxŸH"¼ÙóÎã¹Þ%¼‡JòÇ?3þΪx'üãúÞŠgt¿kÍ“Ïq)û_>gÈçîo±ßØ{'ÎÕö•Ñïõîkð´Æ°¶:N):¿:Ò»¯o´ïéO¬ñôXóäs¿d³¾>¸.Ì} "×i¥ž=ï9†Èµû Þb‡!vb§!vâ‡!~â§!~Ûñäs㎣…GCxµ×/…÷P‰C¾_ïoÙû‹Òß‚Ÿ\â¼›ó k<¾Ù_ì® ÷ù÷ÌþíöõˆæËšð î7* |ˆ‚ž}UA½½m¿—8¢¾uߣ¾Õ?B¾5ŽD>ç™k¿‚ôÒV‘ž÷–>çÌý ¢äRÏvö¼Mä¢Ç½†Øaˆ]†ØiˆÝ†øaˆ_†øiˆß†ð`÷'“=?á<žë]Â3÷OB%ù~½?Ü?\_Ù« üæºço§²?æsÇòõ÷}y‹ü'7ÊýŽòýÛšAþþ'nÓõäýxÞ'ìO8îâüÄš/C×»¸.Ìý“i Î_Dî_p–ëQ"Çž_pÅþ‚÷…Øeˆ†Ømˆ†øeˆŸ†øm?ç8นóK®Ã¯öº¾ð*qÈ÷ë}à@ áÍà…û«*À—Ž?œws~Áqû Þû›}ƒ8xrø;ú–ŽKÏË‘¿W—"qãóÍê!ÏG¢œóJ®¿p’ëù_´ùõ§Çæ‚/¢äÛëá\÷ãúçq¢Ç½öó‡<‹†Ømˆ†øeˆŸ…÷‰ô'wq~Ây¼ðh¯öþ‰ð*qÈO¸{#ø ìi¾™ô:pUóûuüb­~¿uúï‚¢äRÏ^§9ö¼›ó Ñk÷¼/ÄNCì6ÄCü²ãÅçûŽ“9ŸÞìõIáÕž á=T⟠ÏK÷»Á ÷õ¸ÁuZ®GqÞÍùÇQÖsUó-÷ÅÁ¯@ÎÁAš·ƒ­Ç›'ÔãóŒý>ÇÇœGr½…ë’\¿ç>÷ƒy¾€ÈýTîq}œë€\ï༎ãWöÓ|‰†Ømˆ†øeß'â·=îâü„óx®wq]˜û'ÜgÞC%ù úaÂqç'œÇs½‹ëÂÜ?á>#÷ã…÷P‰ƒ·ÅÃ{^!íšç•ן£žkúso¼ ~Ü2Þõæƒîšzë%.[/ñÖ5Ÿ.YOôÖÛݵÞîíG¹k?ÊÛ¯u×~­wžÁ]ç¼ó>Ðëšó>Þy8èuÍy8H»Î‹zç©ÝužÚ{ßÀ]ïxïã¸ë}ï}5w½¯æ½Ïé®÷9½÷Ýõ¾³÷=w}Àû^†»¾—á}OÆ]ß“ñ¾·äªï-yß#s×÷ÈŒƒ‡xè"<ˆï`zèÌ×ûñº›ð{è<ðÃyÊCᛓ}º÷§>§â~ø_éýß²wËó_ø=t KóyèÜ0êA%rªã”Ÿl<–þÒÚs¬vnó§Hùš¿ÃÀ#ˬw¬tióK‹ÇkWZùÿTÿ‰ú[Z‹Ô[yI;ß10ä8å'Š!Sîñê—VîßÕ{²x(¶|é=ú¼E1¨ŽÀcÕ;^û­_ÚvGÖÿ§íO–_'¤ï«wð»ÐêóJ…écå«Þ‰Ê9žüÕ[Z{NTþ‰æŸ(oEóç¶Àïþ‹øùI’ë6<9~æ ùÙWJ 9Núßj¬z'ªïxíOTÿ“?JŸ¯ü1þéý_°3p 0þéýŸ°Sî“Ò`ÈqÒÿVûcÕ;Q}Çk¢úÿž¤ùñó“$×mxrü”qV@Æ]Žô±òUïDåOþ‰ê-­='*ÿDóO”·¢ù2)Õx¬zÇk¢õKÛîÈúÿ´ýÉòë„ôÉ<½8<^ù‰bÈß”[Z;ÿmþ®½ÿÈYÇ Èº–Õ1ðÈòcÕ?^~iñxíJ+ÿŸê?QKËc‘z²Îu_'¯üdã±ô—Öžcµs›?EÊeÄC— ìzè”}ôÿq.Àÿ•Þÿ-{åœÉê?Ö÷?i·œÃòÐ%(ç=t Ê9Þ‚ê_’s²ô¸Ý¾"(çÜ=t Ê{ ºå=)]‚ò¡‡.AyÏÖC· ~ÝC— |§ÁC· þމ‡nAýÝ‚ú;Xº}¾òe}¾²‡­?βþ³þ®4×Âr:¿|0¿šÎ÷ýeýWeå}•,,Ótä¤ÚÁ„OÿsüYæ°ˆ9S•j,•oÓ±U¤ü}z‹ˆ6‘±QÑL·‹ŒmÕ(2NÒÅDÇÄ2U©Md‡F11±™Q®qT ùó´F‘--Q,9­eLl‹ˆh&+G5µ2"ïÐÆªÅ*M¢£ZµŠl¬ .GƒËJñ±M£ãÚÆ6‰hDc+Y91 ›G6j£ý/¤¬’Pô½Šˆ(C q­šEÆZÎøÊV“*EН¾¿æÝ÷Üq׌±¸|תÊE—3ùŽñïÈèB×?‹.T–76·noýa,yé¥ð fU«ÄC%ª._‚êòTË?šò†ü#ÂaC•÷uIºÊ” «L¡®SÅc±wI™#b^é_¼K*ÄF4ŽŠ*þ¶(î>¨Ú$"®Í˱-ãZEÄF¶lÔ±¤B.èRÞgû¼âdܹ§•¤Ë»!\{CTõy7Äɸ!²T| º¼µ7Ä9>ï†87DzLIº¼µ7Ĺ¾¼!jÕzì®jºú†•ÆžN⃸5.x¨DÕÿî 1%´$]Þ áÚ¢šÏ»!NÆ 1qQIº¼µ7Äy>ï†87Dâ›%éòn×Þçû¼âdÜ£7–¤Ë»!\{C\à;á¢æ·×úŸ¸!vÞwŸ â´Ë/ñýÇ7Äàuy7„«nˆò¾Ââ¢#ÂpF£àÖ_tDKÜUÄü“àVŒiÒ$.²Í)‹p‘H–/1’§iSÚ--žñ³,~Œ•’ôKNé”y4ùÿ÷I¿ìT“~4ùÿ7I¯è ýÌ#è©Õ´Y›S TV¶{Ë“„Ř^Î÷¯õ¶ÎÞé˜çJ*–ÜS•|ޤ]TdûV1Qv×S±IT˨6‘Ǹ(N·â¯#ZÂõpº¯ðz8ÃwÄMØ0¢ÑÛMccÚ¶l|Ì!ØÝÿWÚ!Xyc™l*‰ÇŽÐ¿=:êÂ.üw²‡/NnÊ·ŒiüÍL<ÛŠºoóxú kŠ^,GŒ\*ê¡ ›Ä4uJ²’q"¢u%/Žk¡”—Såã^N厺œjá_ ´YÏ(ô Ex*WôzÓ‰rÑQ¼òË5ûœ—¡ð} ï2ü߸ ‹X^•–ßq—ý×Ýö_÷ØÝkÿuŸý×ýö_ð¯;o·ÿºÃþëNû/[ò¶¼; ¥Ø-î°¥Üqg16—;¯•ccbÚÔiÛ0Îb´p”Ï0¸Á@W·Ôü?xïöùð¢rgl/tests/testthat/testdata/mergeVertices.rds0000644000176200001440000000441714145464133021202 0ustar liggesusers‹íMo$5¶ú#Ê'a¤¤‘öÊ0 #! ¤ ‰Ñ¢ ¤9LÜÝú¢ª’L†KÎðC@œ¹gÄ. ¸ •V¬vµÒ®PN{„µ«üêÃ]nWuW%ÐužŸýêùùùÙ~¯\ã5M«kÍýÛ ÙÆeö‡" ^¥¿5ú«iMmÂù¿l‰fWYñæ‰i1 ’GÒÅ[AR4Ð~WÙ@«O ÷¤¥!=â3JpÈkBþw{Ãt’Tã±0r¥¥Y͈ÝjØóÚÕ`¨†Sò9Qt¡®YOàs2±Ç‰®Ba×6ld8»zmÆ ™‚-@uÏÁÝ=Ác:6‰çÛâø‚·K,Ú{Ú#® Ï´mZé»vÄ«ÙA݇÷Ècµ~ЃlßðìSŽM,ÿ²|‚ ‚€ÿ*ÓõPé¼ù{.N¢‡  5‰c"‡,µ$»É24H•±±µ?¸ØÃŽ¿ûÀDÞÃt‰=èæ ñ>p‘å9Èõ¸êØÆáÀ¶Øý¾‡¡´e"w@@—zß°‘O,Ð@ÃGƒÐDƒ©;ÇxóñŸÆ_÷ö:^[˜Oï+ Z]ƒ©òzdWI;Jð¬¯íð!²l+Ö KÇ®ƒ *Û¶Ú>;{”$°ÅÚ\Æ,~tôA s.ìÆ!½žds»¡‚>4Ä ÒÞèYa®Îê×ÓdÚüé_QxüÛÓÿkgÕór ƒôDOÓ=áíÇí¦æa£GL-T1+nòßï n{å—×vrˆ›—îÉê¿ÿÆàñ‰¤þî?\K•0qëd˘4“âêõ?_ú/SïíëÏÕór Sò‹Ú%oA+£©ÓÀŒV„”|…Óò;HjJ5¹yÕAæ0š1¤­¾­]L­¸áäöÈðJûj:ç¯s¯kÂçÑP‹×–ZFû²ýñ…õ{‡žÍõ÷HÇEîáúÝB¼õ{{Žc`“.©ÈXÃ¥Ëÿ‹¾ßO´Ñ‚6ÚÚw,}Ÿ¨xÖ5q#ilýõ#ØÈÀ²]üö#?^Æ BE³° ô ¦½çá»v–,ÝîxØÝ¶%“Öw‘ï¬Eǵ?I—x‰³{.:€ÊÕMѬ²’÷铸ëÇûïœ×EÑr©ï|àØn´á&éf§cGÍ«glSN‘S…Lb€5ûñ¦Ýèbxl‰J°åbüA¼³êŒ’ù°÷™èÑ›qÞ7õ @Gã#ª±XèUD»°ïE{V0y“†=ïbÇ@]\ Íž$¢Võ§•ŒQŒÐ~ò9³Âíj™ç™}=Åù/Iö¹:o¦™ðAæ¨;ð2T,b³ƒ{=ºÕGŒÝa2y¢×5~\ÆÁÑ~ÏUL‹B\™Ì ˜çŽƒž˜+Âd£;AÖÀ`ÎbðÌF˜!Ìüö¼è­·  oÝÉ޹ŚʉÞ|µº±±µuãfôÕP FÓV|à¬ÇûÚ;°‹{» W•‹õâ>'ߣò•‹ø¸òåŸW?Eû+>ŸWÞé¡òKX˜Ð–º¬=^æt%7¤~Gí±›êŽL•…á¿~þùïYð‡íí XuÚüåþý,øŸÏ>;Ê‚ÐS†g•6¿½téZü•“Oøs J¦Z3,o²rqjE.=8Ž5x Pë@iñ»rüÏ?Ü¡ÜT@}Þúqñ 1G¥1BG9—ŸwŽ=ü²Íš¬nV «–ç¬øŸúÑ;嘦™|™’òøô‘qƒn"³h7Šf°ë“n\µ?1 #hLàÇÑé< `MdšŽh) Ë4’ˆc‚ìèb(ªXÕçõÓ=Ô+-¢˜$À?Þ˜$ü˜$™48¡è¸EÑaÜB執^'•/¯\yõtÚÏOªŸJÖÉ’#”EŠ£¬HCI¨"ŠSŠ,¦=I# €'œîœÂSˆ .‰Ë$• ˆËøi˜ÏPŸÙ»×R"‚“t“²nÜtÖÓiò•|t:ªNšTü§r§;'N½ÿПÏ À‰òŒáöìŒá”Îʉ¼ª‹ËªŠÚª‹éª‹øÊK‰¿ió•0‚ºW•‹õk\„²zYû*(ã#¶S”^”_+–G5ªÞ¨¢QY´)¶#â2>²vUQnÑ·E}•G¤“%•þTüŠŽç´ÑW­ŸªøWmo>êm­”ð餴èöŒÎsO+jŸXc¾ªLoô¼[ùö­èÛ¸)ÑCYú)+•õ=ÀŸ-)ßn^°·38J¶ö2ßßn׿þú ÍHáJøÝ†rI#¨+àšô“~¯"¦ã“4T­9›?qþŒÊ'üFÅ_Ù¾²?C6ôŒVŠ{øÍ¹ÿÞFP V¦m{?ïß#îïI1XõxU §íû«¢ôEû[uÊ+Àêí­‚7çäôj¬ïÙÖ´Ù Öìkv‚uÑN°ž —«^Qàªr±þª¡¬^ÅGÖ¾ Êøˆí¥—õO+–GôÏUþ»Ì/“á2>2\ÆGÖ®L>¿ªý†¢òˆt²¤ÒŸŠ_Ññœ6úªõSÿsé§ÎN°*³¬RaÑ4;Á:4;Á/ÍN°f0 OåëY~%ƒÏñ“,”…M2( ß$pv‚5;Áš`eBY:’À¢é¢ž`I`Q{¨Ú“ÉYý´H•u‚uVéHe©z{›`)O°ZZ|‚µ¤ /Ãð&Èzæ-ª#Ô\›XÍA“Ëgà`²n–ä`Êî’N™Mk´ÙŒ4“…ð’BÝ»Øê‹øXbìÿä‰ks•'š‹ZÚÙ]Ì×Þ³z‘f|a÷Í7Ù¿¼§+ÍÍ/_¾ÆFD„òª•7BÙ†§ [zwxÓñЧ¬1#×”–çìâøîë¾=ðS7tÂ;B³-i…ZNÂršÓ²ÒœCæ] /SÛ»ÚÛôÔHÛ[ˆ$î+/Oš!×w…bf†çà S’σä/½ånF¹W¢Ü­(÷R”Ûˆr7287$½_vmÛ¿—¾x5}okC\%Ù:Ýqû°xµ‘argl/tests/testthat/testdata/r3d.rds0000644000176200001440000001352714145464133017070 0ustar liggesusers‹í] |“EÚO›ô ‚€°  béI» ozº«°®Tt9Ò6m9jZŠWYt×k]TÑ…EeÅUP@KI@¡”£-méé•–¶@zÑRŽ~™ÿ›I2¡¡è¢ß·ïë¯>ïæ™çšyg&O&¼ÓýE"‘§Hâaý¿Øz+@þg„³þõ³þyˆ$"?+õ=—õ6€s½üÁÆÿ¹iÂÇãêAô÷=*ðNQ(•òd·¥¼_»œkNïE.÷W\¤‹µ©‰.,Œr¥B-—iÝ–v§ÆÕ-‰R®Ó¹ð «®¾œÛ¹šîR'ñtÂ^j™J®³1 £…I¥FKL™ž&£^+zÚO2U¢B®¦ÐW—.Oš¯”Ñf¾r•B§ShÔ6ì§KS¨­Þ[=²ÅB§ÒhôiTKŠVc—%I”%Í£÷:ÅB¹]{f2½MѤÚnû¦kjýl™Z¯)2*?€ÄúªR½|~¾Vî ³Ò)ô³B•"]%K·ôFÚ:’ôr­s™,•)# åê GCÿdyº>m¶J¦›Ç–èå:êf…î ­L­K—iq H×(³R5êÙš”œ–z«dÚT¥oŠR#Ó+Ô4b½,•¢xt½ˆl[ÿû¸ô¿¯n~¢.I®–ÛïÛœx}EôQ™dWÎãÈI¦g?è±u‘Z£vDPkí»D™RI+j4*G§eÐâôùVŒE.›Ýɳ>)4^ZEjš#"Šäd%eóÊL“Ë•| àƒØõ‘>ôçÙ¸ó$õýœÿk^ÜñªÏI;ÃÙ[ÎK»«·•S>z=Õ›çòMQ*ÁÝŸB¨C/óŠ“*[ˆI±Äöw…š+íS:ÑY¼»ëzùŒuåÄ<ƒÅMýŒ l 1׳«{‡ÉO¯þõ^$¼ÑSÇ ¿ªÞVNùz”g×{-{¢¿ß5cŠaLy]©•½×vÑ„y¤$¶áå±€ÞdÙŸE²}öõN“ãÑr(v^ ö6ú%¾šm½‘Žya••ý›š€û¾ïM˜Œ½Gí7ì7d¡”oçlà8›ãD.kœÎ:Šs‹G7úÝ­÷&déôrUàdE¢V¦Í Œ·.!ºÀ„ùééJ¹Ê:¥Ê”QZëôÿ€^Ÿâ¤Ã›êŠ’ëSko£óšëB"ŽìIº (RÕ­Už¬•eÒ«T-Ã@Jþhm)OÒ;Ö_/]’Ì>]úf(ä™é­}Áuš¤%‰‰»ºL…:Y“9Õ*ɾ©’©J:ˆ$)ŽE[œ$§ÍzY-ˆ×ÊåO8VV_ÂIötíSÉÄ(éTʬ{£Tå“Öˆ9ŒY]È'Ø×,<¼ÎÛG+OWÊ’ä? vÿ¸Fágƒˆ>r«Ÿ¶g†Œ²îö¶ÝØd÷r³Æy*èNFâ´ÿð²nBh…¿\•(ON¶.óöÍ‹&‘Ø£sÝÃ%)e:º‡ó¤} MUÚ×z[x­E¼[ ÉÀǶiðwzú¸ºt­BO¶‰hâm«¦†’Î0ÂÆ302ŽQ± ŒfaL c£ÇÂø(½a Œ g`, c&00:‚Q,ŒŒd`D'°0<ša1 eaH,ƒãÄ:8ždeÈ–Ìå._¾Êz#P ôj*rŸk œf݉ëUóµÉš¤´@]†:pJÖÔ@ë6,P¡Öém¹(] uÛ§W$)夫S]„ØÒo̧ fGémß^OÒîšé/—„”ý£²Çý†Šss‰·†Cz#ñ¾Ã²àvB7ö.Ì&Ôøf6ðÅô:®ü¥ÏÀß:q½‰ÐšÎ e¯lCû–÷ A‹|Æ#š'>›(%ô»i߀¯"W7‡àKË‚Q~ªl¡†®Ìè3?»|'£ÃA›æ¡þ€ùCb‡Á2w1ô×& z Õ¢©Dž¡óÒFØYønèÿáãÄ^CsØa”·ö]}¥Â.ñJô5®> ;‡| »êI5û=þŠmŸáëÕ°#i5ôÏøòÍúîý+|Á×Êõ#|R§½ ·%áøš:¤°÷ľrð•—=umY·ù©µÄ_îHø,ø½âÁ?¡ü_-ÃQÞVsíš!ŸëˆÉ€9Ð/•›ïŸaÓiÈ=ðéø]àÃï.GûÂI£Ïê>G»5}Nžn¾Î¯« §xÚǰçLÚ<øS©@–«Ò? |¡òø×jW"¦•á~üm°GŸ §:ûß×0>q²$€oçˆA¼‹~8%òŽ$Ý—³çÃÞ경ЛwÇ]°ç›6Øa8›óWر1ŠCüÚ‡U Îe5Ïž {rKýÇ“z£HÕz›‡´¡}û¬}hW»î3´»òÆzØ×>4ö›çK`ß‘œbð_¸'ú:º|þÉ?O¦Ë(oOšùfñ\Â/ò‚ß­ËÖÁžÓac ¯î£+ðïxtÚYF=?w.ÕBîѦ.ðWJ.¿«D»-#aÇ Oè©ýD‚v•2¬†¶þ/Áÿœ¹CÀWrä#ØQ°+þžöœnä㑌ö¦þøfƒk?ǧå°goÃX´»’>í¶xrÛvÕ¯&n?ì2´SZ ½ýŠ gÏb~ÝjÞð ôXÊaoóÔ.øU¹p%üyñú7 øê/cû`í“I=÷ÞóX︖.ÌÝ|@¾¸»dú|“*ú…íýbZlã¹:Õï±PäØÊ-q÷¯NÏÍžM\çμ€¡Ê5<÷èiÛ»vË#¡5›7ƒVåç#”MÍhoêÇ/éeÆOŸyK—¢ý‘%K@é†}wÿþàÛt+–n)O…‹¿h<ìñ¡ñ¢ñ£ñ¤ñ¥ñ¦ñ§ýAû‡öí?ÚŸ´iÓþ§ãÁb³ç‰ÚãñÕˆðÇ0r$hÎàÁ y+WÂþü„Ø[d+/))¿'mõ?Žúª)â0p øjmüu §ÞÖ®ñ»ïŸ³;wo‚8Ütô¬­?mã­þ·¿•Zg‡æ'Ÿ­Öë³ ­|çU„šÖ¯7Z>s&êOØÆßñãÇM„=zô Mî¶ñ½mÈàÕ¸íC‡‚ÒñCÇ_t¼ÑñGÇ#Ÿt¼ÒñkÎȥ㛎w:þéó`±Ù!PžÒù³± [FûüJç[:ÿÒù˜ÎÏt¾¦ó7Ïéüž?`(ÿéz@׺^Ü$‰I ôf¤n>êHør )wýhc?ÅDÓÛôä£G"½‘‰'»Äœ ŠD®´Ý$¥.¾†îëûXå|^©[×PáápOH¹ )w!å.¤ÜÑNH¹Ã.!å.¤Ü RîBÊÐ_%åþ3÷‚î~>ÆœØð·5êþ °¯J¦—“SëgÈÉáû!ioœó°C—%Ï¥g>´²d…‚žìH’«õŽÓçÝQOQ,''ŸWÁ>1µ!ö'Gˆm'mM\N_ur˜{N; prX89ì …“Ãö±!œN T ÿ•TôßqrØ\C¼5Ô ò¹Ð³¾žC¨¥è6àÒNò»mw<é:£høPRÏu¿‘ЖÜy„JE“[½Ö£+L„ÖMx‰”.®ZOÚª¸7@ ÿzõæÅ±Ùïè¾ÖÑJÈëlÑ¢þ̽ü×5yÉó¡ç…Ùào›Ç½SsW:ì6íØˆv5“¤}gÚUG! ʵÍzõ/”…ƒZn@»q>ü¬̧ :þ°´øž‘&ø9·vµåßF°!÷› Ô7lÊ„Ûz!U¦#>g×ßÚùÝjе_EBÏ+plÂp©O4ìÞ¦Âït •“‘.1œ»oâœãs/ìµL ƒü®ÊÉð§t:>^sß—Z`Gã{cøþ˜õâRòÄI´_U8ÅÛÇ>©äéпÿaüÕ…ïBÎÑW’x=ò¾ˆGý½±h¿¿é%®8ÄŒvg¥ûÑ®aÞiÄ¡|Ñ‚¥âiƒ]s7‚–oh‡õŠÅà7%xðþ•ûÀïs5« g÷‹À¯¿M Eý¥ÕWÀÿñúuˆã¾™³w¦r-3€O.hGûóÿ.Í÷ñéÞÒŠ(/¼ûï°³zÓr"×è]Fø¸ÆGùôcý·Â¯Ê§?ByG_^NÝžð»¡ßƒ¨o½oä®?¼±àmØÓ¼ñôU?VŠò¯~Š8Öd<ùiŸÂ¯ÂÄÙWʧÿ*&6ÂþCƒÍà?•½–ï‡;Ã`wuíógP‡Þ’¬u°ßë®ûÐ~Ëþ‹à+}mÚWÜq |?ÁK äŽ=ô&g¼oä·> »Ì—‘7”›q;úoÜEØ÷—ýfðu޾ úÛ%#aÿ¾ÄØ[qÏå‡ ]j° =ïnÝ„~lšÈ?—æ¼LÈizfâíˆûA¤‘¸–=H›ZJçûm¨zk†7"î¹ï]†}Õ«ùôêž±ü×e?nŒ•lÍãÓ›üåç+Ï@ŽeçeØWZº~›+¿>3ã%´óúýÛÀM?l€ý§üù4æ¡—K×cUø:k¨EÚÍP8…?ÞdZöêOˆ'CÓó|š¿åO|Ú§v³ôâûKAׯãíiyB_×GCÞ1ñ!øßvoú+ïÓþÀäˆ÷ÃÜXø{Q¾öœzrŠN!=b8t§ö,mòÜ‚!¯·Ig¡½!€O—˜ˆþªkœÇûÇÛJæG®Ógp±ŒO‡ï¸iHî|âϵnBþÇДþhƒ%ümÛ7 ®9ñ?‚ÏEà/š²ú*¾äÓMUÑ›àß¹ƒ2ØeQ}‹vu¾PÞqŸÆÜúÌ{ßø%ì5Š–Ô@îFÁßMG n[Ï!.¾¨‚¼Æ‰÷ÀýóiªmEÐ[»8 r'ëÁ—_„qf°|òWðå,SCþÙ–”ïØ: Ô<#ý{ôßQßt|9ïÏò6Ж\%ôí:ÔK¢šÑ®âdôTÍÆ×oSŸÎ<¿ýÈ1&öí zúcþøAójä¶¿ÿª²&þÜ*ÞŽçkàOy×8è3¿úê[ƤÀކmqÙ kFߎòqo¡¼:c ᓊŸŠö›y>?=ðiŸƒÐß´_“q‡;£Ð®S= òÛŸjBü¾ˆÙ?Leï@~.wí«ïâ÷õ_ÃþÊ—«Áß”‚¯¹öË`sç7¨ßfšÊÇ1€ƒ•{_C}þcGÑŸ›žž{ÎîÆüfhŸò5êOKøômÁ¢_–ɧÛО«yãQؽ1ëðwŒäŸ÷·KÐ/Ò1°s{ˆ v7×~þSõü×w–.܃­E°«Xñ0ü?Ýÿï¼_kÊÑ®­ŸŠÈ7z/œùå»ý@ëkàŸáØ£@®éŽCÛüâ' ÆøTÈëê7õÍfþkÇË»ƒýEÒ˜ÂIað '…»½„“Â.ñN ß\T8),\7á%œ¾É¨pRX ½i©pRø:O )v!Å>!ÅŽz!Å.¤Ø RìBŠP!Å.¤ØIýÍ”bÿo<)ì+rœî+b·´~z«'êT¥ý¬ðÕo±fCäøGqˆÅ±Ï¾Ó`á#ÚSÀàBotùõêý©òz*ï©}7ÚüëÕ7à#ŽÄ5CN¯>úÜÈOv½¹ãÓ¦Í!:mÔà†öÄçZNq7>HnLøîä*³ÖH‰ªë¤†Di½?UŽ;þ_däº=&ç{'a—ÉÖÇ:ÕªdÊîçÞî§ÚÞÖ‰Õ1U^c² 9&Û~¢kþ,Cäâ±HäŒ#¤ÃÍ5Yo¤ƒ«ºn-Çk¤·œ{“0J3öi#ÊÇ„‘Αœý"pÿ§±;“:„ß­Ioýÿtw"­´å¹Gˆ<î¢h&á3,IlŸCpS0v/FÉ~•/÷Ê&´fÅßDh÷öoå:vžÆ`9¿ú áç æ,"|\à |zåöæ#å†FÏÁDwv„èžã×$áŸy> Ù ©hæî—ÿ<¸øiQäæú§Åÿ /‘‡ôÿX y˜Ϋ`~õ×ÕôÜóÝEßv“)r¼1£»ÖÏ? ³Ä%ܾ|榛èîž‚«6ÄŽ~­Þ¿ª™sÏ Ûðë'lÃ…m¸°  Ûð«¶áŒù¿B*G¬H¦,x-˜Êùµ`^D›ôô±µaÞ>õss@Þ"ÇÇ’^"—ÅCÉ¿…Žß©Š\®f­ðÄ÷þ¥Oœtc:qóM¸îÞcÛí¾ÜŒÃkŽ;?þi µãmp µµÃÝŒ_kÿ+^ÙÙcNÐ_ÄŽòØT­f¾:Ùín$4†üw½»‰ýlŽ+ußC7ü#˜Èíõ l·¿1äß²zÕÛÿƒ9÷šs¬·.=Mîøù`Š&Uϼ0•?a÷#©uä8…ëN½{N⫆“ý•ÔîÂæE^+ìºy³ãÍ6;~<ɿи›ÙO˜(„aøc2–ûP˃Bìw¡ö»0û]¸ý.È~7Þ~Üd±ï{k5}ûâG7+·ý_•'+7}¿æÿ”OÉ ~rgl/tests/testthat/test-mesh3d.R0000644000176200001440000000230114127571241016323 0ustar liggesuserstest_that("ensureMatrix works", { expect_equal(dim(ensureMatrix(1, nrow=1)), c(1,1)) }) test_that("mesh3d works", { expect_s3_class(mesh3d(1:3, 1:3, 4, triangles=1:3), "mesh3d") }) test_that("tmesh3d works", { open3d() m <- tmesh3d(rbind(1, 2, 1:3), 1:3, homogeneous=FALSE) expect_s3_class(m, "mesh3d") expect_named(m, c("vb", "it", "material", "normals", "texcoords", "meshColor"), ignore.order = TRUE) shade3d(m) expect_known_scene("tmesh3d") }) test_that("qmesh3d works", { open3d() m <- qmesh3d(rbind(1, 2, 1:4), 1:4, homogeneous=FALSE) expect_s3_class(m, "mesh3d") expect_named(m, c("vb", "ib", "material", "normals", "texcoords", "meshColor"), ignore.order = TRUE) shade3d(m) expect_known_scene("qmesh3d") }) test_that("shade3d, wire3d and dot3d work", { open3d() mesh <- cuboctahedron3d(col = "red") shade3d(mesh) wire3d(translate3d(mesh, 1,1,1)) dot3d(translate3d(mesh, 2,2,2)) expect_known_scene("shade3detc") }) test_that("transformations work", { open3d() mesh <- cuboctahedron3d(col = "red") shade3d(translate3d(mesh, 1,2,3)) shade3d(rotate3d(mesh, 35, 1,2,3)) shade3d(scale3d(mesh, 1,2,3)) expect_known_scene("transformations") }) rgl/tests/testthat/test-r3d.R0000644000176200001440000000072314127571302015634 0ustar liggesusersset.seed(123) test_that("3D sprites work", { open3d() particles3d( rnorm(100), rnorm(100), rnorm(100), color = rainbow(100) ) # is the same as sprites3d( rnorm(100), rnorm(100), rnorm(100), color = rainbow(100), lit = FALSE, alpha = .2, textype = "alpha", texture = system.file("textures/particle.png", package = "rgl") ) sprites3d( rnorm(10) + 6, rnorm(10), rnorm(10), shape = shade3d(tetrahedron3d(), col = "red") ) expect_known_scene("r3d") }) rgl/tests/testthat/test-as.mesh3d.R0000644000176200001440000000046514127571212016734 0ustar liggesuserstest_that("mergeVertices works", { open3d() (mesh1 <- cuboctahedron3d(col = rainbow(14), meshColor = "face")) id <- shade3d(mesh1) (mesh2 <- as.mesh3d(id)) shade3d(translate3d(mesh2, 3, 0, 0)) (mesh3 <- mergeVertices(mesh2)) shade3d(translate3d(mesh3, 6, 0, 0)) expect_known_scene("mergeVertices") }) rgl/tests/boundary.R0000644000176200001440000000054014145464133014152 0ustar liggesuserslibrary(rgl) # WORKING x <- cube3d() b <- getBoundary3d(x) open3d(); shade3d(b) x <- cube3d() x$ib <- x$ib[,-(1:2)] b <- getBoundary3d(x) open3d(); shade3d(x, alpha=0.2, col = "blue"); shade3d(b) x <- cube3d() x$ib <- x$ib[,-(1:2)] b <- getBoundary3d(x, sorted = TRUE, simplify = FALSE) open3d(); shade3d(x, alpha=0.2, col = "blue"); shade3d(b) rgl/tests/bbox3dtests.R0000644000176200001440000000315414145464133014577 0ustar liggesusers# Tests of bbox3d improvements library(rgl) x <- cube3d(col="red", front="culled", back="filled"); open3d(); shade3d(x); rglwidget() open3d();points3d(1:10, 11:20, 21:30); bbox3d(col="red", lit=FALSE,draw_front=TRUE); rglwidget() open3d();points3d(1:10, 11:20, 21:30); bbox3d(col="red", lit=TRUE,draw_front=TRUE); rglwidget() open3d();points3d(1:10, 11:20, 21:30); bbox3d(col="red", lit=TRUE,draw_front=TRUE, front="lines", back = "lines"); rglwidget() open3d();points3d(1:10, 11:20, 21:30); bbox3d(col="red", lit=TRUE,draw_front=TRUE, front="lines", back = "lines"); rglwidget() open3d();points3d(1:10, 11:20, 21:30); bbox3d(col="red", lit=TRUE,draw_front=TRUE, front="lines", back = "filled"); rglwidget() open3d();points3d(1:10, 11:20, 21:30); bbox3d(col="red", lit=TRUE,draw_front=FALSE, front="lines", back = "lines"); rglwidget() open3d();points3d(1:10, 11:20, 21:30); bbox3d(col="red", lit=TRUE,draw_front=FALSE, front="filled", back = "culled"); rglwidget() open3d();points3d(1:10, 11:20, 21:30); bbox3d(col="red", lit=TRUE,draw_front=FALSE, front="culled", back = "filled"); rglwidget() open3d();points3d(1:10, 11:20, 21:30); bbox3d(col="red", lit=FALSE,draw_front=FALSE); rglwidget() open3d();points3d(1:10, 11:20, 21:30); bbox3d(col="red", lit=TRUE,draw_front=FALSE); rglwidget() example(bbox3d); rglwidget() open3d(); spheres3d(rnorm(10), rnorm(10), rnorm(10), radius = runif(10), color = rainbow(10)); rglwidget() open3d(); spheres3d(rnorm(10), rnorm(10), rnorm(10), radius = runif(10), color = rainbow(10), front = "lines", back="culled"); rglwidget() rgl/tests/indices.R0000644000176200001440000000104514145464133013746 0ustar liggesuserslibrary(rgl) tet <- tetrahedron3d() open3d() segments3d(t(tet$vb[1:3,]), indices = c(1,2,1,3,1,4,2,3,2,4,3,4)) open3d() text3d(t(tet$vb[1:3,]), text=1:4) triangles3d(t(tet$vb[1:3,]), indices = c(1,2,3,1,4,2,1,3,4,2,4,3), col = "red") # This displayed a triangle for the red quad (issue #154) quad <- cbind(x = c(-1, 1, 1, -1), y = c( 0, 0, 0, 0), z = c(-1, -1, 1, 1))/2 open3d() triangles3d(quad, alpha = 0.5, col = "red", indices=c(1,2,3,1,3,4)) triangles3d(quad+1, col = "blue", indices=c(1,2,3,1,3,4)) rgl/tests/testthat.R0000644000176200001440000000022414100762641014162 0ustar liggesusersif (require(testthat)) { library(rgl) options(rgl.useNULL = TRUE) test_check("rgl") } else warning("'testthat' package is needed for tests") rgl/configure.ac0000644000176200001440000001605314145447077013346 0ustar liggesusers## ## This file is part of RGL ## ## Process configure.ac with autoconf to produce a configure script. ## NB: the files in src/build/autoconf may need updating for a new ## version of autoconf ## ## ## AC_PREREQ([2.69]) ## ---[ VERSION ]------------------------------------------------------------- AC_INIT AC_CONFIG_AUX_DIR(src/build/autoconf) ## pick up compiler as will be used by R CMD INSTALL/SHLIB if test -n "${R_HOME}"; then CC=`${R_HOME}/bin/R CMD config CC` CFLAGS=`${R_HOME}/bin/R CMD config CFLAGS` fi AC_PROG_CPP AC_PROG_CC if test `uname` = "Darwin" ; then darwin="yes" ## we want the *build* cputype and not the host one. cmd=`echo $CC $CFLAGS | grep -E 'x86_64|ppc64|-m64'` if test -n "$cmd"; then have_64bit="yes" else have_64bit="no" fi else darwin="no" fi ## --- LibPNG ---------------------------------------------------------------- AC_ARG_ENABLE([libpng], [ --disable-libpng compile without PNG image support] ) AC_ARG_ENABLE([libpng-config], [ --disable-libpng-config disable libpng-config test and configuration] ) AC_ARG_ENABLE([libpng-dynamic], [ --disable-libpng-dynamic disable dynamic libpng linkage, force static version linkage (only with --enable-libpng-config)] ) if test "x$enable_libpng" != "xno"; then if test "x$enable_libpng_config" != "xno"; then AC_CHECK_PROG([HAVE_LIBPNG_CONFIG],[libpng-config],[yes],[no]) fi if test "x$HAVE_LIBPNG_CONFIG" = "xyes" ; then AC_MSG_NOTICE([using libpng-config]) CPPFLAGS="${CPPFLAGS} -DHAVE_PNG_H `libpng-config --I_opts`" if test "x$enable_libpng_dynamic" != "xno"; then AC_MSG_NOTICE([using libpng dynamic linkage]) LIBS="${LIBS} `libpng-config --ldflags`" else AC_MSG_NOTICE([using libpng static linkage]) LIBS="${LIBS} `libpng-config --static --L_opts`/libpng.a" fi else AC_MSG_CHECKING([libpng]) save_LIBS="${LIBS}" save_CPPFLAGS="${CPPFLAGS}" AC_CHECK_HEADERS(png.h) AC_CHECK_LIB(png, png_read_update_info) if test "${ac_cv_header_png_h}"; then if test "${ac_cv_lib_png_png_read_update_info}"; then CPPFLAGS="${CPPFLAGS} -DHAVE_PNG_H" LIBS="${LIBS} -lpng" AC_MSG_NOTICE([libpng header and lib found]) if test "x$enable_libpng_dynamic" != "xno"; then AC_MSG_NOTICE([using libpng dynamic linkage]) else AC_MSG_NOTICE([using libpng static linkage]) fi else LIBS=${save_LIBS} CPPFLAGS=${save_CPPFLAGS} AC_MSG_NOTICE([libpng header and lib not found]) fi fi fi fi # ---[ OpenGL enabled?]--------------------------------------------------------------- AC_ARG_ENABLE([opengl], [ --disable-opengl compile without OpenGL support] ) NULL_CPPFLAGS="${CPPFLAGS} -DRGL_NO_OPENGL" NULL_LIBS="${LIBS}" # ---[ X11 ]------------------------------------------------------------------ if test "x$enable_opengl" != "xno"; then AC_PATH_X if test x$no_x = xyes ; then AC_MSG_WARN([X11 not found, continuing without OpenGL support.]) enable_opengl=no else if test -n "${x_includes}"; then CPPFLAGS="${CPPFLAGS} -I${x_includes}" fi if test -n "${x_libraries}"; then LIBS="${LIBS} -L${x_libraries} -lX11" else LIBS="${LIBS} -lX11" fi if test $darwin = yes; then CPPFLAGS="${CPPFLAGS} -DDarwin" if test -e /System/Library/Frameworks/GLKit.framework ; then LIBS="-framework GLKit ${LIBS}" fi # X11 must come *after* the OpenGL stuff CPPFLAGS="${CPPFLAGS} -I/opt/X11/include" fi AC_CHECK_FUNC(XAllocClassHint, [], [enable_opengl=no]) fi fi if test "x$enable_opengl" != "xno"; then ## --- OpenGL ---------------------------------------------------------------- AC_ARG_WITH(gl-includes, [ --with-gl-includes=DIR specify location of OpenGL headers], [CPPFLAGS="${CPPFLAGS} -I${withval}"] ) if test $darwin != yes; then AC_CHECK_HEADERS(GL/gl.h GL/glu.h) if test "x$ac_cv_header_GL_gl_h" = xno; then AC_MSG_WARN(missing required header GL/gl.h, continuing without OpenGL) enable_opengl=no fi if test "x$ac_cv_header_GL_glu_h" = xno; then AC_MSG_WARN(missing required header GL/glu.h, continuing without OpenGL) enable_opengl=no fi fi fi if test "x$enable_opengl" != "xno"; then AC_ARG_WITH(gl-libs, [ --with-gl-libs=DIR specify location of OpenGL libs], [LDFLAGS="${LDFLAGS} -L${withval}" L_LIB="-L${withval}"] ) AC_ARG_WITH(gl-libname, [ --with-gl-libname=NAME specify Library name (defaults to "GL")], [lGL=${withval}], [lGL=GL] ) AC_CHECK_LIB($lGL, glEnd) this=`eval echo '${'$as_ac_Lib'}'` if test "x$this" != xyes; then AC_MSG_WARN(missing required library ${lGL}, continuing without OpenGL) enable_opengl=no else AC_CHECK_FUNC(glEnd, [], [enable_opengl=no]) fi fi if test "x$enable_opengl" != "xno"; then AC_ARG_WITH(glu-libname, [ --with-glu-libname=NAME specify GLU Library name (defaults to "GLU")], [lGLU=${withval}], [lGLU=GLU] ) AC_CHECK_LIB($lGLU, gluErrorString) this=`eval echo '${'$as_ac_Lib'}'` if test "x$this" != xyes; then AC_MSG_WARN(missing required library ${lGLU}, continuing without OpenGL) enable_opengl=no else AC_CHECK_FUNC(gluErrorString, [], [enable_opengl=no]) fi fi if test "x$enable_opengl" != "xno"; then if test x$L_LIB != x; then LIBS="${L_LIB} ${LIBS}" fi ## --- FTGL ------------------------------------------------------------------ AC_ARG_ENABLE([ftgl], [ --disable-ftgl compile without FTGL font support] ) if test "x$enable_ftgl" != "xno"; then if test "x$darwin" = "xyes"; then AC_MSG_NOTICE([Darwin, so ensuring /opt/X11/bin is at the head of the PATH...]) PATH=/opt/X11/bin:${PATH} fi ## new pkg-config bit AC_CHECK_PROG([HAVE_PKG_CONFIG],[pkg-config],[yes],[no]) if test "x$HAVE_PKG_CONFIG" = "xyes" -a "x`pkg-config freetype2 --cflags`" != "x"; then CPPFLAGS="${CPPFLAGS} -DHAVE_FREETYPE -Iext/ftgl `pkg-config freetype2 --cflags`" LIBS="${LIBS} `pkg-config freetype2 --static --libs`" AC_MSG_NOTICE([using Freetype and FTGL]) else AC_CHECK_PROG([HAVE_FREETYPE_CONFIG],[freetype-config],[yes],[no]) if test "x$HAVE_FREETYPE_CONFIG" = "xyes"; then CPPFLAGS="${CPPFLAGS} -DHAVE_FREETYPE -Iext/ftgl `freetype-config --cflags`" LIBS="${LIBS} `freetype-config --static --libs`" AC_MSG_NOTICE([using Freetype and FTGL]) else AC_MSG_NOTICE([compiling without FTGL support]) fi fi else AC_MSG_NOTICE([compiling without FTGL support]) fi fi if test "x$enable_opengl" = "xno"; then AC_MSG_NOTICE([compiling without OpenGL support]) HIDE_IF_NO_OPENGL="#" RGL_NO_OPENGL=TRUE else HIDE_IF_NO_OPENGL="" RGL_NO_OPENGL=FALSE fi ## --- Output ---------------------------------------------------------------- AC_SUBST(CPPFLAGS) AC_SUBST(LIBS) AC_SUBST(NULL_CPPFLAGS) AC_SUBST(NULL_LIBS) AC_SUBST(HIDE_IF_NO_OPENGL) AC_SUBST(RGL_NO_OPENGL) AC_CONFIG_FILES([R/noOpenGL.R src/useNULL/Makevars]) AC_CONFIG_FILES([src/Makevars]) AC_OUTPUT rgl/src/0000755000176200001440000000000014146473375011643 5ustar liggesusersrgl/src/COPYING.GL2PS0000644000176200001440000000161114100762641013506 0ustar liggesusers GL2PS LICENSE Version 2, November 2003 Permission to use, copy, and distribute this software and its documentation for any purpose with or without fee is hereby granted, provided that the copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Permission to modify and distribute modified versions of this software is granted, provided that: 1) the modifications are licensed under the same terms as this software; 2) you make available the source code of any modifications that you distribute, either on the same media as you distribute any executable or other form of this software, or via a mechanism generally accepted in the software development community for the electronic transfer of data. This software is provided "as is" without express or implied warranty. rgl/src/win32lib.cpp0000644000176200001440000000446214137472630013777 0ustar liggesusers#include "config.h" #ifdef RGL_W32 // --------------------------------------------------------------------------- // W32 Library Implementation // --------------------------------------------------------------------------- #include "lib.h" #include "win32gui.h" #include "NULLgui.h" #include #include "assert.h" #include "R.h" using namespace rgl; // --------------------------------------------------------------------------- // GUI Factory // --------------------------------------------------------------------------- Win32GUIFactory* gpWin32GUIFactory = NULL; NULLGUIFactory* gpNULLGUIFactory = NULL; // --------------------------------------------------------------------------- GUIFactory* rgl::getGUIFactory(bool useNULLDevice) { if (useNULLDevice) return (GUIFactory*) gpNULLGUIFactory; else if (gpWin32GUIFactory) return (GUIFactory*) gpWin32GUIFactory; else error("wgl device not initialized"); } // --------------------------------------------------------------------------- const char * rgl::GUIFactoryName(bool useNULLDevice) { return useNULLDevice ? "null" : "wgl"; } // --------------------------------------------------------------------------- // printMessage // --------------------------------------------------------------------------- void rgl::printMessage( const char* string ) { warning("RGL: %s\n", string); } // --------------------------------------------------------------------------- // getTime // --------------------------------------------------------------------------- double rgl::getTime() { return ( (double) ::GetTickCount() ) * ( 1.0 / 1000.0 ); } // --------------------------------------------------------------------------- // init // --------------------------------------------------------------------------- bool rgl::init(bool useNULLDevice) { if (!useNULLDevice) gpWin32GUIFactory = new Win32GUIFactory(); gpNULLGUIFactory = new NULLGUIFactory(); return true; } // --------------------------------------------------------------------------- // quit // --------------------------------------------------------------------------- void rgl::quit() { delete gpWin32GUIFactory; gpWin32GUIFactory = NULL; delete gpNULLGUIFactory; gpNULLGUIFactory = NULL; } // --------------------------------------------------------------------------- #endif // RGL_W32 rgl/src/config.h0000644000176200001440000000116614100762641013250 0ustar liggesusers#ifndef RGL_CONFIG_H #define RGL_CONFIG_H #ifdef RGL_NO_OPENGL #undef RGL_OSX #undef RGL_X11 #undef RGL_W32 #else // --------------------------------------------------------------------------- // Platform detection // --------------------------------------------------------------------------- #if defined(__APPLE__) # define GL_SILENCE_DEPRECATION # define RGL_OSX 1 # define RGL_X11 1 #else # if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) # define RGL_W32 1 # else # define RGL_X11 1 # endif #endif // --------------------------------------------------------------------------- #endif #endif //RGL_CONFIG_H rgl/src/devicemanager.cpp0000644000176200001440000000757314100762641015140 0ustar liggesusers// C++ source // This file is part of RGL. // #include #include #include "DeviceManager.h" #include "types.h" #include "assert.h" #include "lib.h" using namespace rgl; DeviceManager::DeviceManager(bool in_useNULLDevice) : newID(1), devices(), current( devices.end() ), useNULLDevice(in_useNULLDevice) { } DeviceManager::~DeviceManager() { std::vector disposeList; { for( Container::const_iterator i = devices.begin(), end = devices.end() ; i!=end ; ++i ) { disposeList.push_back(*i); } } // disploseList. devices.begin(), devices.end() ); for (std::vector::iterator i = disposeList.begin(); i != disposeList.end() ; ++ i ) { // remove manager from listeners (*i)->removeDisposeListener(this); // close device (*i)->close(); } } bool DeviceManager::openDevice(bool useNULL) { Device* pDevice = new Device(newID, useNULL); if ( pDevice->open() ) { ++newID; pDevice->addDisposeListener(this); devices.insert( devices.end(), pDevice ); setCurrent( pDevice->getID() ); return true; } else { delete pDevice; return false; } } Device* DeviceManager::getCurrentDevice() { if ( current != devices.end() ) return *current; else return NULL; } Device* DeviceManager::getAnyDevice() { Device* pDevice = getCurrentDevice(); if (pDevice == NULL) { if (openDevice(useNULLDevice)) pDevice = getCurrentDevice(); } return pDevice; } Device* DeviceManager::getDevice(int id) { for (Container::iterator i = devices.begin() ; i != devices.end() ; ++i ) { if ( (*i)->getID() == id ) return *i; } return NULL; } bool DeviceManager::setCurrent(int id, bool silent) { char buffer[64]; Container::iterator i; for (i = devices.begin() ; i != devices.end() ; ++ i ) { if ( (*i)->getID() == id ) break; } if ( i != devices.end() ) { if ( !silent && current != devices.end() ) { sprintf(buffer, "RGL device %d", (*current)->getID() ); (*current)->setName(buffer); } current = i; if ( !silent ) { sprintf(buffer, "RGL device %d [Focus]", (*current)->getID() ); (*current)->setName(buffer); } return true; } else return false; } int DeviceManager::getCurrent() { if ( current != devices.end() ) return (*current)->getID(); else return 0; } int DeviceManager::getDeviceCount() { int result = 0; for (Container::iterator i = devices.begin(); i != devices.end() ; ++i, ++result); return result; } void DeviceManager::getDeviceIds(int *buffer, int bufsize) { int count = 0; for (Container::iterator i = devices.begin(); i != devices.end() && count < bufsize; ++i, ++count) { *(buffer++) = (*i)->getID(); } } /** * Device disposed handler **/ void DeviceManager::notifyDisposed(Disposable* disposed) { Container::iterator pos = std::find( devices.begin(), devices.end(), static_cast( disposed ) ); assert( pos != devices.end() ); if ( pos == current ) { if ( devices.size() == 1 ) current = devices.end(); else nextDevice(); } devices.erase(pos); } void DeviceManager::nextDevice() { if ( current != devices.end() ) { // cycle to next Iterator next = ++current; if ( next == devices.end() ) next = devices.begin(); setCurrent( (*next)->getID() ); } else { // ignore: no devices } } void DeviceManager::previousDevice() { if ( current != devices.end() ) { // cycle to previous Iterator prev = current; if (prev == devices.begin() ) prev = devices.end(); --prev; setCurrent( (*prev)->getID() ); } else { // ignore: no devices } } bool DeviceManager::createTestWindow() { bool result = false; Device* pDevice = new Device(newID, false); if ( pDevice ) { if ( pDevice->hasWindow() ) result = true; pDevice->close(); delete pDevice; } return result; } rgl/src/glgui.cpp0000644000176200001440000001443314142256754013457 0ustar liggesusers// C++ source // This file is part of RGL. // #include #ifdef HAVE_FREETYPE #include "FTGL/ftgl.h" #include "R.h" #endif #include "types.h" #include "glgui.h" #include "gl2ps.h" #include "opengl.h" #include "RenderContext.h" #include "subscene.h" #include "platform.h" using namespace rgl; // // CLASS // GLFont // GLboolean GLFont::justify(double twidth, double theight, double adjx, double adjy, double adjz, int pos, const RenderContext& rc) { #ifndef RGL_NO_OPENGL GLdouble pos1[4], pos2[4]; double basex = 0.0, basey = 0.0, basez = 0.5, scaling = 1.0; GLboolean valid; gl2ps_centering = GL2PS_TEXT_BL; if (pos) { double offset = adjx, w = width("m"); switch(pos) { case 0: case 1: case 3: case 5: case 6: adjx = 0.5; break; case 2: adjx = 1.0 + w*offset/twidth; break; case 4: adjx = -w*offset/twidth; break; } switch(pos) { case 0: case 2: case 4: case 5: case 6: adjy = 0.5; break; case 1: adjy = 1.0 + offset; break; case 3: adjy = -offset; break; } switch(pos) { case 0: case 1: case 2: case 3: case 4: adjz = 0.5; break; case 5: adjz = 1.0 + offset; break; case 6: adjz = -offset; break; } } if (adjx > 0) { if (rc.gl2psActive > GL2PS_NONE) scaling = GL2PS_SCALING; if ( adjx > 0.25 && rc.gl2psActive == GL2PS_POSITIONAL) { if (adjx < 0.75) { basex = 0.5; gl2ps_centering = GL2PS_TEXT_B; } else { basex = 1.0; gl2ps_centering = GL2PS_TEXT_BR; } } } if ((adjx != basex) || (adjy != basey) || (adjz != basez)) { glGetDoublev(GL_CURRENT_RASTER_POSITION, pos1); pos1[0] = pos1[0] - scaling*twidth*(adjx-basex); pos1[1] = pos1[1] - scaling*theight*(adjy-basey); pos1[2] = pos1[2] - scaling*theight*(adjz-basez)/1000.0; GLint pviewport[4] = {rc.subscene->pviewport.x, rc.subscene->pviewport.y, rc.subscene->pviewport.width, rc.subscene->pviewport.height}; GLdouble modelMatrix[16], projMatrix[16]; rc.subscene->modelMatrix.getData(modelMatrix); rc.subscene->projMatrix.getData(projMatrix); gluUnProject( pos1[0], pos1[1], pos1[2], modelMatrix, projMatrix, pviewport, pos2, pos2 + 1, pos2 + 2); glRasterPos3dv(pos2); } glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid); return valid; #else return 0; #endif } // // CLASS // GLBitmapFont // GLBitmapFont::~GLBitmapFont() { delete [] widths; #ifndef RGL_NO_OPENGL if (nglyph) glDeleteLists(listBase+GL_BITMAP_FONT_FIRST_GLYPH, nglyph); #endif } double GLBitmapFont::width(const char* text) { double result = 0.0; for(int i=0; text[i]; i++) { int c; if ((int)(text[i]) >= (int)firstGlyph && (c = (int)(text[i]) - (int)firstGlyph) < (int)nglyph) result += widths[(int)c]; } return result; } double GLBitmapFont::width(const wchar_t* text) { double result = 0.0; for(int i=0; text[i]; i++) { wchar_t c; if ((int)text[i] >= (int)firstGlyph && (c = (int)(text[i]) - (int)firstGlyph) < (int)nglyph) result += widths[c]; } return result; } double GLBitmapFont::height() { return ascent; } bool GLBitmapFont::valid(const char* text) { for (int i=0; text[i]; i++) if ((int)text[i] < (int)firstGlyph || (int)text[i] - (int)firstGlyph >= (int)nglyph) return false; return true; } void GLBitmapFont::draw(const char* text, int length, double adjx, double adjy, double adjz, int pos, const RenderContext& rc) { #ifndef RGL_NO_OPENGL if (justify(width(text), height(), adjx, adjy, adjz, pos, rc)) { if (rc.gl2psActive == GL2PS_NONE) { glListBase(listBase); glCallLists(length, GL_UNSIGNED_BYTE, text); } else gl2psTextOpt(text, GL2PS_FONT, static_cast(GL2PS_FONTSIZE*cex), gl2ps_centering, 0.0); } #endif } void GLBitmapFont::draw(const wchar_t* text, int length, double adjx, double adjy, double adjz, int pos, const RenderContext& rc) { #ifndef RGL_NO_OPENGL if (justify(width(text), height(), adjx, adjy, adjz, pos, rc)) { GLenum type = sizeof(wchar_t) == 4 ? GL_UNSIGNED_INT : sizeof(wchar_t) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE ; if (rc.gl2psActive == GL2PS_NONE) { glListBase(listBase); glCallLists(length, type, text); } // gl2ps doesn't support wchar_t? Should convert? } #endif } #ifdef HAVE_FREETYPE GLFTFont::GLFTFont(const char* in_family, int in_style, double in_cex, const char* in_fontname) : GLFont(in_family, in_style, in_cex, in_fontname, true) { font=new FTGLPixmapFont(fontname); if (font->Error()) { errmsg = "Cannot create Freetype font"; delete font; font = NULL; } else { unsigned int size = static_cast(16*cex + 0.5); if (size<1) { size=1; } if (!font->FaceSize(size)) { errmsg = "Cannot create Freetype font of requested size"; delete font; font = NULL; } } /* font->CharMap(ft_encoding_unicode); if (font->Error()) { error("Cannot set unicode encoding."); }*/ } GLFTFont::~GLFTFont() { if (font) delete font; } double GLFTFont::width(const char* text) { return font->Advance(text); } double GLFTFont::width(const wchar_t* text) { return font->Advance(text); } double GLFTFont::height() { return font->Ascender(); } void GLFTFont::draw(const char* text, int length, double adjx, double adjy, double adjz, int pos, const RenderContext& rc) { if ( justify( width(text), height(), adjx, adjy, adjz, pos, rc ) ) { if (rc.gl2psActive == GL2PS_NONE) font->Render(text); else gl2psTextOpt(text, GL2PS_FONT, static_cast(GL2PS_FONTSIZE*cex), gl2ps_centering, 0.0); } } void GLFTFont::draw(const wchar_t* text, int length, double adjx, double adjy, double adjz, int pos, const RenderContext& rc) { if ( justify( width(text), height(), adjx, adjy, adjz, pos, rc ) ) { if (rc.gl2psActive == GL2PS_NONE) font->Render(text); } } #endif rgl/src/pretty.c0000644000176200001440000001462414100762641013330 0ustar liggesusers/* This file is taken from the R sources, r61744 of src/appl/pretty.c, with minimal changes */ #include "pretty.h" #include #include #include #include /* * R : A Computer Language for Statistical Data Analysis * Copyright (C) 1995-2012 The R Core Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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, a copy is available at * http://www.r-project.org/Licenses/ */ /* Pretty Intervals * ---------------- * Constructs m "pretty" values which cover the given interval *lo <= *up * m ~= *ndiv + 1 (i.e., ndiv := approximate number of INTERVALS) * * It is not quite clear what should happen for *lo = *up; * S itself behaves quite funilly, then. * * In my opinion, a proper 'pretty' should always ensure * *lo < *up, and hence *ndiv >=1 in the result. * However, in S and here, we allow *lo == *up, and *ndiv = 0. * Note however, that we are NOT COMPATIBLE to S. [Martin M.] * * NEW (0.63.2): ns, nu are double (==> no danger of integer overflow) * * We determine * if the interval (up - lo) is ``small'' [<==> i_small == TRUE, below]. * For the ``i_small'' situation, there is a parameter shrink_sml, * the factor by which the "scale" is shrunk. ~~~~~~~~~~ * It is advisable to set it to some (smaller) integer power of 2, * since this enables exact floating point division. */ /* Leave out all the R includes that we can #ifdef HAVE_CONFIG_H #include #endif #ifdef ENABLE_NLS #include #define _(String) gettext (String) #else #define _(String) (String) #endif #include #include #include #include #include #ifdef DEBUGpr # include #endif #ifdef HAVE_VISIBILITY_ATTRIBUTE # define attribute_hidden __attribute__ ((visibility ("hidden"))) #else # define attribute_hidden #endif */ /* non-API, used by rgl */ double R_pretty0(double *lo, double *up, int *ndiv, int min_n, double shrink_sml, double high_u_fact[], int eps_correction, int return_bounds) { /* From version 0.65 on, we had rounding_eps := 1e-5, before, r..eps = 0 * 1e-7 is consistent with seq.default() */ #define rounding_eps 1e-7 #define h high_u_fact[0] #define h5 high_u_fact[1] double dx, cell, unit, base, U; double ns, nu; int k; Rboolean i_small; dx = *up - *lo; /* cell := "scale" here */ if(dx == 0 && *up == 0) { /* up == lo == 0 */ cell = 1; i_small = TRUE; } else { cell = fmax2(fabs(*lo),fabs(*up)); /* U = upper bound on cell/unit */ U = (1 + (h5 >= 1.5*h+.5)) ? 1/(1+h) : 1.5/(1+h5); /* added times 3, as several calculations here */ i_small = dx < cell * U * imax2(1,*ndiv) * DBL_EPSILON *3; } /*OLD: cell = FLT_EPSILON+ dx / *ndiv; FLT_EPSILON = 1.192e-07 */ if(i_small) { if(cell > 10) cell = 9 + cell/10; cell *= shrink_sml; if(min_n > 1) cell /= min_n; } else { cell = dx; if(*ndiv > 1) cell /= *ndiv; } if(cell < 20*DBL_MIN) { /* warning(_("Internal(pretty()): very small range.. corrected")); */ cell = 20*DBL_MIN; } else if(cell * 10 > DBL_MAX) { /* warning(_("Internal(pretty()): very large range.. corrected")); */ cell = .1*DBL_MAX; } base = pow(10., floor(log10(cell))); /* base <= cell < 10*base */ /* unit : from { 1,2,5,10 } * base * such that |u - cell| is small, * favoring larger (if h > 1, else smaller) u values; * favor '5' more than '2' if h5 > h (default h5 = .5 + 1.5 h) */ unit = base; if((U = 2*base)-cell < h*(cell-unit)) { unit = U; if((U = 5*base)-cell < h5*(cell-unit)) { unit = U; if((U =10*base)-cell < h*(cell-unit)) unit = U; }} /* Result: c := cell, u := unit, b := base * c in [ 1, (2+ h) /(1+h) ] b ==> u= b * c in ( (2+ h)/(1+h), (5+2h5)/(1+h5)] b ==> u= 2b * c in ( (5+2h)/(1+h), (10+5h) /(1+h) ] b ==> u= 5b * c in ((10+5h)/(1+h), 10 ) b ==> u=10b * * ===> 2/5 *(2+h)/(1+h) <= c/u <= (2+h)/(1+h) */ ns = floor(*lo/unit+rounding_eps); nu = ceil (*up/unit-rounding_eps); #ifdef DEBUGpr REprintf("pretty(lo=%g,up=%g,ndiv=%d,min_n=%d,shrink=%g,high_u=(%g,%g)," "eps=%d)\n\t dx=%g; is.small:%d. ==> cell=%g; unit=%g\n", *lo, *up, *ndiv, min_n, shrink_sml, h, h5, eps_correction, dx, (int)i_small, cell, unit); #endif if(eps_correction && (eps_correction > 1 || !i_small)) { if(*lo != 0.0) *lo *= (1- DBL_EPSILON); else *lo = -DBL_MIN; if(*up != 0.0) *up *= (1+ DBL_EPSILON); else *up = +DBL_MIN; } #ifdef DEBUGpr if(ns*unit > *lo) REprintf("\t ns= %.0f -- while(ns*unit > *lo) ns--;\n", ns); #endif while(ns*unit > *lo + rounding_eps*unit) ns--; #ifdef DEBUGpr if(nu*unit < *up) REprintf("\t nu= %.0f -- while(nu*unit < *up) nu++;\n", nu); #endif while(nu*unit < *up - rounding_eps*unit) nu++; k = (int)(0.5 + nu - ns); if(k < min_n) { /* ensure that nu - ns == min_n */ #ifdef DEBUGpr REprintf("\tnu-ns=%.0f-%.0f=%d SMALL -> ensure nu-ns= min_n=%d\n", nu,ns, k, min_n); #endif k = min_n - k; if(ns >= 0.) { nu += k/2; ns -= k/2 + k%2;/* ==> nu-ns = old(nu-ns) + min_n -k = min_n */ } else { ns -= k/2; nu += k/2 + k%2; } *ndiv = min_n; } else { *ndiv = k; } if(return_bounds) { /* if()'s to ensure that result covers original range */ if(ns * unit < *lo) *lo = ns * unit; if(nu * unit > *up) *up = nu * unit; } else { *lo = ns; *up = nu; } #ifdef DEBUGpr REprintf("\t ns=%.0f ==> lo=%g\n", ns, *lo); REprintf("\t nu=%.0f ==> up=%g ==> ndiv = %d\n", nu, *up, *ndiv); #endif return unit; #undef h #undef h5 } /* attribute_hidden void R_pretty(double *lo, double *up, int *ndiv, int *min_n, double *shrink_sml, double *high_u_fact, int *eps_correction) { R_pretty0(lo, up, ndiv, *min_n, *shrink_sml, high_u_fact, *eps_correction, 1); } */ rgl/src/Color.cpp0000644000176200001440000001263314100762641013415 0ustar liggesusers#include "Color.h" #include "types.h" using namespace std; #include #include // for memcpy using namespace rgl; // // COLOR UTILS // // // FUNCTION // HexCharToNibble // static u8 HexCharToNibble(char c) { u8 nibble = 0; if ((c >= '0') && (c <= '9')) nibble = c - '0'; else if (( c >= 'A') && (c <= 'F')) nibble = (c - 'A') + 10; else if (( c >= 'a') && (c <= 'f')) nibble = (c - 'a') + 10; return nibble; } // // FUNCTION // StringToRGB8 // static void StringToRGB8(const char* string, u8* colorptr) { char* strptr = (char*) string; int cnt = 0; if (( *strptr++ == '#') && (cnt < 3)) { char c; while( (c = *strptr++) != '\0' ) { u8 component; component = static_cast(HexCharToNibble(c) << 4); if ( (c = *strptr++) == '\0') break; component |= HexCharToNibble(c); *colorptr++ = component; cnt++; } } for(int i=cnt;i<3;i++) *colorptr++ = 0x00; } ////////////////////////////////////////////////////////////////////////////// // // CLASS // Color // // Color::Color() { data[0] = 1.0f; data[1] = 1.0f; data[2] = 1.0f; data[3] = 1.0f; } Color::Color(float red, float green, float blue, float alpha) { data[0] = red; data[1] = green; data[2] = blue; data[3] = alpha; } Color::Color(u8 red, u8 green, u8 blue, u8 alpha) { data[0] = ((float)red)/255.0f; data[1] = ((float)green)/255.0f; data[2] = ((float)blue)/255.0f; data[3] = ((float)alpha)/255.0f; } Color::Color(const char* string) { u8 tmp[4]; tmp[3] = 255; StringToRGB8(string, tmp); for (int i=0;i<4;i++) data[i] = ((float)tmp[i])/255.0f; } void Color::set3iv(int* color) { data[0] = ((float)color[0])/255.0f; data[1] = ((float)color[1])/255.0f; data[2] = ((float)color[2])/255.0f; data[3] = 1.0f; } // TODO: move to rendergl.cpp #include "opengl.h" void Color::useClearColor() const { #ifndef RGL_NO_OPENGL glClearColor(data[0],data[1],data[2], data[3]); #endif } void Color::useColor() const { #ifndef RGL_NO_OPENGL glColor4fv(data); #endif } ////////////////////////////////////////////////////////////////////////////// // // CLASS // ColorArray // ColorArray::ColorArray() { arrayptr = NULL; ncolor = 0; nalpha = 0; } ColorArray::ColorArray( Color& bg, Color &fg ) { ncolor = 2; nalpha = 2; arrayptr = (u8*) realloc( NULL, sizeof(u8) * 4 * ncolor); arrayptr[0] = bg.getRedub(); arrayptr[1] = bg.getBlueub(); arrayptr[2] = bg.getGreenub(); arrayptr[3] = bg.getAlphaub(); arrayptr[4] = fg.getRedub(); arrayptr[5] = fg.getBlueub(); arrayptr[6] = fg.getGreenub(); arrayptr[7] = fg.getAlphaub(); hint_alphablend = ( (bg.getAlphaub() < 255) || (fg.getAlphaub() < 255) ) ? true : false; } ColorArray::ColorArray( ColorArray& src ) { ncolor = src.ncolor; nalpha = src.nalpha; hint_alphablend = src.hint_alphablend; if (ncolor > 0) { arrayptr = (u8*) realloc( NULL, sizeof(u8) * 4 * ncolor); memcpy( arrayptr, src.arrayptr, sizeof(u8) * 4 * ncolor); } else { arrayptr = NULL; } } ColorArray::~ColorArray() { if (arrayptr) free(arrayptr); } void ColorArray::set( int in_ncolor, char** in_color, int in_nalpha, double* in_alpha) { ncolor = getMax(in_ncolor, in_nalpha); nalpha = in_nalpha; u8* ptr = arrayptr = (u8*) realloc( arrayptr, sizeof(u8) * 4 * ncolor); hint_alphablend = false; for (unsigned int i=0;i 0) { u8 alpha = (u8) ( clamp( (float) in_alpha[i%in_nalpha], 0.0f, 1.0f) * 255.0f ); if (alpha < 255) hint_alphablend = true; ptr[3] = alpha; } else ptr[3] = 0xFF; ptr += 4; } } void ColorArray::set( int in_ncolor, int* in_color, int in_nalpha, double* in_alpha) { ncolor = getMax(in_ncolor, in_nalpha); nalpha = in_nalpha; u8* ptr = arrayptr = (u8*) realloc( arrayptr, sizeof(u8) * 4 * ncolor); hint_alphablend = false; for (unsigned int i=0;i 0) { u8 alpha = (u8) ( clamp( (float) in_alpha[i%in_nalpha], 0.0f, 1.0f) * 255.0f ); if (alpha < 255) hint_alphablend = true; ptr[3] = alpha; } else ptr[3] = 0xFF; ptr += 4; } } unsigned int ColorArray::getLength() const { return ncolor; } bool ColorArray::hasAlpha() const { return hint_alphablend; } void ColorArray::useArray() const { #ifndef RGL_NO_OPENGL glColorPointer(4, GL_UNSIGNED_BYTE, 0, (const GLvoid*) arrayptr ); #endif } void ColorArray::useColor(int index) const { #ifndef RGL_NO_OPENGL glColor4ubv( (const GLubyte*) &arrayptr[ index * 4] ); #endif } Color ColorArray::getColor(int index) const { return Color( arrayptr[index*4], arrayptr[index*4+1], arrayptr[index*4+2], arrayptr[index*4+3] ); } void ColorArray::recycle(unsigned int newsize) { if (ncolor != newsize) { if (ncolor > 1) { if (newsize > 0) { arrayptr = (u8*) realloc(arrayptr, sizeof(u8)*4*newsize); for(unsigned int i=ncolor;i #include #endif // --------------------------------------------------------------------------- #ifdef RGL_W32 #include #include #include #include #include #endif // --------------------------------------------------------------------------- #ifdef RGL_X11 #include #include #endif #endif // RGL_NO_OPENGL // --------------------------------------------------------------------------- #endif // RGL_OPENGL_H rgl/src/TextSet.cpp0000644000176200001440000001046114142256754013745 0ustar liggesusers#include "TextSet.h" #include "glgui.h" #include "R.h" #include "BBoxDeco.h" #include "subscene.h" #ifdef HAVE_FREETYPE #include #endif using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // TextSet // // INTERNAL TEXTS STORAGE // texts are copied to a buffer without null byte // a separate length buffer holds string lengths in order // TextSet::TextSet(Material& in_material, int in_ntexts, char** in_texts, double *in_center, double in_adjx, double in_adjy, double in_adjz, int in_ignoreExtent, FontArray& in_fonts, int in_npos, const int* in_pos) : Shape(in_material, in_ignoreExtent), textArray(in_ntexts, in_texts), npos(in_npos) { int i; material.lit = false; material.colorPerVertex(false); adjx = in_adjx; adjy = in_adjy; adjz = in_adjz; // init vertex array vertexArray.alloc(in_ntexts); fonts = in_fonts; #ifdef HAVE_FREETYPE blended = true; #endif for (i=0;ivalid(textArray[i].text)) error("text %d contains unsupported character", i+1); } pos = new int[npos]; for (i=0; i= 0) { Subscene* subscene = renderContext->subscene; bboxdeco = subscene->get_bboxdeco(); } GLFont* font; Vertex pt = vertexArray[index]; if (bboxdeco) pt = bboxdeco->marginVecToDataVec(pt, renderContext, &material); if (!pt.missing()) { GLboolean valid; material.useColor(index); glRasterPos3f( pt.x, pt.y, pt.z ); glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid); if (valid) { font = fonts[index % fonts.size()]; if (font) { String text = textArray[index]; font->draw( text.text, text.length, adjx, adjy, adjz, pos[index % npos], *renderContext ); } } } #endif } void TextSet::drawEnd(RenderContext* renderContext) { #ifndef RGL_NO_OPENGL material.endUse(renderContext); Shape::drawEnd(renderContext); #endif } int TextSet::getAttributeCount(AABox& bbox, AttribID attrib) { switch (attrib) { case FAMILY: case FONT: case CEX: return static_cast(fonts.size()); case TEXTS: case VERTICES: return textArray.size(); case ADJ: return 1; case POS: return pos[0] ? npos : 0; } return Shape::getAttributeCount(bbox, attrib); } void TextSet::getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result) { int n = getAttributeCount(bbox, attrib); if (first + count < n) n = first + count; if (first < n) { switch(attrib) { case VERTICES: while (first < n) { *result++ = vertexArray[first].x; *result++ = vertexArray[first].y; *result++ = vertexArray[first].z; first++; } return; case CEX: while (first < n) *result++ = fonts[first++]->cex; return; case FONT: while (first < n) *result++ = fonts[first++]->style; return; case ADJ: *result++ = adjx; *result++ = adjy; *result++ = adjz; return; case POS: while (first < n) *result++ = pos[first++]; return; } Shape::getAttribute(bbox, attrib, first, count, result); } } String TextSet::getTextAttribute(AABox& bbox, AttribID attrib, int index) { int n = getAttributeCount(bbox, attrib); if (index < n) { switch (attrib) { case TEXTS: return textArray[index]; case FAMILY: char* family = fonts[index]->family; return String(static_cast(strlen(family)), family); } } return Shape::getTextAttribute(bbox, attrib, index); } rgl/src/gl2ps.h0000644000176200001440000002064414100762641013034 0ustar liggesusers/* * GL2PS, an OpenGL to PostScript Printing Library * Copyright (C) 1999-2017 C. Geuzaine * * This program is free software; you can redistribute it and/or * modify it under the terms of either: * * a) the GNU Library General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your * option) any later version; or * * b) the GL2PS License as published by Christophe Geuzaine, either * version 2 of the License, or (at your option) any later version. * * 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 either * the GNU Library General Public License or the GL2PS License for * more details. * * You should have received a copy of the GNU Library General Public * License along with this library in the file named "COPYING.LGPL"; * if not, write to the Free Software Foundation, Inc., 51 Franklin * Street, Fifth Floor, Boston, MA 02110-1301, USA. * * You should have received a copy of the GL2PS License with this * library in the file named "COPYING.GL2PS"; if not, I will be glad * to provide one. * * For the latest info about gl2ps and a full list of contributors, * see http://www.geuz.org/gl2ps/. * * Please report all bugs and problems to . */ #ifndef __GL2PS_H__ #define __GL2PS_H__ #ifndef RGL_NO_OPENGL #include #include /* Define GL2PSDLL at compile time to build a Windows DLL */ #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) # if defined(_MSC_VER) # pragma warning(disable:4115) # pragma warning(disable:4127) # pragma warning(disable:4996) # endif # if !defined(NOMINMAX) # define NOMINMAX # include # undef NOMINMAX # else # include # endif # if defined(GL2PSDLL) # if defined(GL2PSDLL_EXPORTS) # define GL2PSDLL_API __declspec(dllexport) # else # define GL2PSDLL_API __declspec(dllimport) # endif # else # define GL2PSDLL_API # endif #else # define GL2PSDLL_API #endif #if defined(__APPLE__) || defined(HAVE_OPENGL_GL_H) #define GL_SILENCE_DEPRECATION # include #else # include #endif /* Support for compressed PostScript/PDF/SVG and for embedded PNG images in SVG */ #if defined(HAVE_ZLIB) || defined(HAVE_LIBZ) # define GL2PS_HAVE_ZLIB # if defined(HAVE_LIBPNG) || defined(HAVE_PNG) # define GL2PS_HAVE_LIBPNG # endif #endif #if defined(HAVE_NO_VSNPRINTF) # define GL2PS_HAVE_NO_VSNPRINTF #endif /* Version number */ #define GL2PS_MAJOR_VERSION 1 #define GL2PS_MINOR_VERSION 4 #define GL2PS_PATCH_VERSION 0 #define GL2PS_EXTRA_VERSION "" #define GL2PS_VERSION (GL2PS_MAJOR_VERSION + \ 0.01 * GL2PS_MINOR_VERSION + \ 0.0001 * GL2PS_PATCH_VERSION) #define GL2PS_COPYRIGHT "(C) 1999-2017 C. Geuzaine" /* Output file formats (the values and the ordering are important!) */ #define GL2PS_PS 0 #define GL2PS_EPS 1 #define GL2PS_TEX 2 #define GL2PS_PDF 3 #define GL2PS_SVG 4 #define GL2PS_PGF 5 /* Sorting algorithms */ #define GL2PS_NO_SORT 1 #define GL2PS_SIMPLE_SORT 2 #define GL2PS_BSP_SORT 3 /* Message levels and error codes */ #define GL2PS_SUCCESS 0 #define GL2PS_INFO 1 #define GL2PS_WARNING 2 #define GL2PS_ERROR 3 #define GL2PS_NO_FEEDBACK 4 #define GL2PS_OVERFLOW 5 #define GL2PS_UNINITIALIZED 6 /* Options for gl2psBeginPage */ #define GL2PS_NONE 0 #define GL2PS_DRAW_BACKGROUND (1<<0) #define GL2PS_SIMPLE_LINE_OFFSET (1<<1) #define GL2PS_SILENT (1<<2) #define GL2PS_BEST_ROOT (1<<3) #define GL2PS_OCCLUSION_CULL (1<<4) #define GL2PS_NO_TEXT (1<<5) #define GL2PS_LANDSCAPE (1<<6) #define GL2PS_NO_PS3_SHADING (1<<7) #define GL2PS_NO_PIXMAP (1<<8) #define GL2PS_USE_CURRENT_VIEWPORT (1<<9) #define GL2PS_COMPRESS (1<<10) #define GL2PS_NO_BLENDING (1<<11) #define GL2PS_TIGHT_BOUNDING_BOX (1<<12) #define GL2PS_NO_OPENGL_CONTEXT (1<<13) /* Arguments for gl2psEnable/gl2psDisable */ #define GL2PS_POLYGON_OFFSET_FILL 1 #define GL2PS_POLYGON_BOUNDARY 2 #define GL2PS_LINE_STIPPLE 3 #define GL2PS_BLEND 4 /* Arguments for gl2psLineCap/Join */ #define GL2PS_LINE_CAP_BUTT 0 #define GL2PS_LINE_CAP_ROUND 1 #define GL2PS_LINE_CAP_SQUARE 2 #define GL2PS_LINE_JOIN_MITER 0 #define GL2PS_LINE_JOIN_ROUND 1 #define GL2PS_LINE_JOIN_BEVEL 2 /* Text alignment (o=raster position; default mode is BL): +---+ +---+ +---+ +---+ +---+ +---+ +-o-+ o---+ +---o | o | o | | o | | | | | | | | | | | | +---+ +---+ +---+ +-o-+ o---+ +---o +---+ +---+ +---+ C CL CR B BL BR T TL TR */ #define GL2PS_TEXT_C 1 #define GL2PS_TEXT_CL 2 #define GL2PS_TEXT_CR 3 #define GL2PS_TEXT_B 4 #define GL2PS_TEXT_BL 5 #define GL2PS_TEXT_BR 6 #define GL2PS_TEXT_T 7 #define GL2PS_TEXT_TL 8 #define GL2PS_TEXT_TR 9 typedef GLfloat GL2PSrgba[4]; typedef GLfloat GL2PSxyz[3]; typedef struct { GL2PSxyz xyz; GL2PSrgba rgba; } GL2PSvertex; /* Primitive types */ #define GL2PS_NO_TYPE -1 #define GL2PS_TEXT 1 #define GL2PS_POINT 2 #define GL2PS_LINE 3 #define GL2PS_QUADRANGLE 4 #define GL2PS_TRIANGLE 5 #define GL2PS_PIXMAP 6 #define GL2PS_IMAGEMAP 7 #define GL2PS_IMAGEMAP_WRITTEN 8 #define GL2PS_IMAGEMAP_VISIBLE 9 #define GL2PS_SPECIAL 10 #if defined(__cplusplus) extern "C" { #endif GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer, GLint viewport[4], GLint format, GLint sort, GLint options, GLint colormode, GLint colorsize, GL2PSrgba *colormap, GLint nr, GLint ng, GLint nb, GLint buffersize, FILE *stream, const char *filename); GL2PSDLL_API GLint gl2psEndPage(void); GL2PSDLL_API GLint gl2psSetOptions(GLint options); GL2PSDLL_API GLint gl2psGetOptions(GLint *options); GL2PSDLL_API GLint gl2psBeginViewport(GLint viewport[4]); GL2PSDLL_API GLint gl2psEndViewport(void); GL2PSDLL_API GLint gl2psText(const char *str, const char *fontname, GLshort fontsize); GL2PSDLL_API GLint gl2psTextOpt(const char *str, const char *fontname, GLshort fontsize, GLint align, GLfloat angle); GL2PSDLL_API GLint gl2psTextOptColor(const char *str, const char *fontname, GLshort fontsize, GLint align, GLfloat angle, GL2PSrgba color); GL2PSDLL_API GLint gl2psSpecial(GLint format, const char *str); GL2PSDLL_API GLint gl2psSpecialColor(GLint format, const char *str, GL2PSrgba rgba); GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height, GLint xorig, GLint yorig, GLenum format, GLenum type, const void *pixels); GL2PSDLL_API GLint gl2psEnable(GLint mode); GL2PSDLL_API GLint gl2psDisable(GLint mode); GL2PSDLL_API GLint gl2psPointSize(GLfloat value); GL2PSDLL_API GLint gl2psLineCap(GLint value); GL2PSDLL_API GLint gl2psLineJoin(GLint value); GL2PSDLL_API GLint gl2psLineWidth(GLfloat value); GL2PSDLL_API GLint gl2psBlendFunc(GLenum sfactor, GLenum dfactor); /* referenced in the documentation, but not fully documented */ GL2PSDLL_API GLint gl2psForceRasterPos(GL2PSvertex *vert); GL2PSDLL_API void gl2psAddPolyPrimitive(GLshort type, GLshort numverts, GL2PSvertex *verts, GLint offset, GLfloat ofactor, GLfloat ounits, GLushort pattern, GLint factor, GLfloat width, GLint linecap, GLint linejoin, char boundary); /* undocumented */ GL2PSDLL_API GLint gl2psDrawImageMap(GLsizei width, GLsizei height, const GLfloat position[3], const unsigned char *imagemap); GL2PSDLL_API const char *gl2psGetFileExtension(GLint format); GL2PSDLL_API const char *gl2psGetFormatDescription(GLint format); GL2PSDLL_API GLint gl2psGetFileFormat(); #if defined(__cplusplus) } #endif #endif #endif /* __GL2PS_H__ */ rgl/src/ABCLineSet.h0000644000176200001440000000203514100762641013650 0ustar liggesusers#ifndef ABCLINESET_H #define ABCLINESET_H #include "scene.h" #include "geom.h" #include "Shape.h" #include "PrimitiveSet.h" #include namespace rgl { class ABCLineSet : public LineSet { private: /* Use parametrization (x,y,z) + s*(a,b,c) */ int nLines; ARRAY base; /* (x,y,z) */ ARRAY direction; /* (a,b,c) */ public: ABCLineSet(Material& in_material, int in_nbase, double* in_base, int in_ndir, double* in_dir); /** * tell type. **/ virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "abclines", buflen); }; /** * overload to update segments first. */ virtual AABox& getBoundingBox(Subscene* subscene); /** * overload to update segments first. */ virtual void renderBegin(RenderContext* renderContext); /** * update mesh */ void updateSegments(const AABox& sceneBBox); /** * update then get attributes */ void getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result); }; } // namespace rgl #endif // PLANESET_H rgl/src/OpenGL/0000755000176200001440000000000014100762641012752 5ustar liggesusersrgl/src/OpenGL/gl.h0000644000176200001440000000644614100762641013537 0ustar liggesusers#ifndef __gl_h_ #define __gl_h_ /* This is extracted from gl.h, part of OpenGL. The following is the * original license statement from that file. */ /* ** License Applicability. Except to the extent portions of this file are ** made subject to an alternative license as permitted in the SGI Free ** Software License B, Version 1.1 (the "License"), the contents of this ** file are subject only to the provisions of the License. You may not use ** this file except in compliance with the License. You may obtain a copy ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: ** ** http://oss.sgi.com/projects/FreeB ** ** Note that, as provided in the License, the Software is distributed on an ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. ** ** Original Code. The Original Code is: OpenGL Sample Implementation, ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. ** Copyright in any portions created by third parties is as indicated ** elsewhere herein. All Rights Reserved. ** ** Additional Notice Provisions: This software was created using the ** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has ** not been independently verified as being compliant with the OpenGL(R) ** version 1.2.1 Specification. */ #include typedef uint32_t GLbitfield; typedef uint8_t GLboolean; typedef uint32_t GLenum; typedef float GLfloat; typedef int32_t GLint; typedef int16_t GLshort; typedef int32_t GLsizei; typedef uint32_t GLuint; typedef uint16_t GLushort; typedef double GLdouble; #ifdef __cplusplus extern "C" { #endif /*************************************************************/ /* AttribMask */ #define GL_DEPTH_BUFFER_BIT 0x00000100 #define GL_COLOR_BUFFER_BIT 0x00004000 /* BeginMode */ #define GL_POINTS 0x0000 #define GL_LINES 0x0001 #define GL_LINE_STRIP 0x0003 #define GL_TRIANGLES 0x0004 #define GL_QUADS 0x0007 /* Boolean */ #define GL_TRUE 1 #define GL_FALSE 0 /* ClipPlaneName */ #define GL_CLIP_PLANE0 0x3000 /* ErrorCode */ #define GL_NO_ERROR 0 /* PixelFormat */ #define GL_ALPHA 0x1906 #define GL_RGB 0x1907 #define GL_RGBA 0x1908 #define GL_LUMINANCE 0x1909 #define GL_LUMINANCE_ALPHA 0x190A /* TextureMagFilter */ #define GL_NEAREST 0x2600 #define GL_LINEAR 0x2601 /* TextureMinFilter */ #define GL_NEAREST_MIPMAP_NEAREST 0x2700 #define GL_LINEAR_MIPMAP_NEAREST 0x2701 #define GL_NEAREST_MIPMAP_LINEAR 0x2702 #define GL_LINEAR_MIPMAP_LINEAR 0x2703 /*************************************************************/ #ifdef __cplusplus } #endif #endif /* __gl_h_ */ rgl/src/geom.cpp0000644000176200001440000000773114100762641013271 0ustar liggesusers#include "geom.h" #include "R.h" using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // AABox // AABox::AABox() { invalidate(); } void AABox::invalidate(void) { vmax = Vertex( -FLT_MAX, -FLT_MAX, -FLT_MAX ); vmin = Vertex( FLT_MAX, FLT_MAX, FLT_MAX ); } void AABox::operator += (const Vertex& v) { if (!ISNAN(v.x)) { vmin.x = getMin(vmin.x, v.x); vmax.x = getMax(vmax.x, v.x); } if (!ISNAN(v.y)) { vmin.y = getMin(vmin.y, v.y); vmax.y = getMax(vmax.y, v.y); } if (!ISNAN(v.z)) { vmin.z = getMin(vmin.z, v.z); vmax.z = getMax(vmax.z, v.z); } } void AABox::operator += (const AABox& aabox) { if (aabox.isValid()) { *this += aabox.vmin; *this += aabox.vmax; } } void AABox::operator += (const Sphere& sphere) { *this += sphere.center - Vertex(sphere.radius,sphere.radius,sphere.radius); *this += sphere.center + Vertex(sphere.radius,sphere.radius,sphere.radius); } bool AABox::operator < (const AABox& that) const { return true; } bool AABox::isValid(void) const { return ((vmax.x >= vmin.x) && (vmax.y >= vmin.y) && (vmax.z >= vmin.z)) ? true : false; } Vertex AABox::getCenter(void) const { return Vertex( (vmax + vmin) * 0.5f ); } ////////////////////////////////////////////////////////////////////////////// // // CLASS // Sphere // Sphere::Sphere(const AABox& bbox) { Vertex hdiagonal( (bbox.vmax - bbox.vmin) * 0.5f ); center = bbox.getCenter(); radius = hdiagonal.getLength(); } Sphere::Sphere(const AABox& bbox, const Vertex& s) { Vertex hdiagonal( ((bbox.vmax - bbox.vmin) * 0.5f).scale(s) ); center = bbox.getCenter(); radius = hdiagonal.getLength(); } Sphere::Sphere(const float in_radius) : center(0.0f, 0.0f, 0.0f), radius(in_radius) { } Sphere::Sphere(const Vertex& in_center, const float in_radius) : center(in_center), radius(in_radius) { } ////////////////////////////////////////////////////////////////////////////// // // CLASS // Frustum // // // setup frustum to enclose the space given by a bounding sphere, // field-of-view angle and window size. // // window size is used to provide aspect ratio. // // void Frustum::enclose(float sphere_radius, float fovangle, int width, int height) { float s=0.5, t=1.0; if (fovangle != 0.0) { float fovradians = math::deg2rad(fovangle/2.0f); s = math::sin(fovradians); t = math::tan(fovradians); ortho = false; } else { ortho = true; } distance = sphere_radius / s; znear = distance - sphere_radius; zfar = znear + sphere_radius*2.0f; float hlen = t * znear; // hold aspect ratio 1:1 float hwidth, hheight; bool inside = false; if (inside) { // inside bounding sphere: fit to max(winsize) if (width >= height) { hwidth = hlen; hheight = hlen * ( (float)height ) / ( (float)width ); } else { hwidth = hlen * ( (float)width ) / ( (float)height ); hheight = hlen; } } else { // outside(in front of) bounding sphere: fit to min(winsize) if (width >= height) { hwidth = hlen * ( (float)width ) / ( (float)height ); hheight = hlen; } else { hwidth = hlen; hheight = hlen * ( (float)height ) / ( (float)width ); } } left = -hwidth; right = hwidth; bottom = -hheight; top = hheight; } Matrix4x4 Frustum::getMatrix() { double data[16]; memset(data, 0, sizeof(data)); if (ortho) { data[0] = 2/(right - left); data[5] = 2/(top - bottom); data[10] = -2/(zfar - znear); data[12] = -(right + left)/(right - left); data[13] = -(top + bottom)/(top - bottom); data[14] = -(zfar + znear)/(zfar - znear); data[15] = 1; } else { data[0] = 2*znear/(right - left); data[5] = 2*znear/(top - bottom); data[8] = (right + left)/(right - left); data[9] = (top + bottom)/(top - bottom); data[10] = -(zfar + znear)/(zfar - znear); data[11] = -1; data[14] = -2*zfar*znear/(zfar - znear); } return Matrix4x4(data); } rgl/src/PlaneSet.h0000644000176200001440000000215114100762641013511 0ustar liggesusers#ifndef PLANESET_H #define PLANESET_H #include "scene.h" #include "geom.h" #include "Shape.h" #include "PrimitiveSet.h" #include namespace rgl { class PlaneSet : public TriangleSet { private: /* Use parametrization ax + by + cz + d = 0 */ int nPlanes; ARRAY normal; /* (a,b,c) */ ARRAY offset; /* d */ public: PlaneSet(Material& in_material, int in_nnormal, double* in_normal, int in_noffset, double* in_offset); // ~PlaneSet(); /** * tell type. **/ virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "planes", buflen); }; /** * overload to update triangles first. */ virtual AABox& getBoundingBox(Subscene* subscene); /** * overload to update triangles first. */ virtual void renderBegin(RenderContext* renderContext); /** * update mesh */ void updateTriangles(const AABox& sceneBBox); /** * update then get attributes */ int getAttributeCount(AABox& bbox, AttribID attrib); void getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result); }; } // namespace rgl #endif // PLANESET_H rgl/src/par3d.cpp0000644000176200001440000004752214146464151013362 0ustar liggesusers/* Avoid conflict with Rinternals.h */ // #undef DEBUG #include "R.h" #include "Rversion.h" #include "DeviceManager.h" #include "rglview.h" #include "api.h" /* These defines are not in the installed version of R */ #define _ #define streql(s, t) (!strcmp((s), (t))) #include #include namespace rgl { void getObserver(double* ddata, Subscene* subscene); void setObserver(bool automatic, double* ddata, RGLView* rglview, Subscene* subscene); } using namespace rgl; /* These two are currently exposed, because observer3d uses them. */ void rgl::getObserver(double* ddata, Subscene* subscene) { UserViewpoint* userviewpoint = subscene->getUserViewpoint(); Vertex res = userviewpoint->getObserver(); ddata[0] = res.x; ddata[1] = res.y; ddata[2] = res.z; } void rgl::setObserver(bool automatic, double* ddata, RGLView* rglview, Subscene* subscene) { UserViewpoint* userviewpoint = subscene->getUserViewpoint(); userviewpoint->setObserver(automatic, Vertex(static_cast(ddata[0]), static_cast(ddata[1]), static_cast(ddata[2]))); rglview->update(); } /* These functions used to be in api.h and api.c, but are only accessed from par3d, so have been made static */ static void getZoom(double* zoom, Subscene* subscene) { UserViewpoint* userviewpoint = subscene->getUserViewpoint(); *zoom = userviewpoint->getZoom(); CHECKGLERROR; } static void setZoom(double* zoom, RGLView* rglview, Subscene* subscene) { UserViewpoint* userviewpoint = subscene->getUserViewpoint(); userviewpoint->setZoom(static_cast(*zoom) ); rglview->update(); CHECKGLERROR; } static void getFOV(double* fov, Subscene* subscene) { UserViewpoint* userviewpoint = subscene->getUserViewpoint(); *fov = userviewpoint->getFOV(); CHECKGLERROR; } static void setFOV(double* fov, RGLView* rglview, Subscene* sub) { UserViewpoint* userviewpoint = sub->getUserViewpoint(); userviewpoint->setFOV(static_cast(*fov)); rglview->update(); CHECKGLERROR; } static void getIgnoreExtent(int* ignoreExtent, Device* device) { *ignoreExtent = device->getIgnoreExtent(); CHECKGLERROR; } static void setIgnoreExtent(int* ignoreExtent, Device* device) { device->setIgnoreExtent(*ignoreExtent); CHECKGLERROR; } static void getSkipRedraw(int* skipRedraw, Device* device) { *skipRedraw = device->getSkipRedraw(); CHECKGLERROR; } static void setSkipRedraw(int* skipRedraw, Device* device) { device->setSkipRedraw(*skipRedraw); CHECKGLERROR; } static void getMouseMode(int *button, int* mode, Subscene* subscene) { *mode = static_cast( subscene->getMouseMode(*button) ); CHECKGLERROR; } static void setMouseMode(int* button, int* mode, RGLView* rglview, Subscene* subscene) { subscene->setMouseMode(*button, (MouseModeID)(*mode)); if (*button == bnNOBUTTON) rglview->windowImpl->watchMouse(subscene->getRootSubscene()->mouseNeedsWatching()); CHECKGLERROR; } static void getUserMatrix(double* userMatrix, Subscene* subscene) { subscene->getUserMatrix(userMatrix); CHECKGLERROR; } static void setUserMatrix(double* userMatrix, RGLView* rglview, Subscene* subscene) { subscene->setUserMatrix(userMatrix); rglview->update(); CHECKGLERROR; } static void getUserProjection(double* userProjection, Subscene* subscene) { subscene->getUserProjection(userProjection); CHECKGLERROR; } static void setUserProjection(double* userProjection, RGLView* rglview, Subscene* subscene) { subscene->setUserProjection(userProjection); rglview->update(); CHECKGLERROR; } static void getPosition(double* position, Subscene* subscene) { subscene->getPosition(position); CHECKGLERROR; } static void setPosition(double* position, RGLView* rglview, Subscene* subscene) { subscene->setPosition(position); rglview->update() CHECKGLERROR; } static void getScale(double* scale, Subscene* subscene) { subscene->getScale(scale); } static void setScale(double* scale, RGLView* rglview, Subscene* subscene) { subscene->setScale(scale); rglview->update(); CHECKGLERROR; } static void setViewport(double* viewport, Device* device, RGLView* rglview, Subscene* subscene) { subscene = subscene->getMaster(EM_VIEWPORT); int left, top, right, bottom; double x, y, width, height; if (subscene->getEmbedding(EM_VIEWPORT) == EMBED_REPLACE) { device->getWindowRect(&left, &top, &right, &bottom); width = right - left; height = bottom - top; bottom = 0; left = 0; } else { left = subscene->getParent()->pviewport.x; bottom = subscene->getParent()->pviewport.y; width = subscene->getParent()->pviewport.width; height = subscene->getParent()->pviewport.height; } x = (viewport[0]-left)/width; y = (viewport[1]-bottom)/height; width = viewport[2]/width; height = viewport[3]/height; subscene->setViewport(x, y, width, height); rglview->update(); } static void getViewport(int* viewport, Subscene* subscene) { viewport[0] = subscene->pviewport.x; viewport[1] = subscene->pviewport.y; viewport[2] = subscene->pviewport.width; viewport[3] = subscene->pviewport.height; CHECKGLERROR; } static void getWindowRect(int* rect, Device* device) { device->getWindowRect(rect, rect+1, rect+2, rect+3); CHECKGLERROR; } static void setWindowRect(int* rect, Device* dev) { dev->setWindowRect(rect[0], rect[1], rect[2], rect[3]); CHECKGLERROR; } static void getBoundingbox(double* bboxvec, Subscene* subscene) { const AABox& bbox = subscene->getBoundingBox(); bboxvec[0] = bbox.vmin.x; bboxvec[1] = bbox.vmax.x; bboxvec[2] = bbox.vmin.y; bboxvec[3] = bbox.vmax.y; bboxvec[4] = bbox.vmin.z; bboxvec[5] = bbox.vmax.z; CHECKGLERROR; } /* font access functions. These are only used from par3d */ static char* getFamily(RGLView* rglview) { const char* f = rglview->getFontFamily(); char* result; result = R_alloc(strlen(f)+1, 1); strcpy(result, f); CHECKGLERROR; return result; } static bool setFamily(const char *family, RGLView* rglview) { rglview->setFontFamily(family); CHECKGLERROR; return true; } static int getFont(RGLView* rglview) { int result = rglview->getFontStyle(); CHECKGLERROR; return result; } static bool setFont(int font, RGLView* rglview) { rglview->setFontStyle(font); CHECKGLERROR; return true; } static double getCex(RGLView* rglview) { double result = rglview->getFontCex(); CHECKGLERROR; return result; } static bool setCex(double cex, RGLView* rglview) { rglview->setFontCex(cex); CHECKGLERROR; return true; } static int getUseFreeType(RGLView* rglview) { int result = (int) rglview->getFontUseFreeType(); CHECKGLERROR; return result; } static bool setUseFreeType(bool useFreeType, RGLView* rglview) { rglview->setFontUseFreeType(useFreeType); CHECKGLERROR; return true; } static char* getFontname(RGLView* rglview) { char* result = NULL; const char* f = rglview->getFontname(); result = R_alloc(strlen(f)+1, 1); strcpy(result, f); CHECKGLERROR; return result; } static int getAntialias(RGLView* rglview) { return rglview->windowImpl->getAntialias(); } static int getMaxClipPlanes(RGLView* rglview) { return rglview->windowImpl->getMaxClipPlanes(); } static double getGlVersion() { #ifndef RGL_NO_OPENGL const char* version = (const char*)glGetString(GL_VERSION); if (version) return atof(version); else #endif return R_NaReal; } static int activeSubscene(RGLView* rglview) { return rglview->getActiveSubscene(); } /* par3d implementation based on R's par implementation * * Main functions: * par3d(.) * Specify(.) [ par(what = value) ] * Query(.) [ par(what) ] */ static void par_error(const char *what) { error(_("invalid value specified for rgl parameter \"%s\""), what); } static void lengthCheck(const char *what, SEXP v, int n) { if (length(v) != n) error(_("parameter \"%s\" has the wrong length"), what); } static void dimCheck(const char *what, SEXP v, int r, int c) { SEXP dim = coerceVector(getAttrib(v, R_DimSymbol), INTSXP); if (length(dim) != 2 || INTEGER(dim)[0] != r || INTEGER(dim)[1] != c) error(_("parameter \"%s\" has the wrong dimension"), what); } #ifdef UNUSED static void nonnegIntCheck(int x, const char *s) { if (x == NA_INTEGER || x < 0) par_error(s); } static void posIntCheck(int x, const char *s) { if (x == NA_INTEGER || x <= 0) par_error(s); } static void naIntCheck(int x, const char *s) { if (x == NA_INTEGER) par_error(s); } #endif static void posRealCheck(double x, const char *s) { if (!R_FINITE(x) || x <= 0) par_error(s); } #ifdef UNUSED static void nonnegRealCheck(double x, const char *s) { if (!R_FINITE(x) || x < 0) par_error(s); } static void naRealCheck(double x, const char *s) { if (!R_FINITE(x)) par_error(s); } #endif static void BoundsCheck(double x, double a, double b, const char *s) { /* Check if a <= x <= b */ if (!R_FINITE(x) || (R_FINITE(a) && x < a) || (R_FINITE(b) && x > b)) par_error(s); } /* These modes must match the definitions of mmTRACKBALL etc in rglview.h ! */ namespace rgl { const char* mouseModes[] = {"none", "trackball", "xAxis", "yAxis", "zAxis", "polar", "selecting", "zoom", "fov", "user", "push", "pull", "user2"}; const char* viewportlabels[] = {"x", "y", "width", "height"}; } #define mmLAST 10 #define wmLAST 13 /* At R 2.6.0, the type of the first arg to psmatch changed to const char *. Conditionally cast to char * if we're in an old version */ #if defined(R_VERSION) && R_VERSION < R_Version(2, 6, 0) #define OLDCAST (char *) #else #define OLDCAST #endif static void Specify(Device* dev, RGLView* rglview, Subscene* sub, const char *what, SEXP value) { /* Do NOT forget to update ../R/par3d.R */ /* if you ADD a NEW par !! */ SEXP x; double v; int iv; int success = 1; if (streql(what, "FOV")) { lengthCheck(what, value, 1); v = asReal(value); BoundsCheck(v, 0.0, 179.0, what); setFOV(&v, rglview, sub); } else if (streql(what, "ignoreExtent")) { lengthCheck(what, value, 1); iv = asLogical(value); setIgnoreExtent(&iv, dev); } else if (streql(what, "mouseMode")) { PROTECT(value = coerceVector(value, STRSXP)); if (length(value) > 5) par_error(what); for (int i=bnNOBUTTON; i<=bnWHEEL && i < length(value); i++) { if (STRING_ELT(value, i) != NA_STRING) { success = 0; /* check exact first, then partial */ for (int mode = 0; mode < (i != bnWHEEL ? mmLAST : wmLAST) ; mode++) { if (psmatch(OLDCAST mouseModes[mode], CHAR(STRING_ELT(value, i)), (Rboolean)TRUE)) { setMouseMode(&i, &mode, rglview, sub); success = 1; break; } } if (!success) { for (int mode = 0; mode < (i != 4 ? mmLAST : wmLAST) ; mode++) { if (psmatch(OLDCAST mouseModes[mode], CHAR(STRING_ELT(value, i)), (Rboolean)FALSE)) { setMouseMode(&i, &mode, rglview, sub); success = 1; break; } } } if (!success) par_error(what); } } UNPROTECT(1); } else if (streql(what, "listeners")) { x = coerceVector(value, INTSXP); rglview->setMouseListeners(sub, length(x), INTEGER(x)); } else if (streql(what, "skipRedraw")) { lengthCheck(what, value, 1); iv = asLogical(value); setSkipRedraw(&iv, dev); } else if (streql(what, "userMatrix")) { dimCheck(what, value, 4, 4); x = coerceVector(value, REALSXP); setUserMatrix(REAL(x), rglview, sub); } else if (streql(what, "userProjection")) { dimCheck(what, value, 4, 4); x = coerceVector(value, REALSXP); setUserProjection(REAL(x), rglview, sub); } else if (streql(what, "scale")) { lengthCheck(what, value, 3); x = coerceVector(value, REALSXP); setScale(REAL(x), rglview, sub); } else if (streql(what, "viewport")) { lengthCheck(what, value, 4); x = coerceVector(value, REALSXP); setViewport(REAL(x), dev, rglview, sub); } else if (streql(what, "zoom")) { lengthCheck(what, value, 1); v = asReal(value); posRealCheck(v, what); setZoom(&v, rglview, sub); } else if (streql(what, ".position")) { lengthCheck(what, value, 2); x = coerceVector(value, REALSXP); setPosition(REAL(x), rglview, sub); } else if (streql(what, "windowRect")) { lengthCheck(what, value, 4); x = coerceVector(value, INTSXP); setWindowRect(INTEGER(x), dev); } else if (streql(what, "family")) { lengthCheck(what, value, 1); x = coerceVector(value, STRSXP); if (!setFamily(CHAR(STRING_ELT(x, 0)), rglview)) success = 0; } else if (streql(what, "font")) { lengthCheck(what, value, 1); x=coerceVector(value, INTSXP); if (INTEGER(x)[0] < 1 || INTEGER(x)[0] > 5) { par_error(what); } if (!setFont(INTEGER(x)[0], rglview)) success = 0; } else if (streql(what, "cex")) { lengthCheck(what, value, 1); x=coerceVector(value, REALSXP); if (REAL(x)[0] <= 0) { par_error(what); } if (!setCex(REAL(x)[0],rglview)) success = 0; } else if (streql(what, "useFreeType")) { lengthCheck(what, value, 1); PROTECT(x=coerceVector(value, LGLSXP)); #ifndef HAVE_FREETYPE if (LOGICAL(x)[0] && strcmp( dev->getDevtype(), "null" )) warning("FreeType not supported in this build"); #endif if (!setUseFreeType(LOGICAL(x)[0], rglview)) success = 0; UNPROTECT(1); } else warning(_("parameter \"%s\" cannot be set"), what); if (!success) par_error(what); return; } /* Do NOT forget to update ../R/par3d.R */ /* if you ADD a NEW par !! */ static SEXP Query(Device* dev, RGLView* rglview, Subscene* sub, const char *what) { SEXP value, names; int i, mode, success = 1; char* buf; value = R_NilValue; if (streql(what, "FOV")) { PROTECT(value = allocVector(REALSXP, 1)); getFOV(REAL(value), sub); } else if (streql(what, "ignoreExtent")) { PROTECT(value = allocVector(LGLSXP, 1)); getIgnoreExtent(LOGICAL(value), dev); } else if (streql(what, "modelMatrix")) { PROTECT(value = allocMatrix(REALSXP, 4, 4)); sub->modelMatrix.getData(REAL(value)); } else if (streql(what, "mouseMode")) { PROTECT(value = allocVector(STRSXP, 5)); for (i=0; i<5; i++) { getMouseMode(&i, &mode, sub); if (mode < 0 || mode > wmLAST) mode = 0; SET_STRING_ELT(value, i, mkChar(mouseModes[mode])); } PROTECT(names = allocVector(STRSXP, 5)); SET_STRING_ELT(names, 0, mkChar("none")); SET_STRING_ELT(names, 1, mkChar("left")); SET_STRING_ELT(names, 2, mkChar("right")); SET_STRING_ELT(names, 3, mkChar("middle")); SET_STRING_ELT(names, 4, mkChar("wheel")); value = namesgets(value, names); UNPROTECT(2); /* names and old values */ PROTECT(value); } else if (streql(what, "observer")) { PROTECT(value = allocVector(REALSXP, 3)); rgl::getObserver(REAL(value), sub); } else if (streql(what, "projMatrix")) { PROTECT(value = allocMatrix(REALSXP, 4, 4)); sub->projMatrix.getData(REAL(value)); } else if (streql(what, "listeners")) { PROTECT(value = allocVector(INTSXP, sub->mouseListeners.size())); sub->getMouseListeners(length(value), INTEGER(value)); } else if (streql(what, "skipRedraw")) { PROTECT(value = allocVector(LGLSXP, 1)); getSkipRedraw(LOGICAL(value), dev); } else if (streql(what, "userMatrix")) { PROTECT(value = allocMatrix(REALSXP, 4, 4)); getUserMatrix(REAL(value), sub); } else if (streql(what, "userProjection")) { PROTECT(value = allocMatrix(REALSXP, 4, 4)); getUserProjection(REAL(value), sub); } else if (streql(what, "scale")) { PROTECT(value = allocVector(REALSXP, 3)); getScale(REAL(value), sub); } else if (streql(what, "viewport")) { PROTECT(value = allocVector(INTSXP, 4)); getViewport(INTEGER(value), sub); PROTECT(names = allocVector(STRSXP, 4)); for (i=0; i<4; i++) SET_STRING_ELT(names, i, mkChar(viewportlabels[i])); value = namesgets(value, names); UNPROTECT(2); PROTECT(value); } else if (streql(what, "zoom")) { PROTECT(value = allocVector(REALSXP, 1)); getZoom(REAL(value), sub); } else if (streql(what, "bbox")) { PROTECT(value = allocVector(REALSXP, 6)); getBoundingbox(REAL(value), sub); } else if (streql(what, ".position")) { PROTECT(value = allocVector(REALSXP, 2)); getPosition(REAL(value), sub); } else if (streql(what, "windowRect")) { PROTECT(value = allocVector(INTSXP, 4)); getWindowRect(INTEGER(value), dev); } else if (streql(what, "family")) { buf = getFamily(rglview); if (buf) { value = mkString(buf); } PROTECT(value); } else if (streql(what, "font")) { PROTECT(value = allocVector(INTSXP, 1)); INTEGER(value)[0] = getFont(rglview); success = INTEGER(value)[0] >= 0; } else if (streql(what, "cex")) { PROTECT(value = allocVector(REALSXP, 1)); REAL(value)[0] = getCex(rglview); success = REAL(value)[0] >= 0; } else if (streql(what, "useFreeType")) { int useFreeType = getUseFreeType(rglview); PROTECT(value = allocVector(LGLSXP, 1)); if (useFreeType < 0) { LOGICAL(value)[0] = false; success = 0; } else { LOGICAL(value)[0] = (bool)useFreeType; } } else if (streql(what, "fontname")) { buf = getFontname(rglview); if (buf) { value = mkString(buf); } PROTECT(value); } else if (streql(what, "antialias")) { PROTECT(value = allocVector(INTSXP, 1)); INTEGER(value)[0] = getAntialias(rglview); } else if (streql(what, "maxClipPlanes")) { PROTECT(value = allocVector(INTSXP, 1)); INTEGER(value)[0] = getMaxClipPlanes(rglview); } else if (streql(what, "glVersion")) { PROTECT(value = allocVector(REALSXP, 1)); REAL(value)[0] = getGlVersion(); } else if (streql(what, "activeSubscene")) { PROTECT(value = allocVector(INTSXP, 1)); INTEGER(value)[0] = activeSubscene(rglview); } else PROTECT(value); UNPROTECT(1); if (! success) error(_("unknown error getting rgl parameter \"%s\""), what); return value; } namespace rgl { extern DeviceManager* deviceManager; } SEXP rgl::rgl_par3d(SEXP device, SEXP subscene, SEXP args) { Device* dev; if (!deviceManager || !(dev = deviceManager->getDevice(asInteger(device)))) error(_("rgl device %d cannot be found"), asInteger(device)); RGLView* rglview = dev->getRGLView(); Scene* scene = rglview->getScene(); Subscene* sub = scene->getSubscene(asInteger(subscene)); if (!sub) error(_("rgl subscene %d cannot be found"), asInteger(subscene)); SEXP value; int nargs; nargs = length(args); if (isNewList(args)) { SEXP oldnames, newnames, tag, val; int i; PROTECT(newnames = allocVector(STRSXP, nargs)); PROTECT(value = allocVector(VECSXP, nargs)); PROTECT(oldnames = getAttrib(args, R_NamesSymbol)); for (i = 0 ; i < nargs ; i++) { if (oldnames != R_NilValue) tag = STRING_ELT(oldnames, i); else tag = R_NilValue; val = VECTOR_ELT(args, i); if (tag != R_NilValue && CHAR(tag)[0]) { SET_VECTOR_ELT(value, i, Query(dev, rglview, sub, CHAR(tag))); SET_STRING_ELT(newnames, i, tag); Specify(dev, rglview, sub, CHAR(tag), val); CHECKGLERROR; } else if (isString(val) && length(val) > 0) { tag = STRING_ELT(val, 0); if (tag != R_NilValue && CHAR(tag)[0]) { SET_VECTOR_ELT(value, i, Query(dev, rglview, sub, CHAR(tag))); SET_STRING_ELT(newnames, i, tag); CHECKGLERROR; } } else { SET_VECTOR_ELT(value, i, R_NilValue); SET_STRING_ELT(newnames, i, R_BlankString); } } setAttrib(value, R_NamesSymbol, newnames); UNPROTECT(3); } else { error(_("invalid parameter passed to par3d()")); return R_NilValue/* -Wall */; } return value; } rgl/src/rglview.cpp0000644000176200001440000003212514137472630014022 0ustar liggesusers// C++ source // This file is part of RGL. // #ifdef __sun #include #else #include #endif #include #include "rglview.h" #include "opengl.h" #include "lib.h" #include "rglmath.h" #include "pixmap.h" #include "fps.h" #include "gl2ps.h" #include "R.h" // for error() using namespace rgl; RGLView::RGLView(Scene* in_scene) : View(0,0,256,256,0), autoUpdate(false) { scene = in_scene; flags = 0; renderContext.rect.x = 0; renderContext.rect.y = 0; // size is set elsewhere activeSubscene = 0; } RGLView::~RGLView() { } void RGLView::show() { fps.init( getTime() ); } void RGLView::hide() { autoUpdate=false; } void RGLView::setWindowImpl(WindowImpl* impl) { View::setWindowImpl(impl); #if defined HAVE_FREETYPE renderContext.font = impl->getFont("sans", 1, 1, true); #else renderContext.font = impl->fonts[0]; #endif } Scene* RGLView::getScene() { return scene; } void RGLView::resize(int in_width, int in_height) { View::resize(in_width, in_height); renderContext.rect.width = in_width; renderContext.rect.height = in_height; update(); if (activeSubscene) { Subscene* subscene = scene->getSubscene(activeSubscene); if (subscene && subscene->drag) captureLost(); } } void RGLView::paint(void) { double last = renderContext.time; double t = getTime(); double dt = (last != 0.0f) ? last - t : 0.0f; renderContext.time = t; renderContext.deltaTime = dt; /* This doesn't do any actual plotting, but it calculates matrices etc., and may call user callbacks */ int saveRedraw = windowImpl->setSkipRedraw(1); scene->update(&renderContext); windowImpl->setSkipRedraw(saveRedraw); #ifndef RGL_NO_OPENGL /* This section does the OpenGL plotting */ if (windowImpl->beginGL()) { SAVEGLERROR; Subscene* subscene = scene->getCurrentSubscene(); scene->render(&renderContext); glViewport(0,0, width, height); if (subscene) { if (flags & FSHOWFPS && subscene->getSelectState() == msNONE) fps.render(renderContext.time, &renderContext ); } glFinish(); windowImpl->endGL(); SAVEGLERROR; } #endif } ////////////////////////////////////////////////////////////////////////////// // // user input // // NB: This code has to deal with three conflicting descriptions of pixel locations. // The calls to buttonPress, buttonRelease, etc. are given in OS window-relative // coordinates, which count mouseX from the left, mouseY down from the top. // These are translated into the OpenGL convention which counts Y up from the bottom, // or subscene-relative coordinates, up from the bottom of the viewport. // We use RGLView::translateCoords to go from OS window-relative to OpenGL window-relative, // and Subscene::translateCoords to go from OpenGL window-relative to viewport-relative. void RGLView::keyPress(int key) { switch(key) { case GUI_KeyF1: flags ^= FSHOWFPS; windowImpl->update(); break; case GUI_KeyESC: Subscene* subscene = scene->getCurrentSubscene(); if (subscene) subscene->setSelectState(msABORT); break; } } void RGLView::buttonPress(int button, int mouseX, int mouseY) { ModelViewpoint* modelviewpoint = scene->getCurrentSubscene()->getModelViewpoint(); if ( modelviewpoint->isInteractive() ) { translateCoords(&mouseX, &mouseY); Subscene* subscene = scene->whichSubscene(mouseX, mouseY); subscene->translateCoords(&mouseX, &mouseY); subscene->drag = button; activeSubscene = subscene->getObjID(); windowImpl->captureMouse(this); subscene->buttonBegin(button ,mouseX, mouseY); View::update(); } } void RGLView::buttonRelease(int button, int mouseX, int mouseY) { Subscene* subscene; if (activeSubscene && (subscene = scene->getSubscene(activeSubscene))) { windowImpl->releaseMouse(); subscene->drag = 0; subscene->buttonEnd(button); View::update(); } // Rprintf("release happened, activeSubscene=0\n"); activeSubscene = 0; } void RGLView::mouseMove(int mouseX, int mouseY) { if (activeSubscene) { translateCoords(&mouseX, &mouseY); Subscene* subscene = scene->getSubscene(activeSubscene); if (!subscene) { buttonRelease(0, mouseX, mouseY); return; } subscene->translateCoords(&mouseX, &mouseY); int vwidth = subscene->pviewport.width, vheight = subscene->pviewport.height; mouseX = clamp(mouseX, 0, vwidth-1); mouseY = clamp(mouseY, 0, vheight-1); if (windowImpl->beginGL()) { subscene->buttonUpdate(subscene->drag, mouseX, mouseY); windowImpl->endGL(); View::update(); } } else { ModelViewpoint* modelviewpoint = scene->getCurrentSubscene()->getModelViewpoint(); if ( modelviewpoint->isInteractive() ) { translateCoords(&mouseX, &mouseY); Subscene* subscene = scene->whichSubscene(mouseX, mouseY); if (subscene && subscene->getMouseMode(bnNOBUTTON) != mmNONE) { subscene->translateCoords(&mouseX, &mouseY); subscene->drag = bnNOBUTTON; subscene->buttonUpdate(bnNOBUTTON, mouseX, mouseY); View::update(); } } } } void RGLView::wheelRotate(int dir, int mouseX, int mouseY) { Subscene* subscene = NULL; ModelViewpoint* modelviewpoint = scene->getCurrentSubscene()->getModelViewpoint(); if ( modelviewpoint->isInteractive() ) { translateCoords(&mouseX, &mouseY); subscene = scene->whichSubscene(mouseX, mouseY); } if (!subscene) subscene = scene->getCurrentSubscene(); subscene->wheelRotate(dir); View::update(); } void RGLView::captureLost() { if (activeSubscene) { Subscene* subscene = scene->getSubscene(activeSubscene); if (subscene) { subscene->buttonEnd(subscene->drag); subscene->drag = 0; } } } // // snapshot // bool RGLView::snapshot(PixmapFileFormatID formatID, const char* filename) { bool success = false; if ( (formatID < PIXMAP_FILEFORMAT_LAST) && (pixmapFormat[formatID])) { // alloc pixmap memory Pixmap snapshot; if (snapshot.init(RGB24, width, height, 8)) { #ifndef RGL_NO_OPENGL paint(); if ( windowImpl->beginGL() ) { // read back buffer glPushAttrib(GL_PIXEL_MODE_BIT); glReadBuffer(GL_BACK); glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(0,0,width,height,GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*) snapshot.data); glPopAttrib(); windowImpl->endGL(); } else #else warning("this build of rgl does not support snapshots"); #endif snapshot.clear(); success = snapshot.save( pixmapFormat[formatID], filename ); } else error("unable to create pixmap"); } else error("pixmap save format not supported in this build"); return success; } bool RGLView::pixels( int* ll, int* size, int component, double* result ) { bool success = false; #ifndef RGL_NO_OPENGL GLenum format[] = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_DEPTH_COMPONENT, GL_LUMINANCE}; paint(); if ( windowImpl->beginGL() ) { /* * Some OSX systems appear to have a glReadPixels * bug causing segfaults when reading the depth component. * Read those column by column. */ bool bycolumn = format[component] == GL_DEPTH_COMPONENT; int n = bycolumn ? size[1] : size[0]*size[1]; GLfloat* buffer = (GLfloat*) R_alloc(n, sizeof(GLfloat)); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); // read front buffer glPushAttrib(GL_PIXEL_MODE_BIT); glReadBuffer(GL_BACK); glPixelStorei(GL_PACK_ALIGNMENT, 1); if (bycolumn) { for(int ix=0; ixendGL(); } #endif return success; } void RGLView::getUserMatrix(double* dest) { Subscene* subscene = NULL; if (activeSubscene) subscene = scene->getSubscene(activeSubscene); if (!subscene) subscene = scene->getCurrentSubscene(); ModelViewpoint* modelviewpoint = subscene->getModelViewpoint(); modelviewpoint->getUserMatrix(dest); } void RGLView::setUserMatrix(double* src) { Subscene* subscene = NULL; if (activeSubscene) subscene = scene->getSubscene(activeSubscene); if (!subscene) subscene = scene->getCurrentSubscene(); subscene->setUserMatrix(src); View::update(); } void RGLView::getScale(double* dest) { Subscene* subscene = NULL; if (activeSubscene) subscene = scene->getSubscene(activeSubscene); if (!subscene) subscene = scene->getCurrentSubscene(); ModelViewpoint* modelviewpoint = subscene->getModelViewpoint(); modelviewpoint->getScale(dest); } void RGLView::setScale(double* src) { Subscene* subscene = NULL; if (activeSubscene) subscene = scene->getSubscene(activeSubscene); if (!subscene) subscene = scene->getCurrentSubscene(); subscene->setScale(src); View::update(); } void RGLView::setDefaultFont(const char* family, int style, double cex, bool useFreeType) { GLFont* font = View::windowImpl->getFont(family, style, cex, useFreeType); if (!font) error("font not available"); renderContext.font = font; } const char* RGLView::getFontFamily() const { if (!renderContext.font) error("font not available"); return renderContext.font->family; } void RGLView::setFontFamily(const char *family) { setDefaultFont(family, getFontStyle(), getFontCex(), getFontUseFreeType()); } int RGLView::getFontStyle() const { if (!renderContext.font) error("font not available"); return renderContext.font->style; } void RGLView::setFontStyle(int style) { setDefaultFont(getFontFamily(), style, getFontCex(), getFontUseFreeType()); } double RGLView::getFontCex() const { if (!renderContext.font) error("font not available"); return renderContext.font->cex; } void RGLView::setFontCex(double cex) { setDefaultFont(getFontFamily(), getFontStyle(), cex, getFontUseFreeType()); } const char* RGLView::getFontname() const { if (!renderContext.font) error("font not available"); return renderContext.font->fontname; } bool RGLView::getFontUseFreeType() const { if (!renderContext.font) error("font not available"); return renderContext.font->useFreeType; } void RGLView::setFontUseFreeType(bool useFreeType) { setDefaultFont(getFontFamily(), getFontStyle(), getFontCex(), useFreeType); } void RGLView::getPosition(double* dest) { Subscene* subscene = NULL; if (activeSubscene) subscene = scene->getSubscene(activeSubscene); if (!subscene) subscene = scene->getCurrentSubscene(); ModelViewpoint* modelviewpoint = subscene->getModelViewpoint(); modelviewpoint->getPosition(dest); } void RGLView::setPosition(double* src) { Subscene* subscene = NULL; if (activeSubscene) subscene = scene->getSubscene(activeSubscene); if (!subscene) subscene = scene->getCurrentSubscene(); ModelViewpoint* modelviewpoint = subscene->getModelViewpoint(); modelviewpoint->setPosition(src); } bool RGLView::postscript(int formatID, const char* filename, bool drawText) { bool success = false; std::FILE *fp = fopen(filename, "wb"); #ifndef RGL_NO_OPENGL char *oldlocale = setlocale(LC_NUMERIC, "C"); GLint buffsize = 0, state = GL2PS_OVERFLOW; GLint vp[4]; GLint options = GL2PS_SILENT | GL2PS_SIMPLE_LINE_OFFSET | GL2PS_NO_BLENDING | GL2PS_OCCLUSION_CULL | GL2PS_BEST_ROOT; if (!drawText) options |= GL2PS_NO_TEXT; if (windowImpl->beginGL()) { glGetIntegerv(GL_VIEWPORT, vp); while( state == GL2PS_OVERFLOW ){ buffsize += 1024*1024; gl2psBeginPage ( filename, "Generated by rgl", vp, formatID, GL2PS_BSP_SORT, options, GL_RGBA, 0, NULL, 0, 0, 0, buffsize, fp, filename ); if ( drawText ) { // signal gl2ps for text scene->invalidateDisplaylists(); if (formatID == GL2PS_PS || formatID == GL2PS_EPS || formatID == GL2PS_TEX || formatID == GL2PS_PGF) renderContext.gl2psActive = GL2PS_POSITIONAL; else renderContext.gl2psActive = GL2PS_LEFT_ONLY; } // redraw: scene->render(&renderContext); glFinish(); if ( drawText ) { scene->invalidateDisplaylists(); renderContext.gl2psActive = GL2PS_NONE; } success = true; state = gl2psEndPage(); } windowImpl->endGL(); } setlocale(LC_NUMERIC, oldlocale); #else warning("this build of rgl does not support postscript"); #endif fclose(fp); return success; } void RGLView::setMouseListeners(Subscene* sub, unsigned int n, int* ids) { sub->clearMouseListeners(); for (unsigned int i=0; igetSubscene(ids[i]); if (subscene) sub->addMouseListener(subscene); } } rgl/src/subscene.h0000644000176200001440000002444314142256754013626 0ustar liggesusers#ifndef SUBSCENE_H #define SUBSCENE_H #include "Shape.h" #include "ClipPlane.h" #include "Viewpoint.h" #include "Background.h" #include "BBoxDeco.h" #include "Light.h" #include namespace rgl { enum Embedding { EMBED_INHERIT=1, EMBED_MODIFY, EMBED_REPLACE }; enum Embedded { EM_VIEWPORT = 0, EM_PROJECTION, EM_MODEL, EM_MOUSEHANDLERS}; enum ButtonID {bnNOBUTTON = 0, bnLEFT, bnRIGHT, bnMIDDLE, bnWHEEL}; enum MouseModeID {mmNONE = 0, mmTRACKBALL, mmXAXIS, mmYAXIS, mmZAXIS, mmPOLAR, mmSELECTING, mmZOOM, mmFOV, mmUSER, wmPUSH, wmPULL, wmUSER2}; enum MouseSelectionID {msNONE=1, msCHANGING, msDONE, msABORT}; typedef void (*userControlPtr)(void *userData, int mouseX, int mouseY); typedef void (*userControlEndPtr)(void *userData); typedef void (*userCleanupPtr)(void **userData); typedef void (*userWheelPtr)(void *userData, int dir); typedef void (Subscene::*viewControlPtr)(int mouseX,int mouseY); typedef void (Subscene::*viewControlEndPtr)(); typedef void (Subscene::*viewWheelPtr)(int dir); class Subscene : public SceneNode { /* Subscenes do their own projection. They can inherit, modify or replace the viewport, projection and model matrices. The root viewport always replaces them, since it doesn't have anything to inherit. */ private: void setupViewport(RenderContext* rctx); void setupProjMatrix(RenderContext* rctx, const Sphere& viewSphere); void setupModelMatrix(RenderContext* rctx, Vertex center); void setupModelViewMatrix(RenderContext* rctx, Vertex center); void setDefaultMouseMode(); void disableLights(RenderContext* rctx); void setupLights(RenderContext* rctx); void newEmbedding(); /* These lists contain pointers to lights and shapes, but don't actually manage them: the Scene does that. */ std::vector lights; std::vector shapes; std::vector unsortedShapes; std::vector zsortShapes; std::vector clipPlanes; /* Subscenes form a tree; this is the parent subscene. The root has a NULL parent. */ Subscene* parent; /* Here are the children */ std::vector subscenes; UserViewpoint* userviewpoint; ModelViewpoint* modelviewpoint; /** * bounded background **/ Background* background; /** * bounded decorator **/ BBoxDeco* bboxdeco; /** * How is this subscene embedded in its parent? **/ Embedding do_viewport, do_projection, do_model, do_mouseHandlers; /** * This viewport on the (0,0) to (1,1) scale **/ Rect2d viewport; public: Subscene(Embedding in_viewport, Embedding in_projection, Embedding in_model, Embedding in_mouseHandlers, bool in_ignoreExtent); virtual ~Subscene( ); bool add(SceneNode* node); void addBackground(Background* newbackground); void addBBoxDeco(BBoxDeco* bboxdeco); void addShape(Shape* shape); void addLight(Light* light); void addSubscene(Subscene* subscene); void addBBox(const AABox& bbox, bool changes); void intersectClipplanes(void); /** * hide shape or light or bboxdeco **/ void hideShape(int id); void hideLight(int id); void hideBBoxDeco(int id); void hideBackground(int id); Subscene* hideSubscene(int id, Subscene* current); void hideViewpoint(int id); /** * recursive search for subscene; could return self, or NULL if not found **/ Subscene* getSubscene(int id); Subscene* whichSubscene(int id); /* which subscene holds this */ Subscene* whichSubscene(int mouseX, int mouseY); /* coordinates are pixels within the window */ /* And here is the root */ Subscene* getRootSubscene(); /** * get parent, or NULL for the root **/ Subscene* getParent() const { return parent; } /** * get children **/ size_t getChildCount() const { return subscenes.size(); } Subscene* getChild(int which) const { return subscenes[which]; } /** * obtain bounding box **/ const AABox& getBoundingBox() const { return data_bbox; } /** * get the bbox */ BBoxDeco* get_bboxdeco(); /** * get a bbox */ BBoxDeco* get_bboxdeco(int id); /** * get the background */ Background* get_background() const { return background; } /** * get a background */ Background* get_background(int id); /** * obtain subscene's axis-aligned bounding box. **/ const AABox& getBoundingBox(); /** * get information about stacks */ int get_id_count(TypeID type, bool recursive); int get_ids(TypeID type, int* ids, char** types, bool recursive); virtual int getAttributeCount(AABox& bbox, AttribID attrib); virtual void getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result); virtual String getTextAttribute(AABox& bbox, AttribID attrib, int index); /* Update matrices etc. in preparation for rendering */ void update(RenderContext* renderContext); /* load the matrices into OpenGL */ void loadMatrices(); /* Do the OpenGL rendering */ void render(RenderContext* renderContext, bool opaquePass); void renderClipplanes(RenderContext* renderContext); void disableClipplanes(RenderContext* renderContext); void renderUnsorted(RenderContext* renderContext); void renderZsort(RenderContext* renderContext); /** * Get and set flag to ignore elements in bounding box **/ int getIgnoreExtent(void) const { return (int) ignoreExtent; } void setIgnoreExtent(int in_ignoreExtent); void setEmbedding(int which, Embedding value); /* which is 0=viewport, 1=projection, 2=model */ Embedding getEmbedding(Embedded which); Subscene* getMaster(Embedded which); void setUserMatrix(double* src); void setUserProjection(double* src); void setScale(double* src); void setViewport(double x, double y, double width, double height); /* Sets relative (i.e. [0,1]x[0,1]) viewport size */ void setPosition(double* src); void getUserMatrix(double* dest); void getUserProjection(double* dest); void getScale(double* dest); void getPosition(double* dest); double* getMousePosition(); void clearMouseListeners(); void addMouseListener(Subscene* sub); void deleteMouseListener(Subscene* sub); void getMouseListeners(size_t max, int* ids); float getDistance(const Vertex& v) const; // Translate from OpenGL window-relative coordinates (relative to bottom left corner of window) to // viewport relative (relative to bottom left corner of viewport) void translateCoords(int* mouseX, int* mouseY) const { *mouseX = *mouseX - pviewport.x; *mouseY = *mouseY - pviewport.y; } UserViewpoint* getUserViewpoint(); ModelViewpoint* getModelViewpoint(); virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "subscene", buflen); }; Background* get_background(); /* This vector lists other subscenes that will be controlled by mouse actions on this one. We need to delete those entries if the subscene is deleted! */ std::vector mouseListeners; // These are set after rendering the scene Vec4 Zrow; Vec4 Wrow; Matrix4x4 modelMatrix, projMatrix; Rect2 pviewport; // viewport in pixels /** * mouse support */ void buttonBegin(int button, int mouseX, int mouseY); void buttonUpdate(int button, int mouseX, int mouseY); void buttonEnd(int button); MouseModeID needsBegin; bool mouseNeedsWatching(); void wheelRotate(int dir); MouseModeID getMouseMode(int button); void setMouseMode(int button, MouseModeID mode); void setMouseCallbacks(int button, userControlPtr begin, userControlPtr update, userControlEndPtr end, userCleanupPtr cleanup, void** user); void getMouseCallbacks(int button, userControlPtr *begin, userControlPtr *update, userControlEndPtr *end, userCleanupPtr *cleanup, void** user); void setWheelCallback(userWheelPtr wheel, void* user); void getWheelCallback(userWheelPtr *wheel, void** user); // o DRAG FEATURE: mouseSelection int drag; double mousePosition[4]; void mouseSelectionBegin(int mouseX,int mouseY); void mouseSelectionUpdate(int mouseX,int mouseY); void mouseSelectionEnd(); MouseSelectionID getSelectState(); void setSelectState(MouseSelectionID state); private: /** * compute bounding-box **/ void calcDataBBox(); /** * shrink bounding-box when something has been removed **/ void shrinkBBox(); /** * bounding box of subscene **/ AABox data_bbox; bool ignoreExtent; bool bboxChanges; /** * mouse support */ viewControlPtr ButtonBeginFunc[5], ButtonUpdateFunc[5]; viewControlEndPtr ButtonEndFunc[5]; viewWheelPtr WheelRotateFunc; viewControlPtr getButtonBeginFunc(int button); viewControlPtr getButtonUpdateFunc(int button); viewControlEndPtr getButtonEndFunc(int button); MouseModeID mouseMode[5]; MouseSelectionID selectState; void noneBegin(int mouseX, int mouseY) {}; void noneUpdate(int mouseX, int mouseY) {}; void noneEnd() {}; // o DRAG FEATURE: adjustDirection void polarBegin(int mouseX, int mouseY); void polarUpdate(int mouseX, int mouseY); void polarEnd(); void trackballBegin(int mouseX, int mouseY); void trackballUpdate(int mouseX, int mouseY); void trackballEnd(); void oneAxisBegin(int mouseX, int mouseY); void oneAxisUpdate(int mouseX, int mouseY); void wheelRotateNone(int dir) {}; void wheelRotatePull(int dir); void wheelRotatePush(int dir); PolarCoord camBase, dragBase, dragCurrent; Vertex rotBase, rotCurrent, axis[3]; // o DRAG FEATURE: adjustZoom void adjustZoomBegin(int mouseX, int mouseY); void adjustZoomUpdate(int mouseX, int mouseY); void adjustZoomEnd(); int zoomBaseY; // o DRAG FEATURE: adjustFOV (field of view) void adjustFOVBegin(int mouseX, int mouseY); void adjustFOVUpdate(int mouseX, int mouseY); void adjustFOVEnd(); int fovBaseY; // o DRAG FEATURE: user supplied callback void userBegin(int mouseX, int mouseY); void userUpdate(int mouseX, int mouseY); void userEnd(); bool busy; int activeButton; void* wheelData; userWheelPtr wheelCallback; void userWheel(int dir); void* userData[15]; userControlPtr beginCallback[5], updateCallback[5]; userControlEndPtr endCallback[5]; userCleanupPtr cleanupCallback[5]; }; } // namespace rgl #endif // SUBSCENE_H rgl/src/ClipPlane.h0000644000176200001440000000244614100762641013654 0ustar liggesusers#ifndef CLIPPLANE_H #define CLIPPLANE_H #include "geom.h" #include "Shape.h" #include "PrimitiveSet.h" #include namespace rgl { class ClipPlaneSet : public Shape { private: /* Use parametrization ax + by + cz + d = 0 */ int nPlanes; GLenum firstPlane; ARRAY normal; /* (a,b,c) */ ARRAY offset; /* d */ public: ClipPlaneSet(Material& in_material, int in_nnormal, double* in_normal, int in_noffset, double* in_offset); // ~PlaneSet(); static int num_planes; // clip plane count for drawing; set to 0 initially, incremented // as each plane is added or drawn. /** * tell type. **/ virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "clipplanes", buflen); }; virtual void renderBegin(RenderContext* renderContext); virtual void drawPrimitive(RenderContext* renderContext, int index); virtual int getElementCount(void) { return nPlanes; } virtual int getAttributeCount(AABox& bbox, AttribID attrib); virtual void getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result); void enable(bool show); // after it has been drawn, this enables it or disables it bool isClipPlane(void) { return true; } void intersectBBox(AABox& bbox); }; } // namespace rgl #endif // CLIPPLANE_H rgl/src/select.cpp0000644000176200001440000000117014100762641013610 0ustar liggesusers// C++ source // This file is part of RGL. // #include "select.h" #include using namespace rgl; void SELECT::render(double* position) { #ifndef RGL_NO_OPENGL GLdouble llx, lly, urx, ury; llx = *position; lly = *(position+1); urx = *(position+2); ury = *(position+3); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0f,1.0f,0.0f,1.0f,0.0f,1.0f); glColor3f(0.5f,0.5f,0.5f); glLineWidth(2.0); glBegin(GL_LINE_LOOP); glVertex2d(llx, lly); glVertex2d(llx, ury); glVertex2d(urx, ury); glVertex2d(urx, lly); glEnd(); #endif } rgl/src/pretty.h0000644000176200001440000000047114100762641013330 0ustar liggesusers#ifndef RGL_PRETTY_H #define RGL_PRETTY_H #ifdef __cplusplus extern "C" { #endif double R_pretty0(double *lo, double *up, int *ndiv, int min_n, double shrink_sml, double high_u_fact[], int eps_correction, int return_bounds); #ifdef __cplusplus } #endif #endif /* RGL_API_H */ rgl/src/Texture.cpp0000644000176200001440000001541414145464133014003 0ustar liggesusers #include "Texture.h" #include "pixmap.h" #include "config.h" #include "platform.h" #include "RenderContext.h" using namespace std; using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // Texture // Texture::Texture( const char* in_filename , Type in_type , bool in_mipmap , unsigned int in_minfilter , unsigned int in_magfilter , bool in_envmap) { texName = 0; pixmap = new Pixmap(); type = in_type; mipmap = in_mipmap; envmap = in_envmap; magfilter = (in_magfilter) ? GL_LINEAR : GL_NEAREST; if (mipmap) { switch(in_minfilter) { case 0: minfilter = GL_NEAREST; break; case 1: minfilter = GL_LINEAR; break; case 2: minfilter = GL_NEAREST_MIPMAP_NEAREST; break; case 3: minfilter = GL_NEAREST_MIPMAP_LINEAR; break; case 4: minfilter = GL_LINEAR_MIPMAP_NEAREST; break; default: minfilter = GL_LINEAR_MIPMAP_LINEAR; break; } } else { switch(in_minfilter) { case 0: minfilter = GL_NEAREST; break; default: minfilter = GL_LINEAR; break; } } filename = new char [1 + strlen(in_filename)]; memcpy(filename, in_filename, 1 + strlen(in_filename)); if ( !pixmap->load(filename) ) { delete pixmap; pixmap = NULL; } } Texture::~Texture() { #ifndef RGL_NO_OPENGL if (texName) { glDeleteTextures(1, &texName); } #endif if (pixmap) delete pixmap; if (filename) delete[] filename; } bool Texture::isValid() const { return (pixmap) ? true : false; } void Texture::getParameters(Type *out_type, bool *out_mipmap, unsigned int *out_minfilter, unsigned int *out_magfilter, bool *out_envmap, int buflen, char *out_filename) { *out_type = type; *out_mipmap = mipmap; switch(minfilter) { case GL_NEAREST: *out_minfilter = 0; break; case GL_LINEAR: *out_minfilter = 1; break; case GL_NEAREST_MIPMAP_NEAREST: *out_minfilter = 2; break; case GL_NEAREST_MIPMAP_LINEAR: *out_minfilter = 3; break; case GL_LINEAR_MIPMAP_NEAREST: *out_minfilter = 4; break; case GL_LINEAR_MIPMAP_LINEAR: *out_minfilter = 5; break; default: *out_minfilter = 6; break; } *out_magfilter = (magfilter == GL_LINEAR) ? 1 : 0; *out_envmap = envmap; strncpy(out_filename, filename, buflen); } #ifndef MODERN_OPENGL #ifndef RGL_NO_OPENGL static unsigned int texsize(unsigned int s) { return 1U << msb(s-1); } #include "lib.h" static void printGluErrorMessage(GLint error) { const GLubyte* gluError; char buf[256]; gluError = gluErrorString (error); sprintf(buf, "GLU Library Error : %s", (const char*) gluError); printMessage(buf); } #endif #endif void Texture::init(RenderContext* renderContext) { #ifndef RGL_NO_OPENGL glGenTextures(1, &texName); glBindTexture(GL_TEXTURE_2D, texName); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magfilter); GLint internalFormat = 0; GLenum format = 0; GLint ualign; unsigned int bytesperpixel = 0; switch(type) { case ALPHA: internalFormat = GL_ALPHA; break; case LUMINANCE: internalFormat = GL_LUMINANCE; break; case LUMINANCE_ALPHA: internalFormat = GL_LUMINANCE_ALPHA; break; case RGB: internalFormat = GL_RGB; break; case RGBA: internalFormat = GL_RGBA; break; } switch(pixmap->typeID) { case GRAY8: ualign = 1; bytesperpixel = 1; switch(internalFormat) { case GL_LUMINANCE: format = GL_LUMINANCE; break; case GL_ALPHA: format = GL_ALPHA; break; case GL_LUMINANCE_ALPHA: format = GL_LUMINANCE; break; } break; case RGB24: ualign = 1; format = GL_RGB; bytesperpixel = 3; break; case RGB32: ualign = 2; format = GL_RGB; bytesperpixel = 4; break; case RGBA32: ualign = 2; format = GL_RGBA; bytesperpixel = 4; break; default: // INVALID return; } glPixelStorei(GL_UNPACK_ALIGNMENT, ualign); GLenum gl_type = GL_UNSIGNED_BYTE; GLint glTexSize; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glTexSize ); #ifdef MODERN_OPENGL glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, pixmap->width, pixmap->height, 0, format, gl_type , pixmap->data); if (mipmap) glGenerateMipmap(GL_TEXTURE_2D); #else unsigned int maxSize = static_cast(glTexSize); if (mipmap) { int gluError = gluBuild2DMipmaps(GL_TEXTURE_2D, internalFormat, pixmap->width, pixmap->height, format, gl_type, pixmap->data); if (gluError) printGluErrorMessage(gluError); } else { unsigned int width = texsize(pixmap->width); unsigned int height = texsize(pixmap->height); if ( (width > maxSize) || (height > maxSize) ) { char buf[256]; sprintf(buf, "GL Library : Maximum texture size of %dx%d exceeded.\n(Perhaps enabling mipmapping could help.)", maxSize,maxSize); printMessage(buf); } else if ( (pixmap->width != width) || ( pixmap->height != height) ) { char* data = new char[width * height * bytesperpixel]; int gluError = gluScaleImage(format, pixmap->width, pixmap->height, gl_type, pixmap->data, width, height, gl_type, data); if (gluError) printGluErrorMessage(gluError); glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, gl_type , data); delete[] data; } else { glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, pixmap->width, pixmap->height, 0, format, gl_type , pixmap->data); } } #endif /* not MODERN_OPENGL */ if (envmap) { glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); } #endif if (pixmap) { delete pixmap; pixmap = NULL; } } void Texture::beginUse(RenderContext* renderContext) { #ifndef RGL_NO_OPENGL if (!texName) { init(renderContext); } glPushAttrib(GL_TEXTURE_BIT|GL_ENABLE_BIT|GL_CURRENT_BIT); glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glBindTexture(GL_TEXTURE_2D, texName); if (type == ALPHA) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); } #endif } void Texture::endUse(RenderContext* renderContext) { #ifndef RGL_NO_OPENGL glPopAttrib(); #endif } rgl/src/glgui.h0000644000176200001440000001205214142256754013117 0ustar liggesusers#ifndef GL_GUI_H #define GL_GUI_H // C++ header // This file is part of rgl #include "opengl.h" #include #ifdef HAVE_FREETYPE #include "FTGL/ftgl.h" #endif #include "RenderContext.h" namespace rgl { // CLASS // GLFont // class GLFont { public: GLFont(const char* in_family, int in_style, double in_cex, const char* in_fontname, bool in_useFreeType): style(in_style), cex(in_cex), useFreeType(in_useFreeType) { family = new char[strlen(in_family) + 1]; memcpy(family, in_family, strlen(in_family) + 1); fontname = new char[strlen(in_fontname) + 1]; memcpy(fontname, in_fontname, strlen(in_fontname) + 1); }; virtual ~GLFont() { delete [] family; delete [] fontname; } virtual void draw(const char* text, int length, double adjx, double adjy, double adjz, int pos, const RenderContext& rc) = 0; virtual void draw(const wchar_t* text, int length, double adjx, double adjy, double adjz, int pos, const RenderContext& rc) = 0; virtual double width(const char* text) = 0; virtual double width(const wchar_t* text) = 0; virtual double height() = 0; virtual bool valid(const char* text) { return true; }; // justify returns false if justification puts the text outside the viewport GLboolean justify(double width, double height, double adjx, double adjy, double adjz, int pos, const RenderContext& rc); char* family; int style; double cex; char* fontname; bool useFreeType; int gl2ps_centering; private: GLFont(const GLFont &); GLFont &operator=(const GLFont &); }; #define GL_BITMAP_FONT_FIRST_GLYPH 32 #define GL_BITMAP_FONT_LAST_GLYPH 127 #define GL_BITMAP_FONT_COUNT (GL_BITMAP_FONT_LAST_GLYPH-GL_BITMAP_FONT_FIRST_GLYPH+1) #define GL2PS_FONT "Helvetica" #define GL2PS_FONTSIZE 12 #define GL2PS_SCALING 0.8 #define GL2PS_NONE 0 #define GL2PS_LEFT_ONLY 1 #define GL2PS_POSITIONAL 2 // // CLASS // GLBitmapFont // class GLBitmapFont : public GLFont { public: // Most initialization of this object is done by the system-specific driver GLBitmapFont(const char* in_family, int in_style, double in_cex, const char* in_fontname): GLFont(in_family, in_style, in_cex, in_fontname, false) {}; ~GLBitmapFont(); void draw(const char* text, int length, double adjx, double adjy, double adjz, int draw, const RenderContext& rc); void draw(const wchar_t* text, int length, double adjx, double adjy, double adjz, int draw, const RenderContext& rc); double width(const char* text); double width(const wchar_t* text); double height(); bool valid(const char* text); GLuint listBase; GLuint firstGlyph; GLuint nglyph; unsigned int* widths; unsigned int ascent; }; // // CLASS // GLFTFont // class GLFTFont : public GLFont { public: GLFTFont(const char* in_family, int in_style, double in_cex, const char* in_fontname); ~GLFTFont(); #ifdef HAVE_FREETYPE void draw(const char* text, int length, double adjx, double adjy, double adjz, int pos, const RenderContext& rc); void draw(const wchar_t* text, int length, double adjx, double adjy, double adjz, int pos, const RenderContext& rc); double width(const char* text); double width(const wchar_t* text); double height(); FTFont *font; const char *errmsg; #endif }; // // CLASS // NULLFont // class NULLFont : public GLFont { public: NULLFont(const char* in_family, int in_style, double in_cex, bool useFreeType): GLFont(in_family, in_style, in_cex, "NULL", useFreeType) {}; void draw(const char* text, int length, double adjx, double adjy, double adjz, int pos, const RenderContext& rc) {}; void draw(const wchar_t* text, int length, double adjx, double adjy, double adjz, int pos, const RenderContext& rc) {}; double width(const char* text) {return 0.0;}; double width(const wchar_t* text) {return 0.0;}; double height() {return 0.0;}; }; /** * FontArray **/ typedef std::vector FontArray; /* The macros below are taken from the R internationalization code, which is marked Copyright (C) 1995-1999, 2000-2007 Free Software Foundation, Inc. */ /* Pathname support. ISSLASH(C) tests whether C is a directory separator character. IS_ABSOLUTE_PATH(P) tests whether P is an absolute path. If it is not, it may be concatenated to a directory pathname. */ #if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ /* Win32, Cygwin, OS/2, DOS */ # define ISSLASH(C) ((C) == '/' || (C) == '\\') # define HAS_DEVICE(P) \ ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ && (P)[1] == ':') # define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P)) #else /* Unix */ # define ISSLASH(C) ((C) == '/') # define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0]) #endif } // namespace rgl #endif /* GL_GUI_H */ rgl/src/gui.cpp0000644000176200001440000002246214137472630013132 0ustar liggesusers// C++ source // This file is part of RGL. // // --------------------------------------------------------------------------- #include "gui.h" #include "lib.h" #include "R.h" using namespace rgl; // --------------------------------------------------------------------------- // WindowImpl common code // --------------------------------------------------------------------------- void WindowImpl::getFonts(FontArray& outfonts, int nfonts, char** family, int* style, double* cex, bool useFreeType) { GLFont* font; outfonts.resize(nfonts); for (int i = 0; i < nfonts; i++) { font = getFont(*(family++), *(style++), *(cex++), useFreeType); outfonts[i] = font; } } int WindowImpl::setSkipRedraw(int in_skipRedraw) { int result = 0; if (window) { result = window->getSkipRedraw(); window->setSkipRedraw(in_skipRedraw, 0); } return result; } // --------------------------------------------------------------------------- // View Implementation // --------------------------------------------------------------------------- View::View() : baseX(0) , baseY(0) , width(0) , height(0) , flags(0) , windowImpl(0) { } // --------------------------------------------------------------------------- View::View(int inBaseX, int inBaseY, int inWidth, int inHeight, int inFlags) : baseX(inBaseX) , baseY(inBaseY) , width(inWidth) , height(inHeight) , flags(inFlags) , windowImpl(0) { } // --------------------------------------------------------------------------- View::~View() { if ((windowImpl) && (flags & WINDOW_IMPL_OWNER)) { windowImpl->unbind(); windowImpl->destroy(); windowImpl = 0; } } // --------------------------------------------------------------------------- void View::setSize(int inWidth, int inHeight) { if ((windowImpl) && (flags & WINDOW_IMPL_OWNER)) { int left, top, right, bottom; windowImpl->getWindowRect(&left, &top, &right, &bottom); windowImpl->setWindowRect(left, top, left+inWidth, top+inHeight); } else resize(inWidth, inHeight); } // --------------------------------------------------------------------------- void View::setLocation(int inBaseX, int inBaseY) { if ((windowImpl) && (flags & WINDOW_IMPL_OWNER)) { int left, top, right, bottom; windowImpl->getWindowRect(&left, &top, &right, &bottom); windowImpl->setWindowRect(inBaseX, inBaseY, inBaseX + left-right, inBaseY + bottom-top); } else relocate(inBaseX, inBaseY); } // --------------------------------------------------------------------------- void View::update(void) { if (windowImpl) windowImpl->update(); } // --------------------------------------------------------------------------- void View::setWindowImpl(WindowImpl* inWindowImpl) { windowImpl = inWindowImpl; } // --------------------------------------------------------------------------- void View::show(void) { } // --------------------------------------------------------------------------- void View::hide(void) { } // --------------------------------------------------------------------------- void View::paint(void) { } // --------------------------------------------------------------------------- void View::resize(int inWidth, int inHeight) { width = inWidth; height = inHeight; } // --------------------------------------------------------------------------- void View::relocate(int inBaseX, int inBaseY) { baseX = inBaseX; baseY = inBaseY; } // --------------------------------------------------------------------------- void View::keyPress(int code) { } // --------------------------------------------------------------------------- void View::keyRelease(int code) { } // --------------------------------------------------------------------------- void View::buttonPress(int button, int mouseX, int mouseY) { } // --------------------------------------------------------------------------- void View::buttonRelease(int button, int mouseX, int mouseY) { } // --------------------------------------------------------------------------- void View::mouseMove(int mouseX, int mouseY) { } // --------------------------------------------------------------------------- void View::wheelRotate(int direction, int mouseX, int mouseY) { } // --------------------------------------------------------------------------- void View::captureLost() { } // --------------------------------------------------------------------------- // Window Implementation // --------------------------------------------------------------------------- Window::Window(View* in_child, GUIFactory* factory) : View(0,0,in_child->width, in_child->height,WINDOW_IMPL_OWNER) , child(in_child) , title("untitled") { skipRedraw = false; if (!factory){ return; } windowImpl = factory->createWindowImpl(this); if (!windowImpl) { return; } if (child) child->setWindowImpl(windowImpl); } // --------------------------------------------------------------------------- Window::~Window() { if (child) { delete child; } fireNotifyDisposed(); } // --------------------------------------------------------------------------- void Window::setWindowImpl(WindowImpl* impl) { View::setWindowImpl(impl); if (child) child->setWindowImpl(impl); } // --------------------------------------------------------------------------- void Window::setTitle(const char* in_title) { if (windowImpl) windowImpl->setTitle(in_title); } // --------------------------------------------------------------------------- void Window::update(void) { windowImpl->update(); } // --------------------------------------------------------------------------- void Window::setVisibility(bool state) { if (state) windowImpl->show(); else windowImpl->hide(); } // --------------------------------------------------------------------------- void Window::bringToTop(int stay) { windowImpl->bringToTop(stay); } // --------------------------------------------------------------------------- void Window::getWindowRect(int *in_left, int *in_top, int *in_width, int *in_height) { windowImpl->getWindowRect(in_left, in_top, in_width, in_height); } // --------------------------------------------------------------------------- void Window::setWindowRect(int left, int top, int right, int bottom) { right = getMax(right, left + 1); bottom = getMax(bottom, top + 1); resize(right-left, bottom-top); // In case message never gets sent, e.g. Xvfb windowImpl->setWindowRect(left, top, right, bottom); } // --------------------------------------------------------------------------- int Window::getSkipRedraw(void) { return (int)skipRedraw; } // --------------------------------------------------------------------------- void Window::setSkipRedraw(int in_skipRedraw, int doUpdate) { skipRedraw = (bool)in_skipRedraw; if (!skipRedraw && doUpdate) update(); } // --------------------------------------------------------------------------- void Window::show(void) { if (child) child->show(); } // --------------------------------------------------------------------------- void Window::hide(void) { if (child) child->hide(); } // --------------------------------------------------------------------------- void Window::resize(int in_width, int in_height) { if (child) child->resize(in_width,in_height); } // --------------------------------------------------------------------------- void Window::paint(void) { if (child) child->paint(); } // --------------------------------------------------------------------------- void Window::notifyDestroy(void) { if (child) { delete child; child = NULL; } fireNotifyDisposed(); } // --------------------------------------------------------------------------- void Window::buttonPress(int button, int mouseX, int mouseY) { if (child) child->buttonPress(button, mouseX, mouseY); } // --------------------------------------------------------------------------- void Window::buttonRelease(int button, int mouseX, int mouseY) { if (child) child->buttonRelease(button, mouseX, mouseY); } // --------------------------------------------------------------------------- void Window::mouseMove(int mouseX, int mouseY) { if (child) child->mouseMove(mouseX, mouseY); } // --------------------------------------------------------------------------- void Window::keyPress(int code) { if (child) child->keyPress(code); } // --------------------------------------------------------------------------- void Window::wheelRotate(int dir, int mouseX, int mouseY) { if (child) child->wheelRotate(dir, mouseX, mouseY); } // --------------------------------------------------------------------------- void Window::on_close() { windowImpl->destroy(); } // --------------------------------------------------------------------------- void Window::getFonts(FontArray& outfonts, int nfonts, char** family, int* style, double* cex, bool useFreeType) { windowImpl->getFonts(outfonts, nfonts, family, style, cex, useFreeType); } // --------------------------------------------------------------------------- int WindowImpl::getAntialias() { #ifndef RGL_NO_OPENGL if (beginGL()) { int result; glGetIntegerv(GL_SAMPLES, &result); endGL(); CHECKGLERROR; return result; } #endif return 1; } int WindowImpl::getMaxClipPlanes() { #ifndef RGL_NO_OPENGL int result; glGetError(); glGetIntegerv(GL_MAX_CLIP_PLANES, &result); if (glGetError() == GL_NO_ERROR) return result; else #endif return 6; } rgl/src/pixmap.cpp0000644000176200001440000000473414100762641013640 0ustar liggesusers// C++ source // This file is part of RGL. // #include #include "pixmap.h" using namespace std; #include "lib.h" // PNG FORMAT IMPLEMENTATION using namespace rgl; #ifdef HAVE_PNG_H #include "pngpixmap.h" namespace rgl { PNGPixmapFormat png; } #endif // PIXMAP FORMAT TABLE PixmapFormat* rgl::pixmapFormat[PIXMAP_FILEFORMAT_LAST] = { // PNG FORMAT #ifdef HAVE_PNG_H &png, #else NULL, #endif }; ////////////////////////////////////////////////////////////////////////////// // // CLASS // Pixmap // Pixmap::Pixmap() { typeID = INVALID; width = 0; height = 0; bits_per_channel = 0; data = NULL; bytesperrow = 0; } Pixmap::~Pixmap() { if (data) delete[] data; } bool Pixmap::init(PixmapTypeID in_typeID, int in_width, int in_height, int in_bits_per_channel) { if (data) delete data; typeID = in_typeID; width = in_width; height = in_height; bits_per_channel = in_bits_per_channel; int channels; if (typeID == RGB24) channels = 3; else if (typeID == RGBA32) channels = 4; else if (typeID == GRAY8) channels = 1; else return false; bytesperrow = ( (channels * bits_per_channel) >> 3 ) * width; data = new unsigned char [ bytesperrow * height ]; if (data) return true; else return false; } void Pixmap::clear() { if (data) memset(data, 0, bytesperrow * height); } bool Pixmap::load(const char* filename) { bool success = false; std::FILE* file = NULL; file = fopen(filename, "rb"); if (!file) { char buffer[256]; sprintf(buffer, "Pixmap load: unable to open file '%s' for reading", filename); printMessage(buffer); return false; } bool support = false; for(int i=0;icheckSignature(file) ) ) { support = true; success = format->load(file, this); break; } } if (!support) { printMessage("Pixmap load: file format unsupported"); } if (!success) { printMessage("Pixmap load: failed"); } fclose(file); return success; } bool Pixmap::save(PixmapFormat* format, const char* filename) { std::FILE* file = NULL; file = fopen(filename, "wb"); if (!file) { char buffer[256]; sprintf(buffer, "Pixmap save: unable to open file '%s' for writing", filename); printMessage(buffer); return false; } bool success = format->save(file, this); fclose(file); return success; } rgl/src/assert.h0000644000176200001440000000162614137472630013313 0ustar liggesusers/* * assert.hpp * Based on assert.h from MinGW, which had the following notice: * This file has no copyright assigned and is placed in the Public Domain. * This file is a part of the mingw-runtime package. * No warranty is given; refer to the file DISCLAIMER within the package. * * Define the assert macro for debug output. * */ /* We should be able to include this file multiple times to allow the assert macro to be enabled/disabled for different parts of code. So don't add a header guard. */ #undef assert #ifdef __cplusplus extern "C" { #endif /* #ifdef NDEBUG * If not debugging, standard assert does nothing; ours always * does the same. #define assert(x) ((void)0) #else */ void rgl_assert (const char*, const char*, int); /* * Definition of the assert macro. */ #define assert(e) ((e) ? (void)0 : rgl_assert(#e, __FILE__, __LINE__)) #ifdef __cplusplus } #endif rgl/src/ABCLineSet.cpp0000644000176200001440000000614414100762641014210 0ustar liggesusers#include #include "ABCLineSet.h" #include "R.h" using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // PlaneSet // ABCLineSet::ABCLineSet(Material& in_material, int in_nbase, double* in_base, int in_ndir, double* in_dir) : LineSet(in_material,true, false/* true */), nLines(max(in_nbase, in_ndir)), base(in_nbase, in_base), direction(in_ndir, in_dir) { /* We'll set up 1 segment per line. Each segment has 2 vertices, and each vertex gets 3 color components and 1 alpha component. */ ARRAY colors(3*nLines); ARRAY alphas(nLines); if (material.colors.getLength() > 1) { material.colors.recycle(nLines); for (int i=0; i vertices(6*nLines); for (int i=0; igetBoundingBox()); return LineSet::getBoundingBox(subscene); } void ABCLineSet::renderBegin(RenderContext* renderContext) { updateSegments(renderContext->subscene->getBoundingBox()); invalidateDisplaylist(); LineSet::renderBegin(renderContext); } void ABCLineSet::updateSegments(const AABox& sceneBBox) { double bbox[2][3] = { {sceneBBox.vmin.x, sceneBBox.vmin.y, sceneBBox.vmin.z}, {sceneBBox.vmax.x, sceneBBox.vmax.y, sceneBBox.vmax.z} }; double x[2][3]; for (int elem = 0; elem < nLines; elem++) { Vertex bv = base.getRecycled(elem); double b[3] = { bv.x, bv.y, bv.z }; Vertex dv = direction.getRecycled(elem); double d[3] = { dv.x, dv.y, dv.z }; // Rprintf("bbox min=%f %f %f max=%f %f %f\n", bbox[0][0], bbox[0][1], bbox[0][2], // bbox[1][0], bbox[1][1], bbox[1][2]); double smin = R_NegInf, smax = R_PosInf; for (int i=0; i<3; i++) { // which coordinate if (d[i] != 0) { double s[2]; for (int j=0; j<2; j++) // which limit s[j] = (bbox[j][i] - b[i])/d[i]; smin = max(smin, min(s[0], s[1])); smax = min(smax, max(s[0], s[1])); } } if (smin <= smax) { for (int k=0; k<3; k++) { x[0][k] = b[k] + smin*d[k]; x[1][k] = b[k] + smax*d[k]; } setVertex(2*elem + 0, x[0]); setVertex(2*elem + 1, x[1]); } else { double missing[3] = {NA_REAL, NA_REAL, NA_REAL}; setVertex(2*elem + 0, missing); setVertex(2*elem + 1, missing); } } } void ABCLineSet::getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result) { updateSegments(bbox); LineSet::getAttribute(bbox, attrib, first, count, result); } rgl/src/lib.h0000644000176200001440000000075014100762641012547 0ustar liggesusers#ifndef RGL_LIB_H #define RGL_LIB_H // --------------------------------------------------------------------------- namespace rgl { // --------------------------------------------------------------------------- bool init(bool onlyNULLDevice); const char * GUIFactoryName(bool useNULLDevice); void quit(); void printMessage(const char* string); double getTime(); // --------------------------------------------------------------------------- } // namespace rgl #endif // RGL_LIB_H rgl/src/Light.cpp0000644000176200001440000000501114100762641013376 0ustar liggesusers#include "Light.h" using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // Light // Light::Light( PolarCoord in_position, Vertex in_finposition, bool in_viewpoint, bool in_posisfinite, Color in_ambient, Color in_diffuse, Color in_specular ) : SceneNode(LIGHT), finposition(in_finposition), ambient(in_ambient), diffuse(in_diffuse), specular(in_specular), id(GL_FALSE), viewpoint(in_viewpoint), posisfinite(in_posisfinite) { if (posisfinite) { position[0] = finposition.x; position[1] = finposition.y; position[2] = finposition.z; position[3] = 1.0f; } else { Vertex v(0.0f, 0.0f, 1.0f); v.rotateX( -in_position.phi ); v.rotateY( in_position.theta ); position[0] = v.x; position[1] = v.y; position[2] = v.z; position[3] = 0.0f; } } void Light::setup(RenderContext* renderContext) { #ifndef RGL_NO_OPENGL glLightfv(id, GL_AMBIENT, ambient.data ); glLightfv(id, GL_DIFFUSE, diffuse.data ); glLightfv(id, GL_SPECULAR, specular.data ); glLightfv(id, GL_POSITION, position ); glLightf(id, GL_SPOT_EXPONENT, 0.0f); glLightf(id, GL_SPOT_CUTOFF, 180.0f); glLightf(id, GL_CONSTANT_ATTENUATION, 1.0f); glLightf(id, GL_LINEAR_ATTENUATION, 0.0f); glLightf(id, GL_QUADRATIC_ATTENUATION, 0.0f); glEnable(id); #endif } int Light::getAttributeCount(AABox& bbox, AttribID attrib) { switch (attrib) { case COLORS: return 3; case VERTICES: return 1; case FLAGS: return 2; } return 0; } void Light::getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result) { int n = getAttributeCount(bbox, attrib); if (first + count < n) n = first + count; if (first < n) { switch (attrib) { case COLORS: { while (first < n) { Color color; switch(first) { case 0: color = ambient; break; case 1: color = diffuse; break; case 2: color = specular;break; } *result++ = color.data[0]; *result++ = color.data[1]; *result++ = color.data[2]; *result++ = color.data[3]; first++; } return; } case VERTICES: { *result++ = position[0]; *result++ = position[1]; *result++ = position[2]; return; } case FLAGS: { if (first == 0) *result++ = (double) viewpoint; *result++ = (double) posisfinite; return; } } } } rgl/src/BBoxDeco.h0000644000176200001440000000472414145464133013437 0ustar liggesusers#ifndef BBOX_DECO_H #define BBOX_DECO_H #include "SceneNode.h" // // CLASS // BBoxDeco // #include "rglmath.h" #include "geom.h" #include "RenderContext.h" #include "String.h" #include "Material.h" namespace rgl { enum { AXIS_CUSTOM, // "custom" AXIS_LENGTH, // "fixednum" AXIS_UNIT, // "fixedstep" AXIS_PRETTY, // "pretty" AXIS_USER, // "user" AXIS_NONE // "none" }; struct AxisInfo { AxisInfo(); AxisInfo(int in_nticks, double* in_values, char** in_texts, int xlen, float xunit); AxisInfo(AxisInfo& from); ~AxisInfo(); void draw(RenderContext* renderContext, Vertex4& v, Vertex4& dir, Matrix4x4& modelview, Vertex& marklen, String& string); int getNticks(float low, float high); double getTick(float low, float high, int index); /* double since it might be NA_REAL */ int mode; int nticks; float* ticks; StringArray textArray; int len; float unit; }; typedef void (*userAxisPtr)(void *userData, int axis, int edge[3]); class BBoxDeco : public SceneNode { public: BBoxDeco(Material& in_material=defaultMaterial, AxisInfo& xaxis=defaultAxis, AxisInfo& yaxis=defaultAxis, AxisInfo& zaxis=defaultAxis, float marklen=15.0, bool marklen_fract=true, float in_expand=1.0, bool in_front=false); void render(RenderContext* renderContext); AABox getBoundingBox(const AABox& boundingBox) const; Vertex getMarkLength(const AABox& boundingBox) const; int getAttributeCount(AABox& bbox, AttribID attrib); void getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result); String getTextAttribute(AABox& bbox, AttribID attrib, int index); Material* getMaterial() { return &material; } virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "bboxdeco", buflen); }; Vec3 marginVecToDataVec(Vec3 marginvec, RenderContext* renderContext, Material* material); Vec3 marginNormalToDataNormal(Vec3 marginvec, RenderContext* renderContext, Material* material); void setAxisCallback(userAxisPtr fn, void * user, int axis); void getAxisCallback(userAxisPtr *fn, void ** user, int axis); private: struct BBoxDecoImpl; Material material; AxisInfo xaxis, yaxis, zaxis; float marklen_value; bool marklen_fract; float expand; bool draw_front; #ifndef RGL_NO_OPENGL bool axisBusy; #endif userAxisPtr axisCallback[3]; void* axisData[3]; static Material defaultMaterial; static AxisInfo defaultAxis; }; } // namespace rgl #endif // BBOX_DECO_H rgl/src/gl2ps.c0000644000176200001440000057736514100762641013050 0ustar liggesusers/* * GL2PS, an OpenGL to PostScript Printing Library * Copyright (C) 1999-2017 C. Geuzaine * * This program is free software; you can redistribute it and/or * modify it under the terms of either: * * a) the GNU Library General Public License as published by the Free * Software Foundation, either version 2 of the License, or (at your * option) any later version; or * * b) the GL2PS License as published by Christophe Geuzaine, either * version 2 of the License, or (at your option) any later version. * * 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 either * the GNU Library General Public License or the GL2PS License for * more details. * * You should have received a copy of the GNU Library General Public * License along with this library in the file named "COPYING.LGPL"; * if not, write to the Free Software Foundation, Inc., 51 Franklin * Street, Fifth Floor, Boston, MA 02110-1301, USA. * * You should have received a copy of the GL2PS License with this * library in the file named "COPYING.GL2PS"; if not, I will be glad * to provide one. * * For the latest info about gl2ps and a full list of contributors, * see http://www.geuz.org/gl2ps/. * * Please report all bugs and problems to . */ #ifdef RGL_NO_OPENGL typedef int make_iso_compiler_happy; #else #include "gl2ps.h" #include #include #include #include #include #include #if defined(GL2PS_HAVE_ZLIB) #include #endif #if defined(GL2PS_HAVE_LIBPNG) #include #endif /********************************************************************* * * Private definitions, data structures and prototypes * *********************************************************************/ /* Magic numbers (assuming that the order of magnitude of window coordinates is 10^3) */ #define GL2PS_EPSILON 5.0e-3F #define GL2PS_ZSCALE 1000.0F #define GL2PS_ZOFFSET 5.0e-2F #define GL2PS_ZOFFSET_LARGE 20.0F #define GL2PS_ZERO(arg) (fabs(arg) < 1.e-20) /* BSP tree primitive comparison */ #define GL2PS_COINCIDENT 1 #define GL2PS_IN_FRONT_OF 2 #define GL2PS_IN_BACK_OF 3 #define GL2PS_SPANNING 4 /* 2D BSP tree primitive comparison */ #define GL2PS_POINT_COINCIDENT 0 #define GL2PS_POINT_INFRONT 1 #define GL2PS_POINT_BACK 2 /* Internal feedback buffer pass-through tokens */ #define GL2PS_BEGIN_OFFSET_TOKEN 1 #define GL2PS_END_OFFSET_TOKEN 2 #define GL2PS_BEGIN_BOUNDARY_TOKEN 3 #define GL2PS_END_BOUNDARY_TOKEN 4 #define GL2PS_BEGIN_STIPPLE_TOKEN 5 #define GL2PS_END_STIPPLE_TOKEN 6 #define GL2PS_POINT_SIZE_TOKEN 7 #define GL2PS_LINE_CAP_TOKEN 8 #define GL2PS_LINE_JOIN_TOKEN 9 #define GL2PS_LINE_WIDTH_TOKEN 10 #define GL2PS_BEGIN_BLEND_TOKEN 11 #define GL2PS_END_BLEND_TOKEN 12 #define GL2PS_SRC_BLEND_TOKEN 13 #define GL2PS_DST_BLEND_TOKEN 14 #define GL2PS_IMAGEMAP_TOKEN 15 #define GL2PS_DRAW_PIXELS_TOKEN 16 #define GL2PS_TEXT_TOKEN 17 typedef enum { T_UNDEFINED = -1, T_CONST_COLOR = 1, T_VAR_COLOR = 1<<1, T_ALPHA_1 = 1<<2, T_ALPHA_LESS_1 = 1<<3, T_VAR_ALPHA = 1<<4 } GL2PS_TRIANGLE_PROPERTY; typedef GLfloat GL2PSplane[4]; typedef struct _GL2PSbsptree2d GL2PSbsptree2d; struct _GL2PSbsptree2d { GL2PSplane plane; GL2PSbsptree2d *front, *back; }; typedef struct { GLint nmax, size, incr, n; char *array; } GL2PSlist; typedef struct _GL2PSbsptree GL2PSbsptree; struct _GL2PSbsptree { GL2PSplane plane; GL2PSlist *primitives; GL2PSbsptree *front, *back; }; typedef struct { GL2PSvertex vertex[3]; int prop; } GL2PStriangle; typedef struct { GLshort fontsize; char *str, *fontname; /* Note: for a 'special' string, 'alignment' holds the format (PostScript, PDF, etc.) of the special string */ GLint alignment; GLfloat angle; } GL2PSstring; typedef struct { GLsizei width, height; /* Note: for an imagemap, 'type' indicates if it has already been written to the file or not, and 'format' indicates if it is visible or not */ GLenum format, type; GLfloat zoom_x, zoom_y; GLfloat *pixels; } GL2PSimage; typedef struct _GL2PSimagemap GL2PSimagemap; struct _GL2PSimagemap { GL2PSimage *image; GL2PSimagemap *next; }; typedef struct { GLshort type, numverts; GLushort pattern; char boundary, offset, culled; GLint factor, linecap, linejoin; GLfloat width, ofactor, ounits; GL2PSvertex *verts; union { GL2PSstring *text; GL2PSimage *image; } data; } GL2PSprimitive; typedef struct { #if defined(GL2PS_HAVE_ZLIB) Bytef *dest, *src, *start; uLongf destLen, srcLen; #else int dummy; #endif } GL2PScompress; typedef struct{ GL2PSlist* ptrlist; int gsno, fontno, imno, shno, maskshno, trgroupno; int gsobjno, fontobjno, imobjno, shobjno, maskshobjno, trgroupobjno; } GL2PSpdfgroup; typedef struct { /* General */ GLint format, sort, options, colorsize, colormode, buffersize; GLint lastlinecap, lastlinejoin; char *title, *producer, *filename; GLboolean boundary, blending; GLfloat *feedback, lastlinewidth; GLint viewport[4], blendfunc[2], lastfactor; GL2PSrgba *colormap, lastrgba, threshold, bgcolor; GLushort lastpattern; GL2PSvertex lastvertex; GL2PSlist *primitives, *auxprimitives; FILE *stream; GL2PScompress *compress; GLboolean header; GL2PSvertex rasterpos; GLboolean forcerasterpos; /* BSP-specific */ GLint maxbestroot; /* Occlusion culling-specific */ GLboolean zerosurfacearea; GL2PSbsptree2d *imagetree; GL2PSprimitive *primitivetoadd; /* PDF-specific */ int streamlength; GL2PSlist *pdfprimlist, *pdfgrouplist; int *xreflist; int objects_stack; /* available objects */ int extgs_stack; /* graphics state object number */ int font_stack; /* font object number */ int im_stack; /* image object number */ int trgroupobjects_stack; /* xobject numbers */ int shader_stack; /* shader object numbers */ int mshader_stack; /* mask shader object numbers */ /* for image map list */ GL2PSimagemap *imagemap_head; GL2PSimagemap *imagemap_tail; } GL2PScontext; typedef struct { void (*printHeader)(void); void (*printFooter)(void); void (*beginViewport)(GLint viewport[4]); GLint (*endViewport)(void); void (*printPrimitive)(void *data); void (*printFinalPrimitive)(void); const char *file_extension; const char *description; } GL2PSbackend; /* The gl2ps context. gl2ps is not thread safe (we should create a local GL2PScontext during gl2psBeginPage) */ static GL2PScontext *gl2ps = NULL; /* Need to forward-declare this one */ static GLint gl2psPrintPrimitives(void); /********************************************************************* * * Utility routines * *********************************************************************/ static void gl2psMsg(GLint level, const char *fmt, ...) { /* Avoid R check complaints: GL2PS_SILENT is always set va_list args; if(!(gl2ps->options & GL2PS_SILENT)){ switch(level){ case GL2PS_INFO : fprintf(stderr, "GL2PS info: "); break; case GL2PS_WARNING : fprintf(stderr, "GL2PS warning: "); break; case GL2PS_ERROR : fprintf(stderr, "GL2PS error: "); break; } va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); fprintf(stderr, "\n"); } */ /* if(level == GL2PS_ERROR) exit(1); */ } static void *gl2psMalloc(size_t size) { void *ptr; if(!size) return NULL; ptr = malloc(size); if(!ptr){ gl2psMsg(GL2PS_ERROR, "Couldn't allocate requested memory"); return NULL; } return ptr; } static void *gl2psRealloc(void *ptr, size_t size) { void *orig = ptr; if(!size) return NULL; ptr = realloc(orig, size); if(!ptr){ gl2psMsg(GL2PS_ERROR, "Couldn't reallocate requested memory"); free(orig); return NULL; } return ptr; } static void gl2psFree(void *ptr) { if(!ptr) return; free(ptr); } static int gl2psWriteBigEndian(unsigned long data, int bytes) { int i; int size = sizeof(unsigned long); for(i = 1; i <= bytes; ++i){ fputc(0xff & (data >> (size - i) * 8), gl2ps->stream); } return bytes; } /* zlib compression helper routines */ #if defined(GL2PS_HAVE_ZLIB) static void gl2psSetupCompress(void) { gl2ps->compress = (GL2PScompress*)gl2psMalloc(sizeof(GL2PScompress)); gl2ps->compress->src = NULL; gl2ps->compress->start = NULL; gl2ps->compress->dest = NULL; gl2ps->compress->srcLen = 0; gl2ps->compress->destLen = 0; } static void gl2psFreeCompress(void) { if(!gl2ps->compress) return; gl2psFree(gl2ps->compress->start); gl2psFree(gl2ps->compress->dest); gl2ps->compress->src = NULL; gl2ps->compress->start = NULL; gl2ps->compress->dest = NULL; gl2ps->compress->srcLen = 0; gl2ps->compress->destLen = 0; } static int gl2psAllocCompress(unsigned int srcsize) { gl2psFreeCompress(); if(!gl2ps->compress || !srcsize) return GL2PS_ERROR; gl2ps->compress->srcLen = srcsize; gl2ps->compress->destLen = (int)ceil(1.001 * gl2ps->compress->srcLen + 12); gl2ps->compress->src = (Bytef*)gl2psMalloc(gl2ps->compress->srcLen); gl2ps->compress->start = gl2ps->compress->src; gl2ps->compress->dest = (Bytef*)gl2psMalloc(gl2ps->compress->destLen); return GL2PS_SUCCESS; } static void *gl2psReallocCompress(unsigned int srcsize) { if(!gl2ps->compress || !srcsize) return NULL; if(srcsize < gl2ps->compress->srcLen) return gl2ps->compress->start; gl2ps->compress->srcLen = srcsize; gl2ps->compress->destLen = (int)ceil(1.001 * gl2ps->compress->srcLen + 12); gl2ps->compress->src = (Bytef*)gl2psRealloc(gl2ps->compress->src, gl2ps->compress->srcLen); gl2ps->compress->start = gl2ps->compress->src; gl2ps->compress->dest = (Bytef*)gl2psRealloc(gl2ps->compress->dest, gl2ps->compress->destLen); return gl2ps->compress->start; } static int gl2psWriteBigEndianCompress(unsigned long data, int bytes) { int i; int size = sizeof(unsigned long); for(i = 1; i <= bytes; ++i){ *gl2ps->compress->src = (Bytef)(0xff & (data >> (size-i) * 8)); ++gl2ps->compress->src; } return bytes; } static int gl2psDeflate(void) { /* For compatibility with older zlib versions, we use compress(...) instead of compress2(..., Z_BEST_COMPRESSION) */ return compress(gl2ps->compress->dest, &gl2ps->compress->destLen, gl2ps->compress->start, gl2ps->compress->srcLen); } #endif static int gl2psPrintf(const char* fmt, ...) { int ret; va_list args; #if defined(GL2PS_HAVE_ZLIB) static char buf[1024]; char *bufptr = buf; GLboolean freebuf = GL_FALSE; unsigned int oldsize = 0; #if !defined(GL2PS_HAVE_NO_VSNPRINTF) /* Try writing the string to a 1024 byte buffer. If it is too small to fit, keep trying larger sizes until it does. */ int bufsize = sizeof(buf); #endif if(gl2ps->options & GL2PS_COMPRESS){ va_start(args, fmt); #if defined(GL2PS_HAVE_NO_VSNPRINTF) ret = vsprintf(buf, fmt, args); #else ret = vsnprintf(bufptr, bufsize, fmt, args); #endif va_end(args); #if !defined(GL2PS_HAVE_NO_VSNPRINTF) while(ret >= (bufsize - 1) || ret < 0){ /* Too big. Allocate a new buffer. */ bufsize *= 2; if(freebuf == GL_TRUE) gl2psFree(bufptr); bufptr = (char *)gl2psMalloc(bufsize); freebuf = GL_TRUE; va_start(args, fmt); ret = vsnprintf(bufptr, bufsize, fmt, args); va_end(args); } #endif oldsize = gl2ps->compress->srcLen; gl2ps->compress->start = (Bytef*)gl2psReallocCompress(oldsize + ret); memcpy(gl2ps->compress->start + oldsize, bufptr, ret); if(freebuf == GL_TRUE) gl2psFree(bufptr); ret = 0; } else{ #endif va_start(args, fmt); ret = vfprintf(gl2ps->stream, fmt, args); va_end(args); #if defined(GL2PS_HAVE_ZLIB) } #endif return ret; } static void gl2psPrintGzipHeader(void) { #if defined(GL2PS_HAVE_ZLIB) char tmp[10] = {'\x1f', '\x8b', /* magic numbers: 0x1f, 0x8b */ 8, /* compression method: Z_DEFLATED */ 0, /* flags */ 0, 0, 0, 0, /* time */ 2, /* extra flags: max compression */ '\x03'}; /* OS code: 0x03 (Unix) */ if(gl2ps->options & GL2PS_COMPRESS){ gl2psSetupCompress(); /* add the gzip file header */ fwrite(tmp, 10, 1, gl2ps->stream); } #endif } static void gl2psPrintGzipFooter(void) { #if defined(GL2PS_HAVE_ZLIB) int n; uLong crc, len; char tmp[8]; if(gl2ps->options & GL2PS_COMPRESS){ if(Z_OK != gl2psDeflate()){ gl2psMsg(GL2PS_ERROR, "Zlib deflate error"); } else{ /* determine the length of the header in the zlib stream */ n = 2; /* CMF+FLG */ if(gl2ps->compress->dest[1] & (1<<5)){ n += 4; /* DICTID */ } /* write the data, without the zlib header and footer */ fwrite(gl2ps->compress->dest+n, gl2ps->compress->destLen-(n+4), 1, gl2ps->stream); /* add the gzip file footer */ crc = crc32(0L, gl2ps->compress->start, gl2ps->compress->srcLen); for(n = 0; n < 4; ++n){ tmp[n] = (char)(crc & 0xff); crc >>= 8; } len = gl2ps->compress->srcLen; for(n = 4; n < 8; ++n){ tmp[n] = (char)(len & 0xff); len >>= 8; } fwrite(tmp, 8, 1, gl2ps->stream); } gl2psFreeCompress(); gl2psFree(gl2ps->compress); gl2ps->compress = NULL; } #endif } /* The list handling routines */ static void gl2psListRealloc(GL2PSlist *list, GLint n) { if(!list){ gl2psMsg(GL2PS_ERROR, "Cannot reallocate NULL list"); return; } if(n <= 0) return; if(!list->array){ list->nmax = n; list->array = (char*)gl2psMalloc(list->nmax * list->size); } else{ if(n > list->nmax){ list->nmax = ((n - 1) / list->incr + 1) * list->incr; list->array = (char*)gl2psRealloc(list->array, list->nmax * list->size); } } } static GL2PSlist *gl2psListCreate(GLint n, GLint incr, GLint size) { GL2PSlist *list; if(n < 0) n = 0; if(incr <= 0) incr = 1; list = (GL2PSlist*)gl2psMalloc(sizeof(GL2PSlist)); list->nmax = 0; list->incr = incr; list->size = size; list->n = 0; list->array = NULL; gl2psListRealloc(list, n); return list; } static void gl2psListReset(GL2PSlist *list) { if(!list) return; list->n = 0; } static void gl2psListDelete(GL2PSlist *list) { if(!list) return; gl2psFree(list->array); gl2psFree(list); } static void gl2psListAdd(GL2PSlist *list, void *data) { if(!list){ gl2psMsg(GL2PS_ERROR, "Cannot add into unallocated list"); return; } list->n++; gl2psListRealloc(list, list->n); memcpy(&list->array[(list->n - 1) * list->size], data, list->size); } static int gl2psListNbr(GL2PSlist *list) { if(!list) return 0; return list->n; } static void *gl2psListPointer(GL2PSlist *list, GLint idx) { if(!list){ gl2psMsg(GL2PS_ERROR, "Cannot point into unallocated list"); return NULL; } if((idx < 0) || (idx >= list->n)){ gl2psMsg(GL2PS_ERROR, "Wrong list index in gl2psListPointer"); return NULL; } return &list->array[idx * list->size]; } static void gl2psListSort(GL2PSlist *list, int (*fcmp)(const void *a, const void *b)) { if(!list) return; qsort(list->array, list->n, list->size, fcmp); } static void gl2psListAction(GL2PSlist *list, void (*action)(void *data)) { GLint i; for(i = 0; i < gl2psListNbr(list); i++){ (*action)(gl2psListPointer(list, i)); } } static void gl2psListActionInverse(GL2PSlist *list, void (*action)(void *data)) { GLint i; for(i = gl2psListNbr(list); i > 0; i--){ (*action)(gl2psListPointer(list, i-1)); } } #if defined(GL2PS_HAVE_LIBPNG) static void gl2psListRead(GL2PSlist *list, int index, void *data) { if((index < 0) || (index >= list->n)) gl2psMsg(GL2PS_ERROR, "Wrong list index in gl2psListRead"); memcpy(data, &list->array[index * list->size], list->size); } static void gl2psEncodeBase64Block(unsigned char in[3], unsigned char out[4], int len) { static const char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; out[0] = cb64[ in[0] >> 2 ]; out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ]; out[2] = (len > 1) ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '='; out[3] = (len > 2) ? cb64[ in[2] & 0x3f ] : '='; } static void gl2psListEncodeBase64(GL2PSlist *list) { unsigned char *buffer, in[3], out[4]; int i, n, index, len; n = list->n * list->size; buffer = (unsigned char*)gl2psMalloc(n * sizeof(unsigned char)); memcpy(buffer, list->array, n * sizeof(unsigned char)); gl2psListReset(list); index = 0; while(index < n) { len = 0; for(i = 0; i < 3; i++) { if(index < n){ in[i] = buffer[index]; len++; } else{ in[i] = 0; } index++; } if(len) { gl2psEncodeBase64Block(in, out, len); for(i = 0; i < 4; i++) gl2psListAdd(list, &out[i]); } } gl2psFree(buffer); } #endif /* Helpers for rgba colors */ static GLboolean gl2psSameColor(GL2PSrgba rgba1, GL2PSrgba rgba2) { if(!GL2PS_ZERO(rgba1[0] - rgba2[0]) || !GL2PS_ZERO(rgba1[1] - rgba2[1]) || !GL2PS_ZERO(rgba1[2] - rgba2[2])) return GL_FALSE; return GL_TRUE; } static GLboolean gl2psVertsSameColor(const GL2PSprimitive *prim) { int i; for(i = 1; i < prim->numverts; i++){ if(!gl2psSameColor(prim->verts[0].rgba, prim->verts[i].rgba)){ return GL_FALSE; } } return GL_TRUE; } static GLboolean gl2psSameColorThreshold(int n, GL2PSrgba rgba[], GL2PSrgba threshold) { int i; if(n < 2) return GL_TRUE; for(i = 1; i < n; i++){ if(fabs(rgba[0][0] - rgba[i][0]) > threshold[0] || fabs(rgba[0][1] - rgba[i][1]) > threshold[1] || fabs(rgba[0][2] - rgba[i][2]) > threshold[2]) return GL_FALSE; } return GL_TRUE; } static void gl2psSetLastColor(GL2PSrgba rgba) { int i; for(i = 0; i < 3; ++i){ gl2ps->lastrgba[i] = rgba[i]; } } static GLfloat gl2psGetRGB(GL2PSimage *im, GLuint x, GLuint y, GLfloat *red, GLfloat *green, GLfloat *blue) { GLsizei width = im->width; GLsizei height = im->height; GLfloat *pixels = im->pixels; GLfloat *pimag; /* OpenGL image is from down to up, PS image is up to down */ switch(im->format){ case GL_RGBA: pimag = pixels + 4 * (width * (height - 1 - y) + x); break; case GL_RGB: default: pimag = pixels + 3 * (width * (height - 1 - y) + x); break; } *red = *pimag; pimag++; *green = *pimag; pimag++; *blue = *pimag; pimag++; return (im->format == GL_RGBA) ? *pimag : 1.0F; } /* Helper routines for pixmaps */ static GL2PSimage *gl2psCopyPixmap(GL2PSimage *im) { int size; GL2PSimage *image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage)); image->width = im->width; image->height = im->height; image->format = im->format; image->type = im->type; image->zoom_x = im->zoom_x; image->zoom_y = im->zoom_y; switch(image->format){ case GL_RGBA: size = image->height * image->width * 4 * sizeof(GLfloat); break; case GL_RGB: default: size = image->height * image->width * 3 * sizeof(GLfloat); break; } image->pixels = (GLfloat*)gl2psMalloc(size); memcpy(image->pixels, im->pixels, size); return image; } static void gl2psFreePixmap(GL2PSimage *im) { if(!im) return; gl2psFree(im->pixels); gl2psFree(im); } #if defined(GL2PS_HAVE_LIBPNG) #if !defined(png_jmpbuf) # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) #endif static void gl2psUserWritePNG(png_structp png_ptr, png_bytep data, png_size_t length) { unsigned int i; GL2PSlist *png = (GL2PSlist*)png_get_io_ptr(png_ptr); for(i = 0; i < length; i++) gl2psListAdd(png, &data[i]); } static void gl2psUserFlushPNG(png_structp png_ptr) { (void) png_ptr; /* not used */ } static void gl2psConvertPixmapToPNG(GL2PSimage *pixmap, GL2PSlist *png) { png_structp png_ptr; png_infop info_ptr; unsigned char *row_data; GLfloat dr, dg, db; int row, col; if(!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) return; if(!(info_ptr = png_create_info_struct(png_ptr))){ png_destroy_write_struct(&png_ptr, NULL); return; } if(setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); return; } png_set_write_fn(png_ptr, (void *)png, gl2psUserWritePNG, gl2psUserFlushPNG); png_set_compression_level(png_ptr, Z_DEFAULT_COMPRESSION); png_set_IHDR(png_ptr, info_ptr, pixmap->width, pixmap->height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); row_data = (unsigned char*)gl2psMalloc(3 * pixmap->width * sizeof(unsigned char)); for(row = 0; row < pixmap->height; row++){ for(col = 0; col < pixmap->width; col++){ gl2psGetRGB(pixmap, col, row, &dr, &dg, &db); row_data[3*col] = (unsigned char)(255. * dr); row_data[3*col+1] = (unsigned char)(255. * dg); row_data[3*col+2] = (unsigned char)(255. * db); } png_write_row(png_ptr, (png_bytep)row_data); } gl2psFree(row_data); png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); } #endif /* Helper routines for text strings */ static GLint gl2psAddText(GLint type, const char *str, const char *fontname, GLshort fontsize, GLint alignment, GLfloat angle, GL2PSrgba color) { GLfloat pos[4]; GL2PSprimitive *prim; GLboolean valid; if(!gl2ps || !str || !fontname) return GL2PS_UNINITIALIZED; if(gl2ps->options & GL2PS_NO_TEXT) return GL2PS_SUCCESS; if (gl2ps->forcerasterpos) { pos[0] = gl2ps->rasterpos.xyz[0]; pos[1] = gl2ps->rasterpos.xyz[1]; pos[2] = gl2ps->rasterpos.xyz[2]; pos[3] = 1.f; } else { glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid); if(GL_FALSE == valid) return GL2PS_SUCCESS; /* the primitive is culled */ glGetFloatv(GL_CURRENT_RASTER_POSITION, pos); } prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); prim->type = (GLshort)type; prim->boundary = 0; prim->numverts = 1; prim->verts = (GL2PSvertex*)gl2psMalloc(sizeof(GL2PSvertex)); prim->verts[0].xyz[0] = pos[0]; prim->verts[0].xyz[1] = pos[1]; prim->verts[0].xyz[2] = pos[2]; prim->culled = 0; prim->offset = 0; prim->ofactor = 0.0; prim->ounits = 0.0; prim->pattern = 0; prim->factor = 0; prim->width = 1; prim->linecap = 0; prim->linejoin = 0; if (color) { memcpy(prim->verts[0].rgba, color, 4 * sizeof(float)); } else { if (gl2ps->forcerasterpos) { prim->verts[0].rgba[0] = gl2ps->rasterpos.rgba[0]; prim->verts[0].rgba[1] = gl2ps->rasterpos.rgba[1]; prim->verts[0].rgba[2] = gl2ps->rasterpos.rgba[2]; prim->verts[0].rgba[3] = gl2ps->rasterpos.rgba[3]; } else { glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba); } } prim->data.text = (GL2PSstring*)gl2psMalloc(sizeof(GL2PSstring)); prim->data.text->str = (char*)gl2psMalloc((strlen(str)+1)*sizeof(char)); strcpy(prim->data.text->str, str); prim->data.text->fontname = (char*)gl2psMalloc((strlen(fontname)+1)*sizeof(char)); strcpy(prim->data.text->fontname, fontname); prim->data.text->fontsize = fontsize; prim->data.text->alignment = alignment; prim->data.text->angle = angle; gl2ps->forcerasterpos = GL_FALSE; /* If no OpenGL context, just add directly to primitives */ if (gl2ps->options & GL2PS_NO_OPENGL_CONTEXT) { gl2psListAdd(gl2ps->primitives, &prim); } else { gl2psListAdd(gl2ps->auxprimitives, &prim); glPassThrough(GL2PS_TEXT_TOKEN); } return GL2PS_SUCCESS; } static GL2PSstring *gl2psCopyText(GL2PSstring *t) { GL2PSstring *text = (GL2PSstring*)gl2psMalloc(sizeof(GL2PSstring)); text->str = (char*)gl2psMalloc((strlen(t->str)+1)*sizeof(char)); strcpy(text->str, t->str); text->fontname = (char*)gl2psMalloc((strlen(t->fontname)+1)*sizeof(char)); strcpy(text->fontname, t->fontname); text->fontsize = t->fontsize; text->alignment = t->alignment; text->angle = t->angle; return text; } static void gl2psFreeText(GL2PSstring *text) { if(!text) return; gl2psFree(text->str); gl2psFree(text->fontname); gl2psFree(text); } /* Helpers for blending modes */ static GLboolean gl2psSupportedBlendMode(GLenum sfactor, GLenum dfactor) { /* returns TRUE if gl2ps supports the argument combination: only two blending modes have been implemented so far */ if( (sfactor == GL_SRC_ALPHA && dfactor == GL_ONE_MINUS_SRC_ALPHA) || (sfactor == GL_ONE && dfactor == GL_ZERO) ) return GL_TRUE; return GL_FALSE; } static void gl2psAdaptVertexForBlending(GL2PSvertex *v) { /* Transforms vertex depending on the actual blending function - currently the vertex v is considered as source vertex and his alpha value is changed to 1.0 if source blending GL_ONE is active. This might be extended in the future */ if(!v || !gl2ps) return; if(gl2ps->options & GL2PS_NO_BLENDING || !gl2ps->blending){ v->rgba[3] = 1.0F; return; } switch(gl2ps->blendfunc[0]){ case GL_ONE: v->rgba[3] = 1.0F; break; default: break; } } static void gl2psAssignTriangleProperties(GL2PStriangle *t) { /* int i; */ t->prop = T_VAR_COLOR; /* Uncommenting the following lines activates an even more fine grained distinction between triangle types - please don't delete, a remarkable amount of PDF handling code inside this file depends on it if activated */ /* t->prop = T_CONST_COLOR; for(i = 0; i < 3; ++i){ if(!GL2PS_ZERO(t->vertex[0].rgba[i] - t->vertex[1].rgba[i]) || !GL2PS_ZERO(t->vertex[1].rgba[i] - t->vertex[2].rgba[i])){ t->prop = T_VAR_COLOR; break; } } */ if(!GL2PS_ZERO(t->vertex[0].rgba[3] - t->vertex[1].rgba[3]) || !GL2PS_ZERO(t->vertex[1].rgba[3] - t->vertex[2].rgba[3])){ t->prop |= T_VAR_ALPHA; } else{ if(t->vertex[0].rgba[3] < 1) t->prop |= T_ALPHA_LESS_1; else t->prop |= T_ALPHA_1; } } static void gl2psFillTriangleFromPrimitive(GL2PStriangle *t, GL2PSprimitive *p, GLboolean assignprops) { t->vertex[0] = p->verts[0]; t->vertex[1] = p->verts[1]; t->vertex[2] = p->verts[2]; if(GL_TRUE == assignprops) gl2psAssignTriangleProperties(t); } static void gl2psInitTriangle(GL2PStriangle *t) { int i; GL2PSvertex vertex = { {-1.0F, -1.0F, -1.0F}, {-1.0F, -1.0F, -1.0F, -1.0F} }; for(i = 0; i < 3; i++) t->vertex[i] = vertex; t->prop = T_UNDEFINED; } /* Miscellaneous helper routines */ static void gl2psResetLineProperties(void) { gl2ps->lastlinewidth = 0.; gl2ps->lastlinecap = gl2ps->lastlinejoin = 0; } static GL2PSprimitive *gl2psCopyPrimitive(GL2PSprimitive *p) { GL2PSprimitive *prim; if(!p){ gl2psMsg(GL2PS_ERROR, "Trying to copy an empty primitive"); return NULL; } prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); prim->type = p->type; prim->numverts = p->numverts; prim->boundary = p->boundary; prim->offset = p->offset; prim->ofactor = p->ofactor; prim->ounits = p->ounits; prim->pattern = p->pattern; prim->factor = p->factor; prim->culled = p->culled; prim->width = p->width; prim->linecap = p->linecap; prim->linejoin = p->linejoin; prim->verts = (GL2PSvertex*)gl2psMalloc(p->numverts*sizeof(GL2PSvertex)); memcpy(prim->verts, p->verts, p->numverts * sizeof(GL2PSvertex)); switch(prim->type){ case GL2PS_PIXMAP : prim->data.image = gl2psCopyPixmap(p->data.image); break; case GL2PS_TEXT : case GL2PS_SPECIAL : prim->data.text = gl2psCopyText(p->data.text); break; default: break; } return prim; } static GLboolean gl2psSamePosition(GL2PSxyz p1, GL2PSxyz p2) { if(!GL2PS_ZERO(p1[0] - p2[0]) || !GL2PS_ZERO(p1[1] - p2[1]) || !GL2PS_ZERO(p1[2] - p2[2])) return GL_FALSE; return GL_TRUE; } /********************************************************************* * * 3D sorting routines * *********************************************************************/ static GLfloat gl2psComparePointPlane(GL2PSxyz point, GL2PSplane plane) { return (plane[0] * point[0] + plane[1] * point[1] + plane[2] * point[2] + plane[3]); } static GLfloat gl2psPsca(GLfloat *a, GLfloat *b) { return (a[0]*b[0] + a[1]*b[1] + a[2]*b[2]); } static void gl2psPvec(GLfloat *a, GLfloat *b, GLfloat *c) { c[0] = a[1]*b[2] - a[2]*b[1]; c[1] = a[2]*b[0] - a[0]*b[2]; c[2] = a[0]*b[1] - a[1]*b[0]; } static GLfloat gl2psNorm(GLfloat *a) { return (GLfloat)sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]); } static void gl2psGetNormal(GLfloat *a, GLfloat *b, GLfloat *c) { GLfloat norm; gl2psPvec(a, b, c); if(!GL2PS_ZERO(norm = gl2psNorm(c))){ c[0] = c[0] / norm; c[1] = c[1] / norm; c[2] = c[2] / norm; } else{ /* The plane is still wrong despite our tests in gl2psGetPlane. Let's return a dummy value for now (this is a hack: we should do more intelligent tests in GetPlane) */ c[0] = c[1] = 0.0F; c[2] = 1.0F; } } static void gl2psGetPlane(GL2PSprimitive *prim, GL2PSplane plane) { GL2PSxyz v = {0.0F, 0.0F, 0.0F}, w = {0.0F, 0.0F, 0.0F}; switch(prim->type){ case GL2PS_TRIANGLE : case GL2PS_QUADRANGLE : v[0] = prim->verts[1].xyz[0] - prim->verts[0].xyz[0]; v[1] = prim->verts[1].xyz[1] - prim->verts[0].xyz[1]; v[2] = prim->verts[1].xyz[2] - prim->verts[0].xyz[2]; w[0] = prim->verts[2].xyz[0] - prim->verts[0].xyz[0]; w[1] = prim->verts[2].xyz[1] - prim->verts[0].xyz[1]; w[2] = prim->verts[2].xyz[2] - prim->verts[0].xyz[2]; if((GL2PS_ZERO(v[0]) && GL2PS_ZERO(v[1]) && GL2PS_ZERO(v[2])) || (GL2PS_ZERO(w[0]) && GL2PS_ZERO(w[1]) && GL2PS_ZERO(w[2]))){ plane[0] = plane[1] = 0.0F; plane[2] = 1.0F; plane[3] = -prim->verts[0].xyz[2]; } else{ gl2psGetNormal(v, w, plane); plane[3] = - plane[0] * prim->verts[0].xyz[0] - plane[1] * prim->verts[0].xyz[1] - plane[2] * prim->verts[0].xyz[2]; } break; case GL2PS_LINE : v[0] = prim->verts[1].xyz[0] - prim->verts[0].xyz[0]; v[1] = prim->verts[1].xyz[1] - prim->verts[0].xyz[1]; v[2] = prim->verts[1].xyz[2] - prim->verts[0].xyz[2]; if(GL2PS_ZERO(v[0]) && GL2PS_ZERO(v[1]) && GL2PS_ZERO(v[2])){ plane[0] = plane[1] = 0.0F; plane[2] = 1.0F; plane[3] = -prim->verts[0].xyz[2]; } else{ if(GL2PS_ZERO(v[0])) w[0] = 1.0F; else if(GL2PS_ZERO(v[1])) w[1] = 1.0F; else w[2] = 1.0F; gl2psGetNormal(v, w, plane); plane[3] = - plane[0] * prim->verts[0].xyz[0] - plane[1] * prim->verts[0].xyz[1] - plane[2] * prim->verts[0].xyz[2]; } break; case GL2PS_POINT : case GL2PS_PIXMAP : case GL2PS_TEXT : case GL2PS_SPECIAL : case GL2PS_IMAGEMAP: plane[0] = plane[1] = 0.0F; plane[2] = 1.0F; plane[3] = -prim->verts[0].xyz[2]; break; default : gl2psMsg(GL2PS_ERROR, "Unknown primitive type in BSP tree"); plane[0] = plane[1] = plane[3] = 0.0F; plane[2] = 1.0F; break; } } static void gl2psCutEdge(GL2PSvertex *a, GL2PSvertex *b, GL2PSplane plane, GL2PSvertex *c) { GL2PSxyz v; GLfloat sect, psca; v[0] = b->xyz[0] - a->xyz[0]; v[1] = b->xyz[1] - a->xyz[1]; v[2] = b->xyz[2] - a->xyz[2]; if(!GL2PS_ZERO(psca = gl2psPsca(plane, v))) sect = -gl2psComparePointPlane(a->xyz, plane) / psca; else sect = 0.0F; c->xyz[0] = a->xyz[0] + v[0] * sect; c->xyz[1] = a->xyz[1] + v[1] * sect; c->xyz[2] = a->xyz[2] + v[2] * sect; c->rgba[0] = (1 - sect) * a->rgba[0] + sect * b->rgba[0]; c->rgba[1] = (1 - sect) * a->rgba[1] + sect * b->rgba[1]; c->rgba[2] = (1 - sect) * a->rgba[2] + sect * b->rgba[2]; c->rgba[3] = (1 - sect) * a->rgba[3] + sect * b->rgba[3]; } static void gl2psCreateSplitPrimitive(GL2PSprimitive *parent, GL2PSplane plane, GL2PSprimitive *child, GLshort numverts, GLshort *index0, GLshort *index1) { GLshort i; if(parent->type == GL2PS_IMAGEMAP){ child->type = GL2PS_IMAGEMAP; child->data.image = parent->data.image; } else{ if(numverts > 4){ gl2psMsg(GL2PS_WARNING, "%d vertices in polygon", numverts); numverts = 4; } switch(numverts){ case 1 : child->type = GL2PS_POINT; break; case 2 : child->type = GL2PS_LINE; break; case 3 : child->type = GL2PS_TRIANGLE; break; case 4 : child->type = GL2PS_QUADRANGLE; break; default: child->type = GL2PS_NO_TYPE; break; } } child->boundary = 0; /* FIXME: not done! */ child->culled = parent->culled; child->offset = parent->offset; child->ofactor = parent->ofactor; child->ounits = parent->ounits; child->pattern = parent->pattern; child->factor = parent->factor; child->width = parent->width; child->linecap = parent->linecap; child->linejoin = parent->linejoin; child->numverts = numverts; child->verts = (GL2PSvertex*)gl2psMalloc(numverts * sizeof(GL2PSvertex)); for(i = 0; i < numverts; i++){ if(index1[i] < 0){ child->verts[i] = parent->verts[index0[i]]; } else{ gl2psCutEdge(&parent->verts[index0[i]], &parent->verts[index1[i]], plane, &child->verts[i]); } } } static void gl2psAddIndex(GLshort *index0, GLshort *index1, GLshort *nb, GLshort i, GLshort j) { GLint k; for(k = 0; k < *nb; k++){ if((index0[k] == i && index1[k] == j) || (index1[k] == i && index0[k] == j)) return; } index0[*nb] = i; index1[*nb] = j; (*nb)++; } static GLshort gl2psGetIndex(GLshort i, GLshort num) { return (i < num - 1) ? i + 1 : 0; } static GLint gl2psTestSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane) { GLint type = GL2PS_COINCIDENT; GLshort i, j; GLfloat d[5]; for(i = 0; i < prim->numverts; i++){ d[i] = gl2psComparePointPlane(prim->verts[i].xyz, plane); } if(prim->numverts < 2){ return 0; } else{ for(i = 0; i < prim->numverts; i++){ j = gl2psGetIndex(i, prim->numverts); if(d[j] > GL2PS_EPSILON){ if(type == GL2PS_COINCIDENT) type = GL2PS_IN_BACK_OF; else if(type != GL2PS_IN_BACK_OF) return 1; if(d[i] < -GL2PS_EPSILON) return 1; } else if(d[j] < -GL2PS_EPSILON){ if(type == GL2PS_COINCIDENT) type = GL2PS_IN_FRONT_OF; else if(type != GL2PS_IN_FRONT_OF) return 1; if(d[i] > GL2PS_EPSILON) return 1; } } } return 0; } static GLint gl2psSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane, GL2PSprimitive **front, GL2PSprimitive **back) { GLshort i, j, in = 0, out = 0, in0[5], in1[5], out0[5], out1[5]; GLint type; GLfloat d[5]; type = GL2PS_COINCIDENT; for(i = 0; i < prim->numverts; i++){ d[i] = gl2psComparePointPlane(prim->verts[i].xyz, plane); } switch(prim->type){ case GL2PS_POINT : if(d[0] > GL2PS_EPSILON) type = GL2PS_IN_BACK_OF; else if(d[0] < -GL2PS_EPSILON) type = GL2PS_IN_FRONT_OF; else type = GL2PS_COINCIDENT; break; default : for(i = 0; i < prim->numverts; i++){ j = gl2psGetIndex(i, prim->numverts); if(d[j] > GL2PS_EPSILON){ if(type == GL2PS_COINCIDENT) type = GL2PS_IN_BACK_OF; else if(type != GL2PS_IN_BACK_OF) type = GL2PS_SPANNING; if(d[i] < -GL2PS_EPSILON){ gl2psAddIndex(in0, in1, &in, i, j); gl2psAddIndex(out0, out1, &out, i, j); type = GL2PS_SPANNING; } gl2psAddIndex(out0, out1, &out, j, -1); } else if(d[j] < -GL2PS_EPSILON){ if(type == GL2PS_COINCIDENT) type = GL2PS_IN_FRONT_OF; else if(type != GL2PS_IN_FRONT_OF) type = GL2PS_SPANNING; if(d[i] > GL2PS_EPSILON){ gl2psAddIndex(in0, in1, &in, i, j); gl2psAddIndex(out0, out1, &out, i, j); type = GL2PS_SPANNING; } gl2psAddIndex(in0, in1, &in, j, -1); } else{ gl2psAddIndex(in0, in1, &in, j, -1); gl2psAddIndex(out0, out1, &out, j, -1); } } break; } if(type == GL2PS_SPANNING){ *back = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); *front = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); gl2psCreateSplitPrimitive(prim, plane, *back, out, out0, out1); gl2psCreateSplitPrimitive(prim, plane, *front, in, in0, in1); } return type; } static void gl2psDivideQuad(GL2PSprimitive *quad, GL2PSprimitive **t1, GL2PSprimitive **t2) { *t1 = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); *t2 = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); (*t1)->type = (*t2)->type = GL2PS_TRIANGLE; (*t1)->numverts = (*t2)->numverts = 3; (*t1)->culled = (*t2)->culled = quad->culled; (*t1)->offset = (*t2)->offset = quad->offset; (*t1)->ofactor = (*t2)->ofactor = quad->ofactor; (*t1)->ounits = (*t2)->ounits = quad->ounits; (*t1)->pattern = (*t2)->pattern = quad->pattern; (*t1)->factor = (*t2)->factor = quad->factor; (*t1)->width = (*t2)->width = quad->width; (*t1)->linecap = (*t2)->linecap = quad->linecap; (*t1)->linejoin = (*t2)->linejoin = quad->linejoin; (*t1)->verts = (GL2PSvertex*)gl2psMalloc(3 * sizeof(GL2PSvertex)); (*t2)->verts = (GL2PSvertex*)gl2psMalloc(3 * sizeof(GL2PSvertex)); (*t1)->verts[0] = quad->verts[0]; (*t1)->verts[1] = quad->verts[1]; (*t1)->verts[2] = quad->verts[2]; (*t1)->boundary = ((quad->boundary & 1) ? 1 : 0) | ((quad->boundary & 2) ? 2 : 0); (*t2)->verts[0] = quad->verts[0]; (*t2)->verts[1] = quad->verts[2]; (*t2)->verts[2] = quad->verts[3]; (*t2)->boundary = ((quad->boundary & 4) ? 2 : 0) | ((quad->boundary & 8) ? 4 : 0); } static int gl2psCompareDepth(const void *a, const void *b) { const GL2PSprimitive *q, *w; GLfloat dq = 0.0F, dw = 0.0F, diff; int i; q = *(const GL2PSprimitive* const*)a; w = *(const GL2PSprimitive* const*)b; for(i = 0; i < q->numverts; i++){ dq += q->verts[i].xyz[2]; } dq /= (GLfloat)q->numverts; for(i = 0; i < w->numverts; i++){ dw += w->verts[i].xyz[2]; } dw /= (GLfloat)w->numverts; diff = dq - dw; if(diff > 0.){ return -1; } else if(diff < 0.){ return 1; } else{ return 0; } } static int gl2psTrianglesFirst(const void *a, const void *b) { const GL2PSprimitive *q, *w; q = *(const GL2PSprimitive* const*)a; w = *(const GL2PSprimitive* const*)b; return (q->type < w->type ? 1 : -1); } static GLint gl2psFindRoot(GL2PSlist *primitives, GL2PSprimitive **root) { GLint i, j, count, best = 1000000, idx = 0; GL2PSprimitive *prim1, *prim2; GL2PSplane plane; GLint maxp; if(!gl2psListNbr(primitives)){ gl2psMsg(GL2PS_ERROR, "Cannot fint root in empty primitive list"); return 0; } *root = *(GL2PSprimitive**)gl2psListPointer(primitives, 0); if(gl2ps->options & GL2PS_BEST_ROOT){ maxp = gl2psListNbr(primitives); if(maxp > gl2ps->maxbestroot){ maxp = gl2ps->maxbestroot; } for(i = 0; i < maxp; i++){ prim1 = *(GL2PSprimitive**)gl2psListPointer(primitives, i); gl2psGetPlane(prim1, plane); count = 0; for(j = 0; j < gl2psListNbr(primitives); j++){ if(j != i){ prim2 = *(GL2PSprimitive**)gl2psListPointer(primitives, j); count += gl2psTestSplitPrimitive(prim2, plane); } if(count > best) break; } if(count < best){ best = count; idx = i; *root = prim1; if(!count) return idx; } } /* if(index) gl2psMsg(GL2PS_INFO, "GL2PS_BEST_ROOT was worth it: %d", index); */ return idx; } else{ return 0; } } static void gl2psFreeImagemap(GL2PSimagemap *list) { GL2PSimagemap *next; while(list != NULL){ next = list->next; gl2psFree(list->image->pixels); gl2psFree(list->image); gl2psFree(list); list = next; } } static void gl2psFreePrimitive(void *data) { GL2PSprimitive *q; q = *(GL2PSprimitive**)data; gl2psFree(q->verts); if(q->type == GL2PS_TEXT || q->type == GL2PS_SPECIAL){ gl2psFreeText(q->data.text); } else if(q->type == GL2PS_PIXMAP){ gl2psFreePixmap(q->data.image); } gl2psFree(q); } static void gl2psAddPrimitiveInList(GL2PSprimitive *prim, GL2PSlist *list) { GL2PSprimitive *t1, *t2; if(prim->type != GL2PS_QUADRANGLE){ gl2psListAdd(list, &prim); } else{ gl2psDivideQuad(prim, &t1, &t2); gl2psListAdd(list, &t1); gl2psListAdd(list, &t2); gl2psFreePrimitive(&prim); } } static void gl2psFreeBspTree(GL2PSbsptree **tree) { if(*tree){ if((*tree)->back) gl2psFreeBspTree(&(*tree)->back); if((*tree)->primitives){ gl2psListAction((*tree)->primitives, gl2psFreePrimitive); gl2psListDelete((*tree)->primitives); } if((*tree)->front) gl2psFreeBspTree(&(*tree)->front); gl2psFree(*tree); *tree = NULL; } } static GLboolean gl2psGreater(GLfloat f1, GLfloat f2) { if(f1 > f2) return GL_TRUE; else return GL_FALSE; } static GLboolean gl2psLess(GLfloat f1, GLfloat f2) { if(f1 < f2) return GL_TRUE; else return GL_FALSE; } static void gl2psBuildBspTree(GL2PSbsptree *tree, GL2PSlist *primitives) { GL2PSprimitive *prim, *frontprim = NULL, *backprim = NULL; GL2PSlist *frontlist, *backlist; GLint i, idx; tree->front = NULL; tree->back = NULL; tree->primitives = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); idx = gl2psFindRoot(primitives, &prim); gl2psGetPlane(prim, tree->plane); gl2psAddPrimitiveInList(prim, tree->primitives); frontlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); backlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); for(i = 0; i < gl2psListNbr(primitives); i++){ if(i != idx){ prim = *(GL2PSprimitive**)gl2psListPointer(primitives,i); switch(gl2psSplitPrimitive(prim, tree->plane, &frontprim, &backprim)){ case GL2PS_COINCIDENT: gl2psAddPrimitiveInList(prim, tree->primitives); break; case GL2PS_IN_BACK_OF: gl2psAddPrimitiveInList(prim, backlist); break; case GL2PS_IN_FRONT_OF: gl2psAddPrimitiveInList(prim, frontlist); break; case GL2PS_SPANNING: gl2psAddPrimitiveInList(backprim, backlist); gl2psAddPrimitiveInList(frontprim, frontlist); gl2psFreePrimitive(&prim); break; } } } if(gl2psListNbr(tree->primitives)){ gl2psListSort(tree->primitives, gl2psTrianglesFirst); } if(gl2psListNbr(frontlist)){ gl2psListSort(frontlist, gl2psTrianglesFirst); tree->front = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree)); gl2psBuildBspTree(tree->front, frontlist); } else{ gl2psListDelete(frontlist); } if(gl2psListNbr(backlist)){ gl2psListSort(backlist, gl2psTrianglesFirst); tree->back = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree)); gl2psBuildBspTree(tree->back, backlist); } else{ gl2psListDelete(backlist); } gl2psListDelete(primitives); } static void gl2psTraverseBspTree(GL2PSbsptree *tree, GL2PSxyz eye, GLfloat epsilon, GLboolean (*compare)(GLfloat f1, GLfloat f2), void (*action)(void *data), int inverse) { GLfloat result; if(!tree) return; result = gl2psComparePointPlane(eye, tree->plane); if(GL_TRUE == compare(result, epsilon)){ gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action, inverse); if(inverse){ gl2psListActionInverse(tree->primitives, action); } else{ gl2psListAction(tree->primitives, action); } gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action, inverse); } else if(GL_TRUE == compare(-epsilon, result)){ gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action, inverse); if(inverse){ gl2psListActionInverse(tree->primitives, action); } else{ gl2psListAction(tree->primitives, action); } gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action, inverse); } else{ gl2psTraverseBspTree(tree->front, eye, epsilon, compare, action, inverse); gl2psTraverseBspTree(tree->back, eye, epsilon, compare, action, inverse); } } static void gl2psRescaleAndOffset(void) { GL2PSprimitive *prim; GLfloat minZ, maxZ, rangeZ, scaleZ; GLfloat factor, units, area, dZ, dZdX, dZdY, maxdZ; int i, j; if(!gl2psListNbr(gl2ps->primitives)) return; /* get z-buffer range */ prim = *(GL2PSprimitive**)gl2psListPointer(gl2ps->primitives, 0); minZ = maxZ = prim->verts[0].xyz[2]; for(i = 1; i < prim->numverts; i++){ if(prim->verts[i].xyz[2] < minZ) minZ = prim->verts[i].xyz[2]; if(prim->verts[i].xyz[2] > maxZ) maxZ = prim->verts[i].xyz[2]; } for(i = 1; i < gl2psListNbr(gl2ps->primitives); i++){ prim = *(GL2PSprimitive**)gl2psListPointer(gl2ps->primitives, i); for(j = 0; j < prim->numverts; j++){ if(prim->verts[j].xyz[2] < minZ) minZ = prim->verts[j].xyz[2]; if(prim->verts[j].xyz[2] > maxZ) maxZ = prim->verts[j].xyz[2]; } } rangeZ = (maxZ - minZ); /* rescale z-buffer coordinate in [0,GL2PS_ZSCALE], to make it of the same order of magnitude as the x and y coordinates */ scaleZ = GL2PS_ZERO(rangeZ) ? GL2PS_ZSCALE : (GL2PS_ZSCALE / rangeZ); /* avoid precision loss (we use floats!) */ if(scaleZ > 100000.F) scaleZ = 100000.F; /* apply offsets */ for(i = 0; i < gl2psListNbr(gl2ps->primitives); i++){ prim = *(GL2PSprimitive**)gl2psListPointer(gl2ps->primitives, i); for(j = 0; j < prim->numverts; j++){ prim->verts[j].xyz[2] = (prim->verts[j].xyz[2] - minZ) * scaleZ; } if((gl2ps->options & GL2PS_SIMPLE_LINE_OFFSET) && (prim->type == GL2PS_LINE)){ if(gl2ps->sort == GL2PS_SIMPLE_SORT){ prim->verts[0].xyz[2] -= GL2PS_ZOFFSET_LARGE; prim->verts[1].xyz[2] -= GL2PS_ZOFFSET_LARGE; } else{ prim->verts[0].xyz[2] -= GL2PS_ZOFFSET; prim->verts[1].xyz[2] -= GL2PS_ZOFFSET; } } else if(prim->offset && (prim->type == GL2PS_TRIANGLE)){ factor = prim->ofactor; units = prim->ounits; area = (prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) * (prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) - (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) * (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]); if(!GL2PS_ZERO(area)){ dZdX = ((prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) * (prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) - (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]) * (prim->verts[2].xyz[2] - prim->verts[1].xyz[2])) / area; dZdY = ((prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) * (prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) - (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) * (prim->verts[1].xyz[2] - prim->verts[0].xyz[2])) / area; maxdZ = (GLfloat)sqrt(dZdX * dZdX + dZdY * dZdY); } else{ maxdZ = 0.0F; } dZ = factor * maxdZ + units; prim->verts[0].xyz[2] += dZ; prim->verts[1].xyz[2] += dZ; prim->verts[2].xyz[2] += dZ; } } } /********************************************************************* * * 2D sorting routines (for occlusion culling) * *********************************************************************/ static GLint gl2psGetPlaneFromPoints(GL2PSxyz a, GL2PSxyz b, GL2PSplane plane) { GLfloat n; plane[0] = b[1] - a[1]; plane[1] = a[0] - b[0]; n = (GLfloat)sqrt(plane[0]*plane[0] + plane[1]*plane[1]); plane[2] = 0.0F; if(!GL2PS_ZERO(n)){ plane[0] /= n; plane[1] /= n; plane[3] = -plane[0]*a[0]-plane[1]*a[1]; return 1; } else{ plane[0] = -1.0F; plane[1] = 0.0F; plane[3] = a[0]; return 0; } } static void gl2psFreeBspImageTree(GL2PSbsptree2d **tree) { if(*tree){ if((*tree)->back) gl2psFreeBspImageTree(&(*tree)->back); if((*tree)->front) gl2psFreeBspImageTree(&(*tree)->front); gl2psFree(*tree); *tree = NULL; } } static GLint gl2psCheckPoint(GL2PSxyz point, GL2PSplane plane) { GLfloat pt_dis; pt_dis = gl2psComparePointPlane(point, plane); if(pt_dis > GL2PS_EPSILON) return GL2PS_POINT_INFRONT; else if(pt_dis < -GL2PS_EPSILON) return GL2PS_POINT_BACK; else return GL2PS_POINT_COINCIDENT; } static void gl2psAddPlanesInBspTreeImage(GL2PSprimitive *prim, GL2PSbsptree2d **tree) { GLint ret = 0; GLint i; GLint offset = 0; GL2PSbsptree2d *head = NULL, *cur = NULL; if((*tree == NULL) && (prim->numverts > 2)){ /* don't cull if transparent for(i = 0; i < prim->numverts - 1; i++) if(prim->verts[i].rgba[3] < 1.0F) return; */ head = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d)); for(i = 0; i < prim->numverts-1; i++){ if(!gl2psGetPlaneFromPoints(prim->verts[i].xyz, prim->verts[i+1].xyz, head->plane)){ if(prim->numverts-i > 3){ offset++; } else{ gl2psFree(head); return; } } else{ break; } } head->back = NULL; head->front = NULL; for(i = 2+offset; i < prim->numverts; i++){ ret = gl2psCheckPoint(prim->verts[i].xyz, head->plane); if(ret != GL2PS_POINT_COINCIDENT) break; } switch(ret){ case GL2PS_POINT_INFRONT : cur = head; for(i = 1+offset; i < prim->numverts-1; i++){ if(cur->front == NULL){ cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d)); } if(gl2psGetPlaneFromPoints(prim->verts[i].xyz, prim->verts[i+1].xyz, cur->front->plane)){ cur = cur->front; cur->front = NULL; cur->back = NULL; } } if(cur->front == NULL){ cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d)); } if(gl2psGetPlaneFromPoints(prim->verts[i].xyz, prim->verts[offset].xyz, cur->front->plane)){ cur->front->front = NULL; cur->front->back = NULL; } else{ gl2psFree(cur->front); cur->front = NULL; } break; case GL2PS_POINT_BACK : for(i = 0; i < 4; i++){ head->plane[i] = -head->plane[i]; } cur = head; for(i = 1+offset; i < prim->numverts-1; i++){ if(cur->front == NULL){ cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d)); } if(gl2psGetPlaneFromPoints(prim->verts[i+1].xyz, prim->verts[i].xyz, cur->front->plane)){ cur = cur->front; cur->front = NULL; cur->back = NULL; } } if(cur->front == NULL){ cur->front = (GL2PSbsptree2d*)gl2psMalloc(sizeof(GL2PSbsptree2d)); } if(gl2psGetPlaneFromPoints(prim->verts[offset].xyz, prim->verts[i].xyz, cur->front->plane)){ cur->front->front = NULL; cur->front->back = NULL; } else{ gl2psFree(cur->front); cur->front = NULL; } break; default: gl2psFree(head); return; } (*tree) = head; } } static GLint gl2psCheckPrimitive(GL2PSprimitive *prim, GL2PSplane plane) { GLint i; GLint pos; pos = gl2psCheckPoint(prim->verts[0].xyz, plane); for(i = 1; i < prim->numverts; i++){ pos |= gl2psCheckPoint(prim->verts[i].xyz, plane); if(pos == (GL2PS_POINT_INFRONT | GL2PS_POINT_BACK)) return GL2PS_SPANNING; } if(pos & GL2PS_POINT_INFRONT) return GL2PS_IN_FRONT_OF; else if(pos & GL2PS_POINT_BACK) return GL2PS_IN_BACK_OF; else return GL2PS_COINCIDENT; } static GL2PSprimitive *gl2psCreateSplitPrimitive2D(GL2PSprimitive *parent, GLshort numverts, GL2PSvertex *vertx) { GLint i; GL2PSprimitive *child = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); if(parent->type == GL2PS_IMAGEMAP){ child->type = GL2PS_IMAGEMAP; child->data.image = parent->data.image; } else { switch(numverts){ case 1 : child->type = GL2PS_POINT; break; case 2 : child->type = GL2PS_LINE; break; case 3 : child->type = GL2PS_TRIANGLE; break; case 4 : child->type = GL2PS_QUADRANGLE; break; default: child->type = GL2PS_NO_TYPE; break; /* FIXME */ } } child->boundary = 0; /* FIXME: not done! */ child->culled = parent->culled; child->offset = parent->offset; child->ofactor = parent->ofactor; child->ounits = parent->ounits; child->pattern = parent->pattern; child->factor = parent->factor; child->width = parent->width; child->linecap = parent->linecap; child->linejoin = parent->linejoin; child->numverts = numverts; child->verts = (GL2PSvertex*)gl2psMalloc(numverts * sizeof(GL2PSvertex)); for(i = 0; i < numverts; i++){ child->verts[i] = vertx[i]; } return child; } static void gl2psSplitPrimitive2D(GL2PSprimitive *prim, GL2PSplane plane, GL2PSprimitive **front, GL2PSprimitive **back) { /* cur will hold the position of the current vertex prev will hold the position of the previous vertex prev0 will hold the position of the vertex number 0 v1 and v2 represent the current and previous vertices, respectively flag is set if the current vertex should be checked against the plane */ GLint cur = -1, prev = -1, i, v1 = 0, v2 = 0, flag = 1, prev0 = -1; /* list of vertices that will go in front and back primitive */ GL2PSvertex *front_list = NULL, *back_list = NULL; /* number of vertices in front and back list */ GLshort front_count = 0, back_count = 0; for(i = 0; i <= prim->numverts; i++){ v1 = i; if(v1 == prim->numverts){ if(prim->numverts < 3) break; v1 = 0; v2 = prim->numverts - 1; cur = prev0; } else if(flag){ cur = gl2psCheckPoint(prim->verts[v1].xyz, plane); if(i == 0){ prev0 = cur; } } if(((prev == -1) || (prev == cur) || (prev == 0) || (cur == 0)) && (i < prim->numverts)){ if(cur == GL2PS_POINT_INFRONT){ front_count++; front_list = (GL2PSvertex*)gl2psRealloc(front_list, sizeof(GL2PSvertex)*front_count); front_list[front_count-1] = prim->verts[v1]; } else if(cur == GL2PS_POINT_BACK){ back_count++; back_list = (GL2PSvertex*)gl2psRealloc(back_list, sizeof(GL2PSvertex)*back_count); back_list[back_count-1] = prim->verts[v1]; } else{ front_count++; front_list = (GL2PSvertex*)gl2psRealloc(front_list, sizeof(GL2PSvertex)*front_count); front_list[front_count-1] = prim->verts[v1]; back_count++; back_list = (GL2PSvertex*)gl2psRealloc(back_list, sizeof(GL2PSvertex)*back_count); back_list[back_count-1] = prim->verts[v1]; } flag = 1; } else if((prev != cur) && (cur != 0) && (prev != 0)){ if(v1 != 0){ v2 = v1-1; i--; } front_count++; front_list = (GL2PSvertex*)gl2psRealloc(front_list, sizeof(GL2PSvertex)*front_count); gl2psCutEdge(&prim->verts[v2], &prim->verts[v1], plane, &front_list[front_count-1]); back_count++; back_list = (GL2PSvertex*)gl2psRealloc(back_list, sizeof(GL2PSvertex)*back_count); back_list[back_count-1] = front_list[front_count-1]; flag = 0; } prev = cur; } *front = gl2psCreateSplitPrimitive2D(prim, front_count, front_list); *back = gl2psCreateSplitPrimitive2D(prim, back_count, back_list); gl2psFree(front_list); gl2psFree(back_list); } static GLint gl2psAddInBspImageTree(GL2PSprimitive *prim, GL2PSbsptree2d **tree) { GLint ret = 0; GL2PSprimitive *frontprim = NULL, *backprim = NULL; /* FIXME: until we consider the actual extent of text strings and pixmaps, never cull them. Otherwise the whole string/pixmap gets culled as soon as the reference point is hidden */ if(prim->type == GL2PS_PIXMAP || prim->type == GL2PS_TEXT || prim->type == GL2PS_SPECIAL){ return 1; } if(*tree == NULL){ if((prim->type != GL2PS_IMAGEMAP) && (GL_FALSE == gl2ps->zerosurfacearea)){ gl2psAddPlanesInBspTreeImage(gl2ps->primitivetoadd, tree); } return 1; } else{ switch(gl2psCheckPrimitive(prim, (*tree)->plane)){ case GL2PS_IN_BACK_OF: return gl2psAddInBspImageTree(prim, &(*tree)->back); case GL2PS_IN_FRONT_OF: if((*tree)->front != NULL) return gl2psAddInBspImageTree(prim, &(*tree)->front); else return 0; case GL2PS_SPANNING: gl2psSplitPrimitive2D(prim, (*tree)->plane, &frontprim, &backprim); ret = gl2psAddInBspImageTree(backprim, &(*tree)->back); if((*tree)->front != NULL){ if(gl2psAddInBspImageTree(frontprim, &(*tree)->front)){ ret = 1; } } gl2psFree(frontprim->verts); gl2psFree(frontprim); gl2psFree(backprim->verts); gl2psFree(backprim); return ret; case GL2PS_COINCIDENT: if((*tree)->back != NULL){ gl2ps->zerosurfacearea = GL_TRUE; ret = gl2psAddInBspImageTree(prim, &(*tree)->back); gl2ps->zerosurfacearea = GL_FALSE; if(ret) return ret; } if((*tree)->front != NULL){ gl2ps->zerosurfacearea = GL_TRUE; ret = gl2psAddInBspImageTree(prim, &(*tree)->front); gl2ps->zerosurfacearea = GL_FALSE; if(ret) return ret; } if(prim->type == GL2PS_LINE) return 1; else return 0; } } return 0; } static void gl2psAddInImageTree(void *data) { GL2PSprimitive *prim = *(GL2PSprimitive **)data; gl2ps->primitivetoadd = prim; if(prim->type == GL2PS_IMAGEMAP && prim->data.image->format == GL2PS_IMAGEMAP_VISIBLE){ prim->culled = 1; } else if(!gl2psAddInBspImageTree(prim, &gl2ps->imagetree)){ prim->culled = 1; } else if(prim->type == GL2PS_IMAGEMAP){ prim->data.image->format = GL2PS_IMAGEMAP_VISIBLE; } } /* Boundary construction */ static void gl2psAddBoundaryInList(GL2PSprimitive *prim, GL2PSlist *list) { GL2PSprimitive *b; GLshort i; GL2PSxyz c; c[0] = c[1] = c[2] = 0.0F; for(i = 0; i < prim->numverts; i++){ c[0] += prim->verts[i].xyz[0]; c[1] += prim->verts[i].xyz[1]; } c[0] /= prim->numverts; c[1] /= prim->numverts; for(i = 0; i < prim->numverts; i++){ if(prim->boundary & (GLint)pow(2., i)){ b = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); b->type = GL2PS_LINE; b->offset = prim->offset; b->ofactor = prim->ofactor; b->ounits = prim->ounits; b->pattern = prim->pattern; b->factor = prim->factor; b->culled = prim->culled; b->width = prim->width; b->linecap = prim->linecap; b->linejoin = prim->linejoin; b->boundary = 0; b->numverts = 2; b->verts = (GL2PSvertex*)gl2psMalloc(2 * sizeof(GL2PSvertex)); #if 0 /* FIXME: need to work on boundary offset... */ v[0] = c[0] - prim->verts[i].xyz[0]; v[1] = c[1] - prim->verts[i].xyz[1]; v[2] = 0.0F; norm = gl2psNorm(v); v[0] /= norm; v[1] /= norm; b->verts[0].xyz[0] = prim->verts[i].xyz[0] +0.1*v[0]; b->verts[0].xyz[1] = prim->verts[i].xyz[1] +0.1*v[1]; b->verts[0].xyz[2] = prim->verts[i].xyz[2]; v[0] = c[0] - prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0]; v[1] = c[1] - prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1]; norm = gl2psNorm(v); v[0] /= norm; v[1] /= norm; b->verts[1].xyz[0] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0] +0.1*v[0]; b->verts[1].xyz[1] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1] +0.1*v[1]; b->verts[1].xyz[2] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[2]; #else b->verts[0].xyz[0] = prim->verts[i].xyz[0]; b->verts[0].xyz[1] = prim->verts[i].xyz[1]; b->verts[0].xyz[2] = prim->verts[i].xyz[2]; b->verts[1].xyz[0] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[0]; b->verts[1].xyz[1] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[1]; b->verts[1].xyz[2] = prim->verts[gl2psGetIndex(i, prim->numverts)].xyz[2]; #endif b->verts[0].rgba[0] = 0.0F; b->verts[0].rgba[1] = 0.0F; b->verts[0].rgba[2] = 0.0F; b->verts[0].rgba[3] = 0.0F; b->verts[1].rgba[0] = 0.0F; b->verts[1].rgba[1] = 0.0F; b->verts[1].rgba[2] = 0.0F; b->verts[1].rgba[3] = 0.0F; gl2psListAdd(list, &b); } } } static void gl2psBuildPolygonBoundary(GL2PSbsptree *tree) { GLint i; GL2PSprimitive *prim; if(!tree) return; gl2psBuildPolygonBoundary(tree->back); for(i = 0; i < gl2psListNbr(tree->primitives); i++){ prim = *(GL2PSprimitive**)gl2psListPointer(tree->primitives, i); if(prim->boundary) gl2psAddBoundaryInList(prim, tree->primitives); } gl2psBuildPolygonBoundary(tree->front); } /********************************************************************* * * Feedback buffer parser * *********************************************************************/ GL2PSDLL_API void gl2psAddPolyPrimitive(GLshort type, GLshort numverts, GL2PSvertex *verts, GLint offset, GLfloat ofactor, GLfloat ounits, GLushort pattern, GLint factor, GLfloat width, GLint linecap, GLint linejoin,char boundary) { GL2PSprimitive *prim; prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); prim->type = type; prim->numverts = numverts; prim->verts = (GL2PSvertex*)gl2psMalloc(numverts * sizeof(GL2PSvertex)); memcpy(prim->verts, verts, numverts * sizeof(GL2PSvertex)); prim->boundary = boundary; prim->offset = (char)offset; prim->ofactor = ofactor; prim->ounits = ounits; prim->pattern = pattern; prim->factor = factor; prim->width = width; prim->linecap = linecap; prim->linejoin = linejoin; prim->culled = 0; /* FIXME: here we should have an option to split stretched tris/quads to enhance SIMPLE_SORT */ gl2psListAdd(gl2ps->primitives, &prim); } static GLint gl2psGetVertex(GL2PSvertex *v, GLfloat *p) { GLint i; v->xyz[0] = p[0]; v->xyz[1] = p[1]; v->xyz[2] = p[2]; if(gl2ps->colormode == GL_COLOR_INDEX && gl2ps->colorsize > 0){ i = (GLint)(p[3] + 0.5); v->rgba[0] = gl2ps->colormap[i][0]; v->rgba[1] = gl2ps->colormap[i][1]; v->rgba[2] = gl2ps->colormap[i][2]; v->rgba[3] = gl2ps->colormap[i][3]; return 4; } else{ v->rgba[0] = p[3]; v->rgba[1] = p[4]; v->rgba[2] = p[5]; v->rgba[3] = p[6]; return 7; } } static void gl2psParseFeedbackBuffer(GLint used) { char flag; GLushort pattern = 0; GLboolean boundary; GLint i, sizeoffloat, count, v, vtot, offset = 0, factor = 0, auxindex = 0; GLint lcap = 0, ljoin = 0; GLfloat lwidth = 1.0F, psize = 1.0F, ofactor = 1.0F, ounits = 1.0F; GLfloat *current; GL2PSvertex vertices[3]; GL2PSprimitive *prim; GL2PSimagemap *node; current = gl2ps->feedback; boundary = gl2ps->boundary = GL_FALSE; while(used > 0){ if(GL_TRUE == boundary) gl2ps->boundary = GL_TRUE; switch((GLint)*current){ case GL_POINT_TOKEN : current ++; used --; i = gl2psGetVertex(&vertices[0], current); current += i; used -= i; gl2psAddPolyPrimitive(GL2PS_POINT, 1, vertices, 0, 0.0, 0.0, pattern, factor, psize, lcap, ljoin, 0); break; case GL_LINE_TOKEN : case GL_LINE_RESET_TOKEN : current ++; used --; i = gl2psGetVertex(&vertices[0], current); current += i; used -= i; i = gl2psGetVertex(&vertices[1], current); current += i; used -= i; gl2psAddPolyPrimitive(GL2PS_LINE, 2, vertices, 0, 0.0, 0.0, pattern, factor, lwidth, lcap, ljoin, 0); break; case GL_POLYGON_TOKEN : count = (GLint)current[1]; current += 2; used -= 2; v = vtot = 0; while(count > 0 && used > 0){ i = gl2psGetVertex(&vertices[v], current); gl2psAdaptVertexForBlending(&vertices[v]); current += i; used -= i; count --; vtot++; if(v == 2){ if(GL_TRUE == boundary){ if(!count && vtot == 2) flag = 1|2|4; else if(!count) flag = 2|4; else if(vtot == 2) flag = 1|2; else flag = 2; } else flag = 0; gl2psAddPolyPrimitive(GL2PS_TRIANGLE, 3, vertices, offset, ofactor, ounits, pattern, factor, 1, lcap, ljoin, flag); vertices[1] = vertices[2]; } else v ++; } break; case GL_BITMAP_TOKEN : case GL_DRAW_PIXEL_TOKEN : case GL_COPY_PIXEL_TOKEN : current ++; used --; i = gl2psGetVertex(&vertices[0], current); current += i; used -= i; break; case GL_PASS_THROUGH_TOKEN : switch((GLint)current[1]){ case GL2PS_BEGIN_OFFSET_TOKEN : offset = 1; current += 2; used -= 2; ofactor = current[1]; current += 2; used -= 2; ounits = current[1]; break; case GL2PS_END_OFFSET_TOKEN : offset = 0; ofactor = 0.0; ounits = 0.0; break; case GL2PS_BEGIN_BOUNDARY_TOKEN : boundary = GL_TRUE; break; case GL2PS_END_BOUNDARY_TOKEN : boundary = GL_FALSE; break; case GL2PS_END_STIPPLE_TOKEN : pattern = 0; factor = 0; break; case GL2PS_BEGIN_BLEND_TOKEN : gl2ps->blending = GL_TRUE; break; case GL2PS_END_BLEND_TOKEN : gl2ps->blending = GL_FALSE; break; case GL2PS_BEGIN_STIPPLE_TOKEN : current += 2; used -= 2; pattern = (GLushort)current[1]; current += 2; used -= 2; factor = (GLint)current[1]; break; case GL2PS_SRC_BLEND_TOKEN : current += 2; used -= 2; gl2ps->blendfunc[0] = (GLint)current[1]; break; case GL2PS_DST_BLEND_TOKEN : current += 2; used -= 2; gl2ps->blendfunc[1] = (GLint)current[1]; break; case GL2PS_POINT_SIZE_TOKEN : current += 2; used -= 2; psize = current[1]; break; case GL2PS_LINE_CAP_TOKEN : current += 2; used -= 2; lcap = (GLint)current[1]; break; case GL2PS_LINE_JOIN_TOKEN : current += 2; used -= 2; ljoin = (GLint)current[1]; break; case GL2PS_LINE_WIDTH_TOKEN : current += 2; used -= 2; lwidth = current[1]; break; case GL2PS_IMAGEMAP_TOKEN : prim = (GL2PSprimitive *)gl2psMalloc(sizeof(GL2PSprimitive)); prim->type = GL2PS_IMAGEMAP; prim->boundary = 0; prim->numverts = 4; prim->verts = (GL2PSvertex *)gl2psMalloc(4 * sizeof(GL2PSvertex)); prim->culled = 0; prim->offset = 0; prim->ofactor = 0.0; prim->ounits = 0.0; prim->pattern = 0; prim->factor = 0; prim->width = 1; node = (GL2PSimagemap*)gl2psMalloc(sizeof(GL2PSimagemap)); node->image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage)); node->image->type = 0; node->image->format = 0; node->image->zoom_x = 1.0F; node->image->zoom_y = 1.0F; node->next = NULL; if(gl2ps->imagemap_head == NULL) gl2ps->imagemap_head = node; else gl2ps->imagemap_tail->next = node; gl2ps->imagemap_tail = node; prim->data.image = node->image; current += 2; used -= 2; i = gl2psGetVertex(&prim->verts[0], ¤t[1]); current += i; used -= i; node->image->width = (GLint)current[2]; current += 2; used -= 2; node->image->height = (GLint)current[2]; prim->verts[0].xyz[0] = prim->verts[0].xyz[0] - (int)(node->image->width / 2) + 0.5F; prim->verts[0].xyz[1] = prim->verts[0].xyz[1] - (int)(node->image->height / 2) + 0.5F; for(i = 1; i < 4; i++){ for(v = 0; v < 3; v++){ prim->verts[i].xyz[v] = prim->verts[0].xyz[v]; prim->verts[i].rgba[v] = prim->verts[0].rgba[v]; } prim->verts[i].rgba[v] = prim->verts[0].rgba[v]; } prim->verts[1].xyz[0] = prim->verts[1].xyz[0] + node->image->width; prim->verts[2].xyz[0] = prim->verts[1].xyz[0]; prim->verts[2].xyz[1] = prim->verts[2].xyz[1] + node->image->height; prim->verts[3].xyz[1] = prim->verts[2].xyz[1]; sizeoffloat = sizeof(GLfloat); v = 2 * sizeoffloat; vtot = node->image->height + node->image->height * ((node->image->width - 1) / 8); node->image->pixels = (GLfloat*)gl2psMalloc(v + vtot); node->image->pixels[0] = prim->verts[0].xyz[0]; node->image->pixels[1] = prim->verts[0].xyz[1]; for(i = 0; i < vtot; i += sizeoffloat){ current += 2; used -= 2; if((vtot - i) >= 4) memcpy(&(((char*)(node->image->pixels))[i + v]), &(current[2]), sizeoffloat); else memcpy(&(((char*)(node->image->pixels))[i + v]), &(current[2]), vtot - i); } current++; used--; gl2psListAdd(gl2ps->primitives, &prim); break; case GL2PS_DRAW_PIXELS_TOKEN : case GL2PS_TEXT_TOKEN : if(auxindex < gl2psListNbr(gl2ps->auxprimitives)) gl2psListAdd(gl2ps->primitives, gl2psListPointer(gl2ps->auxprimitives, auxindex++)); else gl2psMsg(GL2PS_ERROR, "Wrong number of auxiliary tokens in buffer"); break; } current += 2; used -= 2; break; default : gl2psMsg(GL2PS_WARNING, "Unknown token in buffer"); current ++; used --; break; } } gl2psListReset(gl2ps->auxprimitives); } /********************************************************************* * * PostScript routines * *********************************************************************/ static void gl2psWriteByte(unsigned char byte) { unsigned char h = byte / 16; unsigned char l = byte % 16; gl2psPrintf("%x%x", h, l); } static void gl2psPrintPostScriptPixmap(GLfloat x, GLfloat y, GL2PSimage *im) { GLuint nbhex, nbyte, nrgb, nbits; GLuint row, col, ibyte, icase; GLfloat dr = 0., dg = 0., db = 0., fgrey; unsigned char red = 0, green = 0, blue = 0, b, grey; GLuint width = (GLuint)im->width; GLuint height = (GLuint)im->height; /* FIXME: should we define an option for these? Or just keep the 8-bit per component case? */ int greyscale = 0; /* set to 1 to output greyscale image */ int nbit = 8; /* number of bits per color compoment (2, 4 or 8) */ if((width <= 0) || (height <= 0)) return; gl2psPrintf("gsave\n"); gl2psPrintf("%.2f %.2f translate\n", x, y); gl2psPrintf("%.2f %.2f scale\n", width * im->zoom_x, height * im->zoom_y); if(greyscale){ /* greyscale */ gl2psPrintf("/picstr %d string def\n", width); gl2psPrintf("%d %d %d\n", width, height, 8); gl2psPrintf("[ %d 0 0 -%d 0 %d ]\n", width, height, height); gl2psPrintf("{ currentfile picstr readhexstring pop }\n"); gl2psPrintf("image\n"); for(row = 0; row < height; row++){ for(col = 0; col < width; col++){ gl2psGetRGB(im, col, row, &dr, &dg, &db); fgrey = (0.30F * dr + 0.59F * dg + 0.11F * db); grey = (unsigned char)(255. * fgrey); gl2psWriteByte(grey); } gl2psPrintf("\n"); } nbhex = width * height * 2; gl2psPrintf("%%%% nbhex digit :%d\n", nbhex); } else if(nbit == 2){ /* color, 2 bits for r and g and b; rgbs following each other */ nrgb = width * 3; nbits = nrgb * nbit; nbyte = nbits / 8; if((nbyte * 8) != nbits) nbyte++; gl2psPrintf("/rgbstr %d string def\n", nbyte); gl2psPrintf("%d %d %d\n", width, height, nbit); gl2psPrintf("[ %d 0 0 -%d 0 %d ]\n", width, height, height); gl2psPrintf("{ currentfile rgbstr readhexstring pop }\n"); gl2psPrintf("false 3\n"); gl2psPrintf("colorimage\n"); for(row = 0; row < height; row++){ icase = 1; col = 0; b = 0; for(ibyte = 0; ibyte < nbyte; ibyte++){ if(icase == 1) { if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(3. * dr); green = (unsigned char)(3. * dg); blue = (unsigned char)(3. * db); b = red; b = (unsigned char)(b<<2) + green; b = (unsigned char)(b<<2) + blue; if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(3. * dr); green = (unsigned char)(3. * dg); blue = (unsigned char)(3. * db); b = (unsigned char)(b<<2) + red; gl2psWriteByte(b); b = 0; icase++; } else if(icase == 2) { b = green; b = (unsigned char)(b<<2) + blue; if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(3. * dr); green = (unsigned char)(3. * dg); blue = (unsigned char)(3. * db); b = (unsigned char)(b<<2) + red; b = (unsigned char)(b<<2) + green; gl2psWriteByte(b); b = 0; icase++; } else if(icase == 3) { b = blue; if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(3. * dr); green = (unsigned char)(3. * dg); blue = (unsigned char)(3. * db); b = (unsigned char)(b<<2) + red; b = (unsigned char)(b<<2) + green; b = (unsigned char)(b<<2) + blue; gl2psWriteByte(b); b = 0; icase = 1; } } gl2psPrintf("\n"); } } else if(nbit == 4){ /* color, 4 bits for r and g and b; rgbs following each other */ nrgb = width * 3; nbits = nrgb * nbit; nbyte = nbits / 8; if((nbyte * 8) != nbits) nbyte++; gl2psPrintf("/rgbstr %d string def\n", nbyte); gl2psPrintf("%d %d %d\n", width, height, nbit); gl2psPrintf("[ %d 0 0 -%d 0 %d ]\n", width, height, height); gl2psPrintf("{ currentfile rgbstr readhexstring pop }\n"); gl2psPrintf("false 3\n"); gl2psPrintf("colorimage\n"); for(row = 0; row < height; row++){ col = 0; icase = 1; for(ibyte = 0; ibyte < nbyte; ibyte++){ if(icase == 1) { if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(15. * dr); green = (unsigned char)(15. * dg); gl2psPrintf("%x%x", red, green); icase++; } else if(icase == 2) { blue = (unsigned char)(15. * db); if(col < width) { gl2psGetRGB(im, col, row, &dr, &dg, &db); } else { dr = dg = db = 0; } col++; red = (unsigned char)(15. * dr); gl2psPrintf("%x%x", blue, red); icase++; } else if(icase == 3) { green = (unsigned char)(15. * dg); blue = (unsigned char)(15. * db); gl2psPrintf("%x%x", green, blue); icase = 1; } } gl2psPrintf("\n"); } } else{ /* 8 bit for r and g and b */ nbyte = width * 3; gl2psPrintf("/rgbstr %d string def\n", nbyte); gl2psPrintf("%d %d %d\n", width, height, 8); gl2psPrintf("[ %d 0 0 -%d 0 %d ]\n", width, height, height); gl2psPrintf("{ currentfile rgbstr readhexstring pop }\n"); gl2psPrintf("false 3\n"); gl2psPrintf("colorimage\n"); for(row = 0; row < height; row++){ for(col = 0; col < width; col++){ gl2psGetRGB(im, col, row, &dr, &dg, &db); red = (unsigned char)(255. * dr); gl2psWriteByte(red); green = (unsigned char)(255. * dg); gl2psWriteByte(green); blue = (unsigned char)(255. * db); gl2psWriteByte(blue); } gl2psPrintf("\n"); } } gl2psPrintf("grestore\n"); } static void gl2psPrintPostScriptImagemap(GLfloat x, GLfloat y, GLsizei width, GLsizei height, const unsigned char *imagemap){ int i, size; if((width <= 0) || (height <= 0)) return; size = height + height * (width - 1) / 8; gl2psPrintf("gsave\n"); gl2psPrintf("%.2f %.2f translate\n", x, y); gl2psPrintf("%d %d scale\n%d %d\ntrue\n", width, height,width, height); gl2psPrintf("[ %d 0 0 -%d 0 %d ] {<", width, height); for(i = 0; i < size; i++){ gl2psWriteByte(*imagemap); imagemap++; } gl2psPrintf(">} imagemask\ngrestore\n"); } static void gl2psPrintPostScriptHeader(void) { time_t now; /* Since compression is not part of the PostScript standard, compressed PostScript files are just gzipped PostScript files ("ps.gz" or "eps.gz") */ gl2psPrintGzipHeader(); time(&now); if(gl2ps->format == GL2PS_PS){ gl2psPrintf("%%!PS-Adobe-3.0\n"); } else{ gl2psPrintf("%%!PS-Adobe-3.0 EPSF-3.0\n"); } gl2psPrintf("%%%%Title: %s\n" "%%%%Creator: GL2PS %d.%d.%d%s, %s\n" "%%%%For: %s\n" "%%%%CreationDate: %s" "%%%%LanguageLevel: 3\n" "%%%%DocumentData: Clean7Bit\n" "%%%%Pages: 1\n", gl2ps->title, GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION, GL2PS_COPYRIGHT, gl2ps->producer, ctime(&now)); if(gl2ps->format == GL2PS_PS){ gl2psPrintf("%%%%Orientation: %s\n" "%%%%DocumentMedia: Default %d %d 0 () ()\n", (gl2ps->options & GL2PS_LANDSCAPE) ? "Landscape" : "Portrait", (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[3] : (int)gl2ps->viewport[2], (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[2] : (int)gl2ps->viewport[3]); } gl2psPrintf("%%%%BoundingBox: %d %d %d %d\n" "%%%%EndComments\n", (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[1] : (int)gl2ps->viewport[0], (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[0] : (int)gl2ps->viewport[1], (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[3] : (int)gl2ps->viewport[2], (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[2] : (int)gl2ps->viewport[3]); /* RGB color: r g b C (replace C by G in output to change from rgb to gray) Grayscale: r g b G Font choose: size fontname FC Text string: (string) x y size fontname S?? Rotated text string: (string) angle x y size fontname S??R Point primitive: x y size P Line width: width W Line start: x y LS Line joining last point: x y L Line end: x y LE Flat-shaded triangle: x3 y3 x2 y2 x1 y1 T Smooth-shaded triangle: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 ST */ gl2psPrintf("%%%%BeginProlog\n" "/gl2psdict 64 dict def gl2psdict begin\n" "/tryPS3shading %s def %% set to false to force subdivision\n" "/rThreshold %g def %% red component subdivision threshold\n" "/gThreshold %g def %% green component subdivision threshold\n" "/bThreshold %g def %% blue component subdivision threshold\n", (gl2ps->options & GL2PS_NO_PS3_SHADING) ? "false" : "true", gl2ps->threshold[0], gl2ps->threshold[1], gl2ps->threshold[2]); gl2psPrintf("/BD { bind def } bind def\n" "/C { setrgbcolor } BD\n" "/G { 0.082 mul exch 0.6094 mul add exch 0.3086 mul add neg 1.0 add setgray } BD\n" "/W { setlinewidth } BD\n" "/LC { setlinecap } BD\n" "/LJ { setlinejoin } BD\n"); gl2psPrintf("/FC { findfont exch /SH exch def SH scalefont setfont } BD\n" "/SW { dup stringwidth pop } BD\n" "/S { FC moveto show } BD\n" "/SBC{ FC moveto SW -2 div 0 rmoveto show } BD\n" "/SBR{ FC moveto SW neg 0 rmoveto show } BD\n" "/SCL{ FC moveto 0 SH -2 div rmoveto show } BD\n" "/SCC{ FC moveto SW -2 div SH -2 div rmoveto show } BD\n" "/SCR{ FC moveto SW neg SH -2 div rmoveto show } BD\n" "/STL{ FC moveto 0 SH neg rmoveto show } BD\n" "/STC{ FC moveto SW -2 div SH neg rmoveto show } BD\n" "/STR{ FC moveto SW neg SH neg rmoveto show } BD\n"); /* rotated text routines: same nameanem with R appended */ gl2psPrintf("/FCT { FC translate 0 0 } BD\n" "/SR { gsave FCT moveto rotate show grestore } BD\n" "/SBCR{ gsave FCT moveto rotate SW -2 div 0 rmoveto show grestore } BD\n" "/SBRR{ gsave FCT moveto rotate SW neg 0 rmoveto show grestore } BD\n" "/SCLR{ gsave FCT moveto rotate 0 SH -2 div rmoveto show grestore} BD\n"); gl2psPrintf("/SCCR{ gsave FCT moveto rotate SW -2 div SH -2 div rmoveto show grestore} BD\n" "/SCRR{ gsave FCT moveto rotate SW neg SH -2 div rmoveto show grestore} BD\n" "/STLR{ gsave FCT moveto rotate 0 SH neg rmoveto show grestore } BD\n" "/STCR{ gsave FCT moveto rotate SW -2 div SH neg rmoveto show grestore } BD\n" "/STRR{ gsave FCT moveto rotate SW neg SH neg rmoveto show grestore } BD\n"); gl2psPrintf("/P { newpath 0.0 360.0 arc closepath fill } BD\n" "/LS { newpath moveto } BD\n" "/L { lineto } BD\n" "/LE { lineto stroke } BD\n" "/T { newpath moveto lineto lineto closepath fill } BD\n"); /* Smooth-shaded triangle with PostScript level 3 shfill operator: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STshfill */ gl2psPrintf("/STshfill {\n" " /b1 exch def /g1 exch def /r1 exch def /y1 exch def /x1 exch def\n" " /b2 exch def /g2 exch def /r2 exch def /y2 exch def /x2 exch def\n" " /b3 exch def /g3 exch def /r3 exch def /y3 exch def /x3 exch def\n" " gsave << /ShadingType 4 /ColorSpace [/DeviceRGB]\n" " /DataSource [ 0 x1 y1 r1 g1 b1 0 x2 y2 r2 g2 b2 0 x3 y3 r3 g3 b3 ] >>\n" " shfill grestore } BD\n"); /* Flat-shaded triangle with middle color: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 Tm */ gl2psPrintf(/* stack : x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 */ "/Tm { 3 -1 roll 8 -1 roll 13 -1 roll add add 3 div\n" /* r = (r1+r2+r3)/3 */ /* stack : x3 y3 g3 b3 x2 y2 g2 b2 x1 y1 g1 b1 r */ " 3 -1 roll 7 -1 roll 11 -1 roll add add 3 div\n" /* g = (g1+g2+g3)/3 */ /* stack : x3 y3 b3 x2 y2 b2 x1 y1 b1 r g b */ " 3 -1 roll 6 -1 roll 9 -1 roll add add 3 div" /* b = (b1+b2+b3)/3 */ /* stack : x3 y3 x2 y2 x1 y1 r g b */ " C T } BD\n"); /* Split triangle in four sub-triangles (at sides middle points) and call the STnoshfill procedure on each, interpolating the colors in RGB space: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STsplit (in procedure comments key: (Vi) = xi yi ri gi bi) */ gl2psPrintf("/STsplit {\n" " 4 index 15 index add 0.5 mul\n" /* x13 = (x1+x3)/2 */ " 4 index 15 index add 0.5 mul\n" /* y13 = (y1+y3)/2 */ " 4 index 15 index add 0.5 mul\n" /* r13 = (r1+r3)/2 */ " 4 index 15 index add 0.5 mul\n" /* g13 = (g1+g3)/2 */ " 4 index 15 index add 0.5 mul\n" /* b13 = (b1+b3)/2 */ " 5 copy 5 copy 25 15 roll\n"); /* at his point, stack = (V3) (V13) (V13) (V13) (V2) (V1) */ gl2psPrintf(" 9 index 30 index add 0.5 mul\n" /* x23 = (x2+x3)/2 */ " 9 index 30 index add 0.5 mul\n" /* y23 = (y2+y3)/2 */ " 9 index 30 index add 0.5 mul\n" /* r23 = (r2+r3)/2 */ " 9 index 30 index add 0.5 mul\n" /* g23 = (g2+g3)/2 */ " 9 index 30 index add 0.5 mul\n" /* b23 = (b2+b3)/2 */ " 5 copy 5 copy 35 5 roll 25 5 roll 15 5 roll\n"); /* stack = (V3) (V13) (V23) (V13) (V23) (V13) (V23) (V2) (V1) */ gl2psPrintf(" 4 index 10 index add 0.5 mul\n" /* x12 = (x1+x2)/2 */ " 4 index 10 index add 0.5 mul\n" /* y12 = (y1+y2)/2 */ " 4 index 10 index add 0.5 mul\n" /* r12 = (r1+r2)/2 */ " 4 index 10 index add 0.5 mul\n" /* g12 = (g1+g2)/2 */ " 4 index 10 index add 0.5 mul\n" /* b12 = (b1+b2)/2 */ " 5 copy 5 copy 40 5 roll 25 5 roll 15 5 roll 25 5 roll\n"); /* stack = (V3) (V13) (V23) (V13) (V12) (V23) (V13) (V1) (V12) (V23) (V12) (V2) */ gl2psPrintf(" STnoshfill STnoshfill STnoshfill STnoshfill } BD\n"); /* Gouraud shaded triangle using recursive subdivision until the difference between corner colors does not exceed the thresholds: x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 STnoshfill */ gl2psPrintf("/STnoshfill {\n" " 2 index 8 index sub abs rThreshold gt\n" /* |r1-r2|>rth */ " { STsplit }\n" " { 1 index 7 index sub abs gThreshold gt\n" /* |g1-g2|>gth */ " { STsplit }\n" " { dup 6 index sub abs bThreshold gt\n" /* |b1-b2|>bth */ " { STsplit }\n" " { 2 index 13 index sub abs rThreshold gt\n" /* |r1-r3|>rht */ " { STsplit }\n" " { 1 index 12 index sub abs gThreshold gt\n" /* |g1-g3|>gth */ " { STsplit }\n" " { dup 11 index sub abs bThreshold gt\n" /* |b1-b3|>bth */ " { STsplit }\n" " { 7 index 13 index sub abs rThreshold gt\n"); /* |r2-r3|>rht */ gl2psPrintf(" { STsplit }\n" " { 6 index 12 index sub abs gThreshold gt\n" /* |g2-g3|>gth */ " { STsplit }\n" " { 5 index 11 index sub abs bThreshold gt\n" /* |b2-b3|>bth */ " { STsplit }\n" " { Tm }\n" /* all colors sufficiently similar */ " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse }\n" " ifelse } BD\n"); gl2psPrintf("tryPS3shading\n" "{ /shfill where\n" " { /ST { STshfill } BD }\n" " { /ST { STnoshfill } BD }\n" " ifelse }\n" "{ /ST { STnoshfill } BD }\n" "ifelse\n"); gl2psPrintf("end\n" "%%%%EndProlog\n" "%%%%BeginSetup\n" "/DeviceRGB setcolorspace\n" "gl2psdict begin\n" "%%%%EndSetup\n" "%%%%Page: 1 1\n" "%%%%BeginPageSetup\n"); if(gl2ps->options & GL2PS_LANDSCAPE){ gl2psPrintf("%d 0 translate 90 rotate\n", (int)gl2ps->viewport[3]); } gl2psPrintf("%%%%EndPageSetup\n" "mark\n" "gsave\n" "1.0 1.0 scale\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ gl2psPrintf("%g %g %g C\n" "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n" "closepath fill\n", gl2ps->bgcolor[0], gl2ps->bgcolor[1], gl2ps->bgcolor[2], (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3], (int)gl2ps->viewport[0], (int)gl2ps->viewport[3]); } } static void gl2psPrintPostScriptColor(GL2PSrgba rgba) { if(!gl2psSameColor(gl2ps->lastrgba, rgba)){ gl2psSetLastColor(rgba); gl2psPrintf("%g %g %g C\n", rgba[0], rgba[1], rgba[2]); } } static void gl2psResetPostScriptColor(void) { gl2ps->lastrgba[0] = gl2ps->lastrgba[1] = gl2ps->lastrgba[2] = -1.; } static void gl2psEndPostScriptLine(void) { int i; if(gl2ps->lastvertex.rgba[0] >= 0.){ gl2psPrintf("%g %g LE\n", gl2ps->lastvertex.xyz[0], gl2ps->lastvertex.xyz[1]); for(i = 0; i < 3; i++) gl2ps->lastvertex.xyz[i] = -1.; for(i = 0; i < 4; i++) gl2ps->lastvertex.rgba[i] = -1.; } } static void gl2psParseStipplePattern(GLushort pattern, GLint factor, int *nb, int array[10]) { int i, n; int on[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int off[8] = {0, 0, 0, 0, 0, 0, 0, 0}; char tmp[16]; /* extract the 16 bits from the OpenGL stipple pattern */ for(n = 15; n >= 0; n--){ tmp[n] = (char)(pattern & 0x01); pattern >>= 1; } /* compute the on/off pixel sequence */ n = 0; for(i = 0; i < 8; i++){ while(n < 16 && !tmp[n]){ off[i]++; n++; } while(n < 16 && tmp[n]){ on[i]++; n++; } if(n >= 15){ i++; break; } } /* store the on/off array from right to left, starting with off pixels. The PostScript specification allows for at most 11 elements in the on/off array, so we limit ourselves to 5 on/off couples (our longest possible array is thus [on4 off4 on3 off3 on2 off2 on1 off1 on0 off0]) */ *nb = 0; for(n = i - 1; n >= 0; n--){ array[(*nb)++] = factor * on[n]; array[(*nb)++] = factor * off[n]; if(*nb == 10) break; } } static int gl2psPrintPostScriptDash(GLushort pattern, GLint factor, const char *str) { int len = 0, i, n, array[10]; if(pattern == gl2ps->lastpattern && factor == gl2ps->lastfactor) return 0; gl2ps->lastpattern = pattern; gl2ps->lastfactor = factor; if(!pattern || !factor){ /* solid line */ len += gl2psPrintf("[] 0 %s\n", str); } else{ gl2psParseStipplePattern(pattern, factor, &n, array); len += gl2psPrintf("["); for(i = 0; i < n; i++){ if(i) len += gl2psPrintf(" "); len += gl2psPrintf("%d", array[i]); } len += gl2psPrintf("] 0 %s\n", str); } return len; } static void gl2psPrintPostScriptPrimitive(void *data) { int newline; GL2PSprimitive *prim; prim = *(GL2PSprimitive**)data; if((gl2ps->options & GL2PS_OCCLUSION_CULL) && prim->culled) return; /* Every effort is made to draw lines as connected segments (i.e., using a single PostScript path): this is the only way to get nice line joins and to not restart the stippling for every line segment. So if the primitive to print is not a line we must first finish the current line (if any): */ if(prim->type != GL2PS_LINE) gl2psEndPostScriptLine(); switch(prim->type){ case GL2PS_POINT : gl2psPrintPostScriptColor(prim->verts[0].rgba); gl2psPrintf("%g %g %g P\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1], 0.5 * prim->width); break; case GL2PS_LINE : if(!gl2psSamePosition(gl2ps->lastvertex.xyz, prim->verts[0].xyz) || !gl2psSameColor(gl2ps->lastrgba, prim->verts[0].rgba) || gl2ps->lastlinewidth != prim->width || gl2ps->lastlinecap != prim->linecap || gl2ps->lastlinejoin != prim->linejoin || gl2ps->lastpattern != prim->pattern || gl2ps->lastfactor != prim->factor){ /* End the current line if the new segment does not start where the last one ended, or if the color, the width or the stippling have changed (multi-stroking lines with changing colors is necessary until we use /shfill for lines; unfortunately this means that at the moment we can screw up line stippling for smooth-shaded lines) */ gl2psEndPostScriptLine(); newline = 1; } else{ newline = 0; } if(gl2ps->lastlinewidth != prim->width){ gl2ps->lastlinewidth = prim->width; gl2psPrintf("%g W\n", gl2ps->lastlinewidth); } if(gl2ps->lastlinecap != prim->linecap){ gl2ps->lastlinecap = prim->linecap; gl2psPrintf("%d LC\n", gl2ps->lastlinecap); } if(gl2ps->lastlinejoin != prim->linejoin){ gl2ps->lastlinejoin = prim->linejoin; gl2psPrintf("%d LJ\n", gl2ps->lastlinejoin); } gl2psPrintPostScriptDash(prim->pattern, prim->factor, "setdash"); gl2psPrintPostScriptColor(prim->verts[0].rgba); gl2psPrintf("%g %g %s\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1], newline ? "LS" : "L"); gl2ps->lastvertex = prim->verts[1]; break; case GL2PS_TRIANGLE : if(!gl2psVertsSameColor(prim)){ gl2psResetPostScriptColor(); gl2psPrintf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g ST\n", prim->verts[2].xyz[0], prim->verts[2].xyz[1], prim->verts[2].rgba[0], prim->verts[2].rgba[1], prim->verts[2].rgba[2], prim->verts[1].xyz[0], prim->verts[1].xyz[1], prim->verts[1].rgba[0], prim->verts[1].rgba[1], prim->verts[1].rgba[2], prim->verts[0].xyz[0], prim->verts[0].xyz[1], prim->verts[0].rgba[0], prim->verts[0].rgba[1], prim->verts[0].rgba[2]); } else{ gl2psPrintPostScriptColor(prim->verts[0].rgba); gl2psPrintf("%g %g %g %g %g %g T\n", prim->verts[2].xyz[0], prim->verts[2].xyz[1], prim->verts[1].xyz[0], prim->verts[1].xyz[1], prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } break; case GL2PS_QUADRANGLE : gl2psMsg(GL2PS_WARNING, "There should not be any quad left to print"); break; case GL2PS_PIXMAP : gl2psPrintPostScriptPixmap(prim->verts[0].xyz[0], prim->verts[0].xyz[1], prim->data.image); break; case GL2PS_IMAGEMAP : if(prim->data.image->type != GL2PS_IMAGEMAP_WRITTEN){ gl2psPrintPostScriptColor(prim->verts[0].rgba); gl2psPrintPostScriptImagemap(prim->data.image->pixels[0], prim->data.image->pixels[1], prim->data.image->width, prim->data.image->height, (const unsigned char*)(&(prim->data.image->pixels[2]))); prim->data.image->type = GL2PS_IMAGEMAP_WRITTEN; } break; case GL2PS_TEXT : gl2psPrintPostScriptColor(prim->verts[0].rgba); gl2psPrintf("(%s) ", prim->data.text->str); if(prim->data.text->angle != 0.0) gl2psPrintf("%g ", prim->data.text->angle); gl2psPrintf("%g %g %d /%s ", prim->verts[0].xyz[0], prim->verts[0].xyz[1], prim->data.text->fontsize, prim->data.text->fontname); switch(prim->data.text->alignment){ case GL2PS_TEXT_C: gl2psPrintf(prim->data.text->angle != 0.0 ? "SCCR\n" : "SCC\n"); break; case GL2PS_TEXT_CL: gl2psPrintf(prim->data.text->angle != 0.0 ? "SCLR\n" : "SCL\n"); break; case GL2PS_TEXT_CR: gl2psPrintf(prim->data.text->angle != 0.0 ? "SCRR\n" : "SCR\n"); break; case GL2PS_TEXT_B: gl2psPrintf(prim->data.text->angle != 0.0 ? "SBCR\n" : "SBC\n"); break; case GL2PS_TEXT_BR: gl2psPrintf(prim->data.text->angle != 0.0 ? "SBRR\n" : "SBR\n"); break; case GL2PS_TEXT_T: gl2psPrintf(prim->data.text->angle != 0.0 ? "STCR\n" : "STC\n"); break; case GL2PS_TEXT_TL: gl2psPrintf(prim->data.text->angle != 0.0 ? "STLR\n" : "STL\n"); break; case GL2PS_TEXT_TR: gl2psPrintf(prim->data.text->angle != 0.0 ? "STRR\n" : "STR\n"); break; case GL2PS_TEXT_BL: default: gl2psPrintf(prim->data.text->angle != 0.0 ? "SR\n" : "S\n"); break; } break; case GL2PS_SPECIAL : /* alignment contains the format for which the special output text is intended */ if(prim->data.text->alignment == GL2PS_PS || prim->data.text->alignment == GL2PS_EPS) gl2psPrintf("%s\n", prim->data.text->str); break; default : break; } } static void gl2psPrintPostScriptFooter(void) { gl2psPrintf("grestore\n" "showpage\n" "cleartomark\n" "%%%%PageTrailer\n" "%%%%Trailer\n" "end\n" "%%%%EOF\n"); gl2psPrintGzipFooter(); } static void gl2psPrintPostScriptBeginViewport(GLint viewport[4]) { GLint idx; GLfloat rgba[4]; int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3]; glRenderMode(GL_FEEDBACK); if(gl2ps->header){ gl2psPrintPostScriptHeader(); gl2ps->header = GL_FALSE; } gl2psResetPostScriptColor(); gl2psResetLineProperties(); gl2psPrintf("gsave\n" "1.0 1.0 scale\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){ glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba); } else{ glGetIntegerv(GL_INDEX_CLEAR_VALUE, &idx); rgba[0] = gl2ps->colormap[idx][0]; rgba[1] = gl2ps->colormap[idx][1]; rgba[2] = gl2ps->colormap[idx][2]; rgba[3] = 1.0F; } gl2psPrintf("%g %g %g C\n" "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n" "closepath fill\n", rgba[0], rgba[1], rgba[2], x, y, x+w, y, x+w, y+h, x, y+h); } gl2psPrintf("newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n" "closepath clip\n", x, y, x+w, y, x+w, y+h, x, y+h); } static GLint gl2psPrintPostScriptEndViewport(void) { GLint res; res = gl2psPrintPrimitives(); gl2psPrintf("grestore\n"); return res; } static void gl2psPrintPostScriptFinalPrimitive(void) { /* End any remaining line, if any */ gl2psEndPostScriptLine(); } /* definition of the PostScript and Encapsulated PostScript backends */ static GL2PSbackend gl2psPS = { gl2psPrintPostScriptHeader, gl2psPrintPostScriptFooter, gl2psPrintPostScriptBeginViewport, gl2psPrintPostScriptEndViewport, gl2psPrintPostScriptPrimitive, gl2psPrintPostScriptFinalPrimitive, "ps", "Postscript" }; static GL2PSbackend gl2psEPS = { gl2psPrintPostScriptHeader, gl2psPrintPostScriptFooter, gl2psPrintPostScriptBeginViewport, gl2psPrintPostScriptEndViewport, gl2psPrintPostScriptPrimitive, gl2psPrintPostScriptFinalPrimitive, "eps", "Encapsulated Postscript" }; /********************************************************************* * * LaTeX routines * *********************************************************************/ static void gl2psPrintTeXHeader(void) { char name[256]; time_t now; int i; if(gl2ps->filename && strlen(gl2ps->filename) < 256){ for(i = (int)strlen(gl2ps->filename) - 1; i >= 0; i--){ if(gl2ps->filename[i] == '.'){ strncpy(name, gl2ps->filename, i); name[i] = '\0'; break; } } if(i <= 0) strcpy(name, gl2ps->filename); } else{ strcpy(name, "untitled"); } time(&now); fprintf(gl2ps->stream, "%% Title: %s\n" "%% Creator: GL2PS %d.%d.%d%s, %s\n" "%% For: %s\n" "%% CreationDate: %s", gl2ps->title, GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION, GL2PS_COPYRIGHT, gl2ps->producer, ctime(&now)); fprintf(gl2ps->stream, "\\setlength{\\unitlength}{1pt}\n" "\\begin{picture}(0,0)\n" "\\includegraphics{%s}\n" "\\end{picture}%%\n" "%s\\begin{picture}(%d,%d)(0,0)\n", name, (gl2ps->options & GL2PS_LANDSCAPE) ? "\\rotatebox{90}{" : "", (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]); } static void gl2psPrintTeXPrimitive(void *data) { GL2PSprimitive *prim; prim = *(GL2PSprimitive**)data; switch(prim->type){ case GL2PS_TEXT : fprintf(gl2ps->stream, "\\fontsize{%d}{0}\n\\selectfont", prim->data.text->fontsize); fprintf(gl2ps->stream, "\\put(%g,%g)", prim->verts[0].xyz[0], prim->verts[0].xyz[1]); if(prim->data.text->angle != 0.0) fprintf(gl2ps->stream, "{\\rotatebox{%g}", prim->data.text->angle); fprintf(gl2ps->stream, "{\\makebox(0,0)"); switch(prim->data.text->alignment){ case GL2PS_TEXT_C: fprintf(gl2ps->stream, "{"); break; case GL2PS_TEXT_CL: fprintf(gl2ps->stream, "[l]{"); break; case GL2PS_TEXT_CR: fprintf(gl2ps->stream, "[r]{"); break; case GL2PS_TEXT_B: fprintf(gl2ps->stream, "[b]{"); break; case GL2PS_TEXT_BR: fprintf(gl2ps->stream, "[br]{"); break; case GL2PS_TEXT_T: fprintf(gl2ps->stream, "[t]{"); break; case GL2PS_TEXT_TL: fprintf(gl2ps->stream, "[tl]{"); break; case GL2PS_TEXT_TR: fprintf(gl2ps->stream, "[tr]{"); break; case GL2PS_TEXT_BL: default: fprintf(gl2ps->stream, "[bl]{"); break; } fprintf(gl2ps->stream, "\\textcolor[rgb]{%g,%g,%g}{{%s}}", prim->verts[0].rgba[0], prim->verts[0].rgba[1], prim->verts[0].rgba[2], prim->data.text->str); if(prim->data.text->angle != 0.0) fprintf(gl2ps->stream, "}"); fprintf(gl2ps->stream, "}}\n"); break; case GL2PS_SPECIAL : /* alignment contains the format for which the special output text is intended */ if (prim->data.text->alignment == GL2PS_TEX) fprintf(gl2ps->stream, "%s\n", prim->data.text->str); break; default : break; } } static void gl2psPrintTeXFooter(void) { fprintf(gl2ps->stream, "\\end{picture}%s\n", (gl2ps->options & GL2PS_LANDSCAPE) ? "}" : ""); } static void gl2psPrintTeXBeginViewport(GLint viewport[4]) { (void) viewport; /* not used */ glRenderMode(GL_FEEDBACK); gl2psResetLineProperties(); if(gl2ps->header){ gl2psPrintTeXHeader(); gl2ps->header = GL_FALSE; } } static GLint gl2psPrintTeXEndViewport(void) { return gl2psPrintPrimitives(); } static void gl2psPrintTeXFinalPrimitive(void) { } /* definition of the LaTeX backend */ static GL2PSbackend gl2psTEX = { gl2psPrintTeXHeader, gl2psPrintTeXFooter, gl2psPrintTeXBeginViewport, gl2psPrintTeXEndViewport, gl2psPrintTeXPrimitive, gl2psPrintTeXFinalPrimitive, "tex", "LaTeX text" }; /********************************************************************* * * PDF routines * *********************************************************************/ static int gl2psPrintPDFCompressorType(void) { #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ return fprintf(gl2ps->stream, "/Filter [/FlateDecode]\n"); } #endif return 0; } static int gl2psPrintPDFStrokeColor(GL2PSrgba rgba) { int i, offs = 0; gl2psSetLastColor(rgba); for(i = 0; i < 3; ++i){ if(GL2PS_ZERO(rgba[i])) offs += gl2psPrintf("%.0f ", 0.); else if(rgba[i] < 1e-4 || rgba[i] > 1e6) /* avoid %e formatting */ offs += gl2psPrintf("%f ", rgba[i]); else offs += gl2psPrintf("%g ", rgba[i]); } offs += gl2psPrintf("RG\n"); return offs; } static int gl2psPrintPDFFillColor(GL2PSrgba rgba) { int i, offs = 0; for(i = 0; i < 3; ++i){ if(GL2PS_ZERO(rgba[i])) offs += gl2psPrintf("%.0f ", 0.); else if(rgba[i] < 1e-4 || rgba[i] > 1e6) /* avoid %e formatting */ offs += gl2psPrintf("%f ", rgba[i]); else offs += gl2psPrintf("%g ", rgba[i]); } offs += gl2psPrintf("rg\n"); return offs; } static int gl2psPrintPDFLineWidth(GLfloat lw) { if(GL2PS_ZERO(lw)) return gl2psPrintf("%.0f w\n", 0.); else if(lw < 1e-4 || lw > 1e6) /* avoid %e formatting */ return gl2psPrintf("%f w\n", lw); else return gl2psPrintf("%g w\n", lw); } static int gl2psPrintPDFLineCap(GLint lc) { if(gl2ps->lastlinecap == lc) return 0; else return gl2psPrintf("%d J\n", lc); } static int gl2psPrintPDFLineJoin(GLint lj) { if(gl2ps->lastlinejoin == lj) return 0; else return gl2psPrintf("%d j\n", lj); } static void gl2psPutPDFText(GL2PSstring *text, int cnt, GLfloat x, GLfloat y) { GLfloat rad, crad, srad; if(text->angle == 0.0F){ gl2ps->streamlength += gl2psPrintf ("BT\n" "/F%d %d Tf\n" "%f %f Td\n" "(%s) Tj\n" "ET\n", cnt, text->fontsize, x, y, text->str); } else{ rad = (GLfloat)(3.141593F * text->angle / 180.0F); srad = (GLfloat)sin(rad); crad = (GLfloat)cos(rad); gl2ps->streamlength += gl2psPrintf ("BT\n" "/F%d %d Tf\n" "%f %f %f %f %f %f Tm\n" "(%s) Tj\n" "ET\n", cnt, text->fontsize, crad, srad, -srad, crad, x, y, text->str); } } static void gl2psPutPDFSpecial(int prim, int sec, GL2PSstring *text) { gl2ps->streamlength += gl2psPrintf("/GS%d%d gs\n", prim, sec); gl2ps->streamlength += gl2psPrintf("%s\n", text->str); } static void gl2psPutPDFImage(GL2PSimage *image, int cnt, GLfloat x, GLfloat y) { gl2ps->streamlength += gl2psPrintf ("q\n" "%d 0 0 %d %f %f cm\n" "/Im%d Do\n" "Q\n", (int)(image->zoom_x * image->width), (int)(image->zoom_y * image->height), x, y, cnt); } static void gl2psPDFstacksInit(void) { gl2ps->objects_stack = 7 /* FIXED_XREF_ENTRIES */ + 1; gl2ps->extgs_stack = 0; gl2ps->font_stack = 0; gl2ps->im_stack = 0; gl2ps->trgroupobjects_stack = 0; gl2ps->shader_stack = 0; gl2ps->mshader_stack = 0; } static void gl2psPDFgroupObjectInit(GL2PSpdfgroup *gro) { if(!gro) return; gro->ptrlist = NULL; gro->fontno = gro->gsno = gro->imno = gro->maskshno = gro->shno = gro->trgroupno = gro->fontobjno = gro->imobjno = gro->shobjno = gro->maskshobjno = gro->gsobjno = gro->trgroupobjno = -1; } /* Build up group objects and assign name and object numbers */ static void gl2psPDFgroupListInit(void) { int i; GL2PSprimitive *p = NULL; GL2PSpdfgroup gro; int lasttype = GL2PS_NO_TYPE; GL2PSrgba lastrgba = {-1.0F, -1.0F, -1.0F, -1.0F}; GLushort lastpattern = 0; GLint lastfactor = 0; GLfloat lastwidth = 1; GLint lastlinecap = 0; GLint lastlinejoin = 0; GL2PStriangle lastt, tmpt; int lastTriangleWasNotSimpleWithSameColor = 0; if(!gl2ps->pdfprimlist) return; gl2ps->pdfgrouplist = gl2psListCreate(500, 500, sizeof(GL2PSpdfgroup)); gl2psInitTriangle(&lastt); for(i = 0; i < gl2psListNbr(gl2ps->pdfprimlist); ++i){ p = *(GL2PSprimitive**)gl2psListPointer(gl2ps->pdfprimlist, i); switch(p->type){ case GL2PS_PIXMAP: gl2psPDFgroupObjectInit(&gro); gro.ptrlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); gro.imno = gl2ps->im_stack++; gl2psListAdd(gro.ptrlist, &p); gl2psListAdd(gl2ps->pdfgrouplist, &gro); break; case GL2PS_TEXT: gl2psPDFgroupObjectInit(&gro); gro.ptrlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); gro.fontno = gl2ps->font_stack++; gl2psListAdd(gro.ptrlist, &p); gl2psListAdd(gl2ps->pdfgrouplist, &gro); break; case GL2PS_LINE: if(lasttype != p->type || lastwidth != p->width || lastlinecap != p->linecap || lastlinejoin != p->linejoin || lastpattern != p->pattern || lastfactor != p->factor || !gl2psSameColor(p->verts[0].rgba, lastrgba)){ gl2psPDFgroupObjectInit(&gro); gro.ptrlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); gl2psListAdd(gro.ptrlist, &p); gl2psListAdd(gl2ps->pdfgrouplist, &gro); } else{ gl2psListAdd(gro.ptrlist, &p); } lastpattern = p->pattern; lastfactor = p->factor; lastwidth = p->width; lastlinecap = p->linecap; lastlinejoin = p->linejoin; lastrgba[0] = p->verts[0].rgba[0]; lastrgba[1] = p->verts[0].rgba[1]; lastrgba[2] = p->verts[0].rgba[2]; break; case GL2PS_POINT: if(lasttype != p->type || lastwidth != p->width || !gl2psSameColor(p->verts[0].rgba, lastrgba)){ gl2psPDFgroupObjectInit(&gro); gro.ptrlist = gl2psListCreate(1,2,sizeof(GL2PSprimitive*)); gl2psListAdd(gro.ptrlist, &p); gl2psListAdd(gl2ps->pdfgrouplist, &gro); } else{ gl2psListAdd(gro.ptrlist, &p); } lastwidth = p->width; lastrgba[0] = p->verts[0].rgba[0]; lastrgba[1] = p->verts[0].rgba[1]; lastrgba[2] = p->verts[0].rgba[2]; break; case GL2PS_TRIANGLE: gl2psFillTriangleFromPrimitive(&tmpt, p, GL_TRUE); lastTriangleWasNotSimpleWithSameColor = !(tmpt.prop & T_CONST_COLOR && tmpt.prop & T_ALPHA_1) || !gl2psSameColor(tmpt.vertex[0].rgba, lastt.vertex[0].rgba); if(lasttype == p->type && tmpt.prop == lastt.prop && lastTriangleWasNotSimpleWithSameColor){ /* TODO Check here for last alpha */ gl2psListAdd(gro.ptrlist, &p); } else{ gl2psPDFgroupObjectInit(&gro); gro.ptrlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); gl2psListAdd(gro.ptrlist, &p); gl2psListAdd(gl2ps->pdfgrouplist, &gro); } lastt = tmpt; break; case GL2PS_SPECIAL: gl2psPDFgroupObjectInit(&gro); gro.ptrlist = gl2psListCreate(1, 2, sizeof(GL2PSprimitive*)); gl2psListAdd(gro.ptrlist, &p); gl2psListAdd(gl2ps->pdfgrouplist, &gro); break; default: break; } lasttype = p->type; } } static void gl2psSortOutTrianglePDFgroup(GL2PSpdfgroup *gro) { GL2PStriangle t; GL2PSprimitive *prim = NULL; if(!gro) return; if(!gl2psListNbr(gro->ptrlist)) return; prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, 0); if(prim->type != GL2PS_TRIANGLE) return; gl2psFillTriangleFromPrimitive(&t, prim, GL_TRUE); if(t.prop & T_CONST_COLOR && t.prop & T_ALPHA_LESS_1){ gro->gsno = gl2ps->extgs_stack++; gro->gsobjno = gl2ps->objects_stack ++; } else if(t.prop & T_CONST_COLOR && t.prop & T_VAR_ALPHA){ gro->gsno = gl2ps->extgs_stack++; gro->gsobjno = gl2ps->objects_stack++; gro->trgroupno = gl2ps->trgroupobjects_stack++; gro->trgroupobjno = gl2ps->objects_stack++; gro->maskshno = gl2ps->mshader_stack++; gro->maskshobjno = gl2ps->objects_stack++; } else if(t.prop & T_VAR_COLOR && t.prop & T_ALPHA_1){ gro->shno = gl2ps->shader_stack++; gro->shobjno = gl2ps->objects_stack++; } else if(t.prop & T_VAR_COLOR && t.prop & T_ALPHA_LESS_1){ gro->gsno = gl2ps->extgs_stack++; gro->gsobjno = gl2ps->objects_stack++; gro->shno = gl2ps->shader_stack++; gro->shobjno = gl2ps->objects_stack++; } else if(t.prop & T_VAR_COLOR && t.prop & T_VAR_ALPHA){ gro->gsno = gl2ps->extgs_stack++; gro->gsobjno = gl2ps->objects_stack++; gro->shno = gl2ps->shader_stack++; gro->shobjno = gl2ps->objects_stack++; gro->trgroupno = gl2ps->trgroupobjects_stack++; gro->trgroupobjno = gl2ps->objects_stack++; gro->maskshno = gl2ps->mshader_stack++; gro->maskshobjno = gl2ps->objects_stack++; } } /* Main stream data */ static void gl2psPDFgroupListWriteMainStream(void) { int i, j, lastel, count; GL2PSprimitive *prim = NULL, *prev = NULL; GL2PSpdfgroup *gro; GL2PStriangle t; if(!gl2ps->pdfgrouplist) return; count = gl2psListNbr(gl2ps->pdfgrouplist); for(i = 0; i < count; ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); lastel = gl2psListNbr(gro->ptrlist) - 1; if(lastel < 0) continue; prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, 0); switch(prim->type){ case GL2PS_POINT: gl2ps->streamlength += gl2psPrintf("1 J\n"); gl2ps->streamlength += gl2psPrintPDFLineWidth(prim->width); gl2ps->streamlength += gl2psPrintPDFStrokeColor(prim->verts[0].rgba); for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2ps->streamlength += gl2psPrintf("%f %f m %f %f l\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1], prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } gl2ps->streamlength += gl2psPrintf("S\n"); gl2ps->streamlength += gl2psPrintf("0 J\n"); break; case GL2PS_LINE: /* We try to use as few paths as possible to draw lines, in order to get nice stippling even when the individual segments are smaller than the stipple */ gl2ps->streamlength += gl2psPrintPDFLineWidth(prim->width); gl2ps->streamlength += gl2psPrintPDFLineCap(prim->linecap); gl2ps->streamlength += gl2psPrintPDFLineJoin(prim->linejoin); gl2ps->streamlength += gl2psPrintPDFStrokeColor(prim->verts[0].rgba); gl2ps->streamlength += gl2psPrintPostScriptDash(prim->pattern, prim->factor, "d"); /* start new path */ gl2ps->streamlength += gl2psPrintf("%f %f m\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1]); for(j = 1; j <= lastel; ++j){ prev = prim; prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); if(!gl2psSamePosition(prim->verts[0].xyz, prev->verts[1].xyz)){ /* the starting point of the new segment does not match the end point of the previous line, so we end the current path and start a new one */ gl2ps->streamlength += gl2psPrintf("%f %f l\n", prev->verts[1].xyz[0], prev->verts[1].xyz[1]); gl2ps->streamlength += gl2psPrintf("%f %f m\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } else{ /* the two segements are connected, so we just append to the current path */ gl2ps->streamlength += gl2psPrintf("%f %f l\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } } /* end last path */ gl2ps->streamlength += gl2psPrintf("%f %f l\n", prim->verts[1].xyz[0], prim->verts[1].xyz[1]); gl2ps->streamlength += gl2psPrintf("S\n"); break; case GL2PS_TRIANGLE: gl2psFillTriangleFromPrimitive(&t, prim, GL_TRUE); gl2psSortOutTrianglePDFgroup(gro); /* No alpha and const color: Simple PDF draw orders */ if(t.prop & T_CONST_COLOR && t.prop & T_ALPHA_1){ gl2ps->streamlength += gl2psPrintPDFFillColor(t.vertex[0].rgba); for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2psFillTriangleFromPrimitive(&t, prim, GL_FALSE); gl2ps->streamlength += gl2psPrintf("%f %f m\n" "%f %f l\n" "%f %f l\n" "h f\n", t.vertex[0].xyz[0], t.vertex[0].xyz[1], t.vertex[1].xyz[0], t.vertex[1].xyz[1], t.vertex[2].xyz[0], t.vertex[2].xyz[1]); } } /* Const alpha < 1 and const color: Simple PDF draw orders and an extra extended Graphics State for the alpha const */ else if(t.prop & T_CONST_COLOR && t.prop & T_ALPHA_LESS_1){ gl2ps->streamlength += gl2psPrintf("q\n" "/GS%d gs\n", gro->gsno); gl2ps->streamlength += gl2psPrintPDFFillColor(prim->verts[0].rgba); for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2psFillTriangleFromPrimitive(&t, prim, GL_FALSE); gl2ps->streamlength += gl2psPrintf("%f %f m\n" "%f %f l\n" "%f %f l\n" "h f\n", t.vertex[0].xyz[0], t.vertex[0].xyz[1], t.vertex[1].xyz[0], t.vertex[1].xyz[1], t.vertex[2].xyz[0], t.vertex[2].xyz[1]); } gl2ps->streamlength += gl2psPrintf("Q\n"); } /* Variable alpha and const color: Simple PDF draw orders and an extra extended Graphics State + Xobject + Shader object for the alpha mask */ else if(t.prop & T_CONST_COLOR && t.prop & T_VAR_ALPHA){ gl2ps->streamlength += gl2psPrintf("q\n" "/GS%d gs\n" "/TrG%d Do\n", gro->gsno, gro->trgroupno); gl2ps->streamlength += gl2psPrintPDFFillColor(prim->verts[0].rgba); for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2psFillTriangleFromPrimitive(&t, prim, GL_FALSE); gl2ps->streamlength += gl2psPrintf("%f %f m\n" "%f %f l\n" "%f %f l\n" "h f\n", t.vertex[0].xyz[0], t.vertex[0].xyz[1], t.vertex[1].xyz[0], t.vertex[1].xyz[1], t.vertex[2].xyz[0], t.vertex[2].xyz[1]); } gl2ps->streamlength += gl2psPrintf("Q\n"); } /* Variable color and no alpha: Shader Object for the colored triangle(s) */ else if(t.prop & T_VAR_COLOR && t.prop & T_ALPHA_1){ gl2ps->streamlength += gl2psPrintf("/Sh%d sh\n", gro->shno); } /* Variable color and const alpha < 1: Shader Object for the colored triangle(s) and an extra extended Graphics State for the alpha const */ else if(t.prop & T_VAR_COLOR && t.prop & T_ALPHA_LESS_1){ gl2ps->streamlength += gl2psPrintf("q\n" "/GS%d gs\n" "/Sh%d sh\n" "Q\n", gro->gsno, gro->shno); } /* Variable alpha and color: Shader Object for the colored triangle(s) and an extra extended Graphics State + Xobject + Shader object for the alpha mask */ else if(t.prop & T_VAR_COLOR && t.prop & T_VAR_ALPHA){ gl2ps->streamlength += gl2psPrintf("q\n" "/GS%d gs\n" "/TrG%d Do\n" "/Sh%d sh\n" "Q\n", gro->gsno, gro->trgroupno, gro->shno); } break; case GL2PS_PIXMAP: for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2psPutPDFImage(prim->data.image, gro->imno, prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } break; case GL2PS_TEXT: for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2ps->streamlength += gl2psPrintPDFFillColor(prim->verts[0].rgba); gl2psPutPDFText(prim->data.text, gro->fontno, prim->verts[0].xyz[0], prim->verts[0].xyz[1]); } break; case GL2PS_SPECIAL: lastel = gl2psListNbr(gro->ptrlist) - 1; if(lastel < 0) continue; for(j = 0; j <= lastel; ++j){ prim = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2psPutPDFSpecial(i, j, prim->data.text); } default: break; } } } /* Graphics State names */ static int gl2psPDFgroupListWriteGStateResources(void) { GL2PSpdfgroup *gro; int offs = 0; int i; offs += fprintf(gl2ps->stream, "/ExtGState\n" "<<\n" "/GSa 7 0 R\n"); for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); if(gro->gsno >= 0) offs += fprintf(gl2ps->stream, "/GS%d %d 0 R\n", gro->gsno, gro->gsobjno); } offs += fprintf(gl2ps->stream, ">>\n"); return offs; } /* Main Shader names */ static int gl2psPDFgroupListWriteShaderResources(void) { GL2PSpdfgroup *gro; int offs = 0; int i; offs += fprintf(gl2ps->stream, "/Shading\n" "<<\n"); for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); if(gro->shno >= 0) offs += fprintf(gl2ps->stream, "/Sh%d %d 0 R\n", gro->shno, gro->shobjno); if(gro->maskshno >= 0) offs += fprintf(gl2ps->stream, "/TrSh%d %d 0 R\n", gro->maskshno, gro->maskshobjno); } offs += fprintf(gl2ps->stream,">>\n"); return offs; } /* Images & Mask Shader XObject names */ static int gl2psPDFgroupListWriteXObjectResources(void) { int i; GL2PSprimitive *p = NULL; GL2PSpdfgroup *gro; int offs = 0; offs += fprintf(gl2ps->stream, "/XObject\n" "<<\n"); for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); if(!gl2psListNbr(gro->ptrlist)) continue; p = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, 0); switch(p->type){ case GL2PS_PIXMAP: gro->imobjno = gl2ps->objects_stack++; if(GL_RGBA == p->data.image->format) /* reserve one object for image mask */ gl2ps->objects_stack++; offs += fprintf(gl2ps->stream, "/Im%d %d 0 R\n", gro->imno, gro->imobjno); case GL2PS_TRIANGLE: if(gro->trgroupno >=0) offs += fprintf(gl2ps->stream, "/TrG%d %d 0 R\n", gro->trgroupno, gro->trgroupobjno); break; default: break; } } offs += fprintf(gl2ps->stream,">>\n"); return offs; } /* Font names */ static int gl2psPDFgroupListWriteFontResources(void) { int i; GL2PSpdfgroup *gro; int offs = 0; offs += fprintf(gl2ps->stream, "/Font\n<<\n"); for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); if(gro->fontno < 0) continue; gro->fontobjno = gl2ps->objects_stack++; offs += fprintf(gl2ps->stream, "/F%d %d 0 R\n", gro->fontno, gro->fontobjno); } offs += fprintf(gl2ps->stream, ">>\n"); return offs; } static void gl2psPDFgroupListDelete(void) { int i; GL2PSpdfgroup *gro = NULL; if(!gl2ps->pdfgrouplist) return; for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist,i); gl2psListDelete(gro->ptrlist); } gl2psListDelete(gl2ps->pdfgrouplist); gl2ps->pdfgrouplist = NULL; } /* Print 1st PDF object - file info */ static int gl2psPrintPDFInfo(void) { int offs; time_t now; struct tm *newtime; time(&now); newtime = gmtime(&now); offs = fprintf(gl2ps->stream, "1 0 obj\n" "<<\n" "/Title (%s)\n" "/Creator (GL2PS %d.%d.%d%s, %s)\n" "/Producer (%s)\n", gl2ps->title, GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION, GL2PS_COPYRIGHT, gl2ps->producer); if(!newtime){ offs += fprintf(gl2ps->stream, ">>\n" "endobj\n"); return offs; } offs += fprintf(gl2ps->stream, "/CreationDate (D:%d%02d%02d%02d%02d%02d)\n" ">>\n" "endobj\n", newtime->tm_year+1900, newtime->tm_mon+1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec); return offs; } /* Create catalog and page structure - 2nd and 3th PDF object */ static int gl2psPrintPDFCatalog(void) { return fprintf(gl2ps->stream, "2 0 obj\n" "<<\n" "/Type /Catalog\n" "/Pages 3 0 R\n" ">>\n" "endobj\n"); } static int gl2psPrintPDFPages(void) { return fprintf(gl2ps->stream, "3 0 obj\n" "<<\n" "/Type /Pages\n" "/Kids [6 0 R]\n" "/Count 1\n" ">>\n" "endobj\n"); } /* Open stream for data - graphical objects, fonts etc. PDF object 4 */ static int gl2psOpenPDFDataStream(void) { int offs = 0; offs += fprintf(gl2ps->stream, "4 0 obj\n" "<<\n" "/Length 5 0 R\n" ); offs += gl2psPrintPDFCompressorType(); offs += fprintf(gl2ps->stream, ">>\n" "stream\n"); return offs; } /* Stream setup - Graphics state, fill background if allowed */ static int gl2psOpenPDFDataStreamWritePreface(void) { int offs; offs = gl2psPrintf("/GSa gs\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ offs += gl2psPrintPDFFillColor(gl2ps->bgcolor); offs += gl2psPrintf("%d %d %d %d re\n", (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]); offs += gl2psPrintf("f\n"); } return offs; } /* Use the functions above to create the first part of the PDF*/ static void gl2psPrintPDFHeader(void) { int offs = 0; gl2ps->pdfprimlist = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*)); gl2psPDFstacksInit(); gl2ps->xreflist = (int*)gl2psMalloc(sizeof(int) * gl2ps->objects_stack); #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ gl2psSetupCompress(); } #endif gl2ps->xreflist[0] = 0; offs += fprintf(gl2ps->stream, "%%PDF-1.4\n"); gl2ps->xreflist[1] = offs; offs += gl2psPrintPDFInfo(); gl2ps->xreflist[2] = offs; offs += gl2psPrintPDFCatalog(); gl2ps->xreflist[3] = offs; offs += gl2psPrintPDFPages(); gl2ps->xreflist[4] = offs; offs += gl2psOpenPDFDataStream(); gl2ps->xreflist[5] = offs; /* finished in gl2psPrintPDFFooter */ gl2ps->streamlength = gl2psOpenPDFDataStreamWritePreface(); } /* The central primitive drawing */ static void gl2psPrintPDFPrimitive(void *data) { GL2PSprimitive *prim = *(GL2PSprimitive**)data; if((gl2ps->options & GL2PS_OCCLUSION_CULL) && prim->culled) return; prim = gl2psCopyPrimitive(prim); /* deep copy */ gl2psListAdd(gl2ps->pdfprimlist, &prim); } /* close stream and ... */ static int gl2psClosePDFDataStream(void) { int offs = 0; #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ if(Z_OK != gl2psDeflate()) gl2psMsg(GL2PS_ERROR, "Zlib deflate error"); else fwrite(gl2ps->compress->dest, gl2ps->compress->destLen, 1, gl2ps->stream); gl2ps->streamlength += gl2ps->compress->destLen; offs += gl2ps->streamlength; gl2psFreeCompress(); } #endif offs += fprintf(gl2ps->stream, "endstream\n" "endobj\n"); return offs; } /* ... write the now known length object */ static int gl2psPrintPDFDataStreamLength(int val) { return fprintf(gl2ps->stream, "5 0 obj\n" "%d\n" "endobj\n", val); } /* Put the info created before in PDF objects */ static int gl2psPrintPDFOpenPage(void) { int offs; /* Write fixed part */ offs = fprintf(gl2ps->stream, "6 0 obj\n" "<<\n" "/Type /Page\n" "/Parent 3 0 R\n" "/MediaBox [%d %d %d %d]\n", (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]); if(gl2ps->options & GL2PS_LANDSCAPE) offs += fprintf(gl2ps->stream, "/Rotate -90\n"); offs += fprintf(gl2ps->stream, "/Contents 4 0 R\n" "/Resources\n" "<<\n" "/ProcSet [/PDF /Text /ImageB /ImageC] %%/ImageI\n"); return offs; /* End fixed part, proceeds in gl2psPDFgroupListWriteVariableResources() */ } static int gl2psPDFgroupListWriteVariableResources(void) { int offs = 0; /* a) Graphics States for shader alpha masks*/ offs += gl2psPDFgroupListWriteGStateResources(); /* b) Shader and shader masks */ offs += gl2psPDFgroupListWriteShaderResources(); /* c) XObjects (Images & Shader Masks) */ offs += gl2psPDFgroupListWriteXObjectResources(); /* d) Fonts */ offs += gl2psPDFgroupListWriteFontResources(); /* End resources and page */ offs += fprintf(gl2ps->stream, ">>\n" ">>\n" "endobj\n"); return offs; } /* Standard Graphics State */ static int gl2psPrintPDFGSObject(void) { return fprintf(gl2ps->stream, "7 0 obj\n" "<<\n" "/Type /ExtGState\n" "/SA false\n" "/SM 0.02\n" "/OP false\n" "/op false\n" "/OPM 0\n" "/BG2 /Default\n" "/UCR2 /Default\n" "/TR2 /Default\n" ">>\n" "endobj\n"); } /* Put vertex' edge flag (8bit) and coordinates (32bit) in shader stream */ static int gl2psPrintPDFShaderStreamDataCoord(GL2PSvertex *vertex, int (*action)(unsigned long data, int size), GLfloat dx, GLfloat dy, GLfloat xmin, GLfloat ymin) { int offs = 0; unsigned long imap; GLfloat diff; double dmax = ~1UL; char edgeflag = 0; /* FIXME: temp bux fix for 64 bit archs: */ if(sizeof(unsigned long) == 8) dmax = dmax - 2048.; offs += (*action)(edgeflag, 1); /* The Shader stream in PDF requires to be in a 'big-endian' order */ if(GL2PS_ZERO(dx * dy)){ offs += (*action)(0, 4); offs += (*action)(0, 4); } else{ diff = (vertex->xyz[0] - xmin) / dx; if(diff > 1) diff = 1.0F; else if(diff < 0) diff = 0.0F; imap = (unsigned long)(diff * dmax); offs += (*action)(imap, 4); diff = (vertex->xyz[1] - ymin) / dy; if(diff > 1) diff = 1.0F; else if(diff < 0) diff = 0.0F; imap = (unsigned long)(diff * dmax); offs += (*action)(imap, 4); } return offs; } /* Put vertex' rgb value (8bit for every component) in shader stream */ static int gl2psPrintPDFShaderStreamDataRGB(GL2PSvertex *vertex, int (*action)(unsigned long data, int size)) { int offs = 0; unsigned long imap; double dmax = ~1UL; /* FIXME: temp bux fix for 64 bit archs: */ if(sizeof(unsigned long) == 8) dmax = dmax - 2048.; imap = (unsigned long)((vertex->rgba[0]) * dmax); offs += (*action)(imap, 1); imap = (unsigned long)((vertex->rgba[1]) * dmax); offs += (*action)(imap, 1); imap = (unsigned long)((vertex->rgba[2]) * dmax); offs += (*action)(imap, 1); return offs; } /* Put vertex' alpha (8/16bit) in shader stream */ static int gl2psPrintPDFShaderStreamDataAlpha(GL2PSvertex *vertex, int (*action)(unsigned long data, int size), int sigbyte) { int offs = 0; unsigned long imap; double dmax = ~1UL; /* FIXME: temp bux fix for 64 bit archs: */ if(sizeof(unsigned long) == 8) dmax = dmax - 2048.; if(sigbyte != 8 && sigbyte != 16) sigbyte = 8; sigbyte /= 8; imap = (unsigned long)((vertex->rgba[3]) * dmax); offs += (*action)(imap, sigbyte); return offs; } /* Put a triangles raw data in shader stream */ static int gl2psPrintPDFShaderStreamData(GL2PStriangle *triangle, GLfloat dx, GLfloat dy, GLfloat xmin, GLfloat ymin, int (*action)(unsigned long data, int size), int gray) { int i, offs = 0; GL2PSvertex v; if(gray && gray != 8 && gray != 16) gray = 8; for(i = 0; i < 3; ++i){ offs += gl2psPrintPDFShaderStreamDataCoord(&triangle->vertex[i], action, dx, dy, xmin, ymin); if(gray){ v = triangle->vertex[i]; offs += gl2psPrintPDFShaderStreamDataAlpha(&v, action, gray); } else{ offs += gl2psPrintPDFShaderStreamDataRGB(&triangle->vertex[i], action); } } return offs; } static void gl2psPDFRectHull(GLfloat *xmin, GLfloat *xmax, GLfloat *ymin, GLfloat *ymax, GL2PStriangle *triangles, int cnt) { int i, j; *xmin = triangles[0].vertex[0].xyz[0]; *xmax = triangles[0].vertex[0].xyz[0]; *ymin = triangles[0].vertex[0].xyz[1]; *ymax = triangles[0].vertex[0].xyz[1]; for(i = 0; i < cnt; ++i){ for(j = 0; j < 3; ++j){ if(*xmin > triangles[i].vertex[j].xyz[0]) *xmin = triangles[i].vertex[j].xyz[0]; if(*xmax < triangles[i].vertex[j].xyz[0]) *xmax = triangles[i].vertex[j].xyz[0]; if(*ymin > triangles[i].vertex[j].xyz[1]) *ymin = triangles[i].vertex[j].xyz[1]; if(*ymax < triangles[i].vertex[j].xyz[1]) *ymax = triangles[i].vertex[j].xyz[1]; } } } /* Writes shaded triangle gray == 0 means write RGB triangles gray == 8 8bit-grayscale (for alpha masks) gray == 16 16bit-grayscale (for alpha masks) */ static int gl2psPrintPDFShader(int obj, GL2PStriangle *triangles, int size, int gray) { int i, offs = 0, vertexbytes, done = 0; GLfloat xmin, xmax, ymin, ymax; switch(gray){ case 0: vertexbytes = 1+4+4+1+1+1; break; case 8: vertexbytes = 1+4+4+1; break; case 16: vertexbytes = 1+4+4+2; break; default: gray = 8; vertexbytes = 1+4+4+1; break; } gl2psPDFRectHull(&xmin, &xmax, &ymin, &ymax, triangles, size); offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<< " "/ShadingType 4 " "/ColorSpace %s " "/BitsPerCoordinate 32 " "/BitsPerComponent %d " "/BitsPerFlag 8 " "/Decode [%f %f %f %f 0 1 %s] ", obj, (gray) ? "/DeviceGray" : "/DeviceRGB", (gray) ? gray : 8, xmin, xmax, ymin, ymax, (gray) ? "" : "0 1 0 1"); #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ gl2psAllocCompress(vertexbytes * size * 3); for(i = 0; i < size; ++i) gl2psPrintPDFShaderStreamData(&triangles[i], xmax-xmin, ymax-ymin, xmin, ymin, gl2psWriteBigEndianCompress, gray); if(Z_OK == gl2psDeflate() && 23 + gl2ps->compress->destLen < gl2ps->compress->srcLen){ offs += gl2psPrintPDFCompressorType(); offs += fprintf(gl2ps->stream, "/Length %d " ">>\n" "stream\n", (int)gl2ps->compress->destLen); offs += gl2ps->compress->destLen * fwrite(gl2ps->compress->dest, gl2ps->compress->destLen, 1, gl2ps->stream); done = 1; } gl2psFreeCompress(); } #endif if(!done){ /* no compression, or too long after compression, or compress error -> write non-compressed entry */ offs += fprintf(gl2ps->stream, "/Length %d " ">>\n" "stream\n", vertexbytes * 3 * size); for(i = 0; i < size; ++i) offs += gl2psPrintPDFShaderStreamData(&triangles[i], xmax-xmin, ymax-ymin, xmin, ymin, gl2psWriteBigEndian, gray); } offs += fprintf(gl2ps->stream, "\nendstream\n" "endobj\n"); return offs; } /* Writes a XObject for a shaded triangle mask */ static int gl2psPrintPDFShaderMask(int obj, int childobj) { int offs = 0, len; offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<<\n" "/Type /XObject\n" "/Subtype /Form\n" "/BBox [ %d %d %d %d ]\n" "/Group \n<<\n/S /Transparency /CS /DeviceRGB\n" ">>\n", obj, (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]); len = (childobj>0) ? (int)strlen("/TrSh sh\n") + (int)log10((double)childobj)+1 : (int)strlen("/TrSh0 sh\n"); offs += fprintf(gl2ps->stream, "/Length %d\n" ">>\n" "stream\n", len); offs += fprintf(gl2ps->stream, "/TrSh%d sh\n", childobj); offs += fprintf(gl2ps->stream, "endstream\n" "endobj\n"); return offs; } /* Writes a Extended graphics state for a shaded triangle mask if simplealpha ist true the childobj argument is ignored and a /ca statement will be written instead */ static int gl2psPrintPDFShaderExtGS(int obj, int childobj) { int offs = 0; offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<<\n", obj); offs += fprintf(gl2ps->stream, "/SMask << /S /Alpha /G %d 0 R >> ", childobj); offs += fprintf(gl2ps->stream, ">>\n" "endobj\n"); return offs; } /* a simple graphics state */ static int gl2psPrintPDFShaderSimpleExtGS(int obj, GLfloat alpha) { int offs = 0; offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<<\n" "/ca %g" ">>\n" "endobj\n", obj, alpha); return offs; } /* Similar groups of functions for pixmaps and text */ static int gl2psPrintPDFPixmapStreamData(GL2PSimage *im, int (*action)(unsigned long data, int size), int gray) { int x, y, shift; GLfloat r, g, b, a; if(im->format != GL_RGBA && gray) return 0; if(gray && gray != 8 && gray != 16) gray = 8; gray /= 8; shift = (sizeof(unsigned long) - 1) * 8; for(y = 0; y < im->height; ++y){ for(x = 0; x < im->width; ++x){ a = gl2psGetRGB(im, x, y, &r, &g, &b); if(im->format == GL_RGBA && gray){ (*action)((unsigned long)(a * 255) << shift, gray); } else{ (*action)((unsigned long)(r * 255) << shift, 1); (*action)((unsigned long)(g * 255) << shift, 1); (*action)((unsigned long)(b * 255) << shift, 1); } } } switch(gray){ case 0: return 3 * im->width * im->height; case 1: return im->width * im->height; case 2: return 2 * im->width * im->height; default: return 3 * im->width * im->height; } } static int gl2psPrintPDFPixmap(int obj, int childobj, GL2PSimage *im, int gray) { int offs = 0, done = 0, sigbytes = 3; if(gray && gray !=8 && gray != 16) gray = 8; if(gray) sigbytes = gray / 8; offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<<\n" "/Type /XObject\n" "/Subtype /Image\n" "/Width %d\n" "/Height %d\n" "/ColorSpace %s \n" "/BitsPerComponent 8\n", obj, (int)im->width, (int)im->height, (gray) ? "/DeviceGray" : "/DeviceRGB" ); if(GL_RGBA == im->format && gray == 0){ offs += fprintf(gl2ps->stream, "/SMask %d 0 R\n", childobj); } #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ gl2psAllocCompress((int)(im->width * im->height * sigbytes)); gl2psPrintPDFPixmapStreamData(im, gl2psWriteBigEndianCompress, gray); if(Z_OK == gl2psDeflate() && 23 + gl2ps->compress->destLen < gl2ps->compress->srcLen){ offs += gl2psPrintPDFCompressorType(); offs += fprintf(gl2ps->stream, "/Length %d " ">>\n" "stream\n", (int)gl2ps->compress->destLen); offs += gl2ps->compress->destLen * fwrite(gl2ps->compress->dest, gl2ps->compress->destLen, 1, gl2ps->stream); done = 1; } gl2psFreeCompress(); } #endif if(!done){ /* no compression, or too long after compression, or compress error -> write non-compressed entry */ offs += fprintf(gl2ps->stream, "/Length %d " ">>\n" "stream\n", (int)(im->width * im->height * sigbytes)); offs += gl2psPrintPDFPixmapStreamData(im, gl2psWriteBigEndian, gray); } offs += fprintf(gl2ps->stream, "\nendstream\n" "endobj\n"); return offs; } static int gl2psPrintPDFText(int obj, GL2PSstring *s, int fontnumber) { int offs = 0; offs += fprintf(gl2ps->stream, "%d 0 obj\n" "<<\n" "/Type /Font\n" "/Subtype /Type1\n" "/Name /F%d\n" "/BaseFont /%s\n" "/Encoding /MacRomanEncoding\n" ">>\n" "endobj\n", obj, fontnumber, s->fontname); return offs; } /* Write the physical objects */ static int gl2psPDFgroupListWriteObjects(int entryoffs) { int i,j; GL2PSprimitive *p = NULL; GL2PSpdfgroup *gro; int offs = entryoffs; GL2PStriangle *triangles; int size = 0; if(!gl2ps->pdfgrouplist) return offs; for(i = 0; i < gl2psListNbr(gl2ps->pdfgrouplist); ++i){ gro = (GL2PSpdfgroup*)gl2psListPointer(gl2ps->pdfgrouplist, i); if(!gl2psListNbr(gro->ptrlist)) continue; p = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, 0); switch(p->type){ case GL2PS_POINT: break; case GL2PS_LINE: break; case GL2PS_TRIANGLE: size = gl2psListNbr(gro->ptrlist); triangles = (GL2PStriangle*)gl2psMalloc(sizeof(GL2PStriangle) * size); for(j = 0; j < size; ++j){ p = *(GL2PSprimitive**)gl2psListPointer(gro->ptrlist, j); gl2psFillTriangleFromPrimitive(&triangles[j], p, GL_TRUE); } if(triangles[0].prop & T_VAR_COLOR){ gl2ps->xreflist[gro->shobjno] = offs; offs += gl2psPrintPDFShader(gro->shobjno, triangles, size, 0); } if(triangles[0].prop & T_ALPHA_LESS_1){ gl2ps->xreflist[gro->gsobjno] = offs; offs += gl2psPrintPDFShaderSimpleExtGS(gro->gsobjno, triangles[0].vertex[0].rgba[3]); } if(triangles[0].prop & T_VAR_ALPHA){ gl2ps->xreflist[gro->gsobjno] = offs; offs += gl2psPrintPDFShaderExtGS(gro->gsobjno, gro->trgroupobjno); gl2ps->xreflist[gro->trgroupobjno] = offs; offs += gl2psPrintPDFShaderMask(gro->trgroupobjno, gro->maskshno); gl2ps->xreflist[gro->maskshobjno] = offs; offs += gl2psPrintPDFShader(gro->maskshobjno, triangles, size, 8); } gl2psFree(triangles); break; case GL2PS_PIXMAP: gl2ps->xreflist[gro->imobjno] = offs; offs += gl2psPrintPDFPixmap(gro->imobjno, gro->imobjno+1, p->data.image, 0); if(p->data.image->format == GL_RGBA){ gl2ps->xreflist[gro->imobjno+1] = offs; offs += gl2psPrintPDFPixmap(gro->imobjno+1, -1, p->data.image, 8); } break; case GL2PS_TEXT: gl2ps->xreflist[gro->fontobjno] = offs; offs += gl2psPrintPDFText(gro->fontobjno,p->data.text,gro->fontno); break; case GL2PS_SPECIAL : /* alignment contains the format for which the special output text is intended */ if(p->data.text->alignment == GL2PS_PDF) offs += fprintf(gl2ps->stream, "%s\n", p->data.text->str); break; default: break; } } return offs; } /* All variable data has been written at this point and all required functioninality has been gathered, so we can write now file footer with cross reference table and trailer */ static void gl2psPrintPDFFooter(void) { int i, offs; gl2psPDFgroupListInit(); gl2psPDFgroupListWriteMainStream(); offs = gl2ps->xreflist[5] + gl2ps->streamlength; offs += gl2psClosePDFDataStream(); gl2ps->xreflist[5] = offs; offs += gl2psPrintPDFDataStreamLength(gl2ps->streamlength); gl2ps->xreflist[6] = offs; gl2ps->streamlength = 0; offs += gl2psPrintPDFOpenPage(); offs += gl2psPDFgroupListWriteVariableResources(); gl2ps->xreflist = (int*)gl2psRealloc(gl2ps->xreflist, sizeof(int) * (gl2ps->objects_stack + 1)); gl2ps->xreflist[7] = offs; offs += gl2psPrintPDFGSObject(); gl2ps->xreflist[8] = offs; gl2ps->xreflist[gl2ps->objects_stack] = gl2psPDFgroupListWriteObjects(gl2ps->xreflist[8]); /* Start cross reference table. The file has to been opened in binary mode to preserve the 20 digit string length! */ fprintf(gl2ps->stream, "xref\n" "0 %d\n" "%010d 65535 f \n", gl2ps->objects_stack, 0); for(i = 1; i < gl2ps->objects_stack; ++i) fprintf(gl2ps->stream, "%010d 00000 n \n", gl2ps->xreflist[i]); fprintf(gl2ps->stream, "trailer\n" "<<\n" "/Size %d\n" "/Info 1 0 R\n" "/Root 2 0 R\n" ">>\n" "startxref\n%d\n" "%%%%EOF\n", gl2ps->objects_stack, gl2ps->xreflist[gl2ps->objects_stack]); /* Free auxiliary lists and arrays */ gl2psFree(gl2ps->xreflist); gl2psListAction(gl2ps->pdfprimlist, gl2psFreePrimitive); gl2psListDelete(gl2ps->pdfprimlist); gl2psPDFgroupListDelete(); #if defined(GL2PS_HAVE_ZLIB) if(gl2ps->options & GL2PS_COMPRESS){ gl2psFreeCompress(); gl2psFree(gl2ps->compress); gl2ps->compress = NULL; } #endif } /* PDF begin viewport */ static void gl2psPrintPDFBeginViewport(GLint viewport[4]) { int offs = 0; GLint idx; GLfloat rgba[4]; int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3]; glRenderMode(GL_FEEDBACK); gl2psResetLineProperties(); if(gl2ps->header){ gl2psPrintPDFHeader(); gl2ps->header = GL_FALSE; } offs += gl2psPrintf("q\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){ glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba); } else{ glGetIntegerv(GL_INDEX_CLEAR_VALUE, &idx); rgba[0] = gl2ps->colormap[idx][0]; rgba[1] = gl2ps->colormap[idx][1]; rgba[2] = gl2ps->colormap[idx][2]; rgba[3] = 1.0F; } offs += gl2psPrintPDFFillColor(rgba); offs += gl2psPrintf("%d %d %d %d re\n" "W\n" "f\n", x, y, w, h); } else{ offs += gl2psPrintf("%d %d %d %d re\n" "W\n" "n\n", x, y, w, h); } gl2ps->streamlength += offs; } static GLint gl2psPrintPDFEndViewport(void) { GLint res; res = gl2psPrintPrimitives(); gl2ps->streamlength += gl2psPrintf("Q\n"); return res; } static void gl2psPrintPDFFinalPrimitive(void) { } /* definition of the PDF backend */ static GL2PSbackend gl2psPDF = { gl2psPrintPDFHeader, gl2psPrintPDFFooter, gl2psPrintPDFBeginViewport, gl2psPrintPDFEndViewport, gl2psPrintPDFPrimitive, gl2psPrintPDFFinalPrimitive, "pdf", "Portable Document Format" }; /********************************************************************* * * SVG routines * *********************************************************************/ static void gl2psSVGGetCoordsAndColors(int n, GL2PSvertex *verts, GL2PSxyz *xyz, GL2PSrgba *rgba) { int i, j; for(i = 0; i < n; i++){ xyz[i][0] = verts[i].xyz[0]; xyz[i][1] = gl2ps->viewport[3] - verts[i].xyz[1]; xyz[i][2] = 0.0F; for(j = 0; j < 4; j++) rgba[i][j] = verts[i].rgba[j]; } } static void gl2psSVGGetColorString(GL2PSrgba rgba, char str[32]) { int r = (int)(255. * rgba[0]); int g = (int)(255. * rgba[1]); int b = (int)(255. * rgba[2]); int rc = (r < 0) ? 0 : (r > 255) ? 255 : r; int gc = (g < 0) ? 0 : (g > 255) ? 255 : g; int bc = (b < 0) ? 0 : (b > 255) ? 255 : b; sprintf(str, "#%2.2x%2.2x%2.2x", rc, gc, bc); } static void gl2psPrintSVGHeader(void) { int x, y, width, height; char col[32]; time_t now; time(&now); if (gl2ps->options & GL2PS_LANDSCAPE){ x = (int)gl2ps->viewport[1]; y = (int)gl2ps->viewport[0]; width = (int)gl2ps->viewport[3]; height = (int)gl2ps->viewport[2]; } else{ x = (int)gl2ps->viewport[0]; y = (int)gl2ps->viewport[1]; width = (int)gl2ps->viewport[2]; height = (int)gl2ps->viewport[3]; } /* Compressed SVG files (.svgz) are simply gzipped SVG files */ gl2psPrintGzipHeader(); gl2psPrintf("\n"); gl2psPrintf("\n", width, height, x, y, width, height); gl2psPrintf("%s\n", gl2ps->title); gl2psPrintf("\n"); gl2psPrintf("Creator: GL2PS %d.%d.%d%s, %s\n" "For: %s\n" "CreationDate: %s", GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION, GL2PS_COPYRIGHT, gl2ps->producer, ctime(&now)); gl2psPrintf("\n"); gl2psPrintf("\n"); gl2psPrintf("\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ gl2psSVGGetColorString(gl2ps->bgcolor, col); gl2psPrintf("\n", col, (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3], (int)gl2ps->viewport[0], (int)gl2ps->viewport[3]); } /* group all the primitives and disable antialiasing */ gl2psPrintf("\n"); } static void gl2psPrintSVGSmoothTriangle(GL2PSxyz xyz[3], GL2PSrgba rgba[3]) { int i; GL2PSxyz xyz2[3]; GL2PSrgba rgba2[3]; char col[32]; /* Apparently there is no easy way to do Gouraud shading in SVG without explicitly pre-defining gradients, so for now we just do recursive subdivision */ if(gl2psSameColorThreshold(3, rgba, gl2ps->threshold)){ gl2psSVGGetColorString(rgba[0], col); gl2psPrintf("\n", xyz[0][0], xyz[0][1], xyz[1][0], xyz[1][1], xyz[2][0], xyz[2][1]); } else{ /* subdivide into 4 subtriangles */ for(i = 0; i < 3; i++){ xyz2[0][i] = xyz[0][i]; xyz2[1][i] = 0.5F * (xyz[0][i] + xyz[1][i]); xyz2[2][i] = 0.5F * (xyz[0][i] + xyz[2][i]); } for(i = 0; i < 4; i++){ rgba2[0][i] = rgba[0][i]; rgba2[1][i] = 0.5F * (rgba[0][i] + rgba[1][i]); rgba2[2][i] = 0.5F * (rgba[0][i] + rgba[2][i]); } gl2psPrintSVGSmoothTriangle(xyz2, rgba2); for(i = 0; i < 3; i++){ xyz2[0][i] = 0.5F * (xyz[0][i] + xyz[1][i]); xyz2[1][i] = xyz[1][i]; xyz2[2][i] = 0.5F * (xyz[1][i] + xyz[2][i]); } for(i = 0; i < 4; i++){ rgba2[0][i] = 0.5F * (rgba[0][i] + rgba[1][i]); rgba2[1][i] = rgba[1][i]; rgba2[2][i] = 0.5F * (rgba[1][i] + rgba[2][i]); } gl2psPrintSVGSmoothTriangle(xyz2, rgba2); for(i = 0; i < 3; i++){ xyz2[0][i] = 0.5F * (xyz[0][i] + xyz[2][i]); xyz2[1][i] = xyz[2][i]; xyz2[2][i] = 0.5F * (xyz[1][i] + xyz[2][i]); } for(i = 0; i < 4; i++){ rgba2[0][i] = 0.5F * (rgba[0][i] + rgba[2][i]); rgba2[1][i] = rgba[2][i]; rgba2[2][i] = 0.5F * (rgba[1][i] + rgba[2][i]); } gl2psPrintSVGSmoothTriangle(xyz2, rgba2); for(i = 0; i < 3; i++){ xyz2[0][i] = 0.5F * (xyz[0][i] + xyz[1][i]); xyz2[1][i] = 0.5F * (xyz[1][i] + xyz[2][i]); xyz2[2][i] = 0.5F * (xyz[0][i] + xyz[2][i]); } for(i = 0; i < 4; i++){ rgba2[0][i] = 0.5F * (rgba[0][i] + rgba[1][i]); rgba2[1][i] = 0.5F * (rgba[1][i] + rgba[2][i]); rgba2[2][i] = 0.5F * (rgba[0][i] + rgba[2][i]); } gl2psPrintSVGSmoothTriangle(xyz2, rgba2); } } static void gl2psPrintSVGDash(GLushort pattern, GLint factor) { int i, n, array[10]; if(!pattern || !factor) return; /* solid line */ gl2psParseStipplePattern(pattern, factor, &n, array); gl2psPrintf("stroke-dasharray=\""); for(i = 0; i < n; i++){ if(i) gl2psPrintf(","); gl2psPrintf("%d", array[i]); } gl2psPrintf("\" "); } static void gl2psEndSVGLine(void) { int i; if(gl2ps->lastvertex.rgba[0] >= 0.){ gl2psPrintf("%g,%g\"/>\n", gl2ps->lastvertex.xyz[0], gl2ps->viewport[3] - gl2ps->lastvertex.xyz[1]); for(i = 0; i < 3; i++) gl2ps->lastvertex.xyz[i] = -1.; for(i = 0; i < 4; i++) gl2ps->lastvertex.rgba[i] = -1.; } } static void gl2psPrintSVGPixmap(GLfloat x, GLfloat y, GL2PSimage *pixmap) { #if defined(GL2PS_HAVE_LIBPNG) GL2PSlist *png; unsigned char c; int i; /* The only image types supported by the SVG standard are JPEG, PNG and SVG. Here we choose PNG, and since we want to embed the image directly in the SVG stream (and not link to an external image file), we need to encode the pixmap into PNG in memory, then encode it into base64. */ png = gl2psListCreate(pixmap->width * pixmap->height * 3, 1000, sizeof(unsigned char)); gl2psConvertPixmapToPNG(pixmap, png); gl2psListEncodeBase64(png); /* Use "transform" attribute to scale and translate the image from the coordinates origin (0,0) */ y -= pixmap->zoom_y * (GLfloat)pixmap->height; gl2psPrintf("width, pixmap->height); gl2psPrintf("transform=\"matrix(%g,0,0,%g,%g,%g)\"\n", pixmap->zoom_x, pixmap->zoom_y, x, y); gl2psPrintf("xlink:href=\"data:image/png;base64,"); for(i = 0; i < gl2psListNbr(png); i++){ gl2psListRead(png, i, &c); gl2psPrintf("%c", c); } gl2psPrintf("\"/>\n"); gl2psListDelete(png); #else (void) x; (void) y; (void) pixmap; /* not used */ gl2psMsg(GL2PS_WARNING, "GL2PS must be compiled with PNG support in " "order to embed images in SVG streams"); #endif } static void gl2psPrintSVGPrimitive(void *data) { GL2PSprimitive *prim; GL2PSxyz xyz[4]; GL2PSrgba rgba[4]; char col[32]; char lcap[7], ljoin[7]; int newline; prim = *(GL2PSprimitive**)data; if((gl2ps->options & GL2PS_OCCLUSION_CULL) && prim->culled) return; /* We try to draw connected lines as a single path to get nice line joins and correct stippling. So if the primitive to print is not a line we must first finish the current line (if any): */ if(prim->type != GL2PS_LINE) gl2psEndSVGLine(); gl2psSVGGetCoordsAndColors(prim->numverts, prim->verts, xyz, rgba); switch(prim->type){ case GL2PS_POINT : gl2psSVGGetColorString(rgba[0], col); gl2psPrintf("\n", xyz[0][0], xyz[0][1], 0.5 * prim->width); break; case GL2PS_LINE : if(!gl2psSamePosition(gl2ps->lastvertex.xyz, prim->verts[0].xyz) || !gl2psSameColor(gl2ps->lastrgba, prim->verts[0].rgba) || gl2ps->lastlinewidth != prim->width || gl2ps->lastlinecap != prim->linecap || gl2ps->lastlinejoin != prim->linejoin || gl2ps->lastpattern != prim->pattern || gl2ps->lastfactor != prim->factor){ /* End the current line if the new segment does not start where the last one ended, or if the color, the width or the stippling have changed (we will need to use multi-point gradients for smooth-shaded lines) */ gl2psEndSVGLine(); newline = 1; } else{ newline = 0; } gl2ps->lastvertex = prim->verts[1]; gl2psSetLastColor(prim->verts[0].rgba); gl2ps->lastlinewidth = prim->width; gl2ps->lastlinecap = prim->linecap; gl2ps->lastlinejoin = prim->linejoin; gl2ps->lastpattern = prim->pattern; gl2ps->lastfactor = prim->factor; if(newline){ gl2psSVGGetColorString(rgba[0], col); gl2psPrintf("width); switch (prim->linecap){ case GL2PS_LINE_CAP_BUTT: sprintf (lcap, "%s", "butt"); break; case GL2PS_LINE_CAP_ROUND: sprintf (lcap, "%s", "round"); break; case GL2PS_LINE_CAP_SQUARE: sprintf (lcap, "%s", "square"); break; } switch (prim->linejoin){ case GL2PS_LINE_JOIN_MITER: sprintf (ljoin, "%s", "miter"); break; case GL2PS_LINE_JOIN_ROUND: sprintf (ljoin, "%s", "round"); break; case GL2PS_LINE_JOIN_BEVEL: sprintf (ljoin, "%s", "bevel"); break; } gl2psPrintf("stroke-linecap=\"%s\" stroke-linejoin=\"%s\" ", lcap, ljoin); if(rgba[0][3] < 1.0F) gl2psPrintf("stroke-opacity=\"%g\" ", rgba[0][3]); gl2psPrintSVGDash(prim->pattern, prim->factor); gl2psPrintf("points=\"%g,%g ", xyz[0][0], xyz[0][1]); } else{ gl2psPrintf("%g,%g ", xyz[0][0], xyz[0][1]); } break; case GL2PS_TRIANGLE : gl2psPrintSVGSmoothTriangle(xyz, rgba); break; case GL2PS_QUADRANGLE : gl2psMsg(GL2PS_WARNING, "There should not be any quad left to print"); break; case GL2PS_PIXMAP : gl2psPrintSVGPixmap(xyz[0][0], xyz[0][1], prim->data.image); break; case GL2PS_TEXT : gl2psSVGGetColorString(prim->verts[0].rgba, col); gl2psPrintf("data.text->fontsize); if(prim->data.text->angle != 0.0) gl2psPrintf("transform=\"rotate(%g, %g, %g)\" ", -prim->data.text->angle, xyz[0][0], xyz[0][1]); switch(prim->data.text->alignment){ case GL2PS_TEXT_C: gl2psPrintf("text-anchor=\"middle\" dy=\"%d\" ", prim->data.text->fontsize / 2); break; case GL2PS_TEXT_CL: gl2psPrintf("text-anchor=\"start\" dy=\"%d\" ", prim->data.text->fontsize / 2); break; case GL2PS_TEXT_CR: gl2psPrintf("text-anchor=\"end\" dy=\"%d\" ", prim->data.text->fontsize / 2); break; case GL2PS_TEXT_B: gl2psPrintf("text-anchor=\"middle\" dy=\"0\" "); break; case GL2PS_TEXT_BR: gl2psPrintf("text-anchor=\"end\" dy=\"0\" "); break; case GL2PS_TEXT_T: gl2psPrintf("text-anchor=\"middle\" dy=\"%d\" ", prim->data.text->fontsize); break; case GL2PS_TEXT_TL: gl2psPrintf("text-anchor=\"start\" dy=\"%d\" ", prim->data.text->fontsize); break; case GL2PS_TEXT_TR: gl2psPrintf("text-anchor=\"end\" dy=\"%d\" ", prim->data.text->fontsize); break; case GL2PS_TEXT_BL: default: /* same as GL2PS_TEXT_BL */ gl2psPrintf("text-anchor=\"start\" dy=\"0\" "); break; } if(!strcmp(prim->data.text->fontname, "Times-Roman")) gl2psPrintf("font-family=\"Times\">"); else if(!strcmp(prim->data.text->fontname, "Times-Bold")) gl2psPrintf("font-family=\"Times\" font-weight=\"bold\">"); else if(!strcmp(prim->data.text->fontname, "Times-Italic")) gl2psPrintf("font-family=\"Times\" font-style=\"italic\">"); else if(!strcmp(prim->data.text->fontname, "Times-BoldItalic")) gl2psPrintf("font-family=\"Times\" font-style=\"italic\" font-weight=\"bold\">"); else if(!strcmp(prim->data.text->fontname, "Helvetica-Bold")) gl2psPrintf("font-family=\"Helvetica\" font-weight=\"bold\">"); else if(!strcmp(prim->data.text->fontname, "Helvetica-Oblique")) gl2psPrintf("font-family=\"Helvetica\" font-style=\"oblique\">"); else if(!strcmp(prim->data.text->fontname, "Helvetica-BoldOblique")) gl2psPrintf("font-family=\"Helvetica\" font-style=\"oblique\" font-weight=\"bold\">"); else if(!strcmp(prim->data.text->fontname, "Courier-Bold")) gl2psPrintf("font-family=\"Courier\" font-weight=\"bold\">"); else if(!strcmp(prim->data.text->fontname, "Courier-Oblique")) gl2psPrintf("font-family=\"Courier\" font-style=\"oblique\">"); else if(!strcmp(prim->data.text->fontname, "Courier-BoldOblique")) gl2psPrintf("font-family=\"Courier\" font-style=\"oblique\" font-weight=\"bold\">"); else gl2psPrintf("font-family=\"%s\">", prim->data.text->fontname); gl2psPrintf("%s\n", prim->data.text->str); break; case GL2PS_SPECIAL : /* alignment contains the format for which the special output text is intended */ if(prim->data.text->alignment == GL2PS_SVG) gl2psPrintf("%s\n", prim->data.text->str); break; default : break; } } static void gl2psPrintSVGFooter(void) { gl2psPrintf("\n"); gl2psPrintf("\n"); gl2psPrintGzipFooter(); } static void gl2psPrintSVGBeginViewport(GLint viewport[4]) { GLint idx; char col[32]; GLfloat rgba[4]; int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3]; glRenderMode(GL_FEEDBACK); gl2psResetLineProperties(); if(gl2ps->header){ gl2psPrintSVGHeader(); gl2ps->header = GL_FALSE; } if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){ glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba); } else{ glGetIntegerv(GL_INDEX_CLEAR_VALUE, &idx); rgba[0] = gl2ps->colormap[idx][0]; rgba[1] = gl2ps->colormap[idx][1]; rgba[2] = gl2ps->colormap[idx][2]; rgba[3] = 1.0F; } gl2psSVGGetColorString(rgba, col); gl2psPrintf("viewport[3] - y, x + w, gl2ps->viewport[3] - y, x + w, gl2ps->viewport[3] - (y + h), x, gl2ps->viewport[3] - (y + h)); gl2psPrintf("shape-rendering=\"crispEdges\"/>\n"); } gl2psPrintf("\n", x, y, w, h); gl2psPrintf(" \n", x, gl2ps->viewport[3] - y, x + w, gl2ps->viewport[3] - y, x + w, gl2ps->viewport[3] - (y + h), x, gl2ps->viewport[3] - (y + h)); gl2psPrintf("\n"); gl2psPrintf("\n", x, y, w, h); } static GLint gl2psPrintSVGEndViewport(void) { GLint res; res = gl2psPrintPrimitives(); gl2psPrintf("\n"); return res; } static void gl2psPrintSVGFinalPrimitive(void) { /* End any remaining line, if any */ gl2psEndSVGLine(); } /* definition of the SVG backend */ static GL2PSbackend gl2psSVG = { gl2psPrintSVGHeader, gl2psPrintSVGFooter, gl2psPrintSVGBeginViewport, gl2psPrintSVGEndViewport, gl2psPrintSVGPrimitive, gl2psPrintSVGFinalPrimitive, "svg", "Scalable Vector Graphics" }; /********************************************************************* * * PGF routines * *********************************************************************/ static void gl2psPrintPGFColor(GL2PSrgba rgba) { if(!gl2psSameColor(gl2ps->lastrgba, rgba)){ gl2psSetLastColor(rgba); fprintf(gl2ps->stream, "\\color[rgb]{%f,%f,%f}\n", rgba[0], rgba[1], rgba[2]); } } static void gl2psPrintPGFHeader(void) { time_t now; time(&now); fprintf(gl2ps->stream, "%% Title: %s\n" "%% Creator: GL2PS %d.%d.%d%s, %s\n" "%% For: %s\n" "%% CreationDate: %s", gl2ps->title, GL2PS_MAJOR_VERSION, GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION, GL2PS_COPYRIGHT, gl2ps->producer, ctime(&now)); fprintf(gl2ps->stream, "\\begin{pgfpicture}\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ gl2psPrintPGFColor(gl2ps->bgcolor); fprintf(gl2ps->stream, "\\pgfpathrectanglecorners{" "\\pgfpoint{%dpt}{%dpt}}{\\pgfpoint{%dpt}{%dpt}}\n" "\\pgfusepath{fill}\n", (int)gl2ps->viewport[0], (int)gl2ps->viewport[1], (int)gl2ps->viewport[2], (int)gl2ps->viewport[3]); } } static void gl2psPrintPGFDash(GLushort pattern, GLint factor) { int i, n, array[10]; if(pattern == gl2ps->lastpattern && factor == gl2ps->lastfactor) return; gl2ps->lastpattern = pattern; gl2ps->lastfactor = factor; if(!pattern || !factor){ /* solid line */ fprintf(gl2ps->stream, "\\pgfsetdash{}{0pt}\n"); } else{ gl2psParseStipplePattern(pattern, factor, &n, array); fprintf(gl2ps->stream, "\\pgfsetdash{"); for(i = 0; i < n; i++) fprintf(gl2ps->stream, "{%dpt}", array[i]); fprintf(gl2ps->stream, "}{0pt}\n"); } } static const char *gl2psPGFTextAlignment(int align) { switch(align){ case GL2PS_TEXT_C : return "center"; case GL2PS_TEXT_CL : return "west"; case GL2PS_TEXT_CR : return "east"; case GL2PS_TEXT_B : return "south"; case GL2PS_TEXT_BR : return "south east"; case GL2PS_TEXT_T : return "north"; case GL2PS_TEXT_TL : return "north west"; case GL2PS_TEXT_TR : return "north east"; case GL2PS_TEXT_BL : default : return "south west"; } } static void gl2psPrintPGFPrimitive(void *data) { GL2PSprimitive *prim; prim = *(GL2PSprimitive**)data; switch(prim->type){ case GL2PS_POINT : /* Points in openGL are rectangular */ gl2psPrintPGFColor(prim->verts[0].rgba); fprintf(gl2ps->stream, "\\pgfpathrectangle{\\pgfpoint{%fpt}{%fpt}}" "{\\pgfpoint{%fpt}{%fpt}}\n\\pgfusepath{fill}\n", prim->verts[0].xyz[0]-0.5*prim->width, prim->verts[0].xyz[1]-0.5*prim->width, prim->width,prim->width); break; case GL2PS_LINE : gl2psPrintPGFColor(prim->verts[0].rgba); if(gl2ps->lastlinewidth != prim->width){ gl2ps->lastlinewidth = prim->width; fprintf(gl2ps->stream, "\\pgfsetlinewidth{%fpt}\n", gl2ps->lastlinewidth); } if(gl2ps->lastlinecap != prim->linecap){ gl2ps->lastlinecap = prim->linecap; switch (prim->linecap){ case GL2PS_LINE_CAP_BUTT: fprintf(gl2ps->stream, "\\pgfset%s\n", "buttcap"); break; case GL2PS_LINE_CAP_ROUND: fprintf(gl2ps->stream, "\\pgfset%s\n", "roundcap"); break; case GL2PS_LINE_CAP_SQUARE: fprintf(gl2ps->stream, "\\pgfset%s\n", "rectcap"); break; } } if(gl2ps->lastlinejoin != prim->linejoin){ gl2ps->lastlinejoin = prim->linejoin; switch (prim->linejoin){ case GL2PS_LINE_JOIN_MITER: fprintf(gl2ps->stream, "\\pgfset%s\n", "miterjoin"); break; case GL2PS_LINE_JOIN_ROUND: fprintf(gl2ps->stream, "\\pgfset%s\n", "roundjoin"); break; case GL2PS_LINE_JOIN_BEVEL: fprintf(gl2ps->stream, "\\pgfset%s\n", "beveljoin"); break; } } gl2psPrintPGFDash(prim->pattern, prim->factor); fprintf(gl2ps->stream, "\\pgfpathmoveto{\\pgfpoint{%fpt}{%fpt}}\n" "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n" "\\pgfusepath{stroke}\n", prim->verts[1].xyz[0], prim->verts[1].xyz[1], prim->verts[0].xyz[0], prim->verts[0].xyz[1]); break; case GL2PS_TRIANGLE : if(gl2ps->lastlinewidth != 0){ gl2ps->lastlinewidth = 0; fprintf(gl2ps->stream, "\\pgfsetlinewidth{0.01pt}\n"); } if(gl2ps->lastlinecap != prim->linecap){ gl2ps->lastlinecap = prim->linecap; switch (prim->linecap){ case GL2PS_LINE_CAP_BUTT: fprintf(gl2ps->stream, "\\pgfset%s\n", "buttcap"); break; case GL2PS_LINE_CAP_ROUND: fprintf(gl2ps->stream, "\\pgfset%s\n", "roundcap"); break; case GL2PS_LINE_CAP_SQUARE: fprintf(gl2ps->stream, "\\pgfset%s\n", "rectcap"); break; } } if(gl2ps->lastlinejoin != prim->linejoin){ gl2ps->lastlinejoin = prim->linejoin; switch (prim->linejoin){ case GL2PS_LINE_JOIN_MITER: fprintf(gl2ps->stream, "\\pgfset%s\n", "miterjoin"); break; case GL2PS_LINE_JOIN_ROUND: fprintf(gl2ps->stream, "\\pgfset%s\n", "roundjoin"); break; case GL2PS_LINE_JOIN_BEVEL: fprintf(gl2ps->stream, "\\pgfset%s\n", "beveljoin"); break; } } gl2psPrintPGFColor(prim->verts[0].rgba); fprintf(gl2ps->stream, "\\pgfpathmoveto{\\pgfpoint{%fpt}{%fpt}}\n" "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n" "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n" "\\pgfpathclose\n" "\\pgfusepath{fill,stroke}\n", prim->verts[2].xyz[0], prim->verts[2].xyz[1], prim->verts[1].xyz[0], prim->verts[1].xyz[1], prim->verts[0].xyz[0], prim->verts[0].xyz[1]); break; case GL2PS_TEXT : fprintf(gl2ps->stream, "{\n\\pgftransformshift{\\pgfpoint{%fpt}{%fpt}}\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1]); if(prim->data.text->angle != 0.0) fprintf(gl2ps->stream, "\\pgftransformrotate{%f}{", prim->data.text->angle); fprintf(gl2ps->stream, "\\pgfnode{rectangle}{%s}{\\fontsize{%d}{0}\\selectfont", gl2psPGFTextAlignment(prim->data.text->alignment), prim->data.text->fontsize); fprintf(gl2ps->stream, "\\textcolor[rgb]{%g,%g,%g}{{%s}}", prim->verts[0].rgba[0], prim->verts[0].rgba[1], prim->verts[0].rgba[2], prim->data.text->str); fprintf(gl2ps->stream, "}{}{\\pgfusepath{discard}}}"); if(prim->data.text->angle != 0.0) fprintf(gl2ps->stream, "}"); fprintf(gl2ps->stream, "\n"); break; case GL2PS_SPECIAL : /* alignment contains the format for which the special output text is intended */ if (prim->data.text->alignment == GL2PS_PGF) fprintf(gl2ps->stream, "%s\n", prim->data.text->str); break; default : break; } } static void gl2psPrintPGFFooter(void) { fprintf(gl2ps->stream, "\\end{pgfpicture}\n"); } static void gl2psPrintPGFBeginViewport(GLint viewport[4]) { GLint idx; GLfloat rgba[4]; int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3]; glRenderMode(GL_FEEDBACK); gl2psResetLineProperties(); if(gl2ps->header){ gl2psPrintPGFHeader(); gl2ps->header = GL_FALSE; } fprintf(gl2ps->stream, "\\begin{pgfscope}\n"); if(gl2ps->options & GL2PS_DRAW_BACKGROUND){ if(gl2ps->colormode == GL_RGBA || gl2ps->colorsize == 0){ glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba); } else{ glGetIntegerv(GL_INDEX_CLEAR_VALUE, &idx); rgba[0] = gl2ps->colormap[idx][0]; rgba[1] = gl2ps->colormap[idx][1]; rgba[2] = gl2ps->colormap[idx][2]; rgba[3] = 1.0F; } gl2psPrintPGFColor(rgba); fprintf(gl2ps->stream, "\\pgfpathrectangle{\\pgfpoint{%dpt}{%dpt}}" "{\\pgfpoint{%dpt}{%dpt}}\n" "\\pgfusepath{fill}\n", x, y, w, h); } fprintf(gl2ps->stream, "\\pgfpathrectangle{\\pgfpoint{%dpt}{%dpt}}" "{\\pgfpoint{%dpt}{%dpt}}\n" "\\pgfusepath{clip}\n", x, y, w, h); } static GLint gl2psPrintPGFEndViewport(void) { GLint res; res = gl2psPrintPrimitives(); fprintf(gl2ps->stream, "\\end{pgfscope}\n"); return res; } static void gl2psPrintPGFFinalPrimitive(void) { } /* definition of the PGF backend */ static GL2PSbackend gl2psPGF = { gl2psPrintPGFHeader, gl2psPrintPGFFooter, gl2psPrintPGFBeginViewport, gl2psPrintPGFEndViewport, gl2psPrintPGFPrimitive, gl2psPrintPGFFinalPrimitive, "tex", "PGF Latex Graphics" }; /********************************************************************* * * General primitive printing routine * *********************************************************************/ /* Warning: the ordering of the backends must match the format #defines in gl2ps.h */ static GL2PSbackend *gl2psbackends[] = { &gl2psPS, /* 0 */ &gl2psEPS, /* 1 */ &gl2psTEX, /* 2 */ &gl2psPDF, /* 3 */ &gl2psSVG, /* 4 */ &gl2psPGF /* 5 */ }; static void gl2psComputeTightBoundingBox(void *data) { GL2PSprimitive *prim; int i; prim = *(GL2PSprimitive**)data; for(i = 0; i < prim->numverts; i++){ if(prim->verts[i].xyz[0] < gl2ps->viewport[0]) gl2ps->viewport[0] = (GLint)prim->verts[i].xyz[0]; if(prim->verts[i].xyz[0] > gl2ps->viewport[2]) gl2ps->viewport[2] = (GLint)(prim->verts[i].xyz[0] + 0.5F); if(prim->verts[i].xyz[1] < gl2ps->viewport[1]) gl2ps->viewport[1] = (GLint)prim->verts[i].xyz[1]; if(prim->verts[i].xyz[1] > gl2ps->viewport[3]) gl2ps->viewport[3] = (GLint)(prim->verts[i].xyz[1] + 0.5F); } } static GLint gl2psPrintPrimitives(void) { GL2PSbsptree *root; GL2PSxyz eye = {0.0F, 0.0F, 100.0F * GL2PS_ZSCALE}; GLint used = 0; if ((gl2ps->options & GL2PS_NO_OPENGL_CONTEXT) == GL2PS_NONE) { used = glRenderMode(GL_RENDER); } if(used < 0){ gl2psMsg(GL2PS_INFO, "OpenGL feedback buffer overflow"); return GL2PS_OVERFLOW; } if(used > 0) gl2psParseFeedbackBuffer(used); gl2psRescaleAndOffset(); if(gl2ps->header){ if(gl2psListNbr(gl2ps->primitives) && (gl2ps->options & GL2PS_TIGHT_BOUNDING_BOX)){ gl2ps->viewport[0] = gl2ps->viewport[1] = 100000; gl2ps->viewport[2] = gl2ps->viewport[3] = -100000; gl2psListAction(gl2ps->primitives, gl2psComputeTightBoundingBox); } (gl2psbackends[gl2ps->format]->printHeader)(); gl2ps->header = GL_FALSE; } if(!gl2psListNbr(gl2ps->primitives)){ /* empty feedback buffer and/or nothing else to print */ return GL2PS_NO_FEEDBACK; } switch(gl2ps->sort){ case GL2PS_NO_SORT : gl2psListAction(gl2ps->primitives, gl2psbackends[gl2ps->format]->printPrimitive); gl2psListAction(gl2ps->primitives, gl2psFreePrimitive); /* reset the primitive list, waiting for the next viewport */ gl2psListReset(gl2ps->primitives); break; case GL2PS_SIMPLE_SORT : gl2psListSort(gl2ps->primitives, gl2psCompareDepth); if(gl2ps->options & GL2PS_OCCLUSION_CULL){ gl2psListActionInverse(gl2ps->primitives, gl2psAddInImageTree); gl2psFreeBspImageTree(&gl2ps->imagetree); } gl2psListAction(gl2ps->primitives, gl2psbackends[gl2ps->format]->printPrimitive); gl2psListAction(gl2ps->primitives, gl2psFreePrimitive); /* reset the primitive list, waiting for the next viewport */ gl2psListReset(gl2ps->primitives); break; case GL2PS_BSP_SORT : root = (GL2PSbsptree*)gl2psMalloc(sizeof(GL2PSbsptree)); gl2psBuildBspTree(root, gl2ps->primitives); if(GL_TRUE == gl2ps->boundary) gl2psBuildPolygonBoundary(root); if(gl2ps->options & GL2PS_OCCLUSION_CULL){ gl2psTraverseBspTree(root, eye, -GL2PS_EPSILON, gl2psLess, gl2psAddInImageTree, 1); gl2psFreeBspImageTree(&gl2ps->imagetree); } gl2psTraverseBspTree(root, eye, GL2PS_EPSILON, gl2psGreater, gl2psbackends[gl2ps->format]->printPrimitive, 0); gl2psFreeBspTree(&root); /* reallocate the primitive list (it's been deleted by gl2psBuildBspTree) in case there is another viewport */ gl2ps->primitives = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*)); break; } gl2psbackends[gl2ps->format]->printFinalPrimitive(); return GL2PS_SUCCESS; } static GLboolean gl2psCheckOptions(GLint options, GLint colormode) { if (options & GL2PS_NO_OPENGL_CONTEXT) { if (options & GL2PS_DRAW_BACKGROUND) { gl2psMsg(GL2PS_ERROR, "Options GL2PS_NO_OPENGL_CONTEXT and " "GL2PS_DRAW_BACKGROUND are incompatible."); return GL_FALSE; } if (options & GL2PS_USE_CURRENT_VIEWPORT) { gl2psMsg(GL2PS_ERROR, "Options GL2PS_NO_OPENGL_CONTEXT and " "GL2PS_USE_CURRENT_VIEWPORT are incompatible."); return GL_FALSE; } if ((options & GL2PS_NO_BLENDING) == GL2PS_NONE) { gl2psMsg(GL2PS_ERROR, "Option GL2PS_NO_OPENGL_CONTEXT requires " "option GL2PS_NO_BLENDING."); return GL_FALSE; } if (colormode != GL_RGBA) { gl2psMsg(GL2PS_ERROR, "Option GL2PS_NO_OPENGL_CONTEXT requires colormode " "to be GL_RGBA."); return GL_FALSE; } } return GL_TRUE; } /********************************************************************* * * Public routines * *********************************************************************/ GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer, GLint viewport[4], GLint format, GLint sort, GLint options, GLint colormode, GLint colorsize, GL2PSrgba *colormap, GLint nr, GLint ng, GLint nb, GLint buffersize, FILE *stream, const char *filename) { GLint idx; int i; if(gl2ps){ gl2psMsg(GL2PS_ERROR, "gl2psBeginPage called in wrong program state"); return GL2PS_ERROR; } gl2ps = (GL2PScontext*)gl2psMalloc(sizeof(GL2PScontext)); /* Validate options */ if (gl2psCheckOptions(options, colormode) == GL_FALSE) { gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } if(format >= 0 && format < (GLint)(sizeof(gl2psbackends) / sizeof(gl2psbackends[0]))){ gl2ps->format = format; } else { gl2psMsg(GL2PS_ERROR, "Unknown output format: %d", format); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } switch(sort){ case GL2PS_NO_SORT : case GL2PS_SIMPLE_SORT : case GL2PS_BSP_SORT : gl2ps->sort = sort; break; default : gl2psMsg(GL2PS_ERROR, "Unknown sorting algorithm: %d", sort); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } if(stream){ gl2ps->stream = stream; } else{ gl2psMsg(GL2PS_ERROR, "Bad file pointer"); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } gl2ps->header = GL_TRUE; gl2ps->forcerasterpos = GL_FALSE; gl2ps->maxbestroot = 10; gl2ps->options = options; gl2ps->compress = NULL; gl2ps->imagemap_head = NULL; gl2ps->imagemap_tail = NULL; if(gl2ps->options & GL2PS_USE_CURRENT_VIEWPORT){ glGetIntegerv(GL_VIEWPORT, gl2ps->viewport); } else{ for(i = 0; i < 4; i++){ gl2ps->viewport[i] = viewport[i]; } } if(!gl2ps->viewport[2] || !gl2ps->viewport[3]){ gl2psMsg(GL2PS_ERROR, "Incorrect viewport (x=%d, y=%d, width=%d, height=%d)", gl2ps->viewport[0], gl2ps->viewport[1], gl2ps->viewport[2], gl2ps->viewport[3]); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } gl2ps->threshold[0] = nr ? 1.0F / (GLfloat)nr : 0.064F; gl2ps->threshold[1] = ng ? 1.0F / (GLfloat)ng : 0.034F; gl2ps->threshold[2] = nb ? 1.0F / (GLfloat)nb : 0.100F; gl2ps->colormode = colormode; gl2ps->buffersize = buffersize > 0 ? buffersize : 2048 * 2048; for(i = 0; i < 3; i++){ gl2ps->lastvertex.xyz[i] = -1.0F; } for(i = 0; i < 4; i++){ gl2ps->lastvertex.rgba[i] = -1.0F; gl2ps->lastrgba[i] = -1.0F; } gl2ps->lastlinewidth = -1.0F; gl2ps->lastlinecap = 0; gl2ps->lastlinejoin = 0; gl2ps->lastpattern = 0; gl2ps->lastfactor = 0; gl2ps->imagetree = NULL; gl2ps->primitivetoadd = NULL; gl2ps->zerosurfacearea = GL_FALSE; gl2ps->pdfprimlist = NULL; gl2ps->pdfgrouplist = NULL; gl2ps->xreflist = NULL; /* get default blending mode from current OpenGL state (enabled by default for SVG) */ if ((gl2ps->options & GL2PS_NO_BLENDING) == GL2PS_NONE) { gl2ps->blending = (gl2ps->format == GL2PS_SVG) ? GL_TRUE : glIsEnabled(GL_BLEND); glGetIntegerv(GL_BLEND_SRC, &gl2ps->blendfunc[0]); glGetIntegerv(GL_BLEND_DST, &gl2ps->blendfunc[1]); } else { gl2ps->blending = GL_FALSE; } if(gl2ps->colormode == GL_RGBA){ gl2ps->colorsize = 0; gl2ps->colormap = NULL; if ((gl2ps->options & GL2PS_NO_OPENGL_CONTEXT) == GL2PS_NONE) { glGetFloatv(GL_COLOR_CLEAR_VALUE, gl2ps->bgcolor); } } else if(gl2ps->colormode == GL_COLOR_INDEX){ if(!colorsize || !colormap){ gl2psMsg(GL2PS_ERROR, "Missing colormap for GL_COLOR_INDEX rendering"); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } gl2ps->colorsize = colorsize; gl2ps->colormap = (GL2PSrgba*)gl2psMalloc(gl2ps->colorsize * sizeof(GL2PSrgba)); memcpy(gl2ps->colormap, colormap, gl2ps->colorsize * sizeof(GL2PSrgba)); glGetIntegerv(GL_INDEX_CLEAR_VALUE, &idx); gl2ps->bgcolor[0] = gl2ps->colormap[idx][0]; gl2ps->bgcolor[1] = gl2ps->colormap[idx][1]; gl2ps->bgcolor[2] = gl2ps->colormap[idx][2]; gl2ps->bgcolor[3] = 1.0F; } else{ gl2psMsg(GL2PS_ERROR, "Unknown color mode in gl2psBeginPage"); gl2psFree(gl2ps); gl2ps = NULL; return GL2PS_ERROR; } if(!title){ gl2ps->title = (char*)gl2psMalloc(sizeof(char)); gl2ps->title[0] = '\0'; } else{ gl2ps->title = (char*)gl2psMalloc((strlen(title)+1)*sizeof(char)); strcpy(gl2ps->title, title); } if(!producer){ gl2ps->producer = (char*)gl2psMalloc(sizeof(char)); gl2ps->producer[0] = '\0'; } else{ gl2ps->producer = (char*)gl2psMalloc((strlen(producer)+1)*sizeof(char)); strcpy(gl2ps->producer, producer); } if(!filename){ gl2ps->filename = (char*)gl2psMalloc(sizeof(char)); gl2ps->filename[0] = '\0'; } else{ gl2ps->filename = (char*)gl2psMalloc((strlen(filename)+1)*sizeof(char)); strcpy(gl2ps->filename, filename); } gl2ps->primitives = gl2psListCreate(500, 500, sizeof(GL2PSprimitive*)); gl2ps->auxprimitives = gl2psListCreate(100, 100, sizeof(GL2PSprimitive*)); if ((gl2ps->options & GL2PS_NO_OPENGL_CONTEXT) == GL2PS_NONE) { gl2ps->feedback = (GLfloat*)gl2psMalloc(gl2ps->buffersize * sizeof(GLfloat)); glFeedbackBuffer(gl2ps->buffersize, GL_3D_COLOR, gl2ps->feedback); glRenderMode(GL_FEEDBACK); } else { gl2ps->feedback = NULL; gl2ps->buffersize = 0; } return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psEndPage(void) { GLint res; if(!gl2ps) return GL2PS_UNINITIALIZED; res = gl2psPrintPrimitives(); if(res != GL2PS_OVERFLOW) (gl2psbackends[gl2ps->format]->printFooter)(); fflush(gl2ps->stream); gl2psListDelete(gl2ps->primitives); gl2psListDelete(gl2ps->auxprimitives); gl2psFreeImagemap(gl2ps->imagemap_head); gl2psFree(gl2ps->colormap); gl2psFree(gl2ps->title); gl2psFree(gl2ps->producer); gl2psFree(gl2ps->filename); gl2psFree(gl2ps->feedback); gl2psFree(gl2ps); gl2ps = NULL; return res; } GL2PSDLL_API GLint gl2psBeginViewport(GLint viewport[4]) { if(!gl2ps) return GL2PS_UNINITIALIZED; (gl2psbackends[gl2ps->format]->beginViewport)(viewport); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psEndViewport(void) { GLint res; if(!gl2ps) return GL2PS_UNINITIALIZED; res = (gl2psbackends[gl2ps->format]->endViewport)(); /* reset last used colors, line widths */ gl2psResetLineProperties(); return res; } GL2PSDLL_API GLint gl2psTextOptColor(const char *str, const char *fontname, GLshort fontsize, GLint alignment, GLfloat angle, GL2PSrgba color) { return gl2psAddText(GL2PS_TEXT, str, fontname, fontsize, alignment, angle, color); } GL2PSDLL_API GLint gl2psTextOpt(const char *str, const char *fontname, GLshort fontsize, GLint alignment, GLfloat angle) { return gl2psAddText(GL2PS_TEXT, str, fontname, fontsize, alignment, angle, NULL); } GL2PSDLL_API GLint gl2psText(const char *str, const char *fontname, GLshort fontsize) { return gl2psAddText(GL2PS_TEXT, str, fontname, fontsize, GL2PS_TEXT_BL, 0.0F, NULL); } GL2PSDLL_API GLint gl2psSpecial(GLint format, const char *str) { return gl2psAddText(GL2PS_SPECIAL, str, "", 0, format, 0.0F, NULL); } GL2PSDLL_API GLint gl2psSpecialColor(GLint format, const char *str, GL2PSrgba rgba) { return gl2psAddText(GL2PS_SPECIAL, str, "", 0, format, 0.0F, rgba); } GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height, GLint xorig, GLint yorig, GLenum format, GLenum type, const void *pixels) { int size, i; const GLfloat *piv; GLfloat pos[4], zoom_x, zoom_y; GL2PSprimitive *prim; GLboolean valid; if(!gl2ps || !pixels) return GL2PS_UNINITIALIZED; if((width <= 0) || (height <= 0)) return GL2PS_ERROR; if(gl2ps->options & GL2PS_NO_PIXMAP) return GL2PS_SUCCESS; if((format != GL_RGB && format != GL_RGBA) || type != GL_FLOAT){ gl2psMsg(GL2PS_ERROR, "gl2psDrawPixels only implemented for " "GL_RGB/GL_RGBA, GL_FLOAT pixels"); return GL2PS_ERROR; } if (gl2ps->forcerasterpos) { pos[0] = gl2ps->rasterpos.xyz[0]; pos[1] = gl2ps->rasterpos.xyz[1]; pos[2] = gl2ps->rasterpos.xyz[2]; pos[3] = 1.f; /* Hardcode zoom factors (for now?) */ zoom_x = 1.f; zoom_y = 1.f; } else { glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid); if(GL_FALSE == valid) return GL2PS_SUCCESS; /* the primitive is culled */ glGetFloatv(GL_CURRENT_RASTER_POSITION, pos); glGetFloatv(GL_ZOOM_X, &zoom_x); glGetFloatv(GL_ZOOM_Y, &zoom_y); } prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); prim->type = GL2PS_PIXMAP; prim->boundary = 0; prim->numverts = 1; prim->verts = (GL2PSvertex*)gl2psMalloc(sizeof(GL2PSvertex)); prim->verts[0].xyz[0] = pos[0] + xorig; prim->verts[0].xyz[1] = pos[1] + yorig; prim->verts[0].xyz[2] = pos[2]; prim->culled = 0; prim->offset = 0; prim->ofactor = 0.0; prim->ounits = 0.0; prim->pattern = 0; prim->factor = 0; prim->width = 1; if (gl2ps->forcerasterpos) { prim->verts[0].rgba[0] = gl2ps->rasterpos.rgba[0]; prim->verts[0].rgba[1] = gl2ps->rasterpos.rgba[1]; prim->verts[0].rgba[2] = gl2ps->rasterpos.rgba[2]; prim->verts[0].rgba[3] = gl2ps->rasterpos.rgba[3]; } else { glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba); } prim->data.image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage)); prim->data.image->width = width; prim->data.image->height = height; prim->data.image->zoom_x = zoom_x; prim->data.image->zoom_y = zoom_y; prim->data.image->format = format; prim->data.image->type = type; gl2ps->forcerasterpos = GL_FALSE; switch(format){ case GL_RGBA: if(gl2ps->options & GL2PS_NO_BLENDING || !gl2ps->blending){ /* special case: blending turned off */ prim->data.image->format = GL_RGB; size = height * width * 3; prim->data.image->pixels = (GLfloat*)gl2psMalloc(size * sizeof(GLfloat)); piv = (const GLfloat*)pixels; for(i = 0; i < size; ++i, ++piv){ prim->data.image->pixels[i] = *piv; if(!((i + 1) % 3)) ++piv; } } else{ size = height * width * 4; prim->data.image->pixels = (GLfloat*)gl2psMalloc(size * sizeof(GLfloat)); memcpy(prim->data.image->pixels, pixels, size * sizeof(GLfloat)); } break; case GL_RGB: default: size = height * width * 3; prim->data.image->pixels = (GLfloat*)gl2psMalloc(size * sizeof(GLfloat)); memcpy(prim->data.image->pixels, pixels, size * sizeof(GLfloat)); break; } /* If no OpenGL context, just add directly to primitives */ if ((gl2ps->options & GL2PS_NO_OPENGL_CONTEXT) == GL2PS_NONE) { gl2psListAdd(gl2ps->auxprimitives, &prim); glPassThrough(GL2PS_DRAW_PIXELS_TOKEN); } else { gl2psListAdd(gl2ps->primitives, &prim); } return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psDrawImageMap(GLsizei width, GLsizei height, const GLfloat position[3], const unsigned char *imagemap){ int size, i; int sizeoffloat = sizeof(GLfloat); if(!gl2ps || !imagemap) return GL2PS_UNINITIALIZED; if((width <= 0) || (height <= 0)) return GL2PS_ERROR; size = height + height * ((width - 1) / 8); glPassThrough(GL2PS_IMAGEMAP_TOKEN); glBegin(GL_POINTS); glVertex3f(position[0], position[1],position[2]); glEnd(); glPassThrough((GLfloat)width); glPassThrough((GLfloat)height); for(i = 0; i < size; i += sizeoffloat){ const float *value = (const float*)imagemap; glPassThrough(*value); imagemap += sizeoffloat; } return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psEnable(GLint mode) { GLint tmp; GLfloat tmp2; if(!gl2ps) return GL2PS_UNINITIALIZED; switch(mode){ case GL2PS_POLYGON_OFFSET_FILL : glPassThrough(GL2PS_BEGIN_OFFSET_TOKEN); glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &tmp2); glPassThrough(tmp2); glGetFloatv(GL_POLYGON_OFFSET_UNITS, &tmp2); glPassThrough(tmp2); break; case GL2PS_POLYGON_BOUNDARY : glPassThrough(GL2PS_BEGIN_BOUNDARY_TOKEN); break; case GL2PS_LINE_STIPPLE : glPassThrough(GL2PS_BEGIN_STIPPLE_TOKEN); glGetIntegerv(GL_LINE_STIPPLE_PATTERN, &tmp); glPassThrough((GLfloat)tmp); glGetIntegerv(GL_LINE_STIPPLE_REPEAT, &tmp); glPassThrough((GLfloat)tmp); break; case GL2PS_BLEND : glPassThrough(GL2PS_BEGIN_BLEND_TOKEN); break; default : gl2psMsg(GL2PS_WARNING, "Unknown mode in gl2psEnable: %d", mode); return GL2PS_WARNING; } return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psDisable(GLint mode) { if(!gl2ps) return GL2PS_UNINITIALIZED; switch(mode){ case GL2PS_POLYGON_OFFSET_FILL : glPassThrough(GL2PS_END_OFFSET_TOKEN); break; case GL2PS_POLYGON_BOUNDARY : glPassThrough(GL2PS_END_BOUNDARY_TOKEN); break; case GL2PS_LINE_STIPPLE : glPassThrough(GL2PS_END_STIPPLE_TOKEN); break; case GL2PS_BLEND : glPassThrough(GL2PS_END_BLEND_TOKEN); break; default : gl2psMsg(GL2PS_WARNING, "Unknown mode in gl2psDisable: %d", mode); return GL2PS_WARNING; } return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psPointSize(GLfloat value) { if(!gl2ps) return GL2PS_UNINITIALIZED; glPassThrough(GL2PS_POINT_SIZE_TOKEN); glPassThrough(value); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psLineCap(GLint value) { if(!gl2ps) return GL2PS_UNINITIALIZED; glPassThrough(GL2PS_LINE_CAP_TOKEN); glPassThrough(value); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psLineJoin(GLint value) { if(!gl2ps) return GL2PS_UNINITIALIZED; glPassThrough(GL2PS_LINE_JOIN_TOKEN); glPassThrough(value); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psLineWidth(GLfloat value) { if(!gl2ps) return GL2PS_UNINITIALIZED; glPassThrough(GL2PS_LINE_WIDTH_TOKEN); glPassThrough(value); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psBlendFunc(GLenum sfactor, GLenum dfactor) { if(!gl2ps) return GL2PS_UNINITIALIZED; if(GL_FALSE == gl2psSupportedBlendMode(sfactor, dfactor)) return GL2PS_WARNING; glPassThrough(GL2PS_SRC_BLEND_TOKEN); glPassThrough((GLfloat)sfactor); glPassThrough(GL2PS_DST_BLEND_TOKEN); glPassThrough((GLfloat)dfactor); return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psSetOptions(GLint options) { if(!gl2ps) return GL2PS_UNINITIALIZED; if(gl2psCheckOptions(options, gl2ps->colormode) == GL_FALSE) { return GL2PS_ERROR; } gl2ps->options = options; return GL2PS_SUCCESS; } GL2PSDLL_API GLint gl2psGetOptions(GLint *options) { if(!gl2ps) { *options = 0; return GL2PS_UNINITIALIZED; } *options = gl2ps->options; return GL2PS_SUCCESS; } GL2PSDLL_API const char *gl2psGetFileExtension(GLint format) { if(format >= 0 && format < (GLint)(sizeof(gl2psbackends) / sizeof(gl2psbackends[0]))) return gl2psbackends[format]->file_extension; else return "Unknown format"; } GL2PSDLL_API const char *gl2psGetFormatDescription(GLint format) { if(format >= 0 && format < (GLint)(sizeof(gl2psbackends) / sizeof(gl2psbackends[0]))) return gl2psbackends[format]->description; else return "Unknown format"; } GL2PSDLL_API GLint gl2psGetFileFormat() { return gl2ps->format; } GL2PSDLL_API GLint gl2psForceRasterPos(GL2PSvertex *vert) { if(!gl2ps) { return GL2PS_UNINITIALIZED; } gl2ps->forcerasterpos = GL_TRUE; gl2ps->rasterpos.xyz[0] = vert->xyz[0]; gl2ps->rasterpos.xyz[1] = vert->xyz[1]; gl2ps->rasterpos.xyz[2] = vert->xyz[2]; gl2ps->rasterpos.rgba[0] = vert->rgba[0]; gl2ps->rasterpos.rgba[1] = vert->rgba[1]; gl2ps->rasterpos.rgba[2] = vert->rgba[2]; gl2ps->rasterpos.rgba[3] = vert->rgba[3]; return GL2PS_SUCCESS; } #endif rgl/src/callbacks.cpp0000644000176200001440000001740614137472630014267 0ustar liggesusers#include "api.h" #include "rglview.h" #include "DeviceManager.h" using namespace rgl; namespace rgl { extern DeviceManager* deviceManager; } /* These defines are not in the installed version of R */ #include "R.h" #include #include static void userControl(void *userData, int mouseX, int mouseY) { SEXP fn = (SEXP)userData; if (fn) { // Rprintf("userControl called with mouseX=%d userData=%p\n", mouseX, userData); eval(PROTECT(lang3(fn, PROTECT(ScalarInteger(mouseX)), PROTECT(ScalarInteger(mouseY)))), R_GlobalEnv); UNPROTECT(3); } } static void userControlEnd(void *userData) { SEXP fn = (SEXP)userData; if (fn) { eval(PROTECT(lang1(fn)), R_GlobalEnv); UNPROTECT(1); } } static void userCleanup(void **userData) { for (int i=0; i<3; i++) { if (userData[i]) { R_ReleaseObject((SEXP)userData[i]); userData[i] = 0; } } } static void userWheel(void *wheelData, int dir) { SEXP fn = (SEXP)wheelData; eval(PROTECT(lang2(fn, PROTECT(ScalarInteger(dir)))), R_GlobalEnv); UNPROTECT(2); } SEXP rgl::rgl_setMouseCallbacks(SEXP button, SEXP begin, SEXP update, SEXP end, SEXP dev, SEXP sub) { Device* device; if (deviceManager && (device = deviceManager->getDevice(asInteger(dev)))) { RGLView* rglview = device->getRGLView(); void* userData[3] = {0, 0, 0}; userControlPtr beginCallback, updateCallback; userControlEndPtr endCallback; userCleanupPtr cleanupCallback; int b = asInteger(button); if (b < 0 || b > 4) error("button must be 1=left, 2=right, 3=middle, 4=wheel, or 0 for no button"); Scene* scene = rglview->getScene(); Subscene* subscene = scene->getSubscene(asInteger(sub)); if (!subscene) error("subscene not found"); subscene->getMouseCallbacks(b, &beginCallback, &updateCallback, &endCallback, &cleanupCallback, (void**)&userData); if (isFunction(begin)) { beginCallback = &userControl; userData[0] = (void*)begin; R_PreserveObject(begin); } else if (begin == R_NilValue) beginCallback = 0; else error("callback must be a function"); if (isFunction(update)) { updateCallback = &userControl; userData[1] = (void*)update; R_PreserveObject(update); } else if (update == R_NilValue) updateCallback = 0; else error("callback must be a function"); if (isFunction(end)) { endCallback = &userControlEnd; userData[2] = (void*)end; R_PreserveObject(end); } else if (end == R_NilValue) endCallback = 0; else error("callback must be a function"); rglview->captureLost(); // Rprintf("setting mouse callbacks\n"); subscene->setMouseCallbacks(b, beginCallback, updateCallback, endCallback, &userCleanup, userData); if (b == bnNOBUTTON) rglview->windowImpl->watchMouse(subscene->getRootSubscene()->mouseNeedsWatching()); } else error("rgl device is not open"); return R_NilValue; } SEXP rgl::rgl_getMouseCallbacks(SEXP button, SEXP dev, SEXP sub) { Device* device; if (deviceManager && (device = deviceManager->getDevice(asInteger(dev)))) { RGLView* rglview = device->getRGLView(); void* userData[3] = {0, 0, 0}; userControlPtr beginCallback, updateCallback; userControlEndPtr endCallback; userCleanupPtr cleanupCallback; int b = asInteger(button); if (b < 0 || b > 4) error("button must be 1=left, 2=right, 3=middle, 4=wheel, or 0 for no button"); Scene* scene = rglview->getScene(); Subscene* subscene = scene->getSubscene(asInteger(sub)); if (!subscene) error("subscene not found"); subscene->getMouseCallbacks(b, &beginCallback, &updateCallback, &endCallback, &cleanupCallback, (void**)&userData); SEXP result; PROTECT(result = allocVector(VECSXP, 3)); if (beginCallback == &userControl) SET_VECTOR_ELT(result, 0, (SEXP)userData[0]); if (updateCallback == &userControl) SET_VECTOR_ELT(result, 1, (SEXP)userData[1]); if (endCallback == &userControlEnd) SET_VECTOR_ELT(result, 2, (SEXP)userData[2]); UNPROTECT(1); return result; } else error("rgl device is not open"); return R_NilValue; } SEXP rgl::rgl_setWheelCallback(SEXP rotate, SEXP dev, SEXP sub) { Device* device; if (deviceManager && (device = deviceManager->getDevice(asInteger(dev)))) { RGLView* rglview = device->getRGLView(); void* wheelData = 0; userWheelPtr wheelCallback; if (isFunction(rotate)) { wheelCallback = &userWheel; wheelData = (void*)rotate; R_PreserveObject(rotate); } else if (rotate == R_NilValue) wheelCallback = 0; else error("callback must be a function"); Scene* scene = rglview->getScene(); Subscene* subscene = scene->getSubscene(asInteger(sub)); if (!subscene) error("subscene not found"); subscene->setWheelCallback(wheelCallback, wheelData); } else error("rgl device is not open"); return R_NilValue; } SEXP rgl::rgl_getWheelCallback(SEXP dev, SEXP sub) { Device* device; SEXP result = R_NilValue; if (deviceManager && (device = deviceManager->getDevice(asInteger(dev)))) { RGLView* rglview = device->getRGLView(); void* wheelData = 0; userWheelPtr wheelCallback; Scene* scene = rglview->getScene(); Subscene* subscene = scene->getSubscene(asInteger(sub)); if (!subscene) error("subscene not found"); subscene->getWheelCallback(&wheelCallback, (void**)&wheelData); if (wheelCallback == &userWheel) result = (SEXP)wheelData; } else error("rgl device is not open"); return result; } static void userAxis(void *axisData, int axis, int edge[3]) { SEXP fn = (SEXP)axisData; char margin[4] = " "; int i, j = 1; margin[0] = 'x' + axis; for (i = 0; i < 3 && j < 3; i++) { if (edge[i] == 1) margin[j++] = '+'; else if (edge[i] == -1) margin[j++] = '-'; } margin[j] = 0; // Rprintf("margin=%s\n", margin); eval(PROTECT(lang2(fn, PROTECT(ScalarString(mkChar(margin))))), R_GlobalEnv); UNPROTECT(2); } SEXP rgl::rgl_setAxisCallback(SEXP draw, SEXP dev, SEXP sub, SEXP axis) { Device* device; if (deviceManager && (device = deviceManager->getDevice(asInteger(dev)))) { RGLView* rglview = device->getRGLView(); void* axisData = 0; userAxisPtr axisCallback; if (isFunction(draw)) { axisCallback = &userAxis; axisData = (void*)draw; R_PreserveObject(draw); } else if (draw == R_NilValue) axisCallback = 0; else error("callback must be a function"); Scene* scene = rglview->getScene(); Subscene* subscene = scene->getSubscene(asInteger(sub)); if (!subscene) error("subscene not found"); BBoxDeco* bboxdeco = subscene->get_bboxdeco(); if (!bboxdeco) error("no bbox decoration"); int a = asInteger(axis); if (a < 0 || a > 2) error("axis must be 0=x, 1=y, or 2=z"); bboxdeco->setAxisCallback(axisCallback, axisData, a); rglview->update(); } else error("rgl device is not open"); return R_NilValue; } SEXP rgl::rgl_getAxisCallback(SEXP dev, SEXP sub, SEXP axis) { Device* device; SEXP result = R_NilValue; if (deviceManager && (device = deviceManager->getDevice(asInteger(dev)))) { RGLView* rglview = device->getRGLView(); void* axisData = 0; userAxisPtr axisCallback; Scene* scene = rglview->getScene(); Subscene* subscene = scene->getSubscene(asInteger(sub)); if (!subscene) error("subscene not found"); BBoxDeco* bboxdeco = subscene->get_bboxdeco(); if (!bboxdeco) error("bboxdeco not found"); bboxdeco->getAxisCallback(&axisCallback, (void**)&axisData, asInteger(axis)); if (axisCallback == &userAxis) result = (SEXP)axisData; } else error("rgl device is not open"); return result; } rgl/src/SpriteSet.h0000644000176200001440000000366614142256754013745 0ustar liggesusers#ifndef SPRITE_SET_H #define SPRITE_SET_H #include #include "Shape.h" #include "scene.h" namespace rgl { // // SPRITESET // class SpriteSet : public Shape { private: ARRAY vertex; ARRAY size; ARRAY pos; float offset; public: SpriteSet(Material& material, int nvertex, double* vertex, int nsize, double* size, int ignoreExtent, int count = 0, Shape** shapelist = NULL, double* userMatrix = NULL, bool fixedSize = false, Scene* scene = NULL, double* adj = NULL, int npos = 0, int* pos = NULL, double offset = 0.0); ~SpriteSet(); /** * overload **/ virtual void render(RenderContext* renderContext); virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "sprites", buflen); }; virtual int getElementCount(void); int getAttributeCount(AABox& bbox, AttribID attrib); void getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result); String getTextAttribute(AABox& bbox, AttribID attrib, int index); /** * location of individual items **/ virtual Vertex getPrimitiveCenter(int index); /** * begin sending items **/ virtual void drawBegin(RenderContext* renderContext); /** * send one item **/ virtual void drawPrimitive(RenderContext* renderContext, int index); /** * end sending items **/ virtual void drawEnd(RenderContext* renderContext); /** * extract individual shape */ virtual Shape* get_shape(int id); /** * delete a shape */ void remove_shape(int id); private: GLdouble userMatrix[16]; /* Transformation for 3D sprites */ Matrix4x4 m; /* Modelview matrix cache */ Matrix4x4 p; /* Projection matrix cache */ #ifndef RGL_NO_OPENGL bool doTex; #endif std::vector shapes; bool fixedSize; Scene* scene; Vec3 adj; void getAdj(int index); }; } // namespace rgl #endif // SPRITE_SET_H rgl/src/assert.cpp0000644000176200001440000000035114100762641013632 0ustar liggesusers#include "R.h" #include "assert.h" void rgl_assert (const char* assertion, const char* file, int line) { error("Assertion failure: %s\nFile: %s\nLine: %d\nPlease report to rgl maintainer.", assertion, file, line); } rgl/src/render.cpp0000644000176200001440000000704114133075552013617 0ustar liggesusers#include "render.h" #include "opengl.h" #include "R.h" using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // SECTION: MATERIAL // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // CLASS // VertexArray // VertexArray::VertexArray() { arrayptr = NULL; } VertexArray::~VertexArray() { if (arrayptr) delete[] arrayptr; } void VertexArray::alloc(int in_nvertex) { if (arrayptr) { delete[] arrayptr; arrayptr = NULL; } nvertex = in_nvertex; if (nvertex) arrayptr = new float [nvertex*3]; } void VertexArray::copy(int in_nvertex, double* vertices) { if (in_nvertex > nvertex) { warning("Only %d values copied", nvertex); in_nvertex = nvertex; } for(int i=0;i nvertex) { warning("Only %d values copied", nvertex); in_nvertex = nvertex; } for(int i=0;i namespace rgl { // // ABSTRACT CLASS // PrimitiveSet // class PrimitiveSet : public Shape { public: /** * overloaded **/ virtual void draw(RenderContext* renderContext); /** * overloaded **/ virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "primitive", buflen); } /** * overloaded **/ virtual int getElementCount(void) { return nprimitives; } int getAttributeCount(AABox& bbox, AttribID attrib); void getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result); /** * overloaded **/ virtual Vertex getPrimitiveCenter(int item) { return getCenter(item); } /** * begin sending primitives * interface **/ virtual void drawBegin(RenderContext* renderContext); /** * send primitive * interface **/ virtual void drawPrimitive(RenderContext* renderContext, int index); /** * end sending primitives * interface **/ virtual void drawEnd(RenderContext* renderContext); /** * set a vertex **/ const void setVertex(int index, double* v) { vertexArray.setVertex(index, v); } /** * setup all vertices **/ void initPrimitiveSet(int in_nvertices, double* in_vertices, int in_nindices = 0, int* in_indices = NULL); protected: /** * abstract class constructor **/ PrimitiveSet ( Material& in_material, int in_nvertices, double* vertex, int in_type, int in_nverticesperelement, bool in_ignoreExtent, int in_nindices, int* in_indices, bool in_bboxChange = false ); PrimitiveSet( Material& in_material, int in_type, int in_verticesperelement, bool in_ignoreExtent, bool in_bboxChange ); ~PrimitiveSet(); /** * get primitive center point **/ inline Vertex getCenter(int index) { Vertex accu; int begin = index*nverticesperelement; int end = begin+nverticesperelement; for (int i = begin ; i < end ; ++i ) { if (nindices) accu += vertexArray[indices[i]]; else accu += vertexArray[i]; } return accu * ( 1.0f / ( (float) nverticesperelement ) ); } // ---[ PRIMITIVE DRAW INTERFACE ]------------------------------------------ /** * send all elements * interface **/ virtual void drawAll(RenderContext* renderContext); void initPrimitiveSet ( int in_nvertices, double* vertex, int in_type, int in_nverticesperelement, bool in_ignoreExtent, bool in_bboxChange ); int type; int nverticesperelement; int nvertices; int nprimitives; VertexArray vertexArray, /* the vertices given by the user */ verticesTodraw; /* the margin vertices in data coords */ bool hasmissing; /* whether any vertices contain missing values */ int nindices; unsigned int* indices; }; // // ABSTRACT CLASS // FaceSet // class FaceSet : public PrimitiveSet { public: /** * overload **/ virtual void drawBegin(RenderContext* renderContext); /** * overload **/ virtual void drawEnd(RenderContext* renderContext); /** * overloaded **/ virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "faces", buflen); }; int getAttributeCount(AABox& bbox, AttribID attrib); void getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result); protected: /** * Constructor **/ FaceSet( Material& in_material, int in_nvertex, double* in_vertex, double* in_normals, double* in_texcoords, int in_type, int in_nverticesperelement, bool in_ignoreExtent, int in_nindices, int* in_indices, int in_useNormals, int in_useTexcoords, bool in_bboxChange = false ); FaceSet( Material& in_material, int in_type, int in_verticesperelement, bool in_ignoreExtent, bool in_bboxChange = false ); /* (re-)set mesh */ void initFaceSet(int in_nvertex, double* in_vertex, double* in_normals, double* in_texcoords); /* set up normals */ void initNormals(double* in_normals); private: NormalArray normalArray, normalsToDraw; TexCoordArray texCoordArray; }; // // CLASS // PointSet // class PointSet : public PrimitiveSet { public: PointSet(Material& material, int nvertices, double* vertices, bool in_ignoreExtent, int nindices, int* indices, bool bboxChange=false ); /** * overloaded **/ virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "points", buflen); }; }; // // CLASS // LineSet // class LineSet : public PrimitiveSet { public: LineSet(Material& material, int nvertices, double* vertices, bool in_ignoreExtent, int in_nindices, int* in_indices, bool in_bboxChange=false); LineSet(Material& in_material, bool in_ignoreExtent, bool in_bboxChange); /** * overloaded **/ virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "lines", buflen); }; }; // // CLASS // TriangleSet // class TriangleSet : public FaceSet { public: TriangleSet(Material& in_material, int in_nvertex, double* in_vertex, double* in_normals, double* in_texcoords, bool in_ignoreExtent, int in_nindices, int* in_indices, int in_useNormals, int in_useTexcoords, bool in_bboxChange = false) : FaceSet(in_material,in_nvertex, in_vertex, in_normals, in_texcoords, GL_TRIANGLES, 3, in_ignoreExtent, in_nindices, in_indices, in_useNormals, in_useTexcoords, in_bboxChange) { } TriangleSet(Material& in_material, bool in_ignoreExtent, bool in_bboxChange) : FaceSet(in_material, GL_TRIANGLES, 3, in_ignoreExtent, in_bboxChange) { } /** * overloaded **/ virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "triangles", buflen); }; }; // // CLASS // QuadSet // class QuadSet : public FaceSet { public: QuadSet(Material& in_material, int in_nvertex, double* in_vertex, double* in_normals, double* in_texcoords, bool in_ignoreExtent, int in_nindices, int* in_indices, int in_useNormals, int in_useTexcoords) : FaceSet(in_material,in_nvertex,in_vertex, in_normals, in_texcoords, GL_QUADS, 4, in_ignoreExtent, in_nindices, in_indices, in_useNormals, in_useTexcoords) { } /** * overloaded **/ virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "quads", buflen); }; }; // // CLASS // LineStripSet // class LineStripSet : public PrimitiveSet { public: LineStripSet(Material& material, int in_nvertex, double* in_vertex, bool in_ignoreExtent, int in_nindices, int* in_indices, bool in_bboxChange = false); void drawPrimitive(RenderContext* renderContext, int index); /** * overloaded **/ virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "linestrip", buflen); }; }; } // namespace rgl #endif // PRIMITIVE_SET_H rgl/src/Viewpoint.h0000644000176200001440000000463614100762641013774 0ustar liggesusers#ifndef VIEWPOINT_H #define VIEWPOINT_H #include "SceneNode.h" #include "render.h" #include "geom.h" namespace rgl { class ModelViewpoint : public SceneNode { #define VIEWPOINT_MAX_ZOOM 10 public: ModelViewpoint(PolarCoord position=PolarCoord(0.0f,15.0f), Vec3 in_scale=Vec3(1.0f, 1.0f, 1.0f), bool interactive=true); ModelViewpoint(double* userMatrix, Vec3 in_scale=Vec3(1.0f, 1.0f, 1.0f), bool interactive=true); PolarCoord& getPosition(); void setPosition(const PolarCoord& position); void clearMouseMatrix(); void setupTransformation(RenderContext* rctx, Vertex center); void setupOrientation(RenderContext* rctx) const; bool isInteractive() const; void updateMouseMatrix(Vertex dragStart,Vertex dragCurrent); void updateMouseMatrix(PolarCoord newpos); void mouseOneAxis(Vertex dragStart,Vertex dragCurrent,Vertex axis); void mergeMouseMatrix(); void getUserMatrix(double* dest); void setUserMatrix(double* src); void getScale(double* dest); void setScale(double* src); void getPosition(double* dest); void setPosition(double* src); virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "modelviewpoint", buflen); }; Vertex scale; bool scaleChanged; private: PolarCoord position; bool interactive; public: GLdouble userMatrix[16], mouseMatrix[16]; }; class UserViewpoint : public SceneNode { #define VIEWPOINT_MAX_ZOOM 10 public: UserViewpoint(float fov=90.0f, float zoom=1.0f); float getZoom(void) const; void setZoom(const float zoom); float getFOV(void) const; void setFOV(const float in_fov); void setupFrustum(RenderContext* rctx, const Sphere& viewvolumeSphere); void setupProjMatrix(RenderContext* rctx, const Sphere& viewvolumeSphere); Vertex getObserver(); void setObserver(bool automatic, Vertex in_eye); void setupViewer(RenderContext* rctx); virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "userviewpoint", buflen); }; Frustum frustum; void getUserProjection(double* dest); void setUserProjection(double* src); void clearUserProjection(); private: float fov; float zoom; bool viewerInScene; Vertex eye; Matrix4x4 userProjection; }; } // namespace rgl #endif // VIEWPOINT_H rgl/src/PlaneSet.cpp0000644000176200001440000001431014100762641014044 0ustar liggesusers#include #include "PlaneSet.h" #include "Viewpoint.h" #include "R.h" using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // PlaneSet // PlaneSet::PlaneSet(Material& in_material, int in_nnormal, double* in_normal, int in_noffset, double* in_offset) : TriangleSet(in_material,true, false/* true */), nPlanes(max(in_nnormal, in_noffset)), normal(in_nnormal, in_normal), offset(in_noffset, in_offset) { /* We'll set up 4 triangles per plane, in case we need to render a hexagon. Each triangle has 3 vertices (so 12 for the plane), and each vertex gets 3 color components and 1 alpha component. */ ARRAY colors(36*nPlanes); ARRAY alphas(12*nPlanes); if (material.colors.getLength() > 1) { material.colors.recycle(nPlanes); for (int i=0; i vertices(36*nPlanes), normals(36*nPlanes); for (int i=0; igetBoundingBox()); return TriangleSet::getBoundingBox(subscene); } void PlaneSet::renderBegin(RenderContext* renderContext) { updateTriangles(renderContext->subscene->getBoundingBox()); invalidateDisplaylist(); TriangleSet::renderBegin(renderContext); } void PlaneSet::updateTriangles(const AABox& sceneBBox) { int perms[3][3] = { {0,0,1}, {1,2,2}, {2,1,0} }; double bbox[2][3] = { {sceneBBox.vmin.x, sceneBBox.vmin.y, sceneBBox.vmin.z}, {sceneBBox.vmax.x, sceneBBox.vmax.y, sceneBBox.vmax.z} }; double x[12][3]; for (int elem = 0; elem < nPlanes; elem++) { Vertex Av = normal.getRecycled(elem); double A[3] = { Av.x, Av.y, Av.z }; double d = offset.getRecycled(elem); int nhits = 0; int face1[12], face2[12]; /* to identify which faces of the cube we're on */ /* Find intersection of bbox edges with plane. Problem: * there might be 3 edges all intersecting the plane * at the same place, i.e. a vertex of the bbox. Need * to fix this case. */ for (int i=0; i<3; i++) for (int j=0; j<2; j++) for (int k=0; k<2; k++) { int u=perms[0][i], v=perms[1][i], w=perms[2][i]; if (A[w] != 0.0) { double intersect = -(d + A[u]*bbox[j][u] + A[v]*bbox[k][v])/A[w]; if (bbox[0][w] <= intersect && intersect <= bbox[1][w]) { x[nhits][u] = bbox[j][u]; x[nhits][v] = bbox[k][v]; x[nhits][w] = intersect; /* Check for duplicate */ int dup = 0; for (int l=0; l < nhits; l++) { if (abs(x[l][0] - x[nhits][0]) <= 1.e-8*abs(x[l][0]) && abs(x[l][1] - x[nhits][1]) <= 1.e-8*abs(x[l][1]) && abs(x[l][2] - x[nhits][2]) <= 1.e-8*abs(x[l][2])) { dup = 1; break; } } if (!dup) { face1[nhits] = j + 2*u; face2[nhits] = k + 2*v; nhits++; } } } } if (nhits > 3) { /* Re-order the intersections so the triangles work */ for (int i=0; i i+1) { for (int j=0; j<3; j++) swap(x[i+1][j], x[which][j]); swap(face1[i+1], face1[which]); swap(face2[i+1], face2[which]); } } } if (nhits >= 3) { /* Put in order so that the normal points out the FRONT of the faces */ Vec3 v0(static_cast(x[0][0] - x[1][0]), static_cast(x[0][1] - x[1][1]), static_cast(x[0][2] - x[1][2])), v2(static_cast(x[2][0] - x[1][0]), static_cast(x[2][1] - x[1][1]), static_cast(x[2][2] - x[1][2])), vx = v0.cross(v2); bool reverse = vx*Av > 0; for (int i=0; i #include #include "lib.h" #include "DeviceManager.h" #include "init.h" #include "api.h" /* libfreetype 2.6 defines a conflicting TYPEOF macro */ #ifdef TYPEOF # undef TYPEOF #endif #include #include #include "R.h" using namespace rgl; // // FUNCTION // rgl_init // // // GLOBAL: deviceManager pointer // namespace rgl{ DeviceManager* deviceManager = NULL; int gInitValue; void* gHandle; SEXP rglNamespace; bool rglDebug; // // FUNCTION // rgl_init // // PARAMETERS // ioptions - platform-specific options. // Windows: // [0] multiple-document-interface console handle (MDI) // or 0 (SDI) // MacOSX: // [0] Formerly indicator of presence (1) or absence (0) of Carbon/Cocoa, now unused // #ifdef __cplusplus extern "C" { #endif SEXP rgl_init(SEXP initValue, SEXP useNULL, SEXP in_namespace, SEXP debug) { int success = 0; bool useNULLDevice = asLogical(useNULL); gInitValue = 0; gHandle = NULL; rglNamespace = in_namespace; rglDebug = asLogical(debug); if ( isNumeric(initValue) ) { gInitValue = asInteger(initValue); } else if ( TYPEOF(initValue) == EXTPTRSXP ) { gHandle = R_ExternalPtrAddr(initValue); } else if ( !isNull(initValue) ) { return ScalarInteger( 0 ); } /* Some systems write useless messages to stderr. We'll * hide those */ int stderr_copy = STDERR_FILENO; /* suppress "maybe undefined" warning */ if (!rglDebug) { int devNull = #ifdef windows open("nul", O_WRONLY); #else open("/dev/null", O_WRONLY); #endif R_FlushConsole(); stderr_copy = dup(STDERR_FILENO); dup2(devNull, STDERR_FILENO); } if ( init(useNULLDevice) ) { deviceManager = new DeviceManager(useNULLDevice); } if ( deviceManager && (useNULLDevice || deviceManager->createTestWindow())) success = 1; /* Restore STDERR */ if (!rglDebug) { dup2(stderr_copy, STDERR_FILENO); close(stderr_copy); } return(ScalarInteger(success)); } #define FUNDEF(name, n) {#name, (DL_FUNC) &name, n} #undef CHECK_ARGS #ifdef CHECK_ARGS R_NativePrimitiveArgType aI[1] = {INTSXP}; R_NativePrimitiveArgType aL[1] = {LGLSXP}; R_NativePrimitiveArgType aII[2] = {INTSXP, INTSXP}; R_NativePrimitiveArgType aLI[2] = {LGLSXP, INTSXP}; R_NativePrimitiveArgType aLL[2] = {LGLSXP, LGLSXP}; R_NativePrimitiveArgType aIII[3] = {INTSXP, INTSXP, INTSXP}; R_NativePrimitiveArgType aIIS[3] = {INTSXP, INTSXP, STRSXP}; R_NativePrimitiveArgType aIID[3] = {INTSXP, INTSXP, REALSXP}; R_NativePrimitiveArgType aLII[3] = {LGLSXP, INTSXP, INTSXP}; R_NativePrimitiveArgType aLIS[3] = {LGLSXP, INTSXP, STRSXP}; R_NativePrimitiveArgType aLID[3] = {LGLSXP, INTSXP, REALSXP}; R_NativePrimitiveArgType aIIDD[4] = {INTSXP, INTSXP, REALSXP, REALSXP}; R_NativePrimitiveArgType aLISD[4] = {LGLSXP, INTSXP, STRSXP, REALSXP}; R_NativePrimitiveArgType aIISI[4] = {INTSXP, INTSXP, STRSXP, INTSXP}; R_NativePrimitiveArgType aLIDD[4] = {LGLSXP, INTSXP, REALSXP, REALSXP}; R_NativePrimitiveArgType aIIIID[5] = {INTSXP, INTSXP, INTSXP, INTSXP, REALSXP}; R_NativePrimitiveArgType aIIIIS[5] = {INTSXP, INTSXP, INTSXP, INTSXP, STRSXP}; R_NativePrimitiveArgType aLIIIS[5] = {LGLSXP, INTSXP, INTSXP, INTSXP, STRSXP}; R_NativePrimitiveArgType aLIIID[5] = {LGLSXP, INTSXP, INTSXP, INTSXP, REALSXP}; R_NativePrimitiveArgType aLIISD[5] = {LGLSXP, INTSXP, INTSXP, STRSXP, REALSXP}; R_NativePrimitiveArgType aLIIDS[5] = {LGLSXP, INTSXP, INTSXP, REALSXP, STRSXP}; R_NativePrimitiveArgType aLIIIF[5] = {LGLSXP, INTSXP, INTSXP, INTSXP, SINGLESXP}; R_NativePrimitiveArgType aLIDDD[5] = {LGLSXP, INTSXP, REALSXP, REALSXP, REALSXP}; R_NativePrimitiveArgType aIIDDD[5] = {INTSXP, INTSXP, REALSXP, REALSXP, REALSXP}; R_NativePrimitiveArgType aIIDDID[6] = {INTSXP, INTSXP, REALSXP, REALSXP, INTSXP, REALSXP}; R_NativePrimitiveArgType aLIDDDDI[7] = {LGLSXP, INTSXP, REALSXP, REALSXP, REALSXP, REALSXP, INTSXP}; R_NativePrimitiveArgType aLIDDSDSDS[9] = {LGLSXP, INTSXP, REALSXP, REALSXP, STRSXP, REALSXP, STRSXP, REALSXP, STRSXP}; R_NativePrimitiveArgType aIIDSDISIDI[10] = {INTSXP, INTSXP, REALSXP, STRSXP, REALSXP, INTSXP, STRSXP, INTSXP, REALSXP, INTSXP}; R_NativePrimitiveArgType aIIDDDDDDDDIII[13] = {INTSXP, INTSXP, REALSXP, REALSXP, REALSXP, REALSXP, REALSXP, REALSXP, REALSXP, REALSXP, INTSXP, INTSXP, INTSXP}; static const R_CMethodDef CEntries[] = { {"rgl_dev_open", (DL_FUNC) &rgl_dev_open, 2, aLL}, {"rgl_dev_close", (DL_FUNC) &rgl_dev_close, 1, aL}, {"rgl_dev_setcurrent", (DL_FUNC) &rgl_dev_setcurrent, 2, aLI}, {"rgl_snapshot", (DL_FUNC) &rgl_snapshot, 3, aLIS}, {"rgl_postscript", (DL_FUNC) &rgl_postscript, 3, aLIS}, {"rgl_material", (DL_FUNC) &rgl_material, 4, aLISD}, {"rgl_getmaterial", (DL_FUNC) &rgl_getmaterial, 5, aLIISD}, {"rgl_getcolorcount", (DL_FUNC) &rgl_getcolorcount, 1, aI}, {"rgl_dev_bringtotop", (DL_FUNC) &rgl_dev_bringtotop, 2, aLL}, {"rgl_clear", (DL_FUNC) &rgl_clear, 2, aLI}, {"rgl_pop", (DL_FUNC) &rgl_pop, 2, aLI}, {"rgl_id_count", (DL_FUNC) &rgl_id_count, 3, aIII}, {"rgl_ids", (DL_FUNC) &rgl_ids, 4, aIISI}, {"rgl_viewpoint", (DL_FUNC) &rgl_viewpoint, 3, aLID}, {"rgl_getObserver", (DL_FUNC) &rgl_getObserver, 2, aID}, {"rgl_setObserver", (DL_FUNC) &rgl_setObserver, 2, aID}, {"rgl_attrib_count", (DL_FUNC) &rgl_attrib_count, 3, aIII}, {"rgl_attrib", (DL_FUNC) &rgl_attrib, 5, aIIIID}, {"rgl_text_attrib", (DL_FUNC) &rgl_text_attrib, 5, aIIIIS}, {"rgl_bg", (DL_FUNC) &rgl_bg, 3, aLID}, {"rgl_bbox", (DL_FUNC) &rgl_bbox, 9, aLIDDSDSDS}, {"rgl_light", (DL_FUNC) &rgl_light, 3, aIID}, {"rgl_pixels", (DL_FUNC) &rgl_pixels, 5, aLIIIF}, {"rgl_planes", (DL_FUNC) &rgl_planes, 4, aIIDD}, {"rgl_clipplanes", (DL_FUNC) &rgl_planes, 4, aIIDD}, {"rgl_abclines", (DL_FUNC) &rgl_abclines, 4, aIIDD}, {"rgl_primitive", (DL_FUNC) &rgl_primitive, 5, aIIDDD}, {"rgl_surface", (DL_FUNC) &rgl_surface, 13, aIIDDDDDDDDIII}, {"rgl_spheres", (DL_FUNC) &rgl_spheres, 5, aIIDDI}, {"rgl_texts", (DL_FUNC) &rgl_texts, 12, aIIDSDISIDIII}, {"rgl_sprites", (DL_FUNC) &rgl_sprites, 9, aIIDDIDDID}, {"rgl_newsubscene", (DL_FUNC) &rgl_newsubscene, 4, aIIII}, {"rgl_setsubscene", (DL_FUNC) &rgl_setsubscene, 1, aI}, {"rgl_getsubsceneid", (DL_FUNC) &rgl_getsubsceneid, 2, aII}, {"rgl_getsubsceneparent", (DL_FUNC) &rgl_getsubsceneparent, 1, aI}, {"rgl_getsubscenechildcount",(DL_FUNC) &rgl_getsubscenechildcount, 2, aII}, {"rgl_getsubscenechildren", (DL_FUNC) &rgl_getsubscenechildren, 2, aII}, {"rgl_gc", (DL_FUNC) &rgl_gc, 2, aII}, {"rgl_setEmbeddings", (DL_FUNC) &rgl_setEmbeddings, 2, aII}, {"rgl_getEmbeddings", (DL_FUNC) &rgl_getEmbeddings, 2, aII}, {"rgl_addtosubscene", (DL_FUNC) &rgl_addtosubscene, 3, aIII}, {"rgl_delfromsubscene", (DL_FUNC) &rgl_delfromsubscene, 3, aIII}, {"rgl_selectstate", (DL_FUNC) &rgl_selectstate, 5, aIILID}, {"rgl_setselectstate", (DL_FUNC) &rgl_setselectstate, 4, aIILI}, {"rgl_quit", (DL_FUNC) &rgl_quit, 1, aL}, {NULL, NULL, 0} }; #else // don't CHECK_ARGS static const R_CMethodDef CEntries[] = { FUNDEF(rgl_dev_open, 2), FUNDEF(rgl_dev_close, 1), FUNDEF(rgl_dev_setcurrent, 2), FUNDEF(rgl_snapshot, 3), FUNDEF(rgl_postscript, 3), FUNDEF(rgl_material, 4), FUNDEF(rgl_getmaterial, 5), FUNDEF(rgl_getcolorcount, 1), FUNDEF(rgl_dev_bringtotop, 2), FUNDEF(rgl_clear, 2), FUNDEF(rgl_pop, 2), FUNDEF(rgl_id_count, 3), FUNDEF(rgl_ids, 4), FUNDEF(rgl_viewpoint, 3), FUNDEF(rgl_getObserver, 2), FUNDEF(rgl_setObserver, 2), FUNDEF(rgl_attrib_count, 3), FUNDEF(rgl_attrib, 5), FUNDEF(rgl_text_attrib, 5), FUNDEF(rgl_bg, 3), FUNDEF(rgl_bbox, 9), FUNDEF(rgl_light, 3), FUNDEF(rgl_pixels, 5), FUNDEF(rgl_planes, 4), FUNDEF(rgl_clipplanes, 4), FUNDEF(rgl_abclines, 4), FUNDEF(rgl_primitive, 5), FUNDEF(rgl_surface, 13), FUNDEF(rgl_spheres, 5), FUNDEF(rgl_texts, 12), FUNDEF(rgl_sprites, 9), FUNDEF(rgl_newsubscene, 4), FUNDEF(rgl_setsubscene, 1), FUNDEF(rgl_getsubsceneid, 2), FUNDEF(rgl_getsubsceneparent, 1), FUNDEF(rgl_getsubscenechildcount, 2), FUNDEF(rgl_getsubscenechildren, 2), FUNDEF(rgl_gc, 2), FUNDEF(rgl_setEmbeddings, 2), FUNDEF(rgl_getEmbeddings, 2), FUNDEF(rgl_addtosubscene, 3), FUNDEF(rgl_delfromsubscene, 3), FUNDEF(rgl_selectstate, 5), FUNDEF(rgl_setselectstate, 4), FUNDEF(rgl_quit, 1), {NULL, NULL, 0} }; #endif // CHECK_ARGS static const R_CallMethodDef CallEntries[] = { FUNDEF(rgl_init, 4), FUNDEF(rgl_dev_getcurrent, 0), FUNDEF(rgl_dev_list, 0), FUNDEF(rgl_par3d, 3), FUNDEF(rgl_setMouseCallbacks, 6), FUNDEF(rgl_setWheelCallback, 3), FUNDEF(rgl_setAxisCallback, 4), FUNDEF(rgl_getMouseCallbacks, 3), FUNDEF(rgl_getWheelCallback, 2), FUNDEF(rgl_getAxisCallback, 3), {NULL, NULL, 0} }; static const R_ExternalMethodDef ExtEntries[] = { {NULL, NULL, 0} }; void attribute_visible R_init_rgl(DllInfo *dll) { R_registerRoutines(dll, CEntries, CallEntries, NULL, ExtEntries); R_useDynamicSymbols(dll, FALSE); R_forceSymbols(dll, TRUE); } #ifdef __cplusplus } #endif // --------------------------------------------------------------------------- } // namespace rgl // --------------------------------------------------------------------------- rgl/src/PointSet.cpp0000644000176200001440000000102414145464133014100 0ustar liggesusers#include "PrimitiveSet.h" using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // PointSet // PointSet::PointSet(Material& in_material, int in_nvertices, double* in_vertices, bool in_ignoreExtent, int in_nindices, int* in_indices, bool in_bboxChange) : PrimitiveSet(in_material, in_nvertices, in_vertices, GL_POINTS, 1, in_ignoreExtent, in_nindices, in_indices) { material.lit = false; if (material.point_antialias) blended = true; } rgl/src/types.h0000644000176200001440000000562714100762641013155 0ustar liggesusers#ifndef RGL_TYPES_H #define RGL_TYPES_H #include #include "pragma.h" // C++ header file // This file is part of RGL // namespace rgl { // // // constants // // #ifndef NULL #define NULL 0UL #endif // // // fundamental data types // // typedef unsigned char u8; typedef long u32; // // memory management objects // class AutoDestroy { public: AutoDestroy() { refcount = 0; } virtual ~AutoDestroy() { } void ref() { refcount++; } void unref() { if ( !(--refcount) ) delete this; } private: int refcount; }; template class Ref { public: Ref() : ptr(NULL) { } Ref(T* in_ptr) : ptr(in_ptr) { if (ptr) ptr->ref(); } Ref(const Ref& ref) : ptr(ref.ptr) { if (ptr) ptr->ref(); } ~Ref() { if (ptr) ptr->unref(); } Ref& operator = (T* in_ptr) { if (ptr) ptr->unref(); ptr = in_ptr; if (ptr) ptr->ref(); return *this; } T* operator -> () { return ptr; } operator bool () { return (ptr) ? true : false; } private: T* ptr; }; // // CLASS // DestroyHandler // class DestroyHandler { public: virtual ~DestroyHandler(); virtual void notifyDestroy(void* userdata) = 0; }; // // mem copy // template inline void copy(A* from, B* to, int size) { memcpy( (void*) to, (const void*) from, size*sizeof(A) ); } // // TEMPLATE // ARRAY // template struct ARRAY { int _size; T* ptr; inline int size() { return _size; } inline ARRAY(int in_size) : _size(in_size), ptr(new T [_size]) { } template inline ARRAY(int in_size, SRC* src) : _size(in_size), ptr(new T [_size]) { copy(src, ptr,_size); } inline ~ARRAY() { delete [] ptr; } inline T& get(int index) { return ptr[index]; } inline T& getRecycled(int index) { return ptr[index%_size]; }; }; // // cast-copy doubles to floats // template<> inline void copy(double* from, float* to, int size) { while(size--) { *to = (float) *from; from++; to++; } } /** * get most significant bit * @param x unsigned value * @return bit position between 1..32 or 0 if value was 0 **/ inline int msb(unsigned int x) { if (x) { int bit = sizeof(int)*8; unsigned int mask = 1<<((sizeof(int)*8)-1); while ( !(x & mask) ) { --bit; mask >>= 1; } return bit; } else return 0; } // template T getMax(T a, T b) { return (a > b) ? a : b; } // template T getMin(T a, T b) { return (a < b) ? a : b; } inline int getMin(int a, int b) { return (a <= b) ? a : b; } inline float getMin(float a, float b) { return (a <= b) ? a : b; } inline int getMax(int a, int b) { return (a >= b) ? a : b; } inline float getMax(float a, float b) { return (a >= b) ? a : b; } inline float clamp(float v, float floor, float ceil) { return (vceil) ? ceil : v ); } inline int clamp(int v, int floor, int ceil) { return (vceil) ? ceil : v ); } } // namespace rgl #endif /* RGL_TYPES_H */ rgl/src/select.h0000644000176200001440000000044314100762641013257 0ustar liggesusers#ifndef PLX_SELECT_H #define PLX_SELECT_H // C++ header file // This file is part of RGL #include "scene.h" namespace rgl { // // Mouse selection rectangle // class SELECT { public: inline SELECT() { }; void render(double* position); }; } // namespace rgl #endif // PLX_SELECT_H rgl/src/PrimitiveSet.cpp0000644000176200001440000002601514145464133014766 0ustar liggesusers#include "PrimitiveSet.h" #include "BBoxDeco.h" #include "subscene.h" #include "R.h" using namespace rgl; // ===[ PRIMITIVE SET ]======================================================= PrimitiveSet::PrimitiveSet ( Material& in_material, int in_type, int in_nverticesperelement, bool in_ignoreExtent, bool in_bboxChange ) : Shape(in_material, in_ignoreExtent, SHAPE, in_bboxChange) { type = in_type; nverticesperelement = in_nverticesperelement; nvertices = 0; nindices = 0; } void PrimitiveSet::initPrimitiveSet( int in_nvertices, double* in_vertices, int in_nindices, int* in_indices ) { nvertices = in_nvertices; nindices = in_nindices; if (nindices) nprimitives = nindices / nverticesperelement; else nprimitives = nvertices / nverticesperelement; vertexArray.alloc(nvertices); hasmissing = false; for(int i=0;i= 0) { Subscene* subscene = renderContext->subscene; bboxdeco = subscene->get_bboxdeco(); } if (bboxdeco) { invalidateDisplaylist(); verticesTodraw.alloc(vertexArray.size()); for (int i=0; i < vertexArray.size(); i++) verticesTodraw.setVertex(i, bboxdeco->marginVecToDataVec(vertexArray[i], renderContext, &material) ); verticesTodraw.beginUse(); } else vertexArray.beginUse(); SAVEGLERROR; } // --------------------------------------------------------------------------- void PrimitiveSet::drawAll(RenderContext* renderContext) { #ifndef RGL_NO_OPENGL if (!hasmissing) { if (!nindices) glDrawArrays(type, 0, nverticesperelement*nprimitives ); else glDrawElements(type, nindices, GL_UNSIGNED_INT, indices); } else { bool missing = true; for (int i=0; i= 0) { Subscene* subscene = renderContext->subscene; bboxdeco = subscene->get_bboxdeco(); } if (bboxdeco) { normalsToDraw.alloc(normalArray.size()); for (int i=0; i < normalArray.size(); i++) normalsToDraw.setVertex(i, bboxdeco->marginNormalToDataNormal(normalArray[i], renderContext, &material) ); normalsToDraw.beginUse(); } else normalArray.beginUse(); } texCoordArray.beginUse(); } // --------------------------------------------------------------------------- void FaceSet::drawEnd(RenderContext* renderContext) { texCoordArray.endUse(); if (material.lit) normalArray.endUse(); PrimitiveSet::drawEnd(renderContext); } int FaceSet::getAttributeCount(AABox& bbox, AttribID attrib) { switch (attrib) { case NORMALS: return nvertices; case TEXCOORDS: return texCoordArray.size(); } return PrimitiveSet::getAttributeCount(bbox, attrib); } void FaceSet::getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result) { int n = getAttributeCount(bbox, attrib); if (first + count < n) n = first + count; if (first < n) { switch (attrib) { case NORMALS: { if (normalArray.size() < n) initNormals(NULL); while (first < n) { *result++ = normalArray[first].x; *result++ = normalArray[first].y; *result++ = normalArray[first].z; first++; } return; } case TEXCOORDS: { while (first < n) { *result++ = texCoordArray[first].s; *result++ = texCoordArray[first].t; first++; } return; } } PrimitiveSet::getAttribute(bbox, attrib, first, count, result); } } rgl/src/Texture.h0000644000176200001440000000225414145464133013446 0ustar liggesusers#ifndef TEXTURE_H #define TEXTURE_H #include "pixmap.h" #include "types.h" namespace rgl { // // CLASS // Texture // class RenderContext; class Pixmap; #include "opengl.h" class Texture : public AutoDestroy { public: enum Type { ALPHA = 1 , LUMINANCE, LUMINANCE_ALPHA, RGB, RGBA }; Texture(const char* in_filename , Type type , bool mipmap , unsigned int minfilter , unsigned int magfilter , bool envmap); virtual ~Texture(); bool isValid() const; void beginUse(RenderContext* renderContext); void endUse(RenderContext* renderContext); bool is_envmap() const { return envmap; } bool hasAlpha() const { return (type == ALPHA || type == LUMINANCE_ALPHA || type == RGBA ); } void getParameters(Type *out_type, bool *out_mipmap, unsigned int *out_minfilter, unsigned int *out_magfilter, bool *out_envmap, int bufsize, char *out_filename) ; Pixmap* getPixmap() const { return pixmap; } private: void init(RenderContext* renderContext); Pixmap* pixmap; GLuint texName; Type type; bool mipmap; GLenum minfilter; GLenum magfilter; bool envmap; char* filename; }; } // namespace rgl #endif // TEXTURE_H rgl/src/Surface.cpp0000644000176200001440000002016014100762641013721 0ustar liggesusers#include "Surface.h" #include "Material.h" using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // Surface // // in_coords permutes the coordinates to allow surfaces over arbitrary planes // orientation is 1 to swap front and back Surface::Surface(Material& in_material, int in_nx, int in_nz, double* in_x, double* in_z, double* in_y, double* in_normal_x, double* in_normal_z, double* in_normal_y, double* in_texture_s, double* in_texture_t, int* in_coords, int in_orientation, int* in_flags, int in_ignoreExtent) : Shape(in_material, in_ignoreExtent) { nx = in_nx; nz = in_nz; coords[0] = *(in_coords++); coords[1] = *(in_coords++); coords[2] = *(in_coords++); orientation = in_orientation; int nvertex = nx*nz; material.colorPerVertex(true, nvertex); vertexArray.alloc(nvertex); if (material.texture) texCoordArray.alloc(nvertex); Vertex v; float *x,*y,*z, *va[3]; va[0] = &(v.x); va[1] = &(v.y); va[2] = &(v.z); x = va[coords[0]-1]; y = va[coords[1]-1]; z = va[coords[2]-1]; int xmat = in_flags[0]; int zmat = in_flags[1]; user_normals = in_flags[2]; user_textures = in_flags[3]; if (user_normals) normalArray.alloc(nvertex); int iy = 0; for(int iz=0;izis_envmap() ) ) { if (!user_textures) { texCoordArray[iy].s = ((float)ix)/((float)(nx-1)); texCoordArray[iy].t = 1.0f - ((float)iz)/((float)(nz-1)); } else { texCoordArray[iy].s = static_cast(in_texture_s[iy]); texCoordArray[iy].t = static_cast(in_texture_t[iy]); } } } } use_normal = user_normals || material.lit || ( material.texture && material.texture->is_envmap() ); if ( use_normal && !user_normals ) { normalArray.alloc(nvertex); iy = 0; for(int iz=0;izis_envmap() ) ); if ((material.point_antialias && ( material.front == material.POINT_FACE || material.back == material.POINT_FACE)) || (material.line_antialias && ( material.front == material.LINE_FACE || material.back == material.LINE_FACE))) blended = true; } Vertex Surface::getNormal(int ix, int iz) { int i = iz*nx + ix; Vertex total(0.0f,0.0f,0.0f); if (!vertexArray[i].missing()) { // List the 8 surrounding vertices. Repat the 1st one to make looping simpler. int ind[9]; int xv[9] = { 1, 1, 0, -1, -1, -1, 0, 1, 1 }; int zv[9] = { 0, -1, -1, -1, 0, 1, 1, 1, 0 }; int okay[9]; /* checks of surrounding vertices from right counterclockwise */ for (int j=0; j<8; j++) { int xval = ix + xv[j], zval = iz + zv[j]; if (0 <= xval && xval < nx && 0 <= zval && zval < nz) { ind[j] = i + xv[j] + zv[j]*nx; okay[j] = !vertexArray[ind[j]].missing(); } else { okay[j] = 0; ind[j] = 0; } } okay[8] = okay[0]; ind[8] = ind[0]; /* Estimate normal by averaging cross-product in successive triangular sectors */ for (int j=0; j<8; j++) { if (okay[j] && okay[j+1] ) total += vertexArray.getNormal(i, ind[j], ind[j+1] ); } total.normalize(); } if (orientation) { total.x = -total.x; total.y = -total.y; total.z = -total.z; } return total; } void Surface::draw(RenderContext* renderContext) { #ifndef RGL_NO_OPENGL bool missing; drawBegin(renderContext); for(int iz=0;iz #include "types.h" #include "subscene.h" namespace rgl { class Scene { public: Scene(); ~Scene(); // ---[ client services ]--------------------------------------------------- /** * remove all nodes of the given type. This is always recursive through subscenes. **/ bool clear(TypeID type); /** * add node to current subscene **/ bool add(SceneNode* node); /** * remove specified node of given type, or last-added if id==0 **/ bool pop(TypeID stackTypeID, int id); /** * hide specified node in all subscenes **/ void hide(int id); /** * get information about stacks */ int get_id_count(TypeID type); void get_ids(TypeID type, int* ids, char** types); /** * get a SceneNode by id */ SceneNode* get_scenenode(int id); SceneNode* get_scenenode(TypeID type, int id); /** * get information about particular shapes **/ Shape* get_shape(int id); /** * get information about particular lights **/ Light* get_light(int id); /** * get a background */ Background* get_background(int id); /** * get the bbox */ BBoxDeco* get_bboxdeco(int id); /** * get subscene */ Subscene* getSubscene(int id); /* get subscene by its id */ Subscene* whichSubscene(int id); /* get subscene holding this id */ Subscene* whichSubscene(int mouseX, int mouseY); /* get subscene by mouse coords */ /* coordinates are window-relative */ /** * set/get the current subscene **/ Subscene* setCurrentSubscene(Subscene* subscene); /* return previous one */ Subscene* getCurrentSubscene() const { return currentSubscene; } const Subscene* getRootSubscene() const { return &rootSubscene; } // ---[ grouping component ]----------------------------------------------- /** * obtain subscene's axis-aligned bounding box. **/ const AABox& getBoundingBox() const { return currentSubscene->getBoundingBox(); } // ---[ Renderable interface ]--------------------------------------------- /** * update matrices etc. */ void update(RenderContext* renderContext); /** * do OpenGL plotting */ void render(RenderContext* renderContext); // ---[ bindable component ]----------------------------------------------- /** * obtain bounded viewpoint **/ UserViewpoint* getUserViewpoint(); ModelViewpoint* getModelViewpoint(); /** * Get and set flag to ignore elements in bounding box **/ int getIgnoreExtent(void) const { return doIgnoreExtent; } void setIgnoreExtent(int in_ignoreExtent) { doIgnoreExtent = in_ignoreExtent; } /** * invalidate display lists so objects will be rendered again **/ void invalidateDisplaylists(); Subscene rootSubscene; private: // Whether objects created in this scene should affect the bounding box or not bool doIgnoreExtent; void setupLightModel(); // --- [ Subscenes ]------------------------------------------------------- Subscene* currentSubscene; // ---[ nodes ]----------------------------------------------------------- /** * list of scene nodes. The scene owns them, the subscenes display a subset. **/ std::vector nodes; void deleteAll(std::vector list); void removeReferences(SceneNode* node); }; } // namespace rgl #endif /* SCENE_H */ rgl/src/ext/0000755000176200001440000000000014100762641012426 5ustar liggesusersrgl/src/ext/ftgl/0000755000176200001440000000000014100762641013362 5ustar liggesusersrgl/src/ext/ftgl/config.h0000644000176200001440000000050614100762641015001 0ustar liggesusers/* In rgl, we don't run the FTGL configure script, and we don't have RTTI. It appears as though the configure script is not needed for the subset we use (except we need config.h, hence this file), and we can use static_casts in place of dynamic_casts, hence the define below. */ #define dynamic_cast static_cast rgl/src/ext/ftgl/FTGlyphContainer.h0000644000176200001440000001151514100762641016716 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTGlyphContainer__ #define __FTGlyphContainer__ #include #include FT_FREETYPE_H #include FT_GLYPH_H #include "FTGL/ftgl.h" #include "FTVector.h" class FTFace; class FTGlyph; class FTCharmap; /** * FTGlyphContainer holds the post processed FTGlyph objects. * * @see FTGlyph */ class FTGlyphContainer { typedef FTVector GlyphVector; public: /** * Constructor * * @param face The Freetype face */ FTGlyphContainer(FTFace* face); /** * Destructor */ ~FTGlyphContainer(); /** * Sets the character map for the face. * * @param encoding the Freetype encoding symbol. See above. * @return true if charmap was valid * and set correctly */ bool CharMap(FT_Encoding encoding); /** * Get the font index of the input character. * * @param characterCode The character code of the requested glyph in the * current encoding eg apple roman. * @return The font index for the character. */ unsigned int FontIndex(const unsigned int characterCode) const; /** * Adds a glyph to this glyph list. * * @param glyph The FTGlyph to be inserted into the container * @param characterCode The char code of the glyph NOT the glyph index. */ void Add(FTGlyph* glyph, const unsigned int characterCode); /** * Get a glyph from the glyph list * * @param characterCode The char code of the glyph NOT the glyph index * @return An FTGlyph or null is it hasn't been * loaded. */ const FTGlyph* const Glyph(const unsigned int characterCode) const; /** * Get the bounding box for a character. * @param characterCode The char code of the glyph NOT the glyph index */ FTBBox BBox(const unsigned int characterCode) const; /** * Returns the kerned advance width for a glyph. * * @param characterCode glyph index of the character * @param nextCharacterCode the next glyph in a string * @return advance width */ float Advance(const unsigned int characterCode, const unsigned int nextCharacterCode); /** * Renders a character * @param characterCode the glyph to be Rendered * @param nextCharacterCode the next glyph in the string. Used for kerning. * @param penPosition the position to Render the glyph * @param renderMode Render mode to display * @return The distance to advance the pen position after Rendering */ FTPoint Render(const unsigned int characterCode, const unsigned int nextCharacterCode, FTPoint penPosition, int renderMode); /** * Queries the Font for errors. * * @return The current error code. */ FT_Error Error() const { return err; } private: /** * The FTGL face */ FTFace* face; /** * The Character Map object associated with the current face */ FTCharmap* charMap; /** * A structure to hold the glyphs */ GlyphVector glyphs; /** * Current error code. Zero means no error. */ FT_Error err; }; #endif // __FTGlyphContainer__ rgl/src/ext/ftgl/FTVectoriser.h0000644000176200001440000001722714100762641016123 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTVectoriser__ #define __FTVectoriser__ #include "FTGL/ftgl.h" #include "FTContour.h" #include "FTList.h" #include "FTVector.h" #ifndef CALLBACK #define CALLBACK #endif /** * FTTesselation captures points that are output by OpenGL's gluTesselator. */ class FTTesselation { public: /** * Default constructor */ FTTesselation(GLenum m) : meshType(m) { pointList.reserve(128); } /** * Destructor */ ~FTTesselation() { pointList.clear(); } /** * Add a point to the mesh. */ void AddPoint(const FTGL_DOUBLE x, const FTGL_DOUBLE y, const FTGL_DOUBLE z) { pointList.push_back(FTPoint(x, y, z)); } /** * The number of points in this mesh */ size_t PointCount() const { return pointList.size(); } /** * */ const FTPoint& Point(unsigned int index) const { return pointList[index]; } /** * Return the OpenGL polygon type. */ GLenum PolygonType() const { return meshType; } private: /** * Points generated by gluTesselator. */ typedef FTVector PointVector; PointVector pointList; /** * OpenGL primitive type from gluTesselator. */ GLenum meshType; }; /** * FTMesh is a container of FTTesselation's that make up a polygon glyph */ class FTMesh { typedef FTVector TesselationVector; typedef FTList PointList; public: /** * Default constructor */ FTMesh(); /** * Destructor */ ~FTMesh(); /** * Add a point to the mesh */ void AddPoint(const FTGL_DOUBLE x, const FTGL_DOUBLE y, const FTGL_DOUBLE z); /** * Create a combine point for the gluTesselator */ const FTGL_DOUBLE* Combine(const FTGL_DOUBLE x, const FTGL_DOUBLE y, const FTGL_DOUBLE z); /** * Begin a new polygon */ void Begin(GLenum meshType); /** * End a polygon */ void End(); /** * Record a gluTesselation error */ void Error(GLenum e) { err = e; } /** * The number of tesselations in the mesh */ size_t TesselationCount() const { return tesselationList.size(); } /** * Get a tesselation by index */ const FTTesselation* const Tesselation(size_t index) const; /** * Return the temporary point list. For testing only. */ const PointList& TempPointList() const { return tempPointList; } /** * Get the GL ERROR returned by the glu tesselator */ GLenum Error() const { return err; } private: /** * The current sub mesh that we are constructing. */ FTTesselation* currentTesselation; /** * Holds each sub mesh that comprises this glyph. */ TesselationVector tesselationList; /** * Holds extra points created by gluTesselator. See ftglCombine. */ PointList tempPointList; /** * GL ERROR returned by the glu tesselator */ GLenum err; }; const FTGL_DOUBLE FTGL_FRONT_FACING = 1.0; const FTGL_DOUBLE FTGL_BACK_FACING = -1.0; /** * FTVectoriser class is a helper class that converts font outlines into * point data. * * @see FTExtrudeGlyph * @see FTOutlineGlyph * @see FTPolygonGlyph * @see FTContour * @see FTPoint * */ class FTVectoriser { public: /** * Constructor * * @param glyph The freetype glyph to be processed */ FTVectoriser(const FT_GlyphSlot glyph); /** * Destructor */ virtual ~FTVectoriser(); /** * Build an FTMesh from the vector outline data. * * @param zNormal The direction of the z axis of the normal * for this mesh * FIXME: change the following for a constant * @param outsetType Specify the outset type contour * 0 : Original * 1 : Front * 2 : Back * @param outsetSize Specify the outset size contour */ void MakeMesh(FTGL_DOUBLE zNormal = FTGL_FRONT_FACING, int outsetType = 0, float outsetSize = 0.0f); /** * Get the current mesh. */ const FTMesh* const GetMesh() const { return mesh; } /** * Get the total count of points in this outline * * @return the number of points */ size_t PointCount(); /** * Get the count of contours in this outline * * @return the number of contours */ size_t ContourCount() const { return ftContourCount; } /** * Return a contour at index * * @return the number of contours */ const FTContour* const Contour(size_t index) const; /** * Get the number of points in a specific contour in this outline * * @param c The contour index * @return the number of points in contour[c] */ size_t ContourSize(int c) const { return contourList[c]->PointCount(); } /** * Get the flag for the tesselation rule for this outline * * @return The contour flag */ int ContourFlag() const { return contourFlag; } private: /** * Process the freetype outline data into contours of points * * @param front front outset distance * @param back back outset distance */ void ProcessContours(); /** * The list of contours in the glyph */ FTContour** contourList; /** * A Mesh for tesselations */ FTMesh* mesh; /** * The number of contours reported by Freetype */ short ftContourCount; /** * A flag indicating the tesselation rule for the glyph */ int contourFlag; /** * A Freetype outline */ FT_Outline outline; }; #endif // __FTVectoriser__ rgl/src/ext/ftgl/FTFace.cpp0000644000176200001440000001343614100762641015165 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTFace.h" #include "FTLibrary.h" #include FT_TRUETYPE_TABLES_H FTFace::FTFace(const char* fontFilePath, bool precomputeKerning) : numGlyphs(0), fontEncodingList(0), kerningCache(0), err(0) { const FT_Long DEFAULT_FACE_INDEX = 0; ftFace = new FT_Face; err = FT_New_Face(*FTLibrary::Instance().GetLibrary(), fontFilePath, DEFAULT_FACE_INDEX, ftFace); if(err) { delete ftFace; ftFace = 0; return; } numGlyphs = static_cast((*ftFace)->num_glyphs); hasKerningTable = (FT_HAS_KERNING((*ftFace)) != 0); if(hasKerningTable && precomputeKerning) { BuildKerningCache(); } } FTFace::FTFace(const unsigned char *pBufferBytes, size_t bufferSizeInBytes, bool precomputeKerning) : numGlyphs(0), fontEncodingList(0), kerningCache(0), err(0) { const FT_Long DEFAULT_FACE_INDEX = 0; ftFace = new FT_Face; err = FT_New_Memory_Face(*FTLibrary::Instance().GetLibrary(), (FT_Byte const *)pBufferBytes, (FT_Long)bufferSizeInBytes, DEFAULT_FACE_INDEX, ftFace); if(err) { delete ftFace; ftFace = 0; return; } numGlyphs = static_cast((*ftFace)->num_glyphs); hasKerningTable = (FT_HAS_KERNING((*ftFace)) != 0); if(hasKerningTable && precomputeKerning) { BuildKerningCache(); } } FTFace::~FTFace() { if(kerningCache) { delete[] kerningCache; } if(ftFace) { FT_Done_Face(*ftFace); delete ftFace; ftFace = 0; } } bool FTFace::Attach(const char* fontFilePath) { err = FT_Attach_File(*ftFace, fontFilePath); return !err; } bool FTFace::Attach(const unsigned char *pBufferBytes, size_t bufferSizeInBytes) { FT_Open_Args open; open.flags = FT_OPEN_MEMORY; open.memory_base = (FT_Byte const *)pBufferBytes; open.memory_size = (FT_Long)bufferSizeInBytes; err = FT_Attach_Stream(*ftFace, &open); return !err; } const FTSize& FTFace::Size(const unsigned int size, const unsigned int res) { charSize.CharSize(ftFace, size, res, res); err = charSize.Error(); return charSize; } unsigned int FTFace::CharMapCount() const { return (*ftFace)->num_charmaps; } FT_Encoding* FTFace::CharMapList() { if(0 == fontEncodingList) { fontEncodingList = new FT_Encoding[CharMapCount()]; for(size_t i = 0; i < CharMapCount(); ++i) { fontEncodingList[i] = (*ftFace)->charmaps[i]->encoding; } } return fontEncodingList; } FTPoint FTFace::KernAdvance(unsigned int index1, unsigned int index2) { float x, y; if(!hasKerningTable || !index1 || !index2) { return FTPoint(0.0f, 0.0f); } if(kerningCache && index1 < FTFace::MAX_PRECOMPUTED && index2 < FTFace::MAX_PRECOMPUTED) { x = kerningCache[2 * (index2 * FTFace::MAX_PRECOMPUTED + index1)]; y = kerningCache[2 * (index2 * FTFace::MAX_PRECOMPUTED + index1) + 1]; return FTPoint(x, y); } FT_Vector kernAdvance; kernAdvance.x = kernAdvance.y = 0; err = FT_Get_Kerning(*ftFace, index1, index2, ft_kerning_unfitted, &kernAdvance); if(err) { return FTPoint(0.0f, 0.0f); } x = static_cast(kernAdvance.x) / 64.0f; y = static_cast(kernAdvance.y) / 64.0f; return FTPoint(x, y); } FT_GlyphSlot FTFace::Glyph(unsigned int index, FT_Int load_flags) { err = FT_Load_Glyph(*ftFace, index, load_flags); if(err) { return NULL; } return (*ftFace)->glyph; } void FTFace::BuildKerningCache() { FT_Vector kernAdvance; kernAdvance.x = 0; kernAdvance.y = 0; kerningCache = new float[FTFace::MAX_PRECOMPUTED * FTFace::MAX_PRECOMPUTED * 2]; for(unsigned int j = 0; j < FTFace::MAX_PRECOMPUTED; j++) { for(unsigned int i = 0; i < FTFace::MAX_PRECOMPUTED; i++) { err = FT_Get_Kerning(*ftFace, i, j, ft_kerning_unfitted, &kernAdvance); if(err) { delete[] kerningCache; kerningCache = NULL; return; } kerningCache[2 * (j * FTFace::MAX_PRECOMPUTED + i)] = static_cast(kernAdvance.x) / 64.0f; kerningCache[2 * (j * FTFace::MAX_PRECOMPUTED + i) + 1] = static_cast(kernAdvance.y) / 64.0f; } } } rgl/src/ext/ftgl/FTSize.cpp0000644000176200001440000000560714100762641015242 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTSize.h" FTSize::FTSize() : ftFace(0), ftSize(0), size(0), xResolution(0), yResolution(0), err(0) {} FTSize::~FTSize() {} bool FTSize::CharSize(FT_Face* face, unsigned int pointSize, unsigned int xRes, unsigned int yRes) { if(size != pointSize || xResolution != xRes || yResolution != yRes) { err = FT_Set_Char_Size(*face, 0L, pointSize * 64, xResolution, yResolution); if(!err) { ftFace = face; size = pointSize; xResolution = xRes; yResolution = yRes; ftSize = (*ftFace)->size; } } return !err; } unsigned int FTSize::CharSize() const { return size; } float FTSize::Ascender() const { return ftSize == 0 ? 0.0f : static_cast(ftSize->metrics.ascender) / 64.0f; } float FTSize::Descender() const { return ftSize == 0 ? 0.0f : static_cast(ftSize->metrics.descender) / 64.0f; } float FTSize::Height() const { if(0 == ftSize) { return 0.0f; } if(FT_IS_SCALABLE((*ftFace))) { return ((*ftFace)->bbox.yMax - (*ftFace)->bbox.yMin) * ((float)ftSize->metrics.y_ppem / (float)(*ftFace)->units_per_EM); } else { return static_cast(ftSize->metrics.height) / 64.0f; } } float FTSize::Width() const { if(0 == ftSize) { return 0.0f; } if(FT_IS_SCALABLE((*ftFace))) { return ((*ftFace)->bbox.xMax - (*ftFace)->bbox.xMin) * (static_cast(ftSize->metrics.x_ppem) / static_cast((*ftFace)->units_per_EM)); } else { return static_cast(ftSize->metrics.max_advance) / 64.0f; } } float FTSize::Underline() const { return 0.0f; } rgl/src/ext/ftgl/FTGL/0000755000176200001440000000000014100762641014116 5ustar liggesusersrgl/src/ext/ftgl/FTGL/FTLayout.h0000644000176200001440000001454514100762641016007 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTLayout__ #define __FTLayout__ #ifdef __cplusplus class FTLayoutImpl; /** * FTLayout is the interface for layout managers that render text. * * Specific layout manager classes are derived from this class. This class * is abstract and deriving classes must implement the protected * Render methods to render formatted text and * BBox methods to determine the bounding box of output text. * * @see FTFont * @see FTBBox */ class FTGL_EXPORT FTLayout { protected: FTLayout(); private: /** * Internal FTGL FTLayout constructor. For private use only. * * @param pImpl Internal implementation object. Will be destroyed * upon FTLayout deletion. */ FTLayout(FTLayoutImpl *pImpl); /* Allow our internal subclasses to access the private constructor */ friend class FTSimpleLayout; public: /** * Destructor */ virtual ~FTLayout(); /** * Get the bounding box for a formatted string. * * @param string A char string. * @param len The length of the string. If < 0 then all characters * will be checked until a null character is encountered * (optional). * @param position The pen position of the first character (optional). * @return The corresponding bounding box. */ virtual FTBBox BBox(const char* string, const int len = -1, FTPoint position = FTPoint()) = 0; /** * Get the bounding box for a formatted string. * * @param string A wchar_t string. * @param len The length of the string. If < 0 then all characters * will be checked until a null character is encountered * (optional). * @param position The pen position of the first character (optional). * @return The corresponding bounding box. */ virtual FTBBox BBox(const wchar_t* string, const int len = -1, FTPoint position = FTPoint()) = 0; /** * Render a string of characters. * * @param string 'C' style string to be output. * @param len The length of the string. If < 0 then all characters * will be displayed until a null character is encountered * (optional). * @param position The pen position of the first character (optional). * @param renderMode Render mode to display (optional) */ virtual void Render(const char *string, const int len = -1, FTPoint position = FTPoint(), int renderMode = FTGL::RENDER_ALL) = 0; /** * Render a string of characters. * * @param string wchar_t string to be output. * @param len The length of the string. If < 0 then all characters * will be displayed until a null character is encountered * (optional). * @param position The pen position of the first character (optional). * @param renderMode Render mode to display (optional) */ virtual void Render(const wchar_t *string, const int len = -1, FTPoint position = FTPoint(), int renderMode = FTGL::RENDER_ALL) = 0; /** * Queries the Layout for errors. * * @return The current error code. */ virtual FT_Error Error() const; private: /** * Internal FTGL FTLayout implementation object. For private use only. */ FTLayoutImpl *impl; }; #endif //__cplusplus FTGL_BEGIN_C_DECLS /** * FTGLlayout is the interface for layout managers that render text. */ struct _FTGLlayout; typedef struct _FTGLlayout FTGLlayout; /** * Destroy an FTGL layout object. * * @param layout An FTGLlayout* object. */ FTGL_EXPORT void ftglDestroyLayout(FTGLlayout* layout); /** * Get the bounding box for a string. * * @param layout An FTGLlayout* object. * @param string A char buffer * @param bounds An array of 6 float values where the bounding box's lower * left near and upper right far 3D coordinates will be stored. */ FTGL_EXPORT void ftglGetLayoutBBox(FTGLlayout *layout, const char* string, float bounds[6]); /** * Render a string of characters. * * @param layout An FTGLlayout* object. * @param string Char string to be output. * @param mode Render mode to display. */ FTGL_EXPORT void ftglRenderLayout(FTGLlayout *layout, const char *string, int mode); /** * Query a layout for errors. * * @param layout An FTGLlayout* object. * @return The current error code. */ FTGL_EXPORT FT_Error ftglGetLayoutError(FTGLlayout* layout); FTGL_END_C_DECLS #endif /* __FTLayout__ */ rgl/src/ext/ftgl/FTGL/FTBuffer.h0000644000176200001440000000637314100762641015743 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning Please use instead of . # include #endif #ifndef __FTBuffer__ #define __FTBuffer__ #ifdef __cplusplus /** * FTBuffer is a helper class for pixel buffers. * * It provides the interface between FTBufferFont and FTBufferGlyph to * optimise rendering operations. * * @see FTBufferGlyph * @see FTBufferFont */ class FTGL_EXPORT FTBuffer { public: /** * Default constructor. */ FTBuffer(); /** * Destructor */ ~FTBuffer(); /** * Get the pen's position in the buffer. * * @return The pen's position as an FTPoint object. */ inline FTPoint Pos() const { return pos; } /** * Set the pen's position in the buffer. * * @param arg An FTPoint object with the desired pen's position. */ inline void Pos(FTPoint arg) { pos = arg; } /** * Set the buffer's size. * * @param w The buffer's desired width, in pixels. * @param h The buffer's desired height, in pixels. */ void Size(int w, int h); /** * Get the buffer's width. * * @return The buffer's width, in pixels. */ inline int Width() const { return width; } /** * Get the buffer's height. * * @return The buffer's height, in pixels. */ inline int Height() const { return height; } /** * Get the buffer's direct pixel buffer. * * @return A read-write pointer to the buffer's pixels. */ inline unsigned char *Pixels() const { return pixels; } private: /** * Buffer's width and height. */ int width, height; /** * Buffer's pixel buffer. */ unsigned char *pixels; /** * Buffer's internal pen position. */ FTPoint pos; }; #endif //__cplusplus #endif // __FTBuffer__ rgl/src/ext/ftgl/FTGL/FTGLPolygonFont.h0000644000176200001440000000614414100762641017227 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTPolygonFont__ #define __FTPolygonFont__ #ifdef __cplusplus /** * FTPolygonFont is a specialisation of the FTFont class for handling * tesselated Polygon Mesh fonts * * @see FTFont */ class FTGL_EXPORT FTPolygonFont : public FTFont { public: /** * Open and read a font file. Sets Error flag. * * @param fontFilePath font file path. */ FTPolygonFont(const char* fontFilePath); /** * Open and read a font from a buffer in memory. Sets Error flag. * The buffer is owned by the client and is NOT copied by FTGL. The * pointer must be valid while using FTGL. * * @param pBufferBytes the in-memory buffer * @param bufferSizeInBytes the length of the buffer in bytes */ FTPolygonFont(const unsigned char *pBufferBytes, size_t bufferSizeInBytes); /** * Destructor */ ~FTPolygonFont(); protected: /** * Construct a glyph of the correct type. * * Clients must override the function and return their specialised * FTGlyph. * * @param slot A FreeType glyph slot. * @return An FT****Glyph or null on failure. */ virtual FTGlyph* MakeGlyph(FT_GlyphSlot slot); }; #define FTGLPolygonFont FTPolygonFont #endif //__cplusplus FTGL_BEGIN_C_DECLS /** * Create a specialised FTGLfont object for handling tesselated polygon * mesh fonts. * * @param file The font file name. * @return An FTGLfont* object. * * @see FTGLfont */ FTGL_EXPORT FTGLfont *ftglCreatePolygonFont(const char *file); FTGL_END_C_DECLS #endif // __FTPolygonFont__ rgl/src/ext/ftgl/FTGL/FTGLOutlineFont.h0000644000176200001440000000611514100762641017215 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTOutlineFont__ #define __FTOutlineFont__ #ifdef __cplusplus /** * FTOutlineFont is a specialisation of the FTFont class for handling * Vector Outline fonts * * @see FTFont */ class FTGL_EXPORT FTOutlineFont : public FTFont { public: /** * Open and read a font file. Sets Error flag. * * @param fontFilePath font file path. */ FTOutlineFont(const char* fontFilePath); /** * Open and read a font from a buffer in memory. Sets Error flag. * The buffer is owned by the client and is NOT copied by FTGL. The * pointer must be valid while using FTGL. * * @param pBufferBytes the in-memory buffer * @param bufferSizeInBytes the length of the buffer in bytes */ FTOutlineFont(const unsigned char *pBufferBytes, size_t bufferSizeInBytes); /** * Destructor */ ~FTOutlineFont(); protected: /** * Construct a glyph of the correct type. * * Clients must override the function and return their specialised * FTGlyph. * * @param slot A FreeType glyph slot. * @return An FT****Glyph or null on failure. */ virtual FTGlyph* MakeGlyph(FT_GlyphSlot slot); }; #define FTGLOutlineFont FTOutlineFont #endif //__cplusplus FTGL_BEGIN_C_DECLS /** * Create a specialised FTGLfont object for handling vector outline fonts. * * @param file The font file name. * @return An FTGLfont* object. * * @see FTGLfont */ FTGL_EXPORT FTGLfont *ftglCreateOutlineFont(const char *file); FTGL_END_C_DECLS #endif // __FTOutlineFont__ rgl/src/ext/ftgl/FTGL/FTPixmapGlyph.h0000644000176200001440000000472614100762641016774 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTPixmapGlyph__ #define __FTPixmapGlyph__ #ifdef __cplusplus /** * FTPixmapGlyph is a specialisation of FTGlyph for creating pixmaps. */ class FTGL_EXPORT FTPixmapGlyph : public FTGlyph { public: /** * Constructor * * @param glyph The Freetype glyph to be processed */ FTPixmapGlyph(FT_GlyphSlot glyph); /** * Destructor */ virtual ~FTPixmapGlyph(); /** * Render this glyph at the current pen position. * * @param pen The current pen position. * @param renderMode Render mode to display * @return The advance distance for this glyph. */ virtual const FTPoint& Render(const FTPoint& pen, int renderMode); }; #endif //__cplusplus FTGL_BEGIN_C_DECLS /** * Create a specialisation of FTGLglyph for creating pixmaps. * * @param glyph The Freetype glyph to be processed * @return An FTGLglyph* object. */ FTGL_EXPORT FTGLglyph *ftglCreatePixmapGlyph(FT_GlyphSlot glyph); FTGL_END_C_DECLS #endif // __FTPixmapGlyph__ rgl/src/ext/ftgl/FTGL/FTPolyGlyph.h0000644000176200001440000000651114100762641016453 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTPolygonGlyph__ #define __FTPolygonGlyph__ #ifdef __cplusplus /** * FTPolygonGlyph is a specialisation of FTGlyph for creating tessellated * polygon glyphs. */ class FTGL_EXPORT FTPolygonGlyph : public FTGlyph { public: /** * Constructor. Sets the Error to Invalid_Outline if the glyphs * isn't an outline. * * @param glyph The Freetype glyph to be processed * @param outset The outset distance * @param useDisplayList Enable or disable the use of Display Lists * for this glyph * true turns ON display lists. * false turns OFF display lists. */ FTPolygonGlyph(FT_GlyphSlot glyph, float outset, bool useDisplayList); /** * Destructor */ virtual ~FTPolygonGlyph(); /** * Render this glyph at the current pen position. * * @param pen The current pen position. * @param renderMode Render mode to display * @return The advance distance for this glyph. */ virtual const FTPoint& Render(const FTPoint& pen, int renderMode); }; #define FTPolyGlyph FTPolygonGlyph #endif //__cplusplus FTGL_BEGIN_C_DECLS /** * Create a specialisation of FTGLglyph for creating tessellated * polygon glyphs. * * @param glyph The Freetype glyph to be processed * @param outset outset contour size * @param useDisplayList Enable or disable the use of Display Lists * for this glyph * true turns ON display lists. * false turns OFF display lists. * @return An FTGLglyph* object. */ FTGL_EXPORT FTGLglyph *ftglCreatePolygonGlyph(FT_GlyphSlot glyph, float outset, int useDisplayList); FTGL_END_C_DECLS #endif // __FTPolygonGlyph__ rgl/src/ext/ftgl/FTGL/FTSimpleLayout.h0000644000176200001440000001472014100762641017154 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTSimpleLayout__ #define __FTSimpleLayout__ #ifdef __cplusplus class FTFont; /** * FTSimpleLayout is a specialisation of FTLayout for simple text boxes. * * This class has basic support for text wrapping, left, right and centered * alignment, and text justification. * * @see FTLayout */ class FTGL_EXPORT FTSimpleLayout : public FTLayout { public: /** * Initializes line spacing to 1.0, alignment to * ALIGN_LEFT and wrap to 100.0 */ FTSimpleLayout(); /** * Destructor */ ~FTSimpleLayout(); /** * Get the bounding box for a formatted string. * * @param string A char string. * @param len The length of the string. If < 0 then all characters * will be checked until a null character is encountered * (optional). * @param position The pen position of the first character (optional). * @return The corresponding bounding box. */ virtual FTBBox BBox(const char* string, const int len = -1, FTPoint position = FTPoint()); /** * Get the bounding box for a formatted string. * * @param string A wchar_t string. * @param len The length of the string. If < 0 then all characters * will be checked until a null character is encountered * (optional). * @param position The pen position of the first character (optional). * @return The corresponding bounding box. */ virtual FTBBox BBox(const wchar_t* string, const int len = -1, FTPoint position = FTPoint()); /** * Render a string of characters. * * @param string 'C' style string to be output. * @param len The length of the string. If < 0 then all characters * will be displayed until a null character is encountered * (optional). * @param position The pen position of the first character (optional). * @param renderMode Render mode to display (optional) */ virtual void Render(const char *string, const int len = -1, FTPoint position = FTPoint(), int renderMode = FTGL::RENDER_ALL); /** * Render a string of characters. * * @param string wchar_t string to be output. * @param len The length of the string. If < 0 then all characters * will be displayed until a null character is encountered * (optional). * @param position The pen position of the first character (optional). * @param renderMode Render mode to display (optional) */ virtual void Render(const wchar_t *string, const int len = -1, FTPoint position = FTPoint(), int renderMode = FTGL::RENDER_ALL); /** * Set the font to use for rendering the text. * * @param fontInit A pointer to the new font. The font is * referenced by this but will not be * disposed of when this is deleted. */ void SetFont(FTFont *fontInit); /** * @return The current font. */ FTFont *GetFont(); /** * The maximum line length for formatting text. * * @param LineLength The new line length. */ void SetLineLength(const float LineLength); /** * @return The current line length. */ float GetLineLength() const; /** * The text alignment mode used to distribute * space within a line or rendered text. * * @param Alignment The new alignment mode. */ void SetAlignment(const FTGL::TextAlignment Alignment); /** * @return The text alignment mode. */ FTGL::TextAlignment GetAlignment() const; /** * Sets the line height. * * @param LineSpacing The height of each line of text expressed as * a percentage of the current fonts line height. */ void SetLineSpacing(const float LineSpacing); /** * @return The line spacing. */ float GetLineSpacing() const; }; #endif //__cplusplus FTGL_BEGIN_C_DECLS FTGL_EXPORT FTGLlayout *ftglCreateSimpleLayout(void); FTGL_EXPORT void ftglSetLayoutFont(FTGLlayout *, FTGLfont*); FTGL_EXPORT FTGLfont *ftglGetLayoutFont(FTGLlayout *); FTGL_EXPORT void ftglSetLayoutLineLength(FTGLlayout *, const float); FTGL_EXPORT float ftglGetLayoutLineLength(FTGLlayout *); FTGL_EXPORT void ftglSetLayoutAlignment(FTGLlayout *, const int); FTGL_EXPORT int ftglGetLayoutAlignement(FTGLlayout *); FTGL_EXPORT void ftglSetLayoutLineSpacing(FTGLlayout *, const float); FTGL_EXPORT float ftglGetLayoutLineSpacing(FTGLlayout *); FTGL_END_C_DECLS #endif /* __FTSimpleLayout__ */ rgl/src/ext/ftgl/FTGL/FTGLPixmapFont.h0000644000176200001440000000611614100762641017035 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTPixmapFont__ #define __FTPixmapFont__ #ifdef __cplusplus /** * FTPixmapFont is a specialisation of the FTFont class for handling * Pixmap (Grey Scale) fonts * * @see FTFont */ class FTGL_EXPORT FTPixmapFont : public FTFont { public: /** * Open and read a font file. Sets Error flag. * * @param fontFilePath font file path. */ FTPixmapFont(const char* fontFilePath); /** * Open and read a font from a buffer in memory. Sets Error flag. * The buffer is owned by the client and is NOT copied by FTGL. The * pointer must be valid while using FTGL. * * @param pBufferBytes the in-memory buffer * @param bufferSizeInBytes the length of the buffer in bytes */ FTPixmapFont(const unsigned char *pBufferBytes, size_t bufferSizeInBytes); /** * Destructor */ ~FTPixmapFont(); protected: /** * Construct a glyph of the correct type. * * Clients must override the function and return their specialised * FTGlyph. * * @param slot A FreeType glyph slot. * @return An FT****Glyph or null on failure. */ virtual FTGlyph* MakeGlyph(FT_GlyphSlot slot); }; #define FTGLPixmapFont FTPixmapFont #endif // __cplusplus FTGL_BEGIN_C_DECLS /** * Create a specialised FTGLfont object for handling pixmap (grey scale) fonts. * * @param file The font file name. * @return An FTGLfont* object. * * @see FTGLfont */ FTGL_EXPORT FTGLfont *ftglCreatePixmapFont(const char *file); FTGL_END_C_DECLS #endif // __FTPixmapFont__ rgl/src/ext/ftgl/FTGL/FTGlyph.h0000644000176200001440000001414114100762641015605 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTGlyph__ #define __FTGlyph__ #ifdef __cplusplus class FTGlyphImpl; /** * FTGlyph is the base class for FTGL glyphs. * * It provides the interface between Freetype glyphs and their openGL * renderable counterparts. This is an abstract class and derived classes * must implement the Render function. * * @see FTBBox * @see FTPoint */ class FTGL_EXPORT FTGlyph { protected: /** * Create a glyph. * * @param glyph The Freetype glyph to be processed */ FTGlyph(FT_GlyphSlot glyph); private: /** * Internal FTGL FTGlyph constructor. For private use only. * * @param pImpl Internal implementation object. Will be destroyed * upon FTGlyph deletion. */ FTGlyph(FTGlyphImpl *pImpl); /* Allow our internal subclasses to access the private constructor */ friend class FTBitmapGlyph; friend class FTBufferGlyph; friend class FTExtrudeGlyph; friend class FTOutlineGlyph; friend class FTPixmapGlyph; friend class FTPolygonGlyph; friend class FTTextureGlyph; public: /** * Destructor */ virtual ~FTGlyph(); /** * Renders this glyph at the current pen position. * * @param pen The current pen position. * @param renderMode Render mode to display * @return The advance distance for this glyph. */ virtual const FTPoint& Render(const FTPoint& pen, int renderMode) = 0; /** * Return the advance width for this glyph. * * @return advance width. */ virtual float Advance() const; /** * Return the bounding box for this glyph. * * @return bounding box. */ virtual const FTBBox& BBox() const; /** * Queries for errors. * * @return The current error code. */ virtual FT_Error Error() const; private: /** * Internal FTGL FTGlyph implementation object. For private use only. */ FTGlyphImpl *impl; }; #endif //__cplusplus FTGL_BEGIN_C_DECLS /** * FTGLglyph is the base class for FTGL glyphs. * * It provides the interface between Freetype glyphs and their openGL * renderable counterparts. This is an abstract class and derived classes * must implement the ftglRenderGlyph() function. */ struct _FTGLGlyph; typedef struct _FTGLglyph FTGLglyph; /** * Create a custom FTGL glyph object. * FIXME: maybe get rid of "base" and have advanceCallback etc. functions * * @param base The base FTGLglyph* to subclass. * @param data A pointer to private data that will be passed to callbacks. * @param renderCallback A rendering callback function. * @param destroyCallback A callback function to be called upon destruction. * @return An FTGLglyph* object. */ FTGL_EXPORT FTGLglyph *ftglCreateCustomGlyph(FTGLglyph *base, void *data, void (*renderCallback) (FTGLglyph *, void *, FTGL_DOUBLE, FTGL_DOUBLE, int, FTGL_DOUBLE *, FTGL_DOUBLE *), void (*destroyCallback) (FTGLglyph *, void *)); /** * Destroy an FTGL glyph object. * * @param glyph An FTGLglyph* object. */ FTGL_EXPORT void ftglDestroyGlyph(FTGLglyph *glyph); /** * Render a glyph at the current pen position and compute the corresponding * advance. * * @param glyph An FTGLglyph* object. * @param penx The current pen's X position. * @param peny The current pen's Y position. * @param renderMode Render mode to display * @param advancex A pointer to an FTGL_DOUBLE where to write the advance's X * component. * @param advancey A pointer to an FTGL_DOUBLE where to write the advance's Y * component. */ FTGL_EXPORT void ftglRenderGlyph(FTGLglyph *glyph, FTGL_DOUBLE penx, FTGL_DOUBLE peny, int renderMode, FTGL_DOUBLE *advancex, FTGL_DOUBLE *advancey); /** * Return the advance for a glyph. * * @param glyph An FTGLglyph* object. * @return The advance's X component. */ FTGL_EXPORT float ftglGetGlyphAdvance(FTGLglyph *glyph); /** * Return the bounding box for a glyph. * * @param glyph An FTGLglyph* object. * @param bounds An array of 6 float values where the bounding box's lower * left near and upper right far 3D coordinates will be stored. */ FTGL_EXPORT void ftglGetGlyphBBox(FTGLglyph *glyph, float bounds[6]); /** * Query a glyph for errors. * * @param glyph An FTGLglyph* object. * @return The current error code. */ FTGL_EXPORT FT_Error ftglGetGlyphError(FTGLglyph* glyph); FTGL_END_C_DECLS #endif // __FTGlyph__ rgl/src/ext/ftgl/FTGL/FTGLExtrdFont.h0000644000176200001440000000617714100762641016674 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTExtrudeFont__ #define __FTExtrudeFont__ #ifdef __cplusplus /** * FTExtrudeFont is a specialisation of the FTFont class for handling * extruded Polygon fonts * * @see FTFont * @see FTPolygonFont */ class FTGL_EXPORT FTExtrudeFont : public FTFont { public: /** * Open and read a font file. Sets Error flag. * * @param fontFilePath font file path. */ FTExtrudeFont(const char* fontFilePath); /** * Open and read a font from a buffer in memory. Sets Error flag. * The buffer is owned by the client and is NOT copied by FTGL. The * pointer must be valid while using FTGL. * * @param pBufferBytes the in-memory buffer * @param bufferSizeInBytes the length of the buffer in bytes */ FTExtrudeFont(const unsigned char *pBufferBytes, size_t bufferSizeInBytes); /** * Destructor */ ~FTExtrudeFont(); protected: /** * Construct a glyph of the correct type. * * Clients must override the function and return their specialised * FTGlyph. * * @param slot A FreeType glyph slot. * @return An FT****Glyph or null on failure. */ virtual FTGlyph* MakeGlyph(FT_GlyphSlot slot); }; #define FTGLExtrdFont FTExtrudeFont #endif //__cplusplus FTGL_BEGIN_C_DECLS /** * Create a specialised FTGLfont object for handling extruded poygon fonts. * * @param file The font file name. * @return An FTGLfont* object. * * @see FTGLfont * @see ftglCreatePolygonFont */ FTGL_EXPORT FTGLfont *ftglCreateExtrudeFont(const char *file); FTGL_END_C_DECLS #endif // __FTExtrudeFont__ rgl/src/ext/ftgl/FTGL/FTPoint.h0000644000176200001440000001702414100762641015616 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTPoint__ #define __FTPoint__ #ifdef __cplusplus /** * FTPoint class is a basic 3-dimensional point or vector. */ class FTGL_EXPORT FTPoint { public: /** * Default constructor. Point is set to zero. */ inline FTPoint() { values[0] = 0; values[1] = 0; values[2] = 0; } /** * Constructor. Z coordinate is set to zero if unspecified. * * @param x First component * @param y Second component * @param z Third component */ inline FTPoint(const FTGL_DOUBLE x, const FTGL_DOUBLE y, const FTGL_DOUBLE z = 0) { values[0] = x; values[1] = y; values[2] = z; } /** * Constructor. This converts an FT_Vector to an FTPoint * * @param ft_vector A freetype vector */ inline FTPoint(const FT_Vector& ft_vector) { values[0] = ft_vector.x; values[1] = ft_vector.y; values[2] = 0; } /** * Normalise a point's coordinates. If the coordinates are zero, * the point is left untouched. * * @return A vector of norm one. */ FTPoint Normalise(); /** * Operator += In Place Addition. * * @param point * @return this plus point. */ inline FTPoint& operator += (const FTPoint& point) { values[0] += point.values[0]; values[1] += point.values[1]; values[2] += point.values[2]; return *this; } /** * Operator + * * @param point * @return this plus point. */ inline FTPoint operator + (const FTPoint& point) const { FTPoint temp; temp.values[0] = values[0] + point.values[0]; temp.values[1] = values[1] + point.values[1]; temp.values[2] = values[2] + point.values[2]; return temp; } /** * Operator -= In Place Substraction. * * @param point * @return this minus point. */ inline FTPoint& operator -= (const FTPoint& point) { values[0] -= point.values[0]; values[1] -= point.values[1]; values[2] -= point.values[2]; return *this; } /** * Operator - * * @param point * @return this minus point. */ inline FTPoint operator - (const FTPoint& point) const { FTPoint temp; temp.values[0] = values[0] - point.values[0]; temp.values[1] = values[1] - point.values[1]; temp.values[2] = values[2] - point.values[2]; return temp; } /** * Operator * Scalar multiplication * * @param multiplier * @return this multiplied by multiplier. */ inline FTPoint operator * (double multiplier) const { FTPoint temp; temp.values[0] = values[0] * multiplier; temp.values[1] = values[1] * multiplier; temp.values[2] = values[2] * multiplier; return temp; } /** * Operator * Scalar multiplication * * @param point * @param multiplier * @return multiplier multiplied by point. */ inline friend FTPoint operator * (double multiplier, FTPoint& point) { return point * multiplier; } /** * Operator * Scalar product * * @param a First vector. * @param b Second vector. * @return a.b scalar product. */ inline friend double operator * (FTPoint &a, FTPoint& b) { return a.values[0] * b.values[0] + a.values[1] * b.values[1] + a.values[2] * b.values[2]; } /** * Operator ^ Vector product * * @param point Second point * @return this vector point. */ inline FTPoint operator ^ (const FTPoint& point) { FTPoint temp; temp.values[0] = values[1] * point.values[2] - values[2] * point.values[1]; temp.values[1] = values[2] * point.values[0] - values[0] * point.values[2]; temp.values[2] = values[0] * point.values[1] - values[1] * point.values[0]; return temp; } /** * Operator == Tests for equality * * @param a * @param b * @return true if a & b are equal */ friend bool operator == (const FTPoint &a, const FTPoint &b); /** * Operator != Tests for non equality * * @param a * @param b * @return true if a & b are not equal */ friend bool operator != (const FTPoint &a, const FTPoint &b); /** * Cast to FTGL_DOUBLE* */ inline operator const FTGL_DOUBLE*() const { return values; } /** * Setters */ inline void X(FTGL_DOUBLE x) { values[0] = x; }; inline void Y(FTGL_DOUBLE y) { values[1] = y; }; inline void Z(FTGL_DOUBLE z) { values[2] = z; }; /** * Getters */ inline FTGL_DOUBLE X() const { return values[0]; }; inline FTGL_DOUBLE Y() const { return values[1]; }; inline FTGL_DOUBLE Z() const { return values[2]; }; inline FTGL_FLOAT Xf() const { return static_cast(values[0]); }; inline FTGL_FLOAT Yf() const { return static_cast(values[1]); }; inline FTGL_FLOAT Zf() const { return static_cast(values[2]); }; private: /** * The point data */ FTGL_DOUBLE values[3]; }; #endif //__cplusplus #endif // __FTPoint__ rgl/src/ext/ftgl/FTGL/FTExtrdGlyph.h0000644000176200001440000000727514100762641016626 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTExtrudeGlyph__ #define __FTExtrudeGlyph__ #ifdef __cplusplus /** * FTExtrudeGlyph is a specialisation of FTGlyph for creating tessellated * extruded polygon glyphs. */ class FTGL_EXPORT FTExtrudeGlyph : public FTGlyph { public: /** * Constructor. Sets the Error to Invalid_Outline if the glyph isn't * an outline. * * @param glyph The Freetype glyph to be processed * @param depth The distance along the z axis to extrude the glyph * @param frontOutset outset contour size * @param backOutset outset contour size * @param useDisplayList Enable or disable the use of Display Lists * for this glyph * true turns ON display lists. * false turns OFF display lists. */ FTExtrudeGlyph(FT_GlyphSlot glyph, float depth, float frontOutset, float backOutset, bool useDisplayList); /** * Destructor */ virtual ~FTExtrudeGlyph(); /** * Render this glyph at the current pen position. * * @param pen The current pen position. * @param renderMode Render mode to display * @return The advance distance for this glyph. */ virtual const FTPoint& Render(const FTPoint& pen, int renderMode); }; #define FTExtrdGlyph FTExtrudeGlyph #endif //__cplusplus FTGL_BEGIN_C_DECLS /** * Create a specialisation of FTGLglyph for creating tessellated * extruded polygon glyphs. * * @param glyph The Freetype glyph to be processed * @param depth The distance along the z axis to extrude the glyph * @param frontOutset outset contour size * @param backOutset outset contour size * @param useDisplayList Enable or disable the use of Display Lists * for this glyph * true turns ON display lists. * false turns OFF display lists. * @return An FTGLglyph* object. */ FTGL_EXPORT FTGLglyph *ftglCreateExtrudeGlyph(FT_GlyphSlot glyph, float depth, float frontOutset, float backOutset, int useDisplayList); FTGL_END_C_DECLS #endif // __FTExtrudeGlyph__ rgl/src/ext/ftgl/FTGL/FTGLTextureFont.h0000644000176200001440000000612614100762641017240 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTTextureFont__ #define __FTTextureFont__ #ifdef __cplusplus /** * FTTextureFont is a specialisation of the FTFont class for handling * Texture mapped fonts * * @see FTFont */ class FTGL_EXPORT FTTextureFont : public FTFont { public: /** * Open and read a font file. Sets Error flag. * * @param fontFilePath font file path. */ FTTextureFont(const char* fontFilePath); /** * Open and read a font from a buffer in memory. Sets Error flag. * The buffer is owned by the client and is NOT copied by FTGL. The * pointer must be valid while using FTGL. * * @param pBufferBytes the in-memory buffer * @param bufferSizeInBytes the length of the buffer in bytes */ FTTextureFont(const unsigned char *pBufferBytes, size_t bufferSizeInBytes); /** * Destructor */ virtual ~FTTextureFont(); protected: /** * Construct a glyph of the correct type. * * Clients must override the function and return their specialised * FTGlyph. * * @param slot A FreeType glyph slot. * @return An FT****Glyph or null on failure. */ virtual FTGlyph* MakeGlyph(FT_GlyphSlot slot); }; #define FTGLTextureFont FTTextureFont #endif //__cplusplus FTGL_BEGIN_C_DECLS /** * Create a specialised FTGLfont object for handling texture-mapped fonts. * * @param file The font file name. * @return An FTGLfont* object. * * @see FTGLfont */ FTGL_EXPORT FTGLfont *ftglCreateTextureFont(const char *file); FTGL_END_C_DECLS #endif // __FTTextureFont__ rgl/src/ext/ftgl/FTGL/FTGLBitmapFont.h0000644000176200001440000000606314100762641017014 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTBitmapFont__ #define __FTBitmapFont__ #ifdef __cplusplus /** * FTBitmapFont is a specialisation of the FTFont class for handling * Bitmap fonts * * @see FTFont */ class FTGL_EXPORT FTBitmapFont : public FTFont { public: /** * Open and read a font file. Sets Error flag. * * @param fontFilePath font file path. */ FTBitmapFont(const char* fontFilePath); /** * Open and read a font from a buffer in memory. Sets Error flag. * The buffer is owned by the client and is NOT copied by FTGL. The * pointer must be valid while using FTGL. * * @param pBufferBytes the in-memory buffer * @param bufferSizeInBytes the length of the buffer in bytes */ FTBitmapFont(const unsigned char *pBufferBytes, size_t bufferSizeInBytes); /** * Destructor */ ~FTBitmapFont(); protected: /** * Construct a glyph of the correct type. * * Clients must override the function and return their specialised * FTGlyph. * * @param slot A FreeType glyph slot. * @return An FT****Glyph or null on failure. */ virtual FTGlyph* MakeGlyph(FT_GlyphSlot slot); }; #define FTGLBitmapFont FTBitmapFont #endif //__cplusplus FTGL_BEGIN_C_DECLS /** * Create a specialised FTGLfont object for handling bitmap fonts. * * @param file The font file name. * @return An FTGLfont* object. * * @see FTGLfont */ FTGL_EXPORT FTGLfont *ftglCreateBitmapFont(const char *file); FTGL_END_C_DECLS #endif // __FTBitmapFont__ rgl/src/ext/ftgl/FTGL/FTFont.h0000644000176200001440000004730314100762641015436 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTFont__ #define __FTFont__ #ifdef __cplusplus class FTFontImpl; /** * FTFont is the public interface for the FTGL library. * * Specific font classes are derived from this class. It uses the helper * classes FTFace and FTSize to access the Freetype library. This class * is abstract and deriving classes must implement the protected * MakeGlyph function to create glyphs of the * appropriate type. * * It is good practice after using these functions to test the error * code returned. FT_Error Error(). Check the freetype file * fterrdef.h for error definitions. * * @see FTFace * @see FTSize */ class FTGL_EXPORT FTFont { protected: /** * Open and read a font file. Sets Error flag. * * @param fontFilePath font file path. */ FTFont(char const *fontFilePath); /** * Open and read a font from a buffer in memory. Sets Error flag. * The buffer is owned by the client and is NOT copied by FTGL. The * pointer must be valid while using FTGL. * * @param pBufferBytes the in-memory buffer * @param bufferSizeInBytes the length of the buffer in bytes */ FTFont(const unsigned char *pBufferBytes, size_t bufferSizeInBytes); private: /* Allow our internal subclasses to access the private constructor */ friend class FTBitmapFont; friend class FTBufferFont; friend class FTExtrudeFont; friend class FTOutlineFont; friend class FTPixmapFont; friend class FTPolygonFont; friend class FTTextureFont; /** * Internal FTGL FTFont constructor. For private use only. * * @param pImpl Internal implementation object. Will be destroyed * upon FTFont deletion. */ FTFont(FTFontImpl *pImpl); public: virtual ~FTFont(); /** * Attach auxilliary file to font e.g font metrics. * * Note: not all font formats implement this function. * * @param fontFilePath auxilliary font file path. * @return true if file has been attached * successfully. */ virtual bool Attach(const char* fontFilePath); /** * Attach auxilliary data to font e.g font metrics, from memory. * * Note: not all font formats implement this function. * * @param pBufferBytes the in-memory buffer. * @param bufferSizeInBytes the length of the buffer in bytes. * @return true if file has been attached * successfully. */ virtual bool Attach(const unsigned char *pBufferBytes, size_t bufferSizeInBytes); /** * Set the glyph loading flags. By default, fonts use the most * sensible flags when loading a font's glyph using FT_Load_Glyph(). * This function allows to override the default flags. * * @param flags The glyph loading flags. */ virtual void GlyphLoadFlags(FT_Int flags); /** * Set the character map for the face. * * @param encoding Freetype enumerate for char map code. * @return true if charmap was valid and * set correctly. */ virtual bool CharMap(FT_Encoding encoding); /** * Get the number of character maps in this face. * * @return character map count. */ virtual unsigned int CharMapCount() const; /** * Get a list of character maps in this face. * * @return pointer to the first encoding. */ virtual FT_Encoding* CharMapList(); /** * Set the char size for the current face. * * @param size the face size in points (1/72 inch) * @param res the resolution of the target device. * @return true if size was set correctly */ virtual bool FaceSize(const unsigned int size, const unsigned int res = 72); /** * Get the current face size in points (1/72 inch). * * @return face size */ virtual unsigned int FaceSize() const; /** * Set the extrusion distance for the font. Only implemented by * FTExtrudeFont * * @param depth The extrusion distance. */ virtual void Depth(float depth); /** * Set the outset distance for the font. Only implemented by * FTOutlineFont, FTPolygonFont and FTExtrudeFont * * @param outset The outset distance. */ virtual void Outset(float outset); /** * Set the front and back outset distances for the font. Only * implemented by FTExtrudeFont * * @param front The front outset distance. * @param back The back outset distance. */ virtual void Outset(float front, float back); /** * Enable or disable the use of Display Lists inside FTGL * * @param useList true turns ON display lists. * false turns OFF display lists. */ virtual void UseDisplayList(bool useList); /** * Get the global ascender height for the face. * * @return Ascender height */ virtual float Ascender() const; /** * Gets the global descender height for the face. * * @return Descender height */ virtual float Descender() const; /** * Gets the line spacing for the font. * * @return Line height */ virtual float LineHeight() const; /** * Get the bounding box for a string. * * @param string A char buffer. * @param len The length of the string. If < 0 then all characters * will be checked until a null character is encountered * (optional). * @param position The pen position of the first character (optional). * @param spacing A displacement vector to add after each character * has been checked (optional). * @return The corresponding bounding box. */ virtual FTBBox BBox(const char *string, const int len = -1, FTPoint position = FTPoint(), FTPoint spacing = FTPoint()); /** * Get the bounding box for a string (deprecated). * * @param string A char buffer. * @param llx Lower left near x coordinate. * @param lly Lower left near y coordinate. * @param llz Lower left near z coordinate. * @param urx Upper right far x coordinate. * @param ury Upper right far y coordinate. * @param urz Upper right far z coordinate. */ void BBox(const char* string, float& llx, float& lly, float& llz, float& urx, float& ury, float& urz) { FTBBox b = BBox(string); llx = b.Lower().Xf(); lly = b.Lower().Yf(); llz = b.Lower().Zf(); urx = b.Upper().Xf(); ury = b.Upper().Yf(); urz = b.Upper().Zf(); } /** * Get the bounding box for a string. * * @param string A wchar_t buffer. * @param len The length of the string. If < 0 then all characters * will be checked until a null character is encountered * (optional). * @param position The pen position of the first character (optional). * @param spacing A displacement vector to add after each character * has been checked (optional). * @return The corresponding bounding box. */ virtual FTBBox BBox(const wchar_t *string, const int len = -1, FTPoint position = FTPoint(), FTPoint spacing = FTPoint()); /** * Get the bounding box for a string (deprecated). * * @param string A wchar_t buffer. * @param llx Lower left near x coordinate. * @param lly Lower left near y coordinate. * @param llz Lower left near z coordinate. * @param urx Upper right far x coordinate. * @param ury Upper right far y coordinate. * @param urz Upper right far z coordinate. */ void BBox(const wchar_t* string, float& llx, float& lly, float& llz, float& urx, float& ury, float& urz) { FTBBox b = BBox(string); llx = b.Lower().Xf(); lly = b.Lower().Yf(); llz = b.Lower().Zf(); urx = b.Upper().Xf(); ury = b.Upper().Yf(); urz = b.Upper().Zf(); } /** * Get the advance for a string. * * @param string 'C' style string to be checked. * @param len The length of the string. If < 0 then all characters * will be checked until a null character is encountered * (optional). * @param spacing A displacement vector to add after each character * has been checked (optional). * @return The string's advance width. */ virtual float Advance(const char* string, const int len = -1, FTPoint spacing = FTPoint()); /** * Get the advance for a string. * * @param string A wchar_t string * @param len The length of the string. If < 0 then all characters * will be checked until a null character is encountered * (optional). * @param spacing A displacement vector to add after each character * has been checked (optional). * @return The string's advance width. */ virtual float Advance(const wchar_t* string, const int len = -1, FTPoint spacing = FTPoint()); /** * Render a string of characters. * * @param string 'C' style string to be output. * @param len The length of the string. If < 0 then all characters * will be displayed until a null character is encountered * (optional). * @param position The pen position of the first character (optional). * @param spacing A displacement vector to add after each character * has been displayed (optional). * @param renderMode Render mode to use for display (optional). * @return The new pen position after the last character was output. */ virtual FTPoint Render(const char* string, const int len = -1, FTPoint position = FTPoint(), FTPoint spacing = FTPoint(), int renderMode = FTGL::RENDER_ALL); /** * Render a string of characters * * @param string wchar_t string to be output. * @param len The length of the string. If < 0 then all characters * will be displayed until a null character is encountered * (optional). * @param position The pen position of the first character (optional). * @param spacing A displacement vector to add after each character * has been displayed (optional). * @param renderMode Render mode to use for display (optional). * @return The new pen position after the last character was output. */ virtual FTPoint Render(const wchar_t *string, const int len = -1, FTPoint position = FTPoint(), FTPoint spacing = FTPoint(), int renderMode = FTGL::RENDER_ALL); /** * Queries the Font for errors. * * @return The current error code. */ virtual FT_Error Error() const; protected: /* Allow impl to access MakeGlyph */ friend class FTFontImpl; /** * Construct a glyph of the correct type. * * Clients must override the function and return their specialised * FTGlyph. * * @param slot A FreeType glyph slot. * @return An FT****Glyph or null on failure. */ virtual FTGlyph* MakeGlyph(FT_GlyphSlot slot) = 0; private: /** * Internal FTGL FTFont implementation object. For private use only. */ FTFontImpl *impl; }; #endif //__cplusplus FTGL_BEGIN_C_DECLS /** * FTGLfont is the public interface for the FTGL library. * * It is good practice after using these functions to test the error * code returned. FT_Error Error(). Check the freetype file * fterrdef.h for error definitions. */ struct _FTGLFont; typedef struct _FTGLfont FTGLfont; /** * Create a custom FTGL font object. * * @param fontFilePath The font file name. * @param data A pointer to private data that will be passed to callbacks. * @param makeglyphCallback A glyph-making callback function. * @return An FTGLfont* object. */ FTGL_EXPORT FTGLfont *ftglCreateCustomFont(char const *fontFilePath, void *data, FTGLglyph * (*makeglyphCallback) (FT_GlyphSlot, void *)); /** * Destroy an FTGL font object. * * @param font An FTGLfont* object. */ FTGL_EXPORT void ftglDestroyFont(FTGLfont* font); /** * Attach auxilliary file to font e.g. font metrics. * * Note: not all font formats implement this function. * * @param font An FTGLfont* object. * @param path Auxilliary font file path. * @return 1 if file has been attached successfully. */ FTGL_EXPORT int ftglAttachFile(FTGLfont* font, const char* path); /** * Attach auxilliary data to font, e.g. font metrics, from memory. * * Note: not all font formats implement this function. * * @param font An FTGLfont* object. * @param data The in-memory buffer. * @param size The length of the buffer in bytes. * @return 1 if file has been attached successfully. */ FTGL_EXPORT int ftglAttachData(FTGLfont* font, const unsigned char * data, size_t size); /** * Set the character map for the face. * * @param font An FTGLfont* object. * @param encoding Freetype enumerate for char map code. * @return 1 if charmap was valid and set correctly. */ FTGL_EXPORT int ftglSetFontCharMap(FTGLfont* font, FT_Encoding encoding); /** * Get the number of character maps in this face. * * @param font An FTGLfont* object. * @return character map count. */ FTGL_EXPORT unsigned int ftglGetFontCharMapCount(FTGLfont* font); /** * Get a list of character maps in this face. * * @param font An FTGLfont* object. * @return pointer to the first encoding. */ FTGL_EXPORT FT_Encoding* ftglGetFontCharMapList(FTGLfont* font); /** * Set the char size for the current face. * * @param font An FTGLfont* object. * @param size The face size in points (1/72 inch). * @param res The resolution of the target device, or 0 to use the default * value of 72. * @return 1 if size was set correctly. */ FTGL_EXPORT int ftglSetFontFaceSize(FTGLfont* font, unsigned int size, unsigned int res); /** * Get the current face size in points (1/72 inch). * * @param font An FTGLfont* object. * @return face size */ FTGL_EXPORT unsigned int ftglGetFontFaceSize(FTGLfont* font); /** * Set the extrusion distance for the font. Only implemented by * FTExtrudeFont. * * @param font An FTGLfont* object. * @param depth The extrusion distance. */ FTGL_EXPORT void ftglSetFontDepth(FTGLfont* font, float depth); /** * Set the outset distance for the font. Only FTOutlineFont, FTPolygonFont * and FTExtrudeFont implement front outset. Only FTExtrudeFont implements * back outset. * * @param font An FTGLfont* object. * @param front The front outset distance. * @param back The back outset distance. */ FTGL_EXPORT void ftglSetFontOutset(FTGLfont* font, float front, float back); /** * Enable or disable the use of Display Lists inside FTGL. * * @param font An FTGLfont* object. * @param useList 1 turns ON display lists. * 0 turns OFF display lists. */ FTGL_EXPORT void ftglSetFontDisplayList(FTGLfont* font, int useList); /** * Get the global ascender height for the face. * * @param font An FTGLfont* object. * @return Ascender height */ FTGL_EXPORT float ftglGetFontAscender(FTGLfont* font); /** * Gets the global descender height for the face. * * @param font An FTGLfont* object. * @return Descender height */ FTGL_EXPORT float ftglGetFontDescender(FTGLfont* font); /** * Gets the line spacing for the font. * * @param font An FTGLfont* object. * @return Line height */ FTGL_EXPORT float ftglGetFontLineHeight(FTGLfont* font); /** * Get the bounding box for a string. * * @param font An FTGLfont* object. * @param string A char buffer * @param len The length of the string. If < 0 then all characters will be * checked until a null character is encountered (optional). * @param bounds An array of 6 float values where the bounding box's lower * left near and upper right far 3D coordinates will be stored. */ FTGL_EXPORT void ftglGetFontBBox(FTGLfont* font, const char *string, int len, float bounds[6]); /** * Get the advance width for a string. * * @param font An FTGLfont* object. * @param string A char string. * @return Advance width */ FTGL_EXPORT float ftglGetFontAdvance(FTGLfont* font, const char *string); /** * Render a string of characters. * * @param font An FTGLfont* object. * @param string Char string to be output. * @param mode Render mode to display. */ FTGL_EXPORT void ftglRenderFont(FTGLfont* font, const char *string, int mode); /** * Query a font for errors. * * @param font An FTGLfont* object. * @return The current error code. */ FTGL_EXPORT FT_Error ftglGetFontError(FTGLfont* font); FTGL_END_C_DECLS #endif // __FTFont__ rgl/src/ext/ftgl/FTGL/FTBufferGlyph.h0000644000176200001440000000426214100762641016742 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning Please use instead of . # include #endif #ifndef __FTBufferGlyph__ #define __FTBufferGlyph__ #ifdef __cplusplus /** * FTBufferGlyph is a specialisation of FTGlyph for memory buffer rendering. */ class FTGL_EXPORT FTBufferGlyph : public FTGlyph { public: /** * Constructor * * @param glyph The Freetype glyph to be processed * @param buffer An FTBuffer object in which to render the glyph. */ FTBufferGlyph(FT_GlyphSlot glyph, FTBuffer *buffer); /** * Destructor */ virtual ~FTBufferGlyph(); /** * Render this glyph at the current pen position. * * @param pen The current pen position. * @param renderMode Render mode to display * @return The advance distance for this glyph. */ virtual const FTPoint& Render(const FTPoint& pen, int renderMode); }; #endif //__cplusplus #endif // __FTBufferGlyph__ rgl/src/ext/ftgl/FTGL/ftgl.h0000644000176200001440000001017714100762641015231 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ #define __ftgl__ /* We need the Freetype headers */ #include #include FT_FREETYPE_H #include FT_GLYPH_H #include FT_OUTLINE_H /* Floating point types used by the library */ typedef double FTGL_DOUBLE; typedef float FTGL_FLOAT; /* Macros used to declare C-linkage types and symbols */ #ifdef __cplusplus # define FTGL_BEGIN_C_DECLS extern "C" { namespace FTGL { # define FTGL_END_C_DECLS } } #else # define FTGL_BEGIN_C_DECLS # define FTGL_END_C_DECLS #endif #ifdef __cplusplus namespace FTGL { typedef enum { RENDER_FRONT = 0x0001, RENDER_BACK = 0x0002, RENDER_SIDE = 0x0004, RENDER_ALL = 0xffff } RenderMode; typedef enum { ALIGN_LEFT = 0, ALIGN_CENTER = 1, ALIGN_RIGHT = 2, ALIGN_JUSTIFY = 3 } TextAlignment; } #else # define FTGL_RENDER_FRONT 0x0001 # define FTGL_RENDER_BACK 0x0002 # define FTGL_RENDER_SIDE 0x0004 # define FTGL_RENDER_ALL 0xffff # define FTGL_ALIGN_LEFT 0 # define FTGL_ALIGN_CENTER 1 # define FTGL_ALIGN_RIGHT 2 # define FTGL_ALIGN_JUSTIFY 3 #endif // Compiler-specific conditional compilation #ifdef _MSC_VER // MS Visual C++ // Disable various warning. // 4786: template name too long #pragma warning(disable : 4251) #pragma warning(disable : 4275) #pragma warning(disable : 4786) // The following definitions control how symbols are exported. // If the target is a static library ensure that FTGL_LIBRARY_STATIC // is defined. If building a dynamic library (ie DLL) ensure the // FTGL_LIBRARY macro is defined, as it will mark symbols for // export. If compiling a project to _use_ the _dynamic_ library // version of the library, no definition is required. #ifdef FTGL_LIBRARY_STATIC // static lib - no special export required # define FTGL_EXPORT #elif FTGL_LIBRARY // dynamic lib - must export/import symbols appropriately. # define FTGL_EXPORT __declspec(dllexport) #else # define FTGL_EXPORT __declspec(dllimport) #endif #else // Compiler that is not MS Visual C++. // Ensure that the export symbol is defined (and blank) #define FTGL_EXPORT #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif // __ftgl__ rgl/src/ext/ftgl/FTGL/FTBufferFont.h0000644000176200001440000000563414100762641016571 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning Please use instead of . # include #endif #ifndef __FTBufferFont__ #define __FTBufferFont__ #ifdef __cplusplus /** * FTBufferFont is a specialisation of the FTFont class for handling * memory buffer fonts. * * @see FTFont */ class FTGL_EXPORT FTBufferFont : public FTFont { public: /** * Open and read a font file. Sets Error flag. * * @param fontFilePath font file path. */ FTBufferFont(const char* fontFilePath); /** * Open and read a font from a buffer in memory. Sets Error flag. * The buffer is owned by the client and is NOT copied by FTGL. The * pointer must be valid while using FTGL. * * @param pBufferBytes the in-memory buffer * @param bufferSizeInBytes the length of the buffer in bytes */ FTBufferFont(const unsigned char *pBufferBytes, size_t bufferSizeInBytes); /** * Destructor */ ~FTBufferFont(); protected: /** * Construct a glyph of the correct type. * * Clients must override the function and return their specialised * FTGlyph. * * @param slot A FreeType glyph slot. * @return An FT****Glyph or null on failure. */ virtual FTGlyph* MakeGlyph(FT_GlyphSlot slot); }; #endif //__cplusplus FTGL_BEGIN_C_DECLS /** * Create a specialised FTGLfont object for handling memory buffer fonts. * * @param file The font file name. * @return An FTGLfont* object. * * @see FTGLfont */ FTGL_EXPORT FTGLfont *ftglCreateBufferFont(const char *file); FTGL_END_C_DECLS #endif // __FTBufferFont__ rgl/src/ext/ftgl/FTGL/FTOutlineGlyph.h0000644000176200001440000000635114100762641017151 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTOutlineGlyph__ #define __FTOutlineGlyph__ #ifdef __cplusplus /** * FTOutlineGlyph is a specialisation of FTGlyph for creating outlines. */ class FTGL_EXPORT FTOutlineGlyph : public FTGlyph { public: /** * Constructor. Sets the Error to Invalid_Outline if the glyphs isn't * an outline. * * @param glyph The Freetype glyph to be processed * @param outset outset distance * @param useDisplayList Enable or disable the use of Display Lists * for this glyph * true turns ON display lists. * false turns OFF display lists. */ FTOutlineGlyph(FT_GlyphSlot glyph, float outset, bool useDisplayList); /** * Destructor */ virtual ~FTOutlineGlyph(); /** * Render this glyph at the current pen position. * * @param pen The current pen position. * @param renderMode Render mode to display * @return The advance distance for this glyph. */ virtual const FTPoint& Render(const FTPoint& pen, int renderMode); }; #endif //__cplusplus FTGL_BEGIN_C_DECLS /** * Create a specialisation of FTGLglyph for creating outlines. * * @param glyph The Freetype glyph to be processed * @param outset outset contour size * @param useDisplayList Enable or disable the use of Display Lists * for this glyph * true turns ON display lists. * false turns OFF display lists. * @return An FTGLglyph* object. */ FTGL_EXPORT FTGLglyph *ftglCreateOutlineGlyph(FT_GlyphSlot glyph, float outset, int useDisplayList); FTGL_END_C_DECLS #endif // __FTOutlineGlyph__ rgl/src/ext/ftgl/FTGL/FTBBox.h0000644000176200001440000001177714100762641015370 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTBBox__ #define __FTBBox__ #ifdef __cplusplus /** * FTBBox is a convenience class for handling bounding boxes. */ class FTGL_EXPORT FTBBox { public: /** * Default constructor. Bounding box is set to zero. */ FTBBox() : lower(0.0f, 0.0f, 0.0f), upper(0.0f, 0.0f, 0.0f) {} /** * Constructor. */ FTBBox(float lx, float ly, float lz, float ux, float uy, float uz) : lower(lx, ly, lz), upper(ux, uy, uz) {} /** * Constructor. */ FTBBox(FTPoint l, FTPoint u) : lower(l), upper(u) {} /** * Constructor. Extracts a bounding box from a freetype glyph. Uses * the control box for the glyph. FT_Glyph_Get_CBox() * * @param glyph A freetype glyph */ FTBBox(FT_GlyphSlot glyph) : lower(0.0f, 0.0f, 0.0f), upper(0.0f, 0.0f, 0.0f) { FT_BBox bbox; FT_Outline_Get_CBox(&(glyph->outline), &bbox); lower.X(static_cast(bbox.xMin) / 64.0f); lower.Y(static_cast(bbox.yMin) / 64.0f); lower.Z(0.0f); upper.X(static_cast(bbox.xMax) / 64.0f); upper.Y(static_cast(bbox.yMax) / 64.0f); upper.Z(0.0f); } /** * Destructor */ ~FTBBox() {} /** * Mark the bounds invalid by setting all lower dimensions greater * than the upper dimensions. */ void Invalidate() { lower = FTPoint(1.0f, 1.0f, 1.0f); upper = FTPoint(-1.0f, -1.0f, -1.0f); } /** * Determines if this bounding box is valid. * * @return True if all lower values are <= the corresponding * upper values. */ bool IsValid() { return lower.X() <= upper.X() && lower.Y() <= upper.Y() && lower.Z() <= upper.Z(); } /** * Move the Bounding Box by a vector. * * @param vector The vector to move the bbox in 3D space. */ FTBBox& operator += (const FTPoint vector) { lower += vector; upper += vector; return *this; } /** * Combine two bounding boxes. The result is the smallest bounding * box containing the two original boxes. * * @param bbox The bounding box to merge with the second one. */ FTBBox& operator |= (const FTBBox& bbox) { if(bbox.lower.X() < lower.X()) lower.X(bbox.lower.X()); if(bbox.lower.Y() < lower.Y()) lower.Y(bbox.lower.Y()); if(bbox.lower.Z() < lower.Z()) lower.Z(bbox.lower.Z()); if(bbox.upper.X() > upper.X()) upper.X(bbox.upper.X()); if(bbox.upper.Y() > upper.Y()) upper.Y(bbox.upper.Y()); if(bbox.upper.Z() > upper.Z()) upper.Z(bbox.upper.Z()); return *this; } void SetDepth(float depth) { if(depth > 0) upper.Z(lower.Z() + depth); else lower.Z(upper.Z() + depth); } inline FTPoint const Upper() const { return upper; } inline FTPoint const Lower() const { return lower; } private: /** * The bounds of the box */ FTPoint lower, upper; }; #endif //__cplusplus #endif // __FTBBox__ rgl/src/ext/ftgl/FTGL/FTTextureGlyph.h0000644000176200001440000000677714100762641017206 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTTextureGlyph__ #define __FTTextureGlyph__ #ifdef __cplusplus /** * FTTextureGlyph is a specialisation of FTGlyph for creating texture * glyphs. */ class FTGL_EXPORT FTTextureGlyph : public FTGlyph { public: /** * Constructor * * @param glyph The Freetype glyph to be processed * @param id The id of the texture that this glyph will be * drawn in * @param xOffset The x offset into the parent texture to draw * this glyph * @param yOffset The y offset into the parent texture to draw * this glyph * @param width The width of the parent texture * @param height The height (number of rows) of the parent texture */ FTTextureGlyph(FT_GlyphSlot glyph, int id, int xOffset, int yOffset, int width, int height); /** * Destructor */ virtual ~FTTextureGlyph(); /** * Render this glyph at the current pen position. * * @param pen The current pen position. * @param renderMode Render mode to display * @return The advance distance for this glyph. */ virtual const FTPoint& Render(const FTPoint& pen, int renderMode); }; #endif //__cplusplus FTGL_BEGIN_C_DECLS /** * Create a specialisation of FTGLglyph for creating pixmaps. * * @param glyph The Freetype glyph to be processed. * @param id The id of the texture that this glyph will be drawn in. * @param xOffset The x offset into the parent texture to draw this glyph. * @param yOffset The y offset into the parent texture to draw this glyph. * @param width The width of the parent texture. * @param height The height (number of rows) of the parent texture. * @return An FTGLglyph* object. */ FTGL_EXPORT FTGLglyph *ftglCreateTextureGlyph(FT_GlyphSlot glyph, int id, int xOffset, int yOffset, int width, int height); FTGL_END_C_DECLS #endif // __FTTextureGlyph__ rgl/src/ext/ftgl/FTGL/FTBitmapGlyph.h0000644000176200001440000000472514100762641016751 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Sean Morrison * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __ftgl__ # warning This header is deprecated. Please use from now. # include #endif #ifndef __FTBitmapGlyph__ #define __FTBitmapGlyph__ #ifdef __cplusplus /** * FTBitmapGlyph is a specialisation of FTGlyph for creating bitmaps. */ class FTGL_EXPORT FTBitmapGlyph : public FTGlyph { public: /** * Constructor * * @param glyph The Freetype glyph to be processed */ FTBitmapGlyph(FT_GlyphSlot glyph); /** * Destructor */ virtual ~FTBitmapGlyph(); /** * Render this glyph at the current pen position. * * @param pen The current pen position. * @param renderMode Render mode to display * @return The advance distance for this glyph. */ virtual const FTPoint& Render(const FTPoint& pen, int renderMode); }; #endif //__cplusplus FTGL_BEGIN_C_DECLS /** * Create a specialisation of FTGLglyph for creating bitmaps. * * @param glyph The Freetype glyph to be processed * @return An FTGLglyph* object. */ FTGL_EXPORT FTGLglyph *ftglCreateBitmapGlyph(FT_GlyphSlot glyph); FTGL_END_C_DECLS #endif // __FTBitmapGlyph__ rgl/src/ext/ftgl/FTContour.cpp0000644000176200001440000001625314100762641015760 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * Copyright (c) 2008 Éric Beets * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTContour.h" #include static const unsigned int BEZIER_STEPS = 5; void FTContour::AddPoint(FTPoint point) { if(pointList.empty() || (point != pointList[pointList.size() - 1] && point != pointList[0])) { pointList.push_back(point); } } void FTContour::AddOutsetPoint(FTPoint point) { outsetPointList.push_back(point); } void FTContour::AddFrontPoint(FTPoint point) { frontPointList.push_back(point); } void FTContour::AddBackPoint(FTPoint point) { backPointList.push_back(point); } void FTContour::evaluateQuadraticCurve(FTPoint A, FTPoint B, FTPoint C) { for(unsigned int i = 1; i < BEZIER_STEPS; i++) { float t = static_cast(i) / BEZIER_STEPS; FTPoint U = (1.0f - t) * A + t * B; FTPoint V = (1.0f - t) * B + t * C; AddPoint((1.0f - t) * U + t * V); } } void FTContour::evaluateCubicCurve(FTPoint A, FTPoint B, FTPoint C, FTPoint D) { for(unsigned int i = 0; i < BEZIER_STEPS; i++) { float t = static_cast(i) / BEZIER_STEPS; FTPoint U = (1.0f - t) * A + t * B; FTPoint V = (1.0f - t) * B + t * C; FTPoint W = (1.0f - t) * C + t * D; FTPoint M = (1.0f - t) * U + t * V; FTPoint N = (1.0f - t) * V + t * W; AddPoint((1.0f - t) * M + t * N); } } // This function is a bit tricky. Given a path ABC, it returns the // coordinates of the outset point facing B on the left at a distance // of 64.0. // M // - - - - - - X // ^ / ' // | 64.0 / ' // X---->-----X ==> X--v-------X ' // A B \ A B \ .>' // \ \<' 64.0 // \ \ . // \ \ . // C X C X // FTPoint FTContour::ComputeOutsetPoint(FTPoint A, FTPoint B, FTPoint C) { /* Build the rotation matrix from 'ba' vector */ FTPoint ba = (A - B).Normalise(); FTPoint bc = C - B; /* Rotate bc to the left */ FTPoint tmp(bc.X() * -ba.X() + bc.Y() * -ba.Y(), bc.X() * ba.Y() + bc.Y() * -ba.X()); /* Compute the vector bisecting 'abc' */ FTGL_DOUBLE norm = sqrt(tmp.X() * tmp.X() + tmp.Y() * tmp.Y()); FTGL_DOUBLE dist = 64.0 * sqrt((norm - tmp.X()) / (norm + tmp.X())); tmp.X(tmp.Y() < 0.0 ? dist : -dist); tmp.Y(64.0); /* Rotate the new bc to the right */ return FTPoint(tmp.X() * -ba.X() + tmp.Y() * ba.Y(), tmp.X() * -ba.Y() + tmp.Y() * -ba.X()); } void FTContour::SetParity(int parity) { size_t size = PointCount(); FTPoint vOutset; if(((parity & 1) && clockwise) || (!(parity & 1) && !clockwise)) { // Contour orientation is wrong! We must reverse all points. // FIXME: could it be worth writing FTVector::reverse() for this? for(size_t i = 0; i < size / 2; i++) { FTPoint tmp = pointList[i]; pointList[i] = pointList[size - 1 - i]; pointList[size - 1 -i] = tmp; } clockwise = !clockwise; } for(size_t i = 0; i < size; i++) { size_t prev, cur, next; prev = (i + size - 1) % size; cur = i; next = (i + size + 1) % size; vOutset = ComputeOutsetPoint(Point(prev), Point(cur), Point(next)); AddOutsetPoint(vOutset); } } FTContour::FTContour(FT_Vector* contour, char* tags, unsigned int n) { FTPoint prev, cur(contour[(n - 1) % n]), next(contour[0]); FTPoint a, b = next - cur; double olddir, dir = atan2((next - cur).Y(), (next - cur).X()); double angle = 0.0; // See http://freetype.sourceforge.net/freetype2/docs/glyphs/glyphs-6.html // for a full description of FreeType tags. for(unsigned int i = 0; i < n; i++) { prev = cur; cur = next; next = FTPoint(contour[(i + 1) % n]); olddir = dir; dir = atan2((next - cur).Y(), (next - cur).X()); // Compute our path's new direction. double t = dir - olddir; if(t < -M_PI) t += 2 * M_PI; if(t > M_PI) t -= 2 * M_PI; angle += t; // Only process point tags we know. if(n < 2 || FT_CURVE_TAG(tags[i]) == FT_Curve_Tag_On) { AddPoint(cur); } else if(FT_CURVE_TAG(tags[i]) == FT_Curve_Tag_Conic) { FTPoint prev2 = prev, next2 = next; // Previous point is either the real previous point (an "on" // point), or the midpoint between the current one and the // previous "conic off" point. if(FT_CURVE_TAG(tags[(i - 1 + n) % n]) == FT_Curve_Tag_Conic) { prev2 = (cur + prev) * 0.5; AddPoint(prev2); } // Next point is either the real next point or the midpoint. if(FT_CURVE_TAG(tags[(i + 1) % n]) == FT_Curve_Tag_Conic) { next2 = (cur + next) * 0.5; } evaluateQuadraticCurve(prev2, cur, next2); } else if(FT_CURVE_TAG(tags[i]) == FT_Curve_Tag_Cubic && FT_CURVE_TAG(tags[(i + 1) % n]) == FT_Curve_Tag_Cubic) { evaluateCubicCurve(prev, cur, next, FTPoint(contour[(i + 2) % n])); } } // If final angle is positive (+2PI), it's an anti-clockwise contour, // otherwise (-2PI) it's clockwise. clockwise = (angle < 0.0); } void FTContour::buildFrontOutset(float outset) { for(size_t i = 0; i < PointCount(); ++i) { AddFrontPoint(Point(i) + Outset(i) * outset); } } void FTContour::buildBackOutset(float outset) { for(size_t i = 0; i < PointCount(); ++i) { AddBackPoint(Point(i) + Outset(i) * outset); } } rgl/src/ext/ftgl/FTGlyph/0000755000176200001440000000000014100762641014677 5ustar liggesusersrgl/src/ext/ftgl/FTGlyph/FTPixmapGlyphImpl.h0000644000176200001440000000375514100762641020400 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTPixmapGlyphImpl__ #define __FTPixmapGlyphImpl__ #include "FTGlyphImpl.h" class FTPixmapGlyphImpl : public FTGlyphImpl { friend class FTPixmapGlyph; protected: FTPixmapGlyphImpl(FT_GlyphSlot glyph); virtual ~FTPixmapGlyphImpl(); virtual const FTPoint& RenderImpl(const FTPoint& pen, int renderMode); private: /** * The width of the glyph 'image' */ int destWidth; /** * The height of the glyph 'image' */ int destHeight; /** * Vector from the pen position to the topleft corner of the pixmap */ FTPoint pos; /** * Pointer to the 'image' data */ unsigned char* data; }; #endif // __FTPixmapGlyphImpl__ rgl/src/ext/ftgl/FTGlyph/FTBitmapGlyph.cpp0000644000176200001440000000640514100762641020062 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include #include "FTGL/ftgl.h" #include "FTInternals.h" #include "FTBitmapGlyphImpl.h" // // FTGLBitmapGlyph // FTBitmapGlyph::FTBitmapGlyph(FT_GlyphSlot glyph) : FTGlyph(new FTBitmapGlyphImpl(glyph)) {} FTBitmapGlyph::~FTBitmapGlyph() {} const FTPoint& FTBitmapGlyph::Render(const FTPoint& pen, int renderMode) { FTBitmapGlyphImpl *myimpl = dynamic_cast(impl); return myimpl->RenderImpl(pen, renderMode); } // // FTGLBitmapGlyphImpl // FTBitmapGlyphImpl::FTBitmapGlyphImpl(FT_GlyphSlot glyph) : FTGlyphImpl(glyph), destWidth(0), destHeight(0), data(0) { err = FT_Render_Glyph(glyph, FT_RENDER_MODE_MONO); if(err || ft_glyph_format_bitmap != glyph->format) { return; } FT_Bitmap bitmap = glyph->bitmap; unsigned int srcWidth = bitmap.width; unsigned int srcHeight = bitmap.rows; unsigned int srcPitch = bitmap.pitch; destWidth = srcWidth; destHeight = srcHeight; destPitch = srcPitch; if(destWidth && destHeight) { data = new unsigned char[destPitch * destHeight]; unsigned char* dest = data + ((destHeight - 1) * destPitch); unsigned char* src = bitmap.buffer; for(unsigned int y = 0; y < srcHeight; ++y) { memcpy(dest, src, srcPitch); dest -= destPitch; src += srcPitch; } } pos = FTPoint(glyph->bitmap_left, static_cast(srcHeight) - glyph->bitmap_top, 0.0); } FTBitmapGlyphImpl::~FTBitmapGlyphImpl() { delete [] data; } const FTPoint& FTBitmapGlyphImpl::RenderImpl(const FTPoint& pen, int renderMode) { if(data) { float dx, dy; dx = pen.Xf() + pos.Xf(); dy = pen.Yf() - pos.Yf(); glBitmap(0, 0, 0.0f, 0.0f, dx, dy, (const GLubyte*)0); glPixelStorei(GL_UNPACK_ROW_LENGTH, destPitch * 8); glBitmap(destWidth, destHeight, 0.0f, 0.0, 0.0, 0.0, (const GLubyte*)data); glBitmap(0, 0, 0.0f, 0.0f, -dx, -dy, (const GLubyte*)0); } return advance; } rgl/src/ext/ftgl/FTGlyph/FTExtrudeGlyphImpl.h0000644000176200001440000000420114100762641020545 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTExtrudeGlyphImpl__ #define __FTExtrudeGlyphImpl__ #include "FTGlyphImpl.h" class FTVectoriser; class FTExtrudeGlyphImpl : public FTGlyphImpl { friend class FTExtrudeGlyph; protected: FTExtrudeGlyphImpl(FT_GlyphSlot glyph, float depth, float frontOutset, float backOutset, bool useDisplayList); virtual ~FTExtrudeGlyphImpl(); virtual const FTPoint& RenderImpl(const FTPoint& pen, int renderMode); private: /** * Private rendering methods. */ void RenderFront(); void RenderBack(); void RenderSide(); /** * Private rendering variables. */ unsigned int hscale, vscale; float depth; float frontOutset, backOutset; FTVectoriser *vectoriser; /** * OpenGL display list */ GLuint glList; }; #endif // __FTExtrudeGlyphImpl__ rgl/src/ext/ftgl/FTGlyph/FTTextureGlyphImpl.h0000644000176200001440000000537714100762641020604 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTTextureGlyphImpl__ #define __FTTextureGlyphImpl__ #include "FTGlyphImpl.h" class FTTextureGlyphImpl : public FTGlyphImpl { friend class FTTextureGlyph; friend class FTTextureFontImpl; protected: FTTextureGlyphImpl(FT_GlyphSlot glyph, int id, int xOffset, int yOffset, int width, int height); virtual ~FTTextureGlyphImpl(); virtual const FTPoint& RenderImpl(const FTPoint& pen, int renderMode); private: /** * Reset the currently active texture to zero to get into a known * state before drawing a string. This is to get round possible * threading issues. */ static void ResetActiveTexture() { activeTextureID = 0; } /** * The width of the glyph 'image' */ int destWidth; /** * The height of the glyph 'image' */ int destHeight; /** * Vector from the pen position to the topleft corner of the pixmap */ FTPoint corner; /** * The texture co-ords of this glyph within the texture. */ FTPoint uv[2]; /** * The texture index that this glyph is contained in. */ int glTextureID; /** * The texture index of the currently active texture * * We keep track of the currently active texture to try to reduce the * number of texture bind operations. */ static GLint activeTextureID; }; #endif // __FTTextureGlyphImpl__ rgl/src/ext/ftgl/FTGlyph/FTPolygonGlyphImpl.h0000644000176200001440000000377214100762641020570 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTPolygonGlyphImpl__ #define __FTPolygonGlyphImpl__ #include "FTGlyphImpl.h" class FTVectoriser; class FTPolygonGlyphImpl : public FTGlyphImpl { friend class FTPolygonGlyph; public: FTPolygonGlyphImpl(FT_GlyphSlot glyph, float outset, bool useDisplayList); virtual ~FTPolygonGlyphImpl(); virtual const FTPoint& RenderImpl(const FTPoint& pen, int renderMode); private: /** * Private rendering method. */ void DoRender(); /** * Private rendering variables. */ unsigned int hscale, vscale; FTVectoriser *vectoriser; float outset; /** * OpenGL display list */ GLuint glList; }; #endif // __FTPolygonGlyphImpl__ rgl/src/ext/ftgl/FTGlyph/FTBufferGlyph.cpp0000644000176200001440000000641114100762641020054 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include #include "FTGL/ftgl.h" #include "FTInternals.h" #include "FTBufferGlyphImpl.h" // // FTGLBufferGlyph // FTBufferGlyph::FTBufferGlyph(FT_GlyphSlot glyph, FTBuffer *buffer) : FTGlyph(new FTBufferGlyphImpl(glyph, buffer)) {} FTBufferGlyph::~FTBufferGlyph() {} const FTPoint& FTBufferGlyph::Render(const FTPoint& pen, int renderMode) { FTBufferGlyphImpl *myimpl = dynamic_cast(impl); return myimpl->RenderImpl(pen, renderMode); } // // FTGLBufferGlyphImpl // FTBufferGlyphImpl::FTBufferGlyphImpl(FT_GlyphSlot glyph, FTBuffer *p) : FTGlyphImpl(glyph), has_bitmap(false), buffer(p) { err = FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL); if(err || glyph->format != ft_glyph_format_bitmap) { return; } bitmap = glyph->bitmap; pixels = new unsigned char[bitmap.pitch * bitmap.rows]; memcpy(pixels, bitmap.buffer, bitmap.pitch * bitmap.rows); if(bitmap.width && bitmap.rows) { has_bitmap = true; corner = FTPoint(glyph->bitmap_left, glyph->bitmap_top); } } FTBufferGlyphImpl::~FTBufferGlyphImpl() { delete[] pixels; } const FTPoint& FTBufferGlyphImpl::RenderImpl(const FTPoint& pen, int renderMode) { if(has_bitmap) { FTPoint pos(buffer->Pos() + pen + corner); int dx = (int)(pos.Xf() + 0.5f); int dy = buffer->Height() - (int)(pos.Yf() + 0.5f); unsigned char * dest = buffer->Pixels() + dx + dy * buffer->Width(); for(unsigned int y = 0; y < bitmap.rows; y++) { // FIXME: change the loop bounds instead of doing this test if(static_cast(y) + dy < 0 || static_cast(y) + dy >= buffer->Height()) continue; for(unsigned int x = 0; x < bitmap.width; x++) { if(static_cast(x) + dx < 0 || static_cast(x) + dx >= buffer->Width()) continue; unsigned char p = pixels[y * bitmap.pitch + x]; if(p) { dest[y * buffer->Width() + x] = p; } } } } return advance; } rgl/src/ext/ftgl/FTGlyph/FTGlyphGlue.cpp0000644000176200001440000001473414100762641017546 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTGL/ftgl.h" #include "FTInternals.h" static const FTPoint static_ftpoint; static const FTBBox static_ftbbox; FTGL_BEGIN_C_DECLS #define C_TOR(cname, cargs, cxxname, cxxarg, cxxtype) \ FTGLglyph* cname cargs \ { \ cxxname *g = new cxxname cxxarg; \ if(g->Error()) \ { \ delete g; \ return NULL; \ } \ FTGLglyph *ftgl = (FTGLglyph *)malloc(sizeof(FTGLglyph)); \ ftgl->ptr = g; \ ftgl->type = cxxtype; \ return ftgl; \ } // FTBitmapGlyph::FTBitmapGlyph(); C_TOR(ftglCreateBitmapGlyph, (FT_GlyphSlot glyph), FTBitmapGlyph, (glyph), GLYPH_BITMAP); // FTBufferGlyph::FTBufferGlyph(); // FIXME: not implemented // FTExtrudeGlyph::FTExtrudeGlyph(); C_TOR(ftglCreateExtrudeGlyph, (FT_GlyphSlot glyph, float depth, float frontOutset, float backOutset, int useDisplayList), FTExtrudeGlyph, (glyph, depth, frontOutset, backOutset, (useDisplayList != 0)), GLYPH_EXTRUDE); // FTOutlineGlyph::FTOutlineGlyph(); C_TOR(ftglCreateOutlineGlyph, (FT_GlyphSlot glyph, float outset, int useDisplayList), FTOutlineGlyph, (glyph, outset, (useDisplayList != 0)), GLYPH_OUTLINE); // FTPixmapGlyph::FTPixmapGlyph(); C_TOR(ftglCreatePixmapGlyph, (FT_GlyphSlot glyph), FTPixmapGlyph, (glyph), GLYPH_PIXMAP); // FTPolygonGlyph::FTPolygonGlyph(); C_TOR(ftglCreatePolygonGlyph, (FT_GlyphSlot glyph, float outset, int useDisplayList), FTPolygonGlyph, (glyph, outset, (useDisplayList != 0)), GLYPH_POLYGON); // FTTextureGlyph::FTTextureGlyph(); C_TOR(ftglCreateTextureGlyph, (FT_GlyphSlot glyph, int id, int xOffset, int yOffset, int width, int height), FTTextureGlyph, (glyph, id, xOffset, yOffset, width, height), GLYPH_TEXTURE); // FTCustomGlyph::FTCustomGlyph(); class FTCustomGlyph : public FTGlyph { public: FTCustomGlyph(FTGLglyph *base, void *p, void (*render) (FTGLglyph *, void *, FTGL_DOUBLE, FTGL_DOUBLE, int, FTGL_DOUBLE *, FTGL_DOUBLE *), void (*destroy) (FTGLglyph *, void *)) : FTGlyph((FT_GlyphSlot)0), baseGlyph(base), data(p), renderCallback(render), destroyCallback(destroy) {} ~FTCustomGlyph() { destroyCallback(baseGlyph, data); } float Advance() const { return baseGlyph->ptr->Advance(); } const FTPoint& Render(const FTPoint& pen, int renderMode) { FTGL_DOUBLE advancex, advancey; renderCallback(baseGlyph, data, pen.X(), pen.Y(), renderMode, &advancex, &advancey); advance = FTPoint(advancex, advancey); return advance; } const FTBBox& BBox() const { return baseGlyph->ptr->BBox(); } FT_Error Error() const { return baseGlyph->ptr->Error(); } private: FTPoint advance; FTGLglyph *baseGlyph; void *data; void (*renderCallback) (FTGLglyph *, void *, FTGL_DOUBLE, FTGL_DOUBLE, int, FTGL_DOUBLE *, FTGL_DOUBLE *); void (*destroyCallback) (FTGLglyph *, void *); }; C_TOR(ftglCreateCustomGlyph, (FTGLglyph *base, void *data, void (*renderCallback) (FTGLglyph *, void *, FTGL_DOUBLE, FTGL_DOUBLE, int, FTGL_DOUBLE *, FTGL_DOUBLE *), void (*destroyCallback) (FTGLglyph *, void *)), FTCustomGlyph, (base, data, renderCallback, destroyCallback), GLYPH_CUSTOM); #define C_FUN(cret, cname, cargs, cxxerr, cxxname, cxxarg) \ cret cname cargs \ { \ if(!g || !g->ptr) \ { \ fprintf(stderr, "FTGL warning: NULL pointer in %s\n", #cname); \ cxxerr; \ } \ return g->ptr->cxxname cxxarg; \ } // FTGlyph::~FTGlyph(); void ftglDestroyGlyph(FTGLglyph *g) { if(!g || !g->ptr) { fprintf(stderr, "FTGL warning: NULL pointer in %s\n", __FUNCTION__); return; } delete g->ptr; free(g); } // const FTPoint& FTGlyph::Render(const FTPoint& pen, int renderMode); extern "C++" { C_FUN(static const FTPoint&, _ftglRenderGlyph, (FTGLglyph *g, const FTPoint& pen, int renderMode), return static_ftpoint, Render, (pen, renderMode)); } void ftglRenderGlyph(FTGLglyph *g, FTGL_DOUBLE penx, FTGL_DOUBLE peny, int renderMode, FTGL_DOUBLE *advancex, FTGL_DOUBLE *advancey) { FTPoint pen(penx, peny); FTPoint ret = _ftglRenderGlyph(g, pen, renderMode); *advancex = ret.X(); *advancey = ret.Y(); } // float FTGlyph::Advance() const; C_FUN(float, ftglGetGlyphAdvance, (FTGLglyph *g), return 0.0, Advance, ()); // const FTBBox& FTGlyph::BBox() const; extern "C++" { C_FUN(static const FTBBox&, _ftglGetGlyphBBox, (FTGLglyph *g), return static_ftbbox, BBox, ()); } void ftglGetGlyphBBox(FTGLglyph *g, float bounds[6]) { FTBBox ret = _ftglGetGlyphBBox(g); FTPoint lower = ret.Lower(), upper = ret.Upper(); bounds[0] = lower.Xf(); bounds[1] = lower.Yf(); bounds[2] = lower.Zf(); bounds[3] = upper.Xf(); bounds[4] = upper.Yf(); bounds[5] = upper.Zf(); } // FT_Error FTGlyph::Error() const; C_FUN(FT_Error, ftglGetGlyphError, (FTGLglyph *g), return -1, Error, ()); FTGL_END_C_DECLS rgl/src/ext/ftgl/FTGlyph/FTPixmapGlyph.cpp0000644000176200001440000000676714100762641020117 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include #include "FTGL/ftgl.h" #include "FTInternals.h" #include "FTPixmapGlyphImpl.h" // // FTGLPixmapGlyph // FTPixmapGlyph::FTPixmapGlyph(FT_GlyphSlot glyph) : FTGlyph(new FTPixmapGlyphImpl(glyph)) {} FTPixmapGlyph::~FTPixmapGlyph() {} const FTPoint& FTPixmapGlyph::Render(const FTPoint& pen, int renderMode) { FTPixmapGlyphImpl *myimpl = dynamic_cast(impl); return myimpl->RenderImpl(pen, renderMode); } // // FTGLPixmapGlyphImpl // FTPixmapGlyphImpl::FTPixmapGlyphImpl(FT_GlyphSlot glyph) : FTGlyphImpl(glyph), destWidth(0), destHeight(0), data(0) { err = FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL); if(err || ft_glyph_format_bitmap != glyph->format) { return; } FT_Bitmap bitmap = glyph->bitmap; //check the pixel mode //ft_pixel_mode_grays int srcWidth = bitmap.width; int srcHeight = bitmap.rows; destWidth = srcWidth; destHeight = srcHeight; if(destWidth && destHeight) { data = new unsigned char[destWidth * destHeight * 2]; unsigned char* src = bitmap.buffer; unsigned char* dest = data + ((destHeight - 1) * destWidth * 2); size_t destStep = destWidth * 2 * 2; for(int y = 0; y < srcHeight; ++y) { for(int x = 0; x < srcWidth; ++x) { *dest++ = static_cast(255); *dest++ = *src++; } dest -= destStep; } destHeight = srcHeight; } pos.X(glyph->bitmap_left); pos.Y(srcHeight - glyph->bitmap_top); } FTPixmapGlyphImpl::~FTPixmapGlyphImpl() { delete [] data; } const FTPoint& FTPixmapGlyphImpl::RenderImpl(const FTPoint& pen, int renderMode) { if(data) { float dx, dy; dx = floor(pen.Xf() + pos.Xf()); dy = floor(pen.Yf() - pos.Yf()); glBitmap(0, 0, 0.0f, 0.0f, dx, dy, (const GLubyte*)0); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 2); glDrawPixels(destWidth, destHeight, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, (const GLvoid*)data); glBitmap(0, 0, 0.0f, 0.0f, -dx, -dy, (const GLubyte*)0); } return advance; } rgl/src/ext/ftgl/FTGlyph/FTBitmapGlyphImpl.h0000644000176200001440000000414114100762641020344 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTBitmapGlyphImpl__ #define __FTBitmapGlyphImpl__ #include "FTGlyphImpl.h" class FTBitmapGlyphImpl : public FTGlyphImpl { friend class FTBitmapGlyph; protected: FTBitmapGlyphImpl(FT_GlyphSlot glyph); virtual ~FTBitmapGlyphImpl(); virtual const FTPoint& RenderImpl(const FTPoint& pen, int renderMode); private: /** * The width of the glyph 'image' */ unsigned int destWidth; /** * The height of the glyph 'image' */ unsigned int destHeight; /** * The pitch of the glyph 'image' */ unsigned int destPitch; /** * Vector from the pen position to the topleft corner of the bitmap */ FTPoint pos; /** * Pointer to the 'image' data */ unsigned char* data; }; #endif // __FTBitmapGlyphImpl__ rgl/src/ext/ftgl/FTGlyph/FTExtrudeGlyph.cpp0000644000176200001440000001631314100762641020265 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include #include "FTGL/ftgl.h" #include "FTInternals.h" #include "FTExtrudeGlyphImpl.h" #include "FTVectoriser.h" // // FTGLExtrudeGlyph // FTExtrudeGlyph::FTExtrudeGlyph(FT_GlyphSlot glyph, float depth, float frontOutset, float backOutset, bool useDisplayList) : FTGlyph(new FTExtrudeGlyphImpl(glyph, depth, frontOutset, backOutset, useDisplayList)) {} FTExtrudeGlyph::~FTExtrudeGlyph() {} const FTPoint& FTExtrudeGlyph::Render(const FTPoint& pen, int renderMode) { FTExtrudeGlyphImpl *myimpl = dynamic_cast(impl); return myimpl->RenderImpl(pen, renderMode); } // // FTGLExtrudeGlyphImpl // FTExtrudeGlyphImpl::FTExtrudeGlyphImpl(FT_GlyphSlot glyph, float _depth, float _frontOutset, float _backOutset, bool useDisplayList) : FTGlyphImpl(glyph), vectoriser(0), glList(0) { bBox.SetDepth(-_depth); if(ft_glyph_format_outline != glyph->format) { err = 0x14; // Invalid_Outline return; } vectoriser = new FTVectoriser(glyph); if((vectoriser->ContourCount() < 1) || (vectoriser->PointCount() < 3)) { delete vectoriser; vectoriser = NULL; return; } hscale = glyph->face->size->metrics.x_ppem * 64; vscale = glyph->face->size->metrics.y_ppem * 64; depth = _depth; frontOutset = _frontOutset; backOutset = _backOutset; if(useDisplayList) { glList = glGenLists(3); /* Front face */ glNewList(glList + 0, GL_COMPILE); RenderFront(); glEndList(); /* Back face */ glNewList(glList + 1, GL_COMPILE); RenderBack(); glEndList(); /* Side face */ glNewList(glList + 2, GL_COMPILE); RenderSide(); glEndList(); delete vectoriser; vectoriser = NULL; } } FTExtrudeGlyphImpl::~FTExtrudeGlyphImpl() { if(glList) { glDeleteLists(glList, 3); } else if(vectoriser) { delete vectoriser; } } const FTPoint& FTExtrudeGlyphImpl::RenderImpl(const FTPoint& pen, int renderMode) { glTranslatef(pen.Xf(), pen.Yf(), pen.Zf()); if(glList) { if(renderMode & FTGL::RENDER_FRONT) glCallList(glList + 0); if(renderMode & FTGL::RENDER_BACK) glCallList(glList + 1); if(renderMode & FTGL::RENDER_SIDE) glCallList(glList + 2); } else if(vectoriser) { if(renderMode & FTGL::RENDER_FRONT) RenderFront(); if(renderMode & FTGL::RENDER_BACK) RenderBack(); if(renderMode & FTGL::RENDER_SIDE) RenderSide(); } glTranslatef(-pen.Xf(), -pen.Yf(), -pen.Zf()); return advance; } void FTExtrudeGlyphImpl::RenderFront() { vectoriser->MakeMesh(1.0, 1, frontOutset); glNormal3d(0.0, 0.0, 1.0); const FTMesh *mesh = vectoriser->GetMesh(); for(unsigned int j = 0; j < mesh->TesselationCount(); ++j) { const FTTesselation* subMesh = mesh->Tesselation(j); unsigned int polygonType = subMesh->PolygonType(); glBegin(polygonType); for(unsigned int i = 0; i < subMesh->PointCount(); ++i) { FTPoint pt = subMesh->Point(i); glTexCoord2f(pt.Xf() / hscale, pt.Yf() / vscale); glVertex3f(pt.Xf() / 64.0f, pt.Yf() / 64.0f, 0.0f); } glEnd(); } } void FTExtrudeGlyphImpl::RenderBack() { vectoriser->MakeMesh(-1.0, 2, backOutset); glNormal3d(0.0, 0.0, -1.0); const FTMesh *mesh = vectoriser->GetMesh(); for(unsigned int j = 0; j < mesh->TesselationCount(); ++j) { const FTTesselation* subMesh = mesh->Tesselation(j); unsigned int polygonType = subMesh->PolygonType(); glBegin(polygonType); for(unsigned int i = 0; i < subMesh->PointCount(); ++i) { FTPoint pt = subMesh->Point(i); glTexCoord2f(subMesh->Point(i).Xf() / hscale, subMesh->Point(i).Yf() / vscale); glVertex3f(subMesh->Point(i).Xf() / 64.0f, subMesh->Point(i).Yf() / 64.0f, -depth); } glEnd(); } } void FTExtrudeGlyphImpl::RenderSide() { int contourFlag = vectoriser->ContourFlag(); for(size_t c = 0; c < vectoriser->ContourCount(); ++c) { const FTContour* contour = vectoriser->Contour(c); size_t n = contour->PointCount(); if(n < 2) { continue; } glBegin(GL_QUAD_STRIP); for(size_t j = 0; j <= n; ++j) { size_t cur = (j == n) ? 0 : j; size_t next = (cur == n - 1) ? 0 : cur + 1; FTPoint frontPt = contour->FrontPoint(cur); FTPoint nextPt = contour->FrontPoint(next); FTPoint backPt = contour->BackPoint(cur); FTPoint normal = FTPoint(0.f, 0.f, 1.f) ^ (frontPt - nextPt); if(normal != FTPoint(0.0f, 0.0f, 0.0f)) { glNormal3dv(static_cast(normal.Normalise())); } glTexCoord2f(frontPt.Xf() / hscale, frontPt.Yf() / vscale); if(contourFlag & ft_outline_reverse_fill) { glVertex3f(backPt.Xf() / 64.0f, backPt.Yf() / 64.0f, 0.0f); glVertex3f(frontPt.Xf() / 64.0f, frontPt.Yf() / 64.0f, -depth); } else { glVertex3f(backPt.Xf() / 64.0f, backPt.Yf() / 64.0f, -depth); glVertex3f(frontPt.Xf() / 64.0f, frontPt.Yf() / 64.0f, 0.0f); } } glEnd(); } } rgl/src/ext/ftgl/FTGlyph/FTOutlineGlyphImpl.h0000644000176200001440000000403014100762641020544 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTOutlineGlyphImpl__ #define __FTOutlineGlyphImpl__ #include "FTGlyphImpl.h" class FTVectoriser; class FTOutlineGlyphImpl : public FTGlyphImpl { friend class FTOutlineGlyph; protected: FTOutlineGlyphImpl(FT_GlyphSlot glyph, float outset, bool useDisplayList); virtual ~FTOutlineGlyphImpl(); virtual const FTPoint& RenderImpl(const FTPoint& pen, int renderMode); private: /** * Private rendering method. */ void DoRender(); /** * Private rendering variables. */ FTVectoriser *vectoriser; /** * Private rendering variables. */ float outset; /** * OpenGL display list */ GLuint glList; }; #endif // __FTOutlineGlyphImpl__ rgl/src/ext/ftgl/FTGlyph/FTGlyphImpl.h0000644000176200001440000000354014100762641017211 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTGlyphImpl__ #define __FTGlyphImpl__ #include "FTGL/ftgl.h" class FTGlyphImpl { friend class FTGlyph; protected: FTGlyphImpl(FT_GlyphSlot glyph, bool useDisplayList = true); virtual ~FTGlyphImpl(); float Advance() const; const FTBBox& BBox() const; FT_Error Error() const; /** * The advance distance for this glyph */ FTPoint advance; /** * The bounding box of this glyph. */ FTBBox bBox; /** * Current error code. Zero means no error. */ FT_Error err; }; #endif // __FTGlyphImpl__ rgl/src/ext/ftgl/FTGlyph/FTGlyph.cpp0000644000176200001440000000423414100762641016723 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTGL/ftgl.h" #include "FTInternals.h" #include "FTGlyphImpl.h" // // FTGlyph // FTGlyph::FTGlyph(FT_GlyphSlot glyph) { impl = new FTGlyphImpl(glyph); } FTGlyph::FTGlyph(FTGlyphImpl *pImpl) { impl = pImpl; } FTGlyph::~FTGlyph() { delete impl; } float FTGlyph::Advance() const { return impl->Advance(); } const FTBBox& FTGlyph::BBox() const { return impl->BBox(); } FT_Error FTGlyph::Error() const { return impl->Error(); } // // FTGlyphImpl // FTGlyphImpl::FTGlyphImpl(FT_GlyphSlot glyph, bool useList) : err(0) { if(glyph) { bBox = FTBBox(glyph); advance = FTPoint(glyph->advance.x / 64.0f, glyph->advance.y / 64.0f); } } FTGlyphImpl::~FTGlyphImpl() {} float FTGlyphImpl::Advance() const { return advance.Xf(); } const FTBBox& FTGlyphImpl::BBox() const { return bBox; } FT_Error FTGlyphImpl::Error() const { return err; } rgl/src/ext/ftgl/FTGlyph/FTTextureGlyph.cpp0000644000176200001440000001034614100762641020305 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include #include "FTGL/ftgl.h" #include "FTInternals.h" #include "FTTextureGlyphImpl.h" // // FTGLTextureGlyph // FTTextureGlyph::FTTextureGlyph(FT_GlyphSlot glyph, int id, int xOffset, int yOffset, int width, int height) : FTGlyph(new FTTextureGlyphImpl(glyph, id, xOffset, yOffset, width, height)) {} FTTextureGlyph::~FTTextureGlyph() {} const FTPoint& FTTextureGlyph::Render(const FTPoint& pen, int renderMode) { FTTextureGlyphImpl *myimpl = dynamic_cast(impl); return myimpl->RenderImpl(pen, renderMode); } // // FTGLTextureGlyphImpl // GLint FTTextureGlyphImpl::activeTextureID = 0; FTTextureGlyphImpl::FTTextureGlyphImpl(FT_GlyphSlot glyph, int id, int xOffset, int yOffset, int width, int height) : FTGlyphImpl(glyph), destWidth(0), destHeight(0), glTextureID(id) { /* FIXME: need to propagate the render mode all the way down to * here in order to get FT_RENDER_MODE_MONO aliased fonts. */ err = FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL); if(err || glyph->format != ft_glyph_format_bitmap) { return; } FT_Bitmap bitmap = glyph->bitmap; destWidth = bitmap.width; destHeight = bitmap.rows; if(destWidth && destHeight) { glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glBindTexture(GL_TEXTURE_2D, glTextureID); glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, destWidth, destHeight, GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.buffer); glPopClientAttrib(); } // 0 // +----+ // | | // | | // | | // +----+ // 1 uv[0].X(static_cast(xOffset) / static_cast(width)); uv[0].Y(static_cast(yOffset) / static_cast(height)); uv[1].X(static_cast(xOffset + destWidth) / static_cast(width)); uv[1].Y(static_cast(yOffset + destHeight) / static_cast(height)); corner = FTPoint(glyph->bitmap_left, glyph->bitmap_top); } FTTextureGlyphImpl::~FTTextureGlyphImpl() {} const FTPoint& FTTextureGlyphImpl::RenderImpl(const FTPoint& pen, int renderMode) { float dx, dy; if(activeTextureID != glTextureID) { glBindTexture(GL_TEXTURE_2D, (GLuint)glTextureID); activeTextureID = glTextureID; } dx = floor(pen.Xf() + corner.Xf()); dy = floor(pen.Yf() + corner.Yf()); glBegin(GL_QUADS); glTexCoord2f(uv[0].Xf(), uv[0].Yf()); glVertex2f(dx, dy); glTexCoord2f(uv[0].Xf(), uv[1].Yf()); glVertex2f(dx, dy - destHeight); glTexCoord2f(uv[1].Xf(), uv[1].Yf()); glVertex2f(dx + destWidth, dy - destHeight); glTexCoord2f(uv[1].Xf(), uv[0].Yf()); glVertex2f(dx + destWidth, dy); glEnd(); return advance; } rgl/src/ext/ftgl/FTGlyph/FTPolygonGlyph.cpp0000644000176200001440000000754414100762641020302 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Éric Beets * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTGL/ftgl.h" #include "FTInternals.h" #include "FTPolygonGlyphImpl.h" #include "FTVectoriser.h" // // FTGLPolyGlyph // FTPolygonGlyph::FTPolygonGlyph(FT_GlyphSlot glyph, float outset, bool useDisplayList) : FTGlyph(new FTPolygonGlyphImpl(glyph, outset, useDisplayList)) {} FTPolygonGlyph::~FTPolygonGlyph() {} const FTPoint& FTPolygonGlyph::Render(const FTPoint& pen, int renderMode) { FTPolygonGlyphImpl *myimpl = dynamic_cast(impl); return myimpl->RenderImpl(pen, renderMode); } // // FTGLPolyGlyphImpl // FTPolygonGlyphImpl::FTPolygonGlyphImpl(FT_GlyphSlot glyph, float _outset, bool useDisplayList) : FTGlyphImpl(glyph), glList(0) { if(ft_glyph_format_outline != glyph->format) { err = 0x14; // Invalid_Outline return; } vectoriser = new FTVectoriser(glyph); if((vectoriser->ContourCount() < 1) || (vectoriser->PointCount() < 3)) { delete vectoriser; vectoriser = NULL; return; } hscale = glyph->face->size->metrics.x_ppem * 64; vscale = glyph->face->size->metrics.y_ppem * 64; outset = _outset; if(useDisplayList) { glList = glGenLists(1); glNewList(glList, GL_COMPILE); DoRender(); glEndList(); delete vectoriser; vectoriser = NULL; } } FTPolygonGlyphImpl::~FTPolygonGlyphImpl() { if(glList) { glDeleteLists(glList, 1); } else if(vectoriser) { delete vectoriser; } } const FTPoint& FTPolygonGlyphImpl::RenderImpl(const FTPoint& pen, int renderMode) { glTranslatef(pen.Xf(), pen.Yf(), pen.Zf()); if(glList) { glCallList(glList); } else if(vectoriser) { DoRender(); } glTranslatef(-pen.Xf(), -pen.Yf(), -pen.Zf()); return advance; } void FTPolygonGlyphImpl::DoRender() { vectoriser->MakeMesh(1.0, 1, outset); const FTMesh *mesh = vectoriser->GetMesh(); for(unsigned int t = 0; t < mesh->TesselationCount(); ++t) { const FTTesselation* subMesh = mesh->Tesselation(t); unsigned int polygonType = subMesh->PolygonType(); glBegin(polygonType); for(unsigned int i = 0; i < subMesh->PointCount(); ++i) { FTPoint point = subMesh->Point(i); glTexCoord2f(point.Xf() / hscale, point.Yf() / vscale); glVertex3f(point.Xf() / 64.0f, point.Yf() / 64.0f, 0.0f); } glEnd(); } } rgl/src/ext/ftgl/FTGlyph/FTOutlineGlyph.cpp0000644000176200001440000000732614100762641020270 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Éric Beets * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTGL/ftgl.h" #include "FTInternals.h" #include "FTOutlineGlyphImpl.h" #include "FTVectoriser.h" // // FTGLOutlineGlyph // FTOutlineGlyph::FTOutlineGlyph(FT_GlyphSlot glyph, float outset, bool useDisplayList) : FTGlyph(new FTOutlineGlyphImpl(glyph, outset, useDisplayList)) {} FTOutlineGlyph::~FTOutlineGlyph() {} const FTPoint& FTOutlineGlyph::Render(const FTPoint& pen, int renderMode) { FTOutlineGlyphImpl *myimpl = dynamic_cast(impl); return myimpl->RenderImpl(pen, renderMode); } // // FTGLOutlineGlyphImpl // FTOutlineGlyphImpl::FTOutlineGlyphImpl(FT_GlyphSlot glyph, float _outset, bool useDisplayList) : FTGlyphImpl(glyph), glList(0) { if(ft_glyph_format_outline != glyph->format) { err = 0x14; // Invalid_Outline return; } vectoriser = new FTVectoriser(glyph); if((vectoriser->ContourCount() < 1) || (vectoriser->PointCount() < 3)) { delete vectoriser; vectoriser = NULL; return; } outset = _outset; if(useDisplayList) { glList = glGenLists(1); glNewList(glList, GL_COMPILE); DoRender(); glEndList(); delete vectoriser; vectoriser = NULL; } } FTOutlineGlyphImpl::~FTOutlineGlyphImpl() { if(glList) { glDeleteLists(glList, 1); } else if(vectoriser) { delete vectoriser; } } const FTPoint& FTOutlineGlyphImpl::RenderImpl(const FTPoint& pen, int renderMode) { glTranslatef(pen.Xf(), pen.Yf(), pen.Zf()); if(glList) { glCallList(glList); } else if(vectoriser) { DoRender(); } glTranslatef(-pen.Xf(), -pen.Yf(), -pen.Zf()); return advance; } void FTOutlineGlyphImpl::DoRender() { for(unsigned int c = 0; c < vectoriser->ContourCount(); ++c) { const FTContour* contour = vectoriser->Contour(c); glBegin(GL_LINE_LOOP); for(unsigned int i = 0; i < contour->PointCount(); ++i) { FTPoint point = FTPoint(contour->Point(i).X() + contour->Outset(i).X() * outset, contour->Point(i).Y() + contour->Outset(i).Y() * outset, 0); glVertex2f(point.Xf() / 64.0f, point.Yf() / 64.0f); } glEnd(); } } rgl/src/ext/ftgl/FTGlyph/FTBufferGlyphImpl.h0000644000176200001440000000326214100762641020344 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTBufferGlyphImpl__ #define __FTBufferGlyphImpl__ #include "FTGlyphImpl.h" class FTBufferGlyphImpl : public FTGlyphImpl { friend class FTBufferGlyph; protected: FTBufferGlyphImpl(FT_GlyphSlot glyph, FTBuffer *p); virtual ~FTBufferGlyphImpl(); virtual const FTPoint& RenderImpl(const FTPoint& pen, int renderMode); private: bool has_bitmap; FT_Bitmap bitmap; unsigned char *pixels; FTPoint corner; FTBuffer *buffer; }; #endif // __FTBufferGlyphImpl__ rgl/src/ext/ftgl/FTList.h0000644000176200001440000000630214100762641014701 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTList__ #define __FTList__ #include "FTGL/ftgl.h" /** * Provides a non-STL alternative to the STL list */ template class FTList { public: typedef FT_LIST_ITEM_TYPE value_type; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; /** * Constructor */ FTList() : listSize(0), tail(0) { tail = NULL; head = new Node; } /** * Destructor */ ~FTList() { Node* next; for(Node *walk = head; walk; walk = next) { next = walk->next; delete walk; } } /** * Get the number of items in the list */ size_type size() const { return listSize; } /** * Add an item to the end of the list */ void push_back(const value_type& item) { Node* node = new Node(item); if(head->next == NULL) { head->next = node; } if(tail) { tail->next = node; } tail = node; ++listSize; } /** * Get the item at the front of the list */ reference front() const { return head->next->payload; } /** * Get the item at the end of the list */ reference back() const { return tail->payload; } private: struct Node { Node() : next(NULL) {} Node(const value_type& item) : next(NULL) { payload = item; } Node* next; value_type payload; }; size_type listSize; Node* head; Node* tail; }; #endif // __FTList__ rgl/src/ext/ftgl/FTGlyphContainer.cpp0000644000176200001440000000635214100762641017254 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTGL/ftgl.h" #include "FTGlyphContainer.h" #include "FTFace.h" #include "FTCharmap.h" FTGlyphContainer::FTGlyphContainer(FTFace* f) : face(f), err(0) { glyphs.push_back(NULL); charMap = new FTCharmap(face); } FTGlyphContainer::~FTGlyphContainer() { GlyphVector::iterator it; for(it = glyphs.begin(); it != glyphs.end(); ++it) { delete *it; } glyphs.clear(); delete charMap; } bool FTGlyphContainer::CharMap(FT_Encoding encoding) { bool result = charMap->CharMap(encoding); err = charMap->Error(); return result; } unsigned int FTGlyphContainer::FontIndex(const unsigned int charCode) const { return charMap->FontIndex(charCode); } void FTGlyphContainer::Add(FTGlyph* tempGlyph, const unsigned int charCode) { charMap->InsertIndex(charCode, glyphs.size()); glyphs.push_back(tempGlyph); } const FTGlyph* const FTGlyphContainer::Glyph(const unsigned int charCode) const { unsigned int index = charMap->GlyphListIndex(charCode); return glyphs[index]; } FTBBox FTGlyphContainer::BBox(const unsigned int charCode) const { return Glyph(charCode)->BBox(); } float FTGlyphContainer::Advance(const unsigned int charCode, const unsigned int nextCharCode) { unsigned int left = charMap->FontIndex(charCode); unsigned int right = charMap->FontIndex(nextCharCode); return face->KernAdvance(left, right).Xf() + Glyph(charCode)->Advance(); } FTPoint FTGlyphContainer::Render(const unsigned int charCode, const unsigned int nextCharCode, FTPoint penPosition, int renderMode) { unsigned int left = charMap->FontIndex(charCode); unsigned int right = charMap->FontIndex(nextCharCode); FTPoint kernAdvance = face->KernAdvance(left, right); if(!face->Error()) { unsigned int index = charMap->GlyphListIndex(charCode); kernAdvance += glyphs[index]->Render(penPosition, renderMode); } return kernAdvance; } rgl/src/ext/ftgl/FTContour.h0000644000176200001440000001431514100762641015422 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Éric Beets * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTContour__ #define __FTContour__ #include "FTGL/ftgl.h" #include "FTVector.h" /** * FTContour class is a container of points that describe a vector font * outline. It is used as a container for the output of the bezier curve * evaluator in FTVectoriser. * * @see FTOutlineGlyph * @see FTPolygonGlyph * @see FTPoint */ class FTContour { public: /** * Constructor * * @param contour * @param pointTags * @param numberOfPoints */ FTContour(FT_Vector* contour, char* pointTags, unsigned int numberOfPoints); /** * Destructor */ ~FTContour() { pointList.clear(); outsetPointList.clear(); frontPointList.clear(); backPointList.clear(); } /** * Return a point at index. * * @param index of the point in the curve. * @return const point reference */ const FTPoint& Point(size_t index) const { return pointList[index]; } /** * Return a point at index. * * @param index of the point in the outset curve. * @return const point reference */ const FTPoint& Outset(size_t index) const { return outsetPointList[index]; } /** * Return a point at index of the front outset contour. * * @param index of the point in the curve. * @return const point reference */ const FTPoint& FrontPoint(size_t index) const { if(frontPointList.size() == 0) return Point(index); return frontPointList[index]; } /** * Return a point at index of the back outset contour. * * @param index of the point in the curve. * @return const point reference */ const FTPoint& BackPoint(size_t index) const { if(backPointList.size() == 0) return Point(index); return backPointList[index]; } /** * How many points define this contour * * @return the number of points in this contour */ size_t PointCount() const { return pointList.size(); } /** * Make sure the glyph has the proper parity and create the front/back * outset contour. * * @param parity The contour's parity within the glyph. */ void SetParity(int parity); // FIXME: this should probably go away. void buildFrontOutset(float outset); void buildBackOutset(float outset); private: /** * Add a point to this contour. This function tests for duplicate * points. * * @param point The point to be added to the contour. */ inline void AddPoint(FTPoint point); /** * Add a point to this contour. This function tests for duplicate * points. * * @param point The point to be added to the contour. */ inline void AddOutsetPoint(FTPoint point); /* * Add a point to this outset contour. This function tests for duplicate * points. * * @param point The point to be added to the contour outset. */ inline void AddFrontPoint(FTPoint point); inline void AddBackPoint(FTPoint point); /** * De Casteljau (bezier) algorithm contributed by Jed Soane * Evaluates a quadratic or conic (second degree) curve */ inline void evaluateQuadraticCurve(FTPoint, FTPoint, FTPoint); /** * De Casteljau (bezier) algorithm contributed by Jed Soane * Evaluates a cubic (third degree) curve */ inline void evaluateCubicCurve(FTPoint, FTPoint, FTPoint, FTPoint); /** * Compute the vector norm */ inline FTGL_DOUBLE NormVector(const FTPoint &v); /** * Compute a rotation matrix from a vector */ inline void RotationMatrix(const FTPoint &a, const FTPoint &b, FTGL_DOUBLE *matRot, FTGL_DOUBLE *invRot); /** * Matrix and vector multiplication */ inline void MultMatrixVect(FTGL_DOUBLE *mat, FTPoint &v); /** * Compute the vector bisecting from a vector 'v' and a distance 'd' */ inline void ComputeBisec(FTPoint &v); /** * Compute the outset point coordinates */ inline FTPoint ComputeOutsetPoint(FTPoint a, FTPoint b, FTPoint c); /** * The list of points in this contour */ typedef FTVector PointVector; PointVector pointList; PointVector outsetPointList; PointVector frontPointList; PointVector backPointList; /** * Is this contour clockwise or anti-clockwise? */ bool clockwise; }; #endif // __FTContour__ rgl/src/ext/ftgl/FTLayout/0000755000176200001440000000000014100762641015071 5ustar liggesusersrgl/src/ext/ftgl/FTLayout/FTSimpleLayout.cpp0000644000176200001440000003411414100762641020461 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include #include #include "FTInternals.h" #include "FTUnicode.h" #include "FTGlyphContainer.h" #include "FTSimpleLayoutImpl.h" // // FTSimpleLayout // FTSimpleLayout::FTSimpleLayout() : FTLayout(new FTSimpleLayoutImpl()) {} FTSimpleLayout::~FTSimpleLayout() {} FTBBox FTSimpleLayout::BBox(const char *string, const int len, FTPoint pos) { return dynamic_cast(impl)->BBox(string, len, pos); } FTBBox FTSimpleLayout::BBox(const wchar_t *string, const int len, FTPoint pos) { return dynamic_cast(impl)->BBox(string, len, pos); } void FTSimpleLayout::Render(const char *string, const int len, FTPoint pos, int renderMode) { return dynamic_cast(impl)->Render(string, len, pos, renderMode); } void FTSimpleLayout::Render(const wchar_t* string, const int len, FTPoint pos, int renderMode) { return dynamic_cast(impl)->Render(string, len, pos, renderMode); } void FTSimpleLayout::SetFont(FTFont *fontInit) { dynamic_cast(impl)->currentFont = fontInit; } FTFont *FTSimpleLayout::GetFont() { return dynamic_cast(impl)->currentFont; } void FTSimpleLayout::SetLineLength(const float LineLength) { dynamic_cast(impl)->lineLength = LineLength; } float FTSimpleLayout::GetLineLength() const { return dynamic_cast(impl)->lineLength; } void FTSimpleLayout::SetAlignment(const FTGL::TextAlignment Alignment) { dynamic_cast(impl)->alignment = Alignment; } FTGL::TextAlignment FTSimpleLayout::GetAlignment() const { return dynamic_cast(impl)->alignment; } void FTSimpleLayout::SetLineSpacing(const float LineSpacing) { dynamic_cast(impl)->lineSpacing = LineSpacing; } float FTSimpleLayout::GetLineSpacing() const { return dynamic_cast(impl)->lineSpacing; } // // FTSimpleLayoutImpl // FTSimpleLayoutImpl::FTSimpleLayoutImpl() { currentFont = NULL; lineLength = 100.0f; alignment = FTGL::ALIGN_LEFT; lineSpacing = 1.0f; } template inline FTBBox FTSimpleLayoutImpl::BBoxI(const T* string, const int len, FTPoint position) { FTBBox tmp; WrapText(string, len, position, 0, &tmp); return tmp; } FTBBox FTSimpleLayoutImpl::BBox(const char *string, const int len, FTPoint position) { return BBoxI(string, len, position); } FTBBox FTSimpleLayoutImpl::BBox(const wchar_t *string, const int len, FTPoint position) { return BBoxI(string, len, position); } template inline void FTSimpleLayoutImpl::RenderI(const T *string, const int len, FTPoint position, int renderMode) { pen = FTPoint(0.0f, 0.0f); WrapText(string, len, position, renderMode, NULL); } void FTSimpleLayoutImpl::Render(const char *string, const int len, FTPoint position, int renderMode) { RenderI(string, len, position, renderMode); } void FTSimpleLayoutImpl::Render(const wchar_t* string, const int len, FTPoint position, int renderMode) { RenderI(string, len, position, renderMode); } template inline void FTSimpleLayoutImpl::WrapTextI(const T *buf, const int len, FTPoint position, int renderMode, FTBBox *bounds) { FTUnicodeStringItr breakItr(buf); // points to the last break character FTUnicodeStringItr lineStart(buf); // points to the line start float nextStart = 0.0; // total width of the current line float breakWidth = 0.0; // width of the line up to the last word break float currentWidth = 0.0; // width of all characters on the current line float prevWidth; // width of all characters but the current glyph float wordLength = 0.0; // length of the block since the last break char int charCount = 0; // number of characters so far on the line int breakCharCount = 0; // number of characters before the breakItr float glyphWidth, advance; FTBBox glyphBounds; // Reset the pen position pen.Y(0); // If we have bounds mark them invalid if(bounds) { bounds->Invalidate(); } // Scan the input for all characters that need output FTUnicodeStringItr prevItr(buf); for (FTUnicodeStringItr itr(buf); *itr; prevItr = itr++, charCount++) { // Find the width of the current glyph glyphBounds = currentFont->BBox(itr.getBufferFromHere(), 1); glyphWidth = glyphBounds.Upper().Xf() - glyphBounds.Lower().Xf(); advance = currentFont->Advance(itr.getBufferFromHere(), 1); prevWidth = currentWidth; // Compute the width of all glyphs up to the end of buf[i] currentWidth = nextStart + glyphWidth; // Compute the position of the next glyph nextStart += advance; // See if the current character is a space, a break or a regular character if((currentWidth > lineLength) || (*itr == '\n')) { // A non whitespace character has exceeded the line length. Or a // newline character has forced a line break. Output the last // line and start a new line after the break character. // If we have not yet found a break, break on the last character if(breakItr == lineStart || (*itr == '\n')) { // Break on the previous character breakItr = prevItr; breakCharCount = charCount - 1; breakWidth = prevWidth; // None of the previous words will be carried to the next line wordLength = 0; // If the current character is a newline discard its advance if(*itr == '\n') advance = 0; } float remainingWidth = lineLength - breakWidth; // Render the current substring FTUnicodeStringItr breakChar = breakItr; // move past the break character and don't count it on the next line either ++breakChar; --charCount; // If the break character is a newline do not render it if(*breakChar == '\n') { ++breakChar; --charCount; } OutputWrapped(lineStart.getBufferFromHere(), breakCharCount, //breakItr.getBufferFromHere() - lineStart.getBufferFromHere(), position, renderMode, remainingWidth, bounds); // Store the start of the next line lineStart = breakChar; // TODO: Is Height() the right value here? pen -= FTPoint(0, currentFont->LineHeight() * lineSpacing); // The current width is the width since the last break nextStart = wordLength + advance; wordLength += advance; currentWidth = wordLength + advance; // Reset the safe break for the next line breakItr = lineStart; charCount -= breakCharCount; } else if(iswspace(*itr)) { // This is the last word break position wordLength = 0; breakItr = itr; breakCharCount = charCount; // Check to see if this is the first whitespace character in a run if(buf == itr.getBufferFromHere() || !iswspace(*prevItr)) { // Record the width of the start of the block breakWidth = currentWidth; } } else { wordLength += advance; } } float remainingWidth = lineLength - currentWidth; // Render any remaining text on the last line // Disable justification for the last row if(alignment == FTGL::ALIGN_JUSTIFY) { alignment = FTGL::ALIGN_LEFT; OutputWrapped(lineStart.getBufferFromHere(), -1, position, renderMode, remainingWidth, bounds); alignment = FTGL::ALIGN_JUSTIFY; } else { OutputWrapped(lineStart.getBufferFromHere(), -1, position, renderMode, remainingWidth, bounds); } } void FTSimpleLayoutImpl::WrapText(const char *buf, const int len, FTPoint position, int renderMode, FTBBox *bounds) { WrapTextI(buf, len, position, renderMode, bounds); } void FTSimpleLayoutImpl::WrapText(const wchar_t* buf, const int len, FTPoint position, int renderMode, FTBBox *bounds) { WrapTextI(buf, len, position, renderMode, bounds); } template inline void FTSimpleLayoutImpl::OutputWrappedI(const T *buf, const int len, FTPoint position, int renderMode, const float remaining, FTBBox *bounds) { float distributeWidth = 0.0; // Align the text according as specified by Alignment switch (alignment) { case FTGL::ALIGN_LEFT: pen.X(0); break; case FTGL::ALIGN_CENTER: pen.X(remaining / 2); break; case FTGL::ALIGN_RIGHT: pen.X(remaining); break; case FTGL::ALIGN_JUSTIFY: pen.X(0); distributeWidth = remaining; break; } // If we have bounds expand them by the line's bounds, otherwise render // the line. if(bounds) { FTBBox temp = currentFont->BBox(buf, len); // Add the extra space to the upper x dimension temp = FTBBox(temp.Lower() + pen, temp.Upper() + pen + FTPoint(distributeWidth, 0)); // See if this is the first area to be added to the bounds if(bounds->IsValid()) { *bounds |= temp; } else { *bounds = temp; } } else { RenderSpace(buf, len, position, renderMode, distributeWidth); } } void FTSimpleLayoutImpl::OutputWrapped(const char *buf, const int len, FTPoint position, int renderMode, const float remaining, FTBBox *bounds) { OutputWrappedI(buf, len, position, renderMode, remaining, bounds); } void FTSimpleLayoutImpl::OutputWrapped(const wchar_t *buf, const int len, FTPoint position, int renderMode, const float remaining, FTBBox *bounds) { OutputWrappedI(buf, len, position, renderMode, remaining, bounds); } template inline void FTSimpleLayoutImpl::RenderSpaceI(const T *string, const int len, FTPoint position, int renderMode, const float extraSpace) { float space = 0.0; // If there is space to distribute, count the number of spaces if(extraSpace > 0.0) { int numSpaces = 0; // Count the number of space blocks in the input FTUnicodeStringItr prevItr(string), itr(string); for(int i = 0; ((len < 0) && *itr) || ((len >= 0) && (i <= len)); ++i, prevItr = itr++) { // If this is the end of a space block, increment the counter if((i > 0) && !iswspace(*itr) && iswspace(*prevItr)) { numSpaces++; } } space = extraSpace/numSpaces; } // Output all characters of the string FTUnicodeStringItr prevItr(string), itr(string); for(int i = 0; ((len < 0) && *itr) || ((len >= 0) && (i <= len)); ++i, prevItr = itr++) { // If this is the end of a space block, distribute the extra space // inside it if((i > 0) && !iswspace(*itr) && iswspace(*prevItr)) { pen += FTPoint(space, 0); } pen = currentFont->Render(itr.getBufferFromHere(), 1, pen, FTPoint(), renderMode); } } void FTSimpleLayoutImpl::RenderSpace(const char *string, const int len, FTPoint position, int renderMode, const float extraSpace) { RenderSpaceI(string, len, position, renderMode, extraSpace); } void FTSimpleLayoutImpl::RenderSpace(const wchar_t *string, const int len, FTPoint position, int renderMode, const float extraSpace) { RenderSpaceI(string, len, position, renderMode, extraSpace); } rgl/src/ext/ftgl/FTLayout/FTSimpleLayoutImpl.h0000644000176200001440000002311314100762641020745 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTSimpleLayoutImpl__ #define __FTSimpleLayoutImpl__ #include "FTLayoutImpl.h" class FTFont; class FTSimpleLayoutImpl : public FTLayoutImpl { friend class FTSimpleLayout; protected: FTSimpleLayoutImpl(); virtual ~FTSimpleLayoutImpl() {}; virtual FTBBox BBox(const char* string, const int len, FTPoint position); virtual FTBBox BBox(const wchar_t* string, const int len, FTPoint position); virtual void Render(const char *string, const int len, FTPoint position, int renderMode); virtual void Render(const wchar_t *string, const int len, FTPoint position, int renderMode); /** * Render a string of characters and distribute extra space amongst * the whitespace regions of the string. * * @param string A buffer of wchar_t characters to output. * @param len The length of the string. If < 0 then all characters * will be displayed until a null character is encountered. * @param position TODO * @param renderMode Render mode to display * @param extraSpace The amount of extra space to distribute amongst * the characters. */ virtual void RenderSpace(const char *string, const int len, FTPoint position, int renderMode, const float extraSpace); /** * Render a string of characters and distribute extra space amongst * the whitespace regions of the string. * * @param string A buffer of wchar_t characters to output. * @param len The length of the string. If < 0 then all characters * will be displayed until a null character is encountered. * @param position TODO * @param renderMode Render mode to display * @param extraSpace The amount of extra space to distribute amongst * the characters. */ virtual void RenderSpace(const wchar_t *string, const int len, FTPoint position, int renderMode, const float extraSpace); private: /** * Either render a string of characters and wrap lines * longer than a threshold or compute the bounds * of a string of characters when wrapped. The functionality * of this method is exposed by the BBoxWrapped and * RenderWrapped methods. * * @param buf A char string to output. * @param len The length of the string. If < 0 then all characters * will be displayed until a null character is encountered. * @param position TODO * @param renderMode Render mode to display * @param bounds A pointer to a bounds object. If non null * the bounds of the text when laid out * will be stored in bounds. If null the * text will be rendered. */ virtual void WrapText(const char *buf, const int len, FTPoint position, int renderMode, FTBBox *bounds); /** * Either render a string of characters and wrap lines * longer than a threshold or compute the bounds * of a string of characters when wrapped. The functionality * of this method is exposed by the BBoxWrapped and * RenderWrapped methods. * * @param buf A wchar_t style string to output. * @param len The length of the string. If < 0 then all characters * will be displayed until a null character is encountered. * @param position TODO * @param renderMode Render mode to display * @param bounds A pointer to a bounds object. If non null * the bounds of the text when laid out * will be stored in bounds. If null the * text will be rendered. */ virtual void WrapText(const wchar_t *buf, const int len, FTPoint position, int renderMode, FTBBox *bounds); /** * A helper method used by WrapText to either output the text or * compute it's bounds. * * @param buf A pointer to an array of character data. * @param len The length of the string. If < 0 then all characters * will be displayed until a null character is encountered. * @param position TODO * @param renderMode Render mode to display * @param RemainingWidth The amount of extra space left on the line. * @param bounds A pointer to a bounds object. If non null the * bounds will be initialized or expanded by the * bounds of the line. If null the text will be * rendered. If the bounds are invalid (lower > upper) * they will be initialized. Otherwise they * will be expanded. */ void OutputWrapped(const char *buf, const int len, FTPoint position, int renderMode, const float RemainingWidth, FTBBox *bounds); /** * A helper method used by WrapText to either output the text or * compute it's bounds. * * @param buf A pointer to an array of character data. * @param len The length of the string. If < 0 then all characters * will be displayed until a null character is encountered. * @param position TODO * @param renderMode Render mode to display * @param RemainingWidth The amount of extra space left on the line. * @param bounds A pointer to a bounds object. If non null the * bounds will be initialized or expanded by the * bounds of the line. If null the text will be * rendered. If the bounds are invalid (lower > upper) * they will be initialized. Otherwise they * will be expanded. */ void OutputWrapped(const wchar_t *buf, const int len, FTPoint position, int renderMode, const float RemainingWidth, FTBBox *bounds); /** * The font to use for rendering the text. The font is * referenced by this but will not be disposed of when this * is deleted. */ FTFont *currentFont; /** * The maximum line length for formatting text. */ float lineLength; /** * The text alignment mode used to distribute * space within a line or rendered text. */ FTGL::TextAlignment alignment; /** * The height of each line of text expressed as * a percentage of the font's line height. */ float lineSpacing; /* Internal generic BBox() implementation */ template inline FTBBox BBoxI(const T* string, const int len, FTPoint position); /* Internal generic Render() implementation */ template inline void RenderI(const T* string, const int len, FTPoint position, int renderMode); /* Internal generic RenderSpace() implementation */ template inline void RenderSpaceI(const T* string, const int len, FTPoint position, int renderMode, const float extraSpace); /* Internal generic WrapText() implementation */ template void WrapTextI(const T* buf, const int len, FTPoint position, int renderMode, FTBBox *bounds); /* Internal generic OutputWrapped() implementation */ template void OutputWrappedI(const T* buf, const int len, FTPoint position, int renderMode, const float RemainingWidth, FTBBox *bounds); }; #endif // __FTSimpleLayoutImpl__ rgl/src/ext/ftgl/FTLayout/FTLayoutGlue.cpp0000644000176200001440000001255114100762641020125 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Éric Beets * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTInternals.h" static const FTBBox static_ftbbox; FTGL_BEGIN_C_DECLS #define C_TOR(cname, cargs, cxxname, cxxarg, cxxtype) \ FTGLlayout* cname cargs \ { \ cxxname *l = new cxxname cxxarg; \ if(l->Error()) \ { \ delete l; \ return NULL; \ } \ FTGLlayout *ftgl = (FTGLlayout *)malloc(sizeof(FTGLlayout)); \ ftgl->ptr = l; \ ftgl->type = cxxtype; \ return ftgl; \ } // FTSimpleLayout::FTSimpleLayout(); C_TOR(ftglCreateSimpleLayout, (), FTSimpleLayout, (), LAYOUT_SIMPLE); #define C_FUN(cret, cname, cargs, cxxerr, cxxname, cxxarg) \ cret cname cargs \ { \ if(!l || !l->ptr) \ { \ fprintf(stderr, "FTGL warning: NULL pointer in %s\n", #cname); \ cxxerr; \ } \ return l->ptr->cxxname cxxarg; \ } // FTLayout::~FTLayout(); void ftglDestroyLayout(FTGLlayout *l) { if(!l || !l->ptr) { fprintf(stderr, "FTGL warning: NULL pointer in %s\n", __FUNCTION__); return; } delete l->ptr; free(l); } // virtual FTBBox FTLayout::BBox(const char* string) extern "C++" { C_FUN(static FTBBox, _ftgGetlLayoutBBox, (FTGLlayout *l, const char *s), return static_ftbbox, BBox, (s)); } void ftgGetlLayoutBBox(FTGLlayout *l, const char * s, float c[6]) { FTBBox ret = _ftgGetlLayoutBBox(l, s); FTPoint lower = ret.Lower(), upper = ret.Upper(); c[0] = lower.Xf(); c[1] = lower.Yf(); c[2] = lower.Zf(); c[3] = upper.Xf(); c[4] = upper.Yf(); c[5] = upper.Zf(); } // virtual void FTLayout::Render(const char* string, int renderMode); C_FUN(void, ftglRenderLayout, (FTGLlayout *l, const char *s, int r), return, Render, (s, r)); // FT_Error FTLayout::Error() const; C_FUN(FT_Error, ftglGetLayoutError, (FTGLlayout *l), return -1, Error, ()); // void FTSimpleLayout::SetFont(FTFont *fontInit) void ftglSetLayoutFont(FTGLlayout *l, FTGLfont *font) { if(!l || !l->ptr) { fprintf(stderr, "FTGL warning: NULL pointer in %s\n", __FUNCTION__); return; } if(l->type != FTGL::LAYOUT_SIMPLE) { fprintf(stderr, "FTGL warning: %s not implemented for %d\n", __FUNCTION__, l->type); } l->font = font; return dynamic_cast(l->ptr)->SetFont(font->ptr); } // FTFont *FTSimpleLayout::GetFont() FTGLfont *ftglGetLayoutFont(FTGLlayout *l) { if(!l || !l->ptr) { fprintf(stderr, "FTGL warning: NULL pointer in %s\n", __FUNCTION__); return NULL; } if(l->type != FTGL::LAYOUT_SIMPLE) { fprintf(stderr, "FTGL warning: %s not implemented for %d\n", __FUNCTION__, l->type); } return l->font; } #undef C_FUN #define C_FUN(cret, cname, cargs, cxxerr, cxxname, cxxarg) \ cret cname cargs \ { \ if(!l || !l->ptr) \ { \ fprintf(stderr, "FTGL warning: NULL pointer in %s\n", #cname); \ cxxerr; \ } \ if(l->type != FTGL::LAYOUT_SIMPLE) \ { \ fprintf(stderr, "FTGL warning: %s not implemented for %d\n", \ __FUNCTION__, l->type); \ cxxerr; \ } \ return dynamic_cast(l->ptr)->cxxname cxxarg; \ } // void FTSimpleLayout::SetLineLength(const float LineLength); C_FUN(void, ftglSetLayoutLineLength, (FTGLlayout *l, const float length), return, SetLineLength, (length)); // float FTSimpleLayout::GetLineLength() const C_FUN(float, ftglGetLayoutLineLength, (FTGLlayout *l), return 0.0f, GetLineLength, ()); // void FTSimpleLayout::SetAlignment(const TextAlignment Alignment) C_FUN(void, ftglSetLayoutAlignment, (FTGLlayout *l, const int a), return, SetAlignment, ((FTGL::TextAlignment)a)); // TextAlignment FTSimpleLayout::GetAlignment() const C_FUN(int, ftglGetLayoutAlignement, (FTGLlayout *l), return FTGL::ALIGN_LEFT, GetAlignment, ()); // void FTSimpleLayout::SetLineSpacing(const float LineSpacing) C_FUN(void, ftglSetLayoutLineSpacing, (FTGLlayout *l, const float f), return, SetLineSpacing, (f)); FTGL_END_C_DECLS rgl/src/ext/ftgl/FTLayout/FTLayoutImpl.h0000644000176200001440000000324114100762641017573 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTLayoutImpl__ #define __FTLayoutImpl__ #include "FTSize.h" #include "FTGlyphContainer.h" class FTLayoutImpl { friend class FTLayout; protected: FTLayoutImpl(); virtual ~FTLayoutImpl(); protected: /** * Current pen or cursor position; */ FTPoint pen; /** * Current error code. Zero means no error. */ FT_Error err; }; #endif // __FTLayoutImpl__ rgl/src/ext/ftgl/FTLayout/FTLayout.cpp0000644000176200001440000000325514100762641017311 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTGL/ftgl.h" #include "../FTFont/FTFontImpl.h" #include "./FTLayoutImpl.h" // // FTLayout // FTLayout::FTLayout() { impl = new FTLayoutImpl(); } FTLayout::FTLayout(FTLayoutImpl *pImpl) { impl = pImpl; } FTLayout::~FTLayout() { delete impl; } FT_Error FTLayout::Error() const { return impl->err; } // // FTLayoutImpl // FTLayoutImpl::FTLayoutImpl() : err(0) { ; } FTLayoutImpl::~FTLayoutImpl() { ; } rgl/src/ext/ftgl/FTBuffer.cpp0000644000176200001440000000324214100762641015532 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTGL/ftgl.h" FTBuffer::FTBuffer() : width(0), height(0), pixels(0), pos(FTPoint()) { } FTBuffer::~FTBuffer() { if(pixels) { delete[] pixels; } } void FTBuffer::Size(int w, int h) { if(w == width && h == height) { return; } if(w * h != width * height) { if(pixels) { delete[] pixels; } pixels = new unsigned char[w * h]; } memset(pixels, 0, w * h); width = w; height = h; } rgl/src/ext/ftgl/FTLibrary.cpp0000644000176200001440000000404414100762641015726 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTLibrary.h" const FTLibrary& FTLibrary::Instance() { static FTLibrary ftlib; return ftlib; } FTLibrary::~FTLibrary() { if(library != 0) { FT_Done_FreeType(*library); delete library; library= 0; } // if(manager != 0) // { // FTC_Manager_Done(manager); // // delete manager; // manager= 0; // } } FTLibrary::FTLibrary() : library(0), err(0) { Initialise(); } bool FTLibrary::Initialise() { if(library != 0) return true; library = new FT_Library; err = FT_Init_FreeType(library); if(err) { delete library; library = 0; return false; } // FTC_Manager* manager; // // if(FTC_Manager_New(lib, 0, 0, 0, my_face_requester, 0, manager) // { // delete manager; // manager= 0; // return false; // } return true; } rgl/src/ext/ftgl/FTCharToGlyphIndexMap.h0000644000176200001440000001147614100762641017610 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTCharToGlyphIndexMap__ #define __FTCharToGlyphIndexMap__ #include #include "FTGL/ftgl.h" /** * Provides a non-STL alternative to the STL map * which maps character codes to glyph indices inside FTCharmap. * * Implementation: * - NumberOfBuckets buckets are considered. * - Each bucket has BucketSize entries. * - When the glyph index for the character code C has to be stored, the * bucket this character belongs to is found using 'C div BucketSize'. * If this bucket has not been allocated yet, do it now. * The entry in the bucked is found using 'C mod BucketSize'. * If it is set to IndexNotFound, then the glyph entry has not been set. * - Try to mimic the calls made to the STL map API. * * Caveats: * - The glyph index is now a signed long instead of unsigned long, so * the special value IndexNotFound (= -1) can be used to specify that the * glyph index has not been stored yet. */ class FTCharToGlyphIndexMap { public: typedef unsigned long CharacterCode; typedef signed long GlyphIndex; enum { NumberOfBuckets = 256, BucketSize = 256, IndexNotFound = -1 }; FTCharToGlyphIndexMap() { this->Indices = 0; } virtual ~FTCharToGlyphIndexMap() { if(this->Indices) { // Free all buckets this->clear(); // Free main structure delete [] this->Indices; this->Indices = 0; } } void clear() { if(this->Indices) { for(int i = 0; i < FTCharToGlyphIndexMap::NumberOfBuckets; i++) { if(this->Indices[i]) { delete [] this->Indices[i]; this->Indices[i] = 0; } } } } const GlyphIndex find(CharacterCode c) { if(!this->Indices) { return 0; } // Find position of char code in buckets div_t pos = div(static_cast(c), FTCharToGlyphIndexMap::BucketSize); if(!this->Indices[pos.quot]) { return 0; } const FTCharToGlyphIndexMap::GlyphIndex *ptr = &this->Indices[pos.quot][pos.rem]; if(*ptr == FTCharToGlyphIndexMap::IndexNotFound) { return 0; } return *ptr; } void insert(CharacterCode c, GlyphIndex g) { if(!this->Indices) { this->Indices = new GlyphIndex* [FTCharToGlyphIndexMap::NumberOfBuckets]; for(int i = 0; i < FTCharToGlyphIndexMap::NumberOfBuckets; i++) { this->Indices[i] = 0; } } // Find position of char code in buckets div_t pos = div(static_cast(c), FTCharToGlyphIndexMap::BucketSize); // Allocate bucket if does not exist yet if(!this->Indices[pos.quot]) { this->Indices[pos.quot] = new GlyphIndex [FTCharToGlyphIndexMap::BucketSize]; for(int i = 0; i < FTCharToGlyphIndexMap::BucketSize; i++) { this->Indices[pos.quot][i] = FTCharToGlyphIndexMap::IndexNotFound; } } this->Indices[pos.quot][pos.rem] = g; } private: GlyphIndex** Indices; }; #endif // __FTCharToGlyphIndexMap__ rgl/src/ext/ftgl/FTSize.h0000644000176200001440000001126714100762641014706 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTSize__ #define __FTSize__ #include #include FT_FREETYPE_H #include "FTGL/ftgl.h" /** * FTSize class provides an abstraction layer for the Freetype Size. * * @see "Freetype 2 Documentation" * */ class FTSize { public: /** * Default Constructor */ FTSize(); /** * Destructor */ virtual ~FTSize(); /** * Sets the char size for the current face. * * This doesn't guarantee that the size was set correctly. Clients * should check errors. If an error does occur the size object isn't modified. * * @param face Parent face for this size object * @param point_size the face size in points (1/72 inch) * @param x_resolution the horizontal resolution of the target device. * @param y_resolution the vertical resolution of the target device. * @return true if the size has been set. Clients should check Error() for more information if this function returns false() */ bool CharSize(FT_Face* face, unsigned int point_size, unsigned int x_resolution, unsigned int y_resolution); /** * get the char size for the current face. * * @return The char size in points */ unsigned int CharSize() const; /** * Gets the global ascender height for the face in pixels. * * @return Ascender height */ float Ascender() const; /** * Gets the global descender height for the face in pixels. * * @return Ascender height */ float Descender() const; /** * Gets the global face height for the face. * * If the face is scalable this returns the height of the global * bounding box which ensures that any glyph will be less than or * equal to this height. If the font isn't scalable there is no * guarantee that glyphs will not be taller than this value. * * @return height in pixels. */ float Height() const; /** * Gets the global face width for the face. * * If the face is scalable this returns the width of the global * bounding box which ensures that any glyph will be less than or * equal to this width. If the font isn't scalable this value is * the max_advance for the face. * * @return width in pixels. */ float Width() const; /** * Gets the underline position for the face. * * @return underline position in pixels */ float Underline() const; /** * Queries for errors. * * @return The current error code. */ FT_Error Error() const { return err; } private: /** * The current Freetype face that this FTSize object relates to. */ FT_Face* ftFace; /** * The Freetype size. */ FT_Size ftSize; /** * The size in points. */ unsigned int size; /** * The horizontal resolution. */ unsigned int xResolution; /** * The vertical resolution. */ unsigned int yResolution; /** * Current error code. Zero means no error. */ FT_Error err; }; #endif // __FTSize__ rgl/src/ext/ftgl/FTInternals.h0000644000176200001440000000644714100762641015737 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Éric Beets * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTINTERNALS_H__ #define __FTINTERNALS_H__ #include "FTGL/ftgl.h" #include #include // Fixes for deprecated identifiers in 2.1.5 #ifndef FT_OPEN_MEMORY #define FT_OPEN_MEMORY (FT_Open_Flags)1 #endif #ifndef FT_RENDER_MODE_MONO #define FT_RENDER_MODE_MONO ft_render_mode_mono #endif #ifndef FT_RENDER_MODE_NORMAL #define FT_RENDER_MODE_NORMAL ft_render_mode_normal #endif #ifdef WIN32 // Under windows avoid including is overrated. // Sure, it can be avoided and "name space pollution" can be // avoided, but why? It really doesn't make that much difference // these days. #define WIN32_LEAN_AND_MEAN #include #ifndef __gl_h_ #include #include #endif #else // Non windows platforms - don't require nonsense as seen above :-) #ifndef __gl_h_ #ifdef SDL_main #include "SDL_opengl.h" #elif __APPLE_CC__ #define GL_SILENCE_DEPRECATION #include #include #else #include #include #endif #endif // Required for compatibility with glext.h style function definitions of // OpenGL extensions, such as in src/osg/Point.cpp. #ifndef APIENTRY #define APIENTRY #endif #endif FTGL_BEGIN_C_DECLS typedef enum { GLYPH_CUSTOM, GLYPH_BITMAP, GLYPH_BUFFER, GLYPH_PIXMAP, GLYPH_OUTLINE, GLYPH_POLYGON, GLYPH_EXTRUDE, GLYPH_TEXTURE } GlyphType; struct _FTGLglyph { FTGlyph *ptr; FTGL::GlyphType type; }; typedef enum { FONT_CUSTOM, FONT_BITMAP, FONT_BUFFER, FONT_PIXMAP, FONT_OUTLINE, FONT_POLYGON, FONT_EXTRUDE, FONT_TEXTURE } FontType; struct _FTGLfont { FTFont *ptr; FTGL::FontType type; }; typedef enum { LAYOUT_SIMPLE } LayoutType; struct _FTGLlayout { FTLayout *ptr; FTGLfont *font; FTGL::LayoutType type; }; FTGL_END_C_DECLS #endif //__FTINTERNALS_H__ rgl/src/ext/ftgl/FTPoint.cpp0000644000176200001440000000363214100762641015415 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include #include "FTGL/ftgl.h" bool operator == (const FTPoint &a, const FTPoint &b) { return((a.values[0] == b.values[0]) && (a.values[1] == b.values[1]) && (a.values[2] == b.values[2])); } bool operator != (const FTPoint &a, const FTPoint &b) { return((a.values[0] != b.values[0]) || (a.values[1] != b.values[1]) || (a.values[2] != b.values[2])); } FTPoint FTPoint::Normalise() { double norm = sqrt(values[0] * values[0] + values[1] * values[1] + values[2] * values[2]); if(norm == 0.0) { return *this; } FTPoint temp(values[0] / norm, values[1] / norm, values[2] / norm); return temp; } rgl/src/ext/ftgl/FTFace.h0000644000176200001440000001223514100762641014626 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTFace__ #define __FTFace__ #include #include FT_FREETYPE_H #include FT_GLYPH_H #include "FTGL/ftgl.h" #include "FTSize.h" /** * FTFace class provides an abstraction layer for the Freetype Face. * * @see "Freetype 2 Documentation" * */ class FTFace { public: /** * Opens and reads a face file. Error is set. * * @param fontFilePath font file path. */ FTFace(const char* fontFilePath, bool precomputeKerning = true); /** * Read face data from an in-memory buffer. Error is set. * * @param pBufferBytes the in-memory buffer * @param bufferSizeInBytes the length of the buffer in bytes */ FTFace(const unsigned char *pBufferBytes, size_t bufferSizeInBytes, bool precomputeKerning = true); /** * Destructor * * Disposes of the current Freetype Face. */ virtual ~FTFace(); /** * Attach auxilliary file to font (e.g., font metrics). * * @param fontFilePath auxilliary font file path. * @return true if file has opened * successfully. */ bool Attach(const char* fontFilePath); /** * Attach auxilliary data to font (e.g., font metrics) from memory * * @param pBufferBytes the in-memory buffer * @param bufferSizeInBytes the length of the buffer in bytes * @return true if file has opened * successfully. */ bool Attach(const unsigned char *pBufferBytes, size_t bufferSizeInBytes); /** * Get the freetype face object.. * * @return pointer to an FT_Face. */ FT_Face* Face() const { return ftFace; } /** * Sets the char size for the current face. * * This doesn't guarantee that the size was set correctly. Clients * should check errors. * * @param size the face size in points (1/72 inch) * @param res the resolution of the target device. * @return FTSize object */ const FTSize& Size(const unsigned int size, const unsigned int res); /** * Get the number of character maps in this face. * * @return character map count. */ unsigned int CharMapCount() const; /** * Get a list of character maps in this face. * * @return pointer to the first encoding. */ FT_Encoding* CharMapList(); /** * Gets the kerning vector between two glyphs */ FTPoint KernAdvance(unsigned int index1, unsigned int index2); /** * Loads and creates a Freetype glyph. */ FT_GlyphSlot Glyph(unsigned int index, FT_Int load_flags); /** * Gets the number of glyphs in the current face. */ unsigned int GlyphCount() const { return numGlyphs; } /** * Queries for errors. * * @return The current error code. */ FT_Error Error() const { return err; } private: /** * The Freetype face */ FT_Face* ftFace; /** * The size object associated with this face */ FTSize charSize; /** * The number of glyphs in this face */ int numGlyphs; FT_Encoding* fontEncodingList; /** * This face has kerning tables */ bool hasKerningTable; /** * If this face has kerning tables, we can cache them. */ void BuildKerningCache(); static const unsigned int MAX_PRECOMPUTED = 128; float *kerningCache; /** * Current error code. Zero means no error. */ FT_Error err; }; #endif // __FTFace__ rgl/src/ext/ftgl/FTVectoriser.cpp0000644000176200001440000002106414100762641016450 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Éric Beets * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTInternals.h" #include "FTVectoriser.h" #ifndef CALLBACK #define CALLBACK #endif #if defined __APPLE_CC__ && __APPLE_CC__ < 5465 typedef GLvoid (*GLUTesselatorFunction) (...); #elif defined WIN32 && !defined __CYGWIN__ typedef GLvoid (CALLBACK *GLUTesselatorFunction) (); #else typedef GLvoid (*GLUTesselatorFunction) (); #endif void CALLBACK ftglError(GLenum errCode, FTMesh* mesh) { mesh->Error(errCode); } void CALLBACK ftglVertex(void* data, FTMesh* mesh) { FTGL_DOUBLE* vertex = static_cast(data); mesh->AddPoint(vertex[0], vertex[1], vertex[2]); } void CALLBACK ftglCombine(FTGL_DOUBLE coords[3], void* vertex_data[4], GLfloat weight[4], void** outData, FTMesh* mesh) { const FTGL_DOUBLE* vertex = static_cast(coords); *outData = const_cast(mesh->Combine(vertex[0], vertex[1], vertex[2])); } void CALLBACK ftglBegin(GLenum type, FTMesh* mesh) { mesh->Begin(type); } void CALLBACK ftglEnd(FTMesh* mesh) { mesh->End(); } FTMesh::FTMesh() : currentTesselation(0), err(0) { tesselationList.reserve(16); } FTMesh::~FTMesh() { for(size_t t = 0; t < tesselationList.size(); ++t) { delete tesselationList[t]; } tesselationList.clear(); } void FTMesh::AddPoint(const FTGL_DOUBLE x, const FTGL_DOUBLE y, const FTGL_DOUBLE z) { currentTesselation->AddPoint(x, y, z); } const FTGL_DOUBLE* FTMesh::Combine(const FTGL_DOUBLE x, const FTGL_DOUBLE y, const FTGL_DOUBLE z) { tempPointList.push_back(FTPoint(x, y,z)); return static_cast(tempPointList.back()); } void FTMesh::Begin(GLenum meshType) { currentTesselation = new FTTesselation(meshType); } void FTMesh::End() { tesselationList.push_back(currentTesselation); } const FTTesselation* const FTMesh::Tesselation(size_t index) const { return (index < tesselationList.size()) ? tesselationList[index] : NULL; } FTVectoriser::FTVectoriser(const FT_GlyphSlot glyph) : contourList(0), mesh(0), ftContourCount(0), contourFlag(0) { if(glyph) { outline = glyph->outline; ftContourCount = outline.n_contours; contourList = 0; contourFlag = outline.flags; ProcessContours(); } } FTVectoriser::~FTVectoriser() { for(size_t c = 0; c < ContourCount(); ++c) { delete contourList[c]; } delete [] contourList; delete mesh; } void FTVectoriser::ProcessContours() { short contourLength = 0; short startIndex = 0; short endIndex = 0; contourList = new FTContour*[ftContourCount]; for(int i = 0; i < ftContourCount; ++i) { FT_Vector* pointList = &outline.points[startIndex]; char* tagList = &outline.tags[startIndex]; endIndex = outline.contours[i]; contourLength = (endIndex - startIndex) + 1; FTContour* contour = new FTContour(pointList, tagList, contourLength); contourList[i] = contour; startIndex = endIndex + 1; } // Compute each contour's parity. FIXME: see if FT_Outline_Get_Orientation // can do it for us. for(int i = 0; i < ftContourCount; i++) { FTContour *c1 = contourList[i]; // 1. Find the leftmost point. FTPoint leftmost(65536.0, 0.0); for(size_t n = 0; n < c1->PointCount(); n++) { FTPoint p = c1->Point(n); if(p.X() < leftmost.X()) { leftmost = p; } } // 2. Count how many other contours we cross when going further to // the left. int parity = 0; for(int j = 0; j < ftContourCount; j++) { if(j == i) { continue; } FTContour *c2 = contourList[j]; for(size_t n = 0; n < c2->PointCount(); n++) { FTPoint p1 = c2->Point(n); FTPoint p2 = c2->Point((n + 1) % c2->PointCount()); /* FIXME: combinations of >= > <= and < do not seem stable */ if((p1.Y() < leftmost.Y() && p2.Y() < leftmost.Y()) || (p1.Y() >= leftmost.Y() && p2.Y() >= leftmost.Y()) || (p1.X() > leftmost.X() && p2.X() > leftmost.X())) { continue; } else if(p1.X() < leftmost.X() && p2.X() < leftmost.X()) { parity++; } else { FTPoint a = p1 - leftmost; FTPoint b = p2 - leftmost; if(b.X() * a.Y() > b.Y() * a.X()) { parity++; } } } } // 3. Make sure the glyph has the proper parity. c1->SetParity(parity); } } size_t FTVectoriser::PointCount() { size_t s = 0; for(size_t c = 0; c < ContourCount(); ++c) { s += contourList[c]->PointCount(); } return s; } const FTContour* const FTVectoriser::Contour(size_t index) const { return (index < ContourCount()) ? contourList[index] : NULL; } void FTVectoriser::MakeMesh(FTGL_DOUBLE zNormal, int outsetType, float outsetSize) { if(mesh) { delete mesh; } mesh = new FTMesh; GLUtesselator* tobj = gluNewTess(); gluTessCallback(tobj, GLU_TESS_BEGIN_DATA, (GLUTesselatorFunction)ftglBegin); gluTessCallback(tobj, GLU_TESS_VERTEX_DATA, (GLUTesselatorFunction)ftglVertex); gluTessCallback(tobj, GLU_TESS_COMBINE_DATA, (GLUTesselatorFunction)ftglCombine); gluTessCallback(tobj, GLU_TESS_END_DATA, (GLUTesselatorFunction)ftglEnd); gluTessCallback(tobj, GLU_TESS_ERROR_DATA, (GLUTesselatorFunction)ftglError); if(contourFlag & ft_outline_even_odd_fill) // ft_outline_reverse_fill { gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); } else { gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO); } gluTessProperty(tobj, GLU_TESS_TOLERANCE, 0); gluTessNormal(tobj, 0.0f, 0.0f, zNormal); gluTessBeginPolygon(tobj, mesh); for(size_t c = 0; c < ContourCount(); ++c) { /* Build the */ switch(outsetType) { case 1 : contourList[c]->buildFrontOutset(outsetSize); break; case 2 : contourList[c]->buildBackOutset(outsetSize); break; } const FTContour* contour = contourList[c]; gluTessBeginContour(tobj); for(size_t p = 0; p < contour->PointCount(); ++p) { const FTGL_DOUBLE* d; switch(outsetType) { case 1: d = contour->FrontPoint(p); break; case 2: d = contour->BackPoint(p); break; case 0: default: d = contour->Point(p); break; } // XXX: gluTessVertex doesn't modify the data but does not // specify "const" in its prototype, so we cannot cast to // a const type. gluTessVertex(tobj, (GLdouble *)d, (GLvoid *)d); } gluTessEndContour(tobj); } gluTessEndPolygon(tobj); gluDeleteTess(tobj); } rgl/src/ext/ftgl/FTFont/0000755000176200001440000000000014100762641014522 5ustar liggesusersrgl/src/ext/ftgl/FTFont/FTPixmapFont.cpp0000644000176200001440000000770714100762641017560 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTGL/ftgl.h" #include "FTInternals.h" #include "FTPixmapFontImpl.h" // // FTPixmapFont // FTPixmapFont::FTPixmapFont(char const *fontFilePath) : FTFont(new FTPixmapFontImpl(this, fontFilePath)) {} FTPixmapFont::FTPixmapFont(const unsigned char *pBufferBytes, size_t bufferSizeInBytes) : FTFont(new FTPixmapFontImpl(this, pBufferBytes, bufferSizeInBytes)) {} FTPixmapFont::~FTPixmapFont() {} FTGlyph* FTPixmapFont::MakeGlyph(FT_GlyphSlot ftGlyph) { return new FTPixmapGlyph(ftGlyph); } // // FTPixmapFontImpl // FTPixmapFontImpl::FTPixmapFontImpl(FTFont *ftFont, const char* fontFilePath) : FTFontImpl(ftFont, fontFilePath) { load_flags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP; } FTPixmapFontImpl::FTPixmapFontImpl(FTFont *ftFont, const unsigned char *pBufferBytes, size_t bufferSizeInBytes) : FTFontImpl(ftFont, pBufferBytes, bufferSizeInBytes) { load_flags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP; } template inline FTPoint FTPixmapFontImpl::RenderI(const T* string, const int len, FTPoint position, FTPoint spacing, int renderMode) { // Protect GL_TEXTURE_2D and GL_BLEND, glPixelTransferf(), and blending // functions. glPushAttrib(GL_ENABLE_BIT | GL_PIXEL_MODE_BIT | GL_COLOR_BUFFER_BIT | GL_POLYGON_BIT); // Protect glPixelStorei() calls (made by FTPixmapGlyphImpl::RenderImpl). glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); // Needed on OSX glPolygonMode(GL_FRONT, GL_FILL); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_TEXTURE_2D); GLfloat ftglColour[4]; glGetFloatv(GL_CURRENT_RASTER_COLOR, ftglColour); glPixelTransferf(GL_RED_SCALE, ftglColour[0]); glPixelTransferf(GL_GREEN_SCALE, ftglColour[1]); glPixelTransferf(GL_BLUE_SCALE, ftglColour[2]); glPixelTransferf(GL_ALPHA_SCALE, ftglColour[3]); FTPoint tmp = FTFontImpl::Render(string, len, position, spacing, renderMode); glPopClientAttrib(); glPopAttrib(); return tmp; } FTPoint FTPixmapFontImpl::Render(const char * string, const int len, FTPoint position, FTPoint spacing, int renderMode) { return RenderI(string, len, position, spacing, renderMode); } FTPoint FTPixmapFontImpl::Render(const wchar_t * string, const int len, FTPoint position, FTPoint spacing, int renderMode) { return RenderI(string, len, position, spacing, renderMode); } rgl/src/ext/ftgl/FTFont/FTOutlineFont.cpp0000644000176200001440000000733214100762641017733 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTGL/ftgl.h" #include "FTInternals.h" #include "FTOutlineFontImpl.h" // // FTOutlineFont // FTOutlineFont::FTOutlineFont(char const *fontFilePath) : FTFont(new FTOutlineFontImpl(this, fontFilePath)) {} FTOutlineFont::FTOutlineFont(const unsigned char *pBufferBytes, size_t bufferSizeInBytes) : FTFont(new FTOutlineFontImpl(this, pBufferBytes, bufferSizeInBytes)) {} FTOutlineFont::~FTOutlineFont() {} FTGlyph* FTOutlineFont::MakeGlyph(FT_GlyphSlot ftGlyph) { FTOutlineFontImpl *myimpl = dynamic_cast(impl); if(!myimpl) { return NULL; } return new FTOutlineGlyph(ftGlyph, myimpl->outset, myimpl->useDisplayLists); } // // FTOutlineFontImpl // FTOutlineFontImpl::FTOutlineFontImpl(FTFont *ftFont, const char* fontFilePath) : FTFontImpl(ftFont, fontFilePath), outset(0.0f) { load_flags = FT_LOAD_NO_HINTING; } FTOutlineFontImpl::FTOutlineFontImpl(FTFont *ftFont, const unsigned char *pBufferBytes, size_t bufferSizeInBytes) : FTFontImpl(ftFont, pBufferBytes, bufferSizeInBytes), outset(0.0f) { load_flags = FT_LOAD_NO_HINTING; } template inline FTPoint FTOutlineFontImpl::RenderI(const T* string, const int len, FTPoint position, FTPoint spacing, int renderMode) { // Protect GL_TEXTURE_2D, glHint(), GL_LINE_SMOOTH and blending functions glPushAttrib(GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_COLOR_BUFFER_BIT); glDisable(GL_TEXTURE_2D); glEnable(GL_LINE_SMOOTH); glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE FTPoint tmp = FTFontImpl::Render(string, len, position, spacing, renderMode); glPopAttrib(); return tmp; } FTPoint FTOutlineFontImpl::Render(const char * string, const int len, FTPoint position, FTPoint spacing, int renderMode) { return RenderI(string, len, position, spacing, renderMode); } FTPoint FTOutlineFontImpl::Render(const wchar_t * string, const int len, FTPoint position, FTPoint spacing, int renderMode) { return RenderI(string, len, position, spacing, renderMode); } rgl/src/ext/ftgl/FTFont/FTTextureFont.cpp0000644000176200001440000001644714100762641017763 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include #include // For memset #include "FTGL/ftgl.h" #include "FTInternals.h" #include "../FTGlyph/FTTextureGlyphImpl.h" #include "./FTTextureFontImpl.h" // // FTTextureFont // FTTextureFont::FTTextureFont(char const *fontFilePath) : FTFont(new FTTextureFontImpl(this, fontFilePath)) {} FTTextureFont::FTTextureFont(const unsigned char *pBufferBytes, size_t bufferSizeInBytes) : FTFont(new FTTextureFontImpl(this, pBufferBytes, bufferSizeInBytes)) {} FTTextureFont::~FTTextureFont() {} FTGlyph* FTTextureFont::MakeGlyph(FT_GlyphSlot ftGlyph) { FTTextureFontImpl *myimpl = dynamic_cast(impl); if(!myimpl) { return NULL; } return myimpl->MakeGlyphImpl(ftGlyph); } // // FTTextureFontImpl // static inline GLuint NextPowerOf2(GLuint in) { in -= 1; in |= in >> 16; in |= in >> 8; in |= in >> 4; in |= in >> 2; in |= in >> 1; return in + 1; } FTTextureFontImpl::FTTextureFontImpl(FTFont *ftFont, const char* fontFilePath) : FTFontImpl(ftFont, fontFilePath), maximumGLTextureSize(0), textureWidth(0), textureHeight(0), glyphHeight(0), glyphWidth(0), padding(3), xOffset(0), yOffset(0) { load_flags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP; remGlyphs = numGlyphs = face.GlyphCount(); } FTTextureFontImpl::FTTextureFontImpl(FTFont *ftFont, const unsigned char *pBufferBytes, size_t bufferSizeInBytes) : FTFontImpl(ftFont, pBufferBytes, bufferSizeInBytes), maximumGLTextureSize(0), textureWidth(0), textureHeight(0), glyphHeight(0), glyphWidth(0), padding(3), xOffset(0), yOffset(0) { load_flags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP; remGlyphs = numGlyphs = face.GlyphCount(); } FTTextureFontImpl::~FTTextureFontImpl() { if(textureIDList.size()) { glDeleteTextures((GLsizei)textureIDList.size(), (const GLuint*)&textureIDList[0]); } } FTGlyph* FTTextureFontImpl::MakeGlyphImpl(FT_GlyphSlot ftGlyph) { glyphHeight = static_cast(charSize.Height() + 0.5); glyphWidth = static_cast(charSize.Width() + 0.5); if(glyphHeight < 1) glyphHeight = 1; if(glyphWidth < 1) glyphWidth = 1; if(textureIDList.empty()) { textureIDList.push_back(CreateTexture()); xOffset = yOffset = padding; } if(xOffset > (textureWidth - glyphWidth)) { xOffset = padding; yOffset += glyphHeight; if(yOffset > (textureHeight - glyphHeight)) { textureIDList.push_back(CreateTexture()); yOffset = padding; } } FTTextureGlyph* tempGlyph = new FTTextureGlyph(ftGlyph, textureIDList[textureIDList.size() - 1], xOffset, yOffset, textureWidth, textureHeight); xOffset += static_cast(tempGlyph->BBox().Upper().X() - tempGlyph->BBox().Lower().X() + padding + 0.5); --remGlyphs; return tempGlyph; } void FTTextureFontImpl::CalculateTextureSize() { if(!maximumGLTextureSize) { maximumGLTextureSize = 1024; glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&maximumGLTextureSize); assert(maximumGLTextureSize); // If you hit this then you have an invalid OpenGL context. } textureWidth = NextPowerOf2((remGlyphs * glyphWidth) + (padding * 2)); textureWidth = textureWidth > maximumGLTextureSize ? maximumGLTextureSize : textureWidth; int h = static_cast((textureWidth - (padding * 2)) / glyphWidth + 0.5); textureHeight = NextPowerOf2(((numGlyphs / h) + 1) * glyphHeight); textureHeight = textureHeight > maximumGLTextureSize ? maximumGLTextureSize : textureHeight; } GLuint FTTextureFontImpl::CreateTexture() { CalculateTextureSize(); int totalMemory = textureWidth * textureHeight; unsigned char* textureMemory = new unsigned char[totalMemory]; memset(textureMemory, 0, totalMemory); GLuint textID; glGenTextures(1, (GLuint*)&textID); glBindTexture(GL_TEXTURE_2D, textID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, textureWidth, textureHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, textureMemory); delete [] textureMemory; return textID; } bool FTTextureFontImpl::FaceSize(const unsigned int size, const unsigned int res) { if(!textureIDList.empty()) { glDeleteTextures((GLsizei)textureIDList.size(), (const GLuint*)&textureIDList[0]); textureIDList.clear(); remGlyphs = numGlyphs = face.GlyphCount(); } return FTFontImpl::FaceSize(size, res); } template inline FTPoint FTTextureFontImpl::RenderI(const T* string, const int len, FTPoint position, FTPoint spacing, int renderMode) { // Protect GL_TEXTURE_2D, GL_BLEND and blending functions glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE glEnable(GL_TEXTURE_2D); FTTextureGlyphImpl::ResetActiveTexture(); FTPoint tmp = FTFontImpl::Render(string, len, position, spacing, renderMode); glPopAttrib(); return tmp; } FTPoint FTTextureFontImpl::Render(const char * string, const int len, FTPoint position, FTPoint spacing, int renderMode) { return RenderI(string, len, position, spacing, renderMode); } FTPoint FTTextureFontImpl::Render(const wchar_t * string, const int len, FTPoint position, FTPoint spacing, int renderMode) { return RenderI(string, len, position, spacing, renderMode); } rgl/src/ext/ftgl/FTFont/FTTextureFontImpl.h0000644000176200001440000001100514100762641020233 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTTextureFontImpl__ #define __FTTextureFontImpl__ #include "FTFontImpl.h" #include "FTVector.h" class FTTextureGlyph; class FTTextureFontImpl : public FTFontImpl { friend class FTTextureFont; protected: FTTextureFontImpl(FTFont *ftFont, const char* fontFilePath); FTTextureFontImpl(FTFont *ftFont, const unsigned char *pBufferBytes, size_t bufferSizeInBytes); virtual ~FTTextureFontImpl(); /** * Set the char size for the current face. * * @param size the face size in points (1/72 inch) * @param res the resolution of the target device. * @return true if size was set correctly */ virtual bool FaceSize(const unsigned int size, const unsigned int res = 72); virtual FTPoint Render(const char *s, const int len, FTPoint position, FTPoint spacing, int renderMode); virtual FTPoint Render(const wchar_t *s, const int len, FTPoint position, FTPoint spacing, int renderMode); private: /** * Create an FTTextureGlyph object for the base class. */ FTGlyph* MakeGlyphImpl(FT_GlyphSlot ftGlyph); /** * Get the size of a block of memory required to layout the glyphs * * Calculates a width and height based on the glyph sizes and the * number of glyphs. It over estimates. */ inline void CalculateTextureSize(); /** * Creates a 'blank' OpenGL texture object. * * The format is GL_ALPHA and the params are * GL_TEXTURE_WRAP_S = GL_CLAMP * GL_TEXTURE_WRAP_T = GL_CLAMP * GL_TEXTURE_MAG_FILTER = GL_LINEAR * GL_TEXTURE_MIN_FILTER = GL_LINEAR * Note that mipmapping is NOT used */ inline GLuint CreateTexture(); /** * The maximum texture dimension on this OpenGL implemetation */ GLsizei maximumGLTextureSize; /** * The minimum texture width required to hold the glyphs */ GLsizei textureWidth; /** * The minimum texture height required to hold the glyphs */ GLsizei textureHeight; /** *An array of texture ids */ FTVector textureIDList; /** * The max height for glyphs in the current font */ int glyphHeight; /** * The max width for glyphs in the current font */ int glyphWidth; /** * A value to be added to the height and width to ensure that * glyphs don't overlap in the texture */ unsigned int padding; /** * */ unsigned int numGlyphs; /** */ unsigned int remGlyphs; /** */ int xOffset; /** */ int yOffset; /* Internal generic Render() implementation */ template inline FTPoint RenderI(const T *s, const int len, FTPoint position, FTPoint spacing, int mode); }; #endif // __FTTextureFontImpl__ rgl/src/ext/ftgl/FTFont/FTOutlineFontImpl.h0000644000176200001440000000506014100762641020216 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTOutlineFontImpl__ #define __FTOutlineFontImpl__ #include "FTFontImpl.h" class FTGlyph; class FTOutlineFontImpl : public FTFontImpl { friend class FTOutlineFont; protected: FTOutlineFontImpl(FTFont *ftFont, const char* fontFilePath); FTOutlineFontImpl(FTFont *ftFont, const unsigned char *pBufferBytes, size_t bufferSizeInBytes); /** * Set the outset distance for the font. Only implemented by * FTOutlineFont, FTPolygonFont and FTExtrudeFont * * @param outset The outset distance. */ virtual void Outset(float o) { outset = o; } virtual FTPoint Render(const char *s, const int len, FTPoint position, FTPoint spacing, int renderMode); virtual FTPoint Render(const wchar_t *s, const int len, FTPoint position, FTPoint spacing, int renderMode); private: /** * The outset distance for the font. */ float outset; /* Internal generic Render() implementation */ template inline FTPoint RenderI(const T *s, const int len, FTPoint position, FTPoint spacing, int mode); }; #endif // __FTOutlineFontImpl__ rgl/src/ext/ftgl/FTFont/FTPixmapFontImpl.h0000644000176200001440000000430714100762641020040 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTPixmapFontImpl__ #define __FTPixmapFontImpl__ #include "FTFontImpl.h" class FTGlyph; class FTPixmapFontImpl : public FTFontImpl { friend class FTPixmapFont; protected: FTPixmapFontImpl(FTFont *ftFont, const char* fontFilePath); FTPixmapFontImpl(FTFont *ftFont, const unsigned char *pBufferBytes, size_t bufferSizeInBytes); virtual FTPoint Render(const char *s, const int len, FTPoint position, FTPoint spacing, int renderMode); virtual FTPoint Render(const wchar_t *s, const int len, FTPoint position, FTPoint spacing, int renderMode); private: /* Internal generic Render() implementation */ template inline FTPoint RenderI(const T *s, const int len, FTPoint position, FTPoint spacing, int mode); }; #endif // __FTPixmapFontImpl__ rgl/src/ext/ftgl/FTFont/FTFontGlue.cpp0000644000176200001440000001701014100762641017202 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Éric Beets * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTInternals.h" static const FTPoint static_ftpoint; static const FTBBox static_ftbbox; FTGL_BEGIN_C_DECLS #define C_TOR(cname, cargs, cxxname, cxxarg, cxxtype) \ FTGLfont* cname cargs \ { \ cxxname *f = new cxxname cxxarg; \ if(f->Error()) \ { \ delete f; \ return NULL; \ } \ FTGLfont *ftgl = (FTGLfont *)malloc(sizeof(FTGLfont)); \ ftgl->ptr = f; \ ftgl->type = cxxtype; \ return ftgl; \ } // FTBitmapFont::FTBitmapFont(); C_TOR(ftglCreateBitmapFont, (const char *fontname), FTBitmapFont, (fontname), FONT_BITMAP); // FTBufferFont::FTBufferFont(); C_TOR(ftglCreateBufferFont, (const char *fontname), FTBufferFont, (fontname), FONT_BUFFER); // FTExtrudeFont::FTExtrudeFont(); C_TOR(ftglCreateExtrudeFont, (const char *fontname), FTExtrudeFont, (fontname), FONT_EXTRUDE); // FTOutlineFont::FTOutlineFont(); C_TOR(ftglCreateOutlineFont, (const char *fontname), FTOutlineFont, (fontname), FONT_OUTLINE); // FTPixmapFont::FTPixmapFont(); C_TOR(ftglCreatePixmapFont, (const char *fontname), FTPixmapFont, (fontname), FONT_PIXMAP); // FTPolygonFont::FTPolygonFont(); C_TOR(ftglCreatePolygonFont, (const char *fontname), FTPolygonFont, (fontname), FONT_POLYGON); // FTTextureFont::FTTextureFont(); C_TOR(ftglCreateTextureFont, (const char *fontname), FTTextureFont, (fontname), FONT_TEXTURE); // FTCustomFont::FTCustomFont(); class FTCustomFont : public FTFont { public: FTCustomFont(char const *fontFilePath, void *p, FTGLglyph * (*makeglyph) (FT_GlyphSlot, void *)) : FTFont(fontFilePath), data(p), makeglyphCallback(makeglyph) {} ~FTCustomFont() {} FTGlyph* MakeGlyph(FT_GlyphSlot slot) { FTGLglyph *g = makeglyphCallback(slot, data); FTGlyph *glyph = g->ptr; // XXX: we no longer need g, and no one will free it for us. Not // very elegant, and we need to make sure no one else will try to // use it. free(g); return glyph; } private: void *data; FTGLglyph *(*makeglyphCallback) (FT_GlyphSlot, void *); }; C_TOR(ftglCreateCustomFont, (char const *fontFilePath, void *data, FTGLglyph * (*makeglyphCallback) (FT_GlyphSlot, void *)), FTCustomFont, (fontFilePath, data, makeglyphCallback), FONT_CUSTOM); #define C_FUN(cret, cname, cargs, cxxerr, cxxname, cxxarg) \ cret cname cargs \ { \ if(!f || !f->ptr) \ { \ fprintf(stderr, "FTGL warning: NULL pointer in %s\n", #cname); \ cxxerr; \ } \ return f->ptr->cxxname cxxarg; \ } // FTFont::~FTFont(); void ftglDestroyFont(FTGLfont *f) { if(!f || !f->ptr) { fprintf(stderr, "FTGL warning: NULL pointer in %s\n", __FUNCTION__); return; } delete f->ptr; free(f); } // bool FTFont::Attach(const char* fontFilePath); C_FUN(int, ftglAttachFile, (FTGLfont *f, const char* path), return 0, Attach, (path)); // bool FTFont::Attach(const unsigned char *pBufferBytes, // size_t bufferSizeInBytes); C_FUN(int, ftglAttachData, (FTGLfont *f, const unsigned char *p, size_t s), return 0, Attach, (p, s)); // void FTFont::GlyphLoadFlags(FT_Int flags); C_FUN(void, ftglSetFontGlyphLoadFlags, (FTGLfont *f, FT_Int flags), return, GlyphLoadFlags, (flags)); // bool FTFont::CharMap(FT_Encoding encoding); C_FUN(int, ftglSetFontCharMap, (FTGLfont *f, FT_Encoding enc), return 0, CharMap, (enc)); // unsigned int FTFont::CharMapCount(); C_FUN(unsigned int, ftglGetFontCharMapCount, (FTGLfont *f), return 0, CharMapCount, ()); // FT_Encoding* FTFont::CharMapList(); C_FUN(FT_Encoding *, ftglGetFontCharMapList, (FTGLfont* f), return NULL, CharMapList, ()); // virtual bool FTFont::FaceSize(const unsigned int size, // const unsigned int res = 72); C_FUN(int, ftglSetFontFaceSize, (FTGLfont *f, unsigned int s, unsigned int r), return 0, FaceSize, (s, r > 0 ? r : 72)); // unsigned int FTFont::FaceSize() const; // XXX: need to call FaceSize() as FTFont::FaceSize() because of FTGLTexture C_FUN(unsigned int, ftglGetFontFaceSize, (FTGLfont *f), return 0, FTFont::FaceSize, ()); // virtual void FTFont::Depth(float depth); C_FUN(void, ftglSetFontDepth, (FTGLfont *f, float d), return, Depth, (d)); // virtual void FTFont::Outset(float front, float back); C_FUN(void, ftglSetFontOutset, (FTGLfont *f, float front, float back), return, FTFont::Outset, (front, back)); // void FTFont::UseDisplayList(bool useList); C_FUN(void, ftglSetFontDisplayList, (FTGLfont *f, int l), return, UseDisplayList, (l != 0)); // float FTFont::Ascender() const; C_FUN(float, ftglGetFontAscender, (FTGLfont *f), return 0.f, Ascender, ()); // float FTFont::Descender() const; C_FUN(float, ftglGetFontDescender, (FTGLfont *f), return 0.f, Descender, ()); // float FTFont::LineHeight() const; C_FUN(float, ftglGetFontLineHeight, (FTGLfont *f), return 0.f, LineHeight, ()); // void FTFont::BBox(const char* string, float& llx, float& lly, float& llz, // float& urx, float& ury, float& urz); extern "C++" { C_FUN(static FTBBox, _ftglGetFontBBox, (FTGLfont *f, char const *s, int len), return static_ftbbox, BBox, (s, len)); } void ftglGetFontBBox(FTGLfont *f, const char* s, int len, float c[6]) { FTBBox ret = _ftglGetFontBBox(f, s, len); FTPoint lower = ret.Lower(), upper = ret.Upper(); c[0] = lower.Xf(); c[1] = lower.Yf(); c[2] = lower.Zf(); c[3] = upper.Xf(); c[4] = upper.Yf(); c[5] = upper.Zf(); } // float FTFont::Advance(const char* string); C_FUN(float, ftglGetFontAdvance, (FTGLfont *f, char const *s), return 0.0, Advance, (s)); // virtual void Render(const char* string, int renderMode); extern "C++" { C_FUN(static FTPoint, _ftglRenderFont, (FTGLfont *f, char const *s, int len, FTPoint pos, FTPoint spacing, int mode), return static_ftpoint, Render, (s, len, pos, spacing, mode)); } void ftglRenderFont(FTGLfont *f, const char *s, int mode) { _ftglRenderFont(f, s, -1, FTPoint(), FTPoint(), mode); } // FT_Error FTFont::Error() const; C_FUN(FT_Error, ftglGetFontError, (FTGLfont *f), return -1, Error, ()); FTGL_END_C_DECLS rgl/src/ext/ftgl/FTFont/FTPolygonFont.cpp0000644000176200001440000000471714100762641017747 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTGL/ftgl.h" #include "FTInternals.h" #include "FTPolygonFontImpl.h" // // FTPolygonFont // FTPolygonFont::FTPolygonFont(char const *fontFilePath) : FTFont(new FTPolygonFontImpl(this, fontFilePath)) {} FTPolygonFont::FTPolygonFont(const unsigned char *pBufferBytes, size_t bufferSizeInBytes) : FTFont(new FTPolygonFontImpl(this, pBufferBytes, bufferSizeInBytes)) {} FTPolygonFont::~FTPolygonFont() {} FTGlyph* FTPolygonFont::MakeGlyph(FT_GlyphSlot ftGlyph) { FTPolygonFontImpl *myimpl = dynamic_cast(impl); if(!myimpl) { return NULL; } return new FTPolygonGlyph(ftGlyph, myimpl->outset, myimpl->useDisplayLists); } // // FTPolygonFontImpl // FTPolygonFontImpl::FTPolygonFontImpl(FTFont *ftFont, const char* fontFilePath) : FTFontImpl(ftFont, fontFilePath), outset(0.0f) { load_flags = FT_LOAD_NO_HINTING; } FTPolygonFontImpl::FTPolygonFontImpl(FTFont *ftFont, const unsigned char *pBufferBytes, size_t bufferSizeInBytes) : FTFontImpl(ftFont, pBufferBytes, bufferSizeInBytes), outset(0.0f) { load_flags = FT_LOAD_NO_HINTING; } rgl/src/ext/ftgl/FTFont/FTExtrudeFont.cpp0000644000176200001440000000503314100762641017730 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTGL/ftgl.h" #include "FTInternals.h" #include "FTExtrudeFontImpl.h" // // FTExtrudeFont // FTExtrudeFont::FTExtrudeFont(char const *fontFilePath) : FTFont(new FTExtrudeFontImpl(this, fontFilePath)) {} FTExtrudeFont::FTExtrudeFont(const unsigned char *pBufferBytes, size_t bufferSizeInBytes) : FTFont(new FTExtrudeFontImpl(this, pBufferBytes, bufferSizeInBytes)) {} FTExtrudeFont::~FTExtrudeFont() {} FTGlyph* FTExtrudeFont::MakeGlyph(FT_GlyphSlot ftGlyph) { FTExtrudeFontImpl *myimpl = dynamic_cast(impl); if(!myimpl) { return NULL; } return new FTExtrudeGlyph(ftGlyph, myimpl->depth, myimpl->front, myimpl->back, myimpl->useDisplayLists); } // // FTExtrudeFontImpl // FTExtrudeFontImpl::FTExtrudeFontImpl(FTFont *ftFont, const char* fontFilePath) : FTFontImpl(ftFont, fontFilePath), depth(0.0f), front(0.0f), back(0.0f) { load_flags = FT_LOAD_NO_HINTING; } FTExtrudeFontImpl::FTExtrudeFontImpl(FTFont *ftFont, const unsigned char *pBufferBytes, size_t bufferSizeInBytes) : FTFontImpl(ftFont, pBufferBytes, bufferSizeInBytes), depth(0.0f), front(0.0f), back(0.0f) { load_flags = FT_LOAD_NO_HINTING; } rgl/src/ext/ftgl/FTFont/FTBufferFont.cpp0000644000176200001440000002265114100762641017526 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include #include "FTGL/ftgl.h" #include "FTInternals.h" #include "FTBufferFontImpl.h" // // FTBufferFont // FTBufferFont::FTBufferFont(char const *fontFilePath) : FTFont(new FTBufferFontImpl(this, fontFilePath)) {} FTBufferFont::FTBufferFont(unsigned char const *pBufferBytes, size_t bufferSizeInBytes) : FTFont(new FTBufferFontImpl(this, pBufferBytes, bufferSizeInBytes)) {} FTBufferFont::~FTBufferFont() {} FTGlyph* FTBufferFont::MakeGlyph(FT_GlyphSlot ftGlyph) { FTBufferFontImpl *myimpl = dynamic_cast(impl); if(!myimpl) { return NULL; } return myimpl->MakeGlyphImpl(ftGlyph); } // // FTBufferFontImpl // FTBufferFontImpl::FTBufferFontImpl(FTFont *ftFont, const char* fontFilePath) : FTFontImpl(ftFont, fontFilePath), buffer(new FTBuffer()) { load_flags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP; glGenTextures(BUFFER_CACHE_SIZE, idCache); for(int i = 0; i < BUFFER_CACHE_SIZE; i++) { stringCache[i] = NULL; glBindTexture(GL_TEXTURE_2D, idCache[i]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } lastString = 0; } FTBufferFontImpl::FTBufferFontImpl(FTFont *ftFont, const unsigned char *pBufferBytes, size_t bufferSizeInBytes) : FTFontImpl(ftFont, pBufferBytes, bufferSizeInBytes), buffer(new FTBuffer()) { load_flags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP; glGenTextures(BUFFER_CACHE_SIZE, idCache); for(int i = 0; i < BUFFER_CACHE_SIZE; i++) { stringCache[i] = NULL; glBindTexture(GL_TEXTURE_2D, idCache[i]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } lastString = 0; } FTBufferFontImpl::~FTBufferFontImpl() { glDeleteTextures(BUFFER_CACHE_SIZE, idCache); for(int i = 0; i < BUFFER_CACHE_SIZE; i++) { if(stringCache[i]) { free(stringCache[i]); } } delete buffer; } FTGlyph* FTBufferFontImpl::MakeGlyphImpl(FT_GlyphSlot ftGlyph) { return new FTBufferGlyph(ftGlyph, buffer); } bool FTBufferFontImpl::FaceSize(const unsigned int size, const unsigned int res) { for(int i = 0; i < BUFFER_CACHE_SIZE; i++) { if(stringCache[i]) { free(stringCache[i]); stringCache[i] = NULL; } } return FTFontImpl::FaceSize(size, res); } static inline GLuint NextPowerOf2(GLuint in) { in -= 1; in |= in >> 16; in |= in >> 8; in |= in >> 4; in |= in >> 2; in |= in >> 1; return in + 1; } inline int StringCompare(void const *a, char const *b, int len) { return len < 0 ? strcmp((char const *)a, b) : strncmp((char const *)a, b, len); } inline int StringCompare(void const *a, wchar_t const *b, int len) { return len < 0 ? wcscmp((wchar_t const *)a, b) : wcsncmp((wchar_t const *)a, b, len); } inline char *StringCopy(char const *s, int len) { if(len < 0) { return strdup(s); } else { #ifdef HAVE_STRNDUP return strndup(s, len); #else char *s2 = (char*)malloc(len + 1); memcpy(s2, s, len); s2[len] = 0; return s2; #endif } } inline wchar_t *StringCopy(wchar_t const *s, int len) { if(len < 0) { #if defined HAVE_WCSDUP return wcsdup(s); #else len = (int)wcslen(s); #endif } wchar_t *s2 = (wchar_t *)malloc((len + 1) * sizeof(wchar_t)); memcpy(s2, s, len * sizeof(wchar_t)); s2[len] = 0; return s2; } template inline FTPoint FTBufferFontImpl::RenderI(const T* string, const int len, FTPoint position, FTPoint spacing, int renderMode) { const float padding = 3.0f; int width, height, texWidth, texHeight; int cacheIndex = -1; bool inCache = false; // Protect blending functions, GL_BLEND and GL_TEXTURE_2D glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); // Protect glPixelStorei() calls glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE // Search whether the string is already in a texture we uploaded for(int n = 0; n < BUFFER_CACHE_SIZE; n++) { int i = (lastString + n + BUFFER_CACHE_SIZE) % BUFFER_CACHE_SIZE; if(stringCache[i] && !StringCompare(stringCache[i], string, len)) { cacheIndex = i; inCache = true; break; } } // If the string was not found, we need to put it in the cache and compute // its new bounding box. if(!inCache) { // FIXME: this cache is not very efficient. We should first expire // strings that are not used very often. cacheIndex = lastString; lastString = (lastString + 1) % BUFFER_CACHE_SIZE; if(stringCache[cacheIndex]) { free(stringCache[cacheIndex]); } // FIXME: only the first N bytes are copied; we want the first N chars. stringCache[cacheIndex] = StringCopy(string, len); bboxCache[cacheIndex] = BBox(string, len, FTPoint(), spacing); } FTBBox bbox = bboxCache[cacheIndex]; width = static_cast(bbox.Upper().X() - bbox.Lower().X() + padding + padding + 0.5); height = static_cast(bbox.Upper().Y() - bbox.Lower().Y() + padding + padding + 0.5); texWidth = NextPowerOf2(width); texHeight = NextPowerOf2(height); glBindTexture(GL_TEXTURE_2D, idCache[cacheIndex]); // If the string was not found, we need to render the text in a new // texture buffer, then upload it to the OpenGL layer. if(!inCache) { buffer->Size(texWidth, texHeight); buffer->Pos(FTPoint(padding, padding) - bbox.Lower()); advanceCache[cacheIndex] = FTFontImpl::Render(string, len, FTPoint(), spacing, renderMode); glBindTexture(GL_TEXTURE_2D, idCache[cacheIndex]); glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* TODO: use glTexSubImage2D later? */ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texWidth, texHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, (GLvoid *)buffer->Pixels()); buffer->Size(0, 0); } FTPoint low = position + bbox.Lower(); FTPoint up = position + bbox.Upper(); glBegin(GL_QUADS); glNormal3f(0.0f, 0.0f, 1.0f); glTexCoord2f(padding / texWidth, (texHeight - height + padding) / texHeight); glVertex2f(low.Xf(), up.Yf()); glTexCoord2f(padding / texWidth, (texHeight - padding) / texHeight); glVertex2f(low.Xf(), low.Yf()); glTexCoord2f((width - padding) / texWidth, (texHeight - padding) / texHeight); glVertex2f(up.Xf(), low.Yf()); glTexCoord2f((width - padding) / texWidth, (texHeight - height + padding) / texHeight); glVertex2f(up.Xf(), up.Yf()); glEnd(); glPopClientAttrib(); glPopAttrib(); return position + advanceCache[cacheIndex]; } FTPoint FTBufferFontImpl::Render(const char * string, const int len, FTPoint position, FTPoint spacing, int renderMode) { return RenderI(string, len, position, spacing, renderMode); } FTPoint FTBufferFontImpl::Render(const wchar_t * string, const int len, FTPoint position, FTPoint spacing, int renderMode) { return RenderI(string, len, position, spacing, renderMode); } rgl/src/ext/ftgl/FTFont/FTExtrudeFontImpl.h0000644000176200001440000000510514100762641020217 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTExtrudeFontImpl__ #define __FTExtrudeFontImpl__ #include "FTFontImpl.h" class FTGlyph; class FTExtrudeFontImpl : public FTFontImpl { friend class FTExtrudeFont; protected: FTExtrudeFontImpl(FTFont *ftFont, const char* fontFilePath); FTExtrudeFontImpl(FTFont *ftFont, const unsigned char *pBufferBytes, size_t bufferSizeInBytes); /** * Set the extrusion distance for the font. * * @param d The extrusion distance. */ virtual void Depth(float d) { depth = d; } /** * Set the outset distance for the font. Only implemented by * FTOutlineFont, FTPolygonFont and FTExtrudeFont * * @param o The outset distance. */ virtual void Outset(float o) { front = back = o; } /** * Set the outset distance for the font. Only implemented by * FTExtrudeFont * * @param f The front outset distance. * @param b The back outset distance. */ virtual void Outset(float f, float b) { front = f; back = b; } private: /** * The extrusion distance for the font. */ float depth; /** * The outset distance (front and back) for the font. */ float front, back; }; #endif // __FTExtrudeFontImpl__ rgl/src/ext/ftgl/FTFont/FTFont.cpp0000644000176200001440000002601714100762641016374 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTInternals.h" #include "FTUnicode.h" #include "FTFontImpl.h" #include "FTBitmapFontImpl.h" #include "FTExtrudeFontImpl.h" #include "FTOutlineFontImpl.h" #include "FTPixmapFontImpl.h" #include "FTPolygonFontImpl.h" #include "FTTextureFontImpl.h" #include "FTGlyphContainer.h" #include "FTFace.h" // // FTFont // FTFont::FTFont(char const *fontFilePath) { impl = new FTFontImpl(this, fontFilePath); } FTFont::FTFont(const unsigned char *pBufferBytes, size_t bufferSizeInBytes) { impl = new FTFontImpl(this, pBufferBytes, bufferSizeInBytes); } FTFont::FTFont(FTFontImpl *pImpl) { impl = pImpl; } FTFont::~FTFont() { delete impl; } bool FTFont::Attach(const char* fontFilePath) { return impl->Attach(fontFilePath); } bool FTFont::Attach(const unsigned char *pBufferBytes, size_t bufferSizeInBytes) { return impl->Attach(pBufferBytes, bufferSizeInBytes); } bool FTFont::FaceSize(const unsigned int size, const unsigned int res) { return impl->FaceSize(size, res); } unsigned int FTFont::FaceSize() const { return impl->FaceSize(); } void FTFont::Depth(float depth) { return impl->Depth(depth); } void FTFont::Outset(float outset) { return impl->Outset(outset); } void FTFont::Outset(float front, float back) { return impl->Outset(front, back); } void FTFont::GlyphLoadFlags(FT_Int flags) { return impl->GlyphLoadFlags(flags); } bool FTFont::CharMap(FT_Encoding encoding) { return impl->CharMap(encoding); } unsigned int FTFont::CharMapCount() const { return impl->CharMapCount(); } FT_Encoding* FTFont::CharMapList() { return impl->CharMapList(); } void FTFont::UseDisplayList(bool useList) { return impl->UseDisplayList(useList); } float FTFont::Ascender() const { return impl->Ascender(); } float FTFont::Descender() const { return impl->Descender(); } float FTFont::LineHeight() const { return impl->LineHeight(); } FTPoint FTFont::Render(const char * string, const int len, FTPoint position, FTPoint spacing, int renderMode) { return impl->Render(string, len, position, spacing, renderMode); } FTPoint FTFont::Render(const wchar_t * string, const int len, FTPoint position, FTPoint spacing, int renderMode) { return impl->Render(string, len, position, spacing, renderMode); } float FTFont::Advance(const char * string, const int len, FTPoint spacing) { return impl->Advance(string, len, spacing); } float FTFont::Advance(const wchar_t * string, const int len, FTPoint spacing) { return impl->Advance(string, len, spacing); } FTBBox FTFont::BBox(const char *string, const int len, FTPoint position, FTPoint spacing) { return impl->BBox(string, len, position, spacing); } FTBBox FTFont::BBox(const wchar_t *string, const int len, FTPoint position, FTPoint spacing) { return impl->BBox(string, len, position, spacing); } FT_Error FTFont::Error() const { return impl->err; } // // FTFontImpl // FTFontImpl::FTFontImpl(FTFont *ftFont, char const *fontFilePath) : face(fontFilePath), useDisplayLists(true), load_flags(FT_LOAD_DEFAULT), intf(ftFont), glyphList(0) { err = face.Error(); if(err == 0) { glyphList = new FTGlyphContainer(&face); } } FTFontImpl::FTFontImpl(FTFont *ftFont, const unsigned char *pBufferBytes, size_t bufferSizeInBytes) : face(pBufferBytes, bufferSizeInBytes), useDisplayLists(true), load_flags(FT_LOAD_DEFAULT), intf(ftFont), glyphList(0) { err = face.Error(); if(err == 0) { glyphList = new FTGlyphContainer(&face); } } FTFontImpl::~FTFontImpl() { if(glyphList) { delete glyphList; } } bool FTFontImpl::Attach(const char* fontFilePath) { if(!face.Attach(fontFilePath)) { err = face.Error(); return false; } err = 0; return true; } bool FTFontImpl::Attach(const unsigned char *pBufferBytes, size_t bufferSizeInBytes) { if(!face.Attach(pBufferBytes, bufferSizeInBytes)) { err = face.Error(); return false; } err = 0; return true; } bool FTFontImpl::FaceSize(const unsigned int size, const unsigned int res) { if(glyphList != NULL) { delete glyphList; glyphList = NULL; } charSize = face.Size(size, res); err = face.Error(); if(err != 0) { return false; } glyphList = new FTGlyphContainer(&face); return true; } unsigned int FTFontImpl::FaceSize() const { return charSize.CharSize(); } void FTFontImpl::Depth(float depth) { ; } void FTFontImpl::Outset(float outset) { ; } void FTFontImpl::Outset(float front, float back) { ; } void FTFontImpl::GlyphLoadFlags(FT_Int flags) { load_flags = flags; } bool FTFontImpl::CharMap(FT_Encoding encoding) { bool result = glyphList->CharMap(encoding); err = glyphList->Error(); return result; } unsigned int FTFontImpl::CharMapCount() const { return face.CharMapCount(); } FT_Encoding* FTFontImpl::CharMapList() { return face.CharMapList(); } void FTFontImpl::UseDisplayList(bool useList) { useDisplayLists = useList; } float FTFontImpl::Ascender() const { return charSize.Ascender(); } float FTFontImpl::Descender() const { return charSize.Descender(); } float FTFontImpl::LineHeight() const { return charSize.Height(); } template inline FTBBox FTFontImpl::BBoxI(const T* string, const int len, FTPoint position, FTPoint spacing) { FTBBox totalBBox; /* Only compute the bounds if string is non-empty. */ if(string && ('\0' != string[0])) { // for multibyte - we can't rely on sizeof(T) == character FTUnicodeStringItr ustr(string); unsigned int thisChar = *ustr++; unsigned int nextChar = *ustr; if(CheckGlyph(thisChar)) { totalBBox = glyphList->BBox(thisChar); totalBBox += position; position += FTPoint(glyphList->Advance(thisChar, nextChar), 0.0); } /* Expand totalBox by each glyph in string */ for(int i = 1; (len < 0 && *ustr) || (len >= 0 && i < len); i++) { thisChar = *ustr++; nextChar = *ustr; if(CheckGlyph(thisChar)) { position += spacing; FTBBox tempBBox = glyphList->BBox(thisChar); tempBBox += position; totalBBox |= tempBBox; position += FTPoint(glyphList->Advance(thisChar, nextChar), 0.0); } } } return totalBBox; } FTBBox FTFontImpl::BBox(const char *string, const int len, FTPoint position, FTPoint spacing) { /* The chars need to be unsigned because they are cast to int later */ return BBoxI((const unsigned char *)string, len, position, spacing); } FTBBox FTFontImpl::BBox(const wchar_t *string, const int len, FTPoint position, FTPoint spacing) { return BBoxI(string, len, position, spacing); } template inline float FTFontImpl::AdvanceI(const T* string, const int len, FTPoint spacing) { float advance = 0.0f; FTUnicodeStringItr ustr(string); for(int i = 0; (len < 0 && *ustr) || (len >= 0 && i < len); i++) { unsigned int thisChar = *ustr++; unsigned int nextChar = *ustr; if(CheckGlyph(thisChar)) { advance += glyphList->Advance(thisChar, nextChar); } if(nextChar) { advance += spacing.Xf(); } } return advance; } float FTFontImpl::Advance(const char* string, const int len, FTPoint spacing) { /* The chars need to be unsigned because they are cast to int later */ return AdvanceI((const unsigned char *)string, len, spacing); } float FTFontImpl::Advance(const wchar_t* string, const int len, FTPoint spacing) { return AdvanceI(string, len, spacing); } template inline FTPoint FTFontImpl::RenderI(const T* string, const int len, FTPoint position, FTPoint spacing, int renderMode) { // for multibyte - we can't rely on sizeof(T) == character FTUnicodeStringItr ustr(string); for(int i = 0; (len < 0 && *ustr) || (len >= 0 && i < len); i++) { unsigned int thisChar = *ustr++; unsigned int nextChar = *ustr; if(CheckGlyph(thisChar)) { position += glyphList->Render(thisChar, nextChar, position, renderMode); } if(nextChar) { position += spacing; } } return position; } FTPoint FTFontImpl::Render(const char * string, const int len, FTPoint position, FTPoint spacing, int renderMode) { return RenderI((const unsigned char *)string, len, position, spacing, renderMode); } FTPoint FTFontImpl::Render(const wchar_t * string, const int len, FTPoint position, FTPoint spacing, int renderMode) { return RenderI(string, len, position, spacing, renderMode); } bool FTFontImpl::CheckGlyph(const unsigned int characterCode) { if(glyphList->Glyph(characterCode)) { return true; } unsigned int glyphIndex = glyphList->FontIndex(characterCode); FT_GlyphSlot ftSlot = face.Glyph(glyphIndex, load_flags); if(!ftSlot) { err = face.Error(); return false; } FTGlyph* tempGlyph = intf->MakeGlyph(ftSlot); if(!tempGlyph) { if(0 == err) { err = 0x13; } return false; } glyphList->Add(tempGlyph, characterCode); return true; } rgl/src/ext/ftgl/FTFont/FTBitmapFontImpl.h0000644000176200001440000000447614100762641020025 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTBitmapFontImpl__ #define __FTBitmapFontImpl__ #include "FTFontImpl.h" class FTGlyph; class FTBitmapFontImpl : public FTFontImpl { friend class FTBitmapFont; protected: FTBitmapFontImpl(FTFont *ftFont, const char* fontFilePath) : FTFontImpl(ftFont, fontFilePath) {}; FTBitmapFontImpl(FTFont *ftFont, const unsigned char *pBufferBytes, size_t bufferSizeInBytes) : FTFontImpl(ftFont, pBufferBytes, bufferSizeInBytes) {}; virtual FTPoint Render(const char *s, const int len, FTPoint position, FTPoint spacing, int renderMode); virtual FTPoint Render(const wchar_t *s, const int len, FTPoint position, FTPoint spacing, int renderMode); private: /* Internal generic Render() implementation */ template inline FTPoint RenderI(const T *s, const int len, FTPoint position, FTPoint spacing, int mode); }; #endif // __FTBitmapFontImpl__ rgl/src/ext/ftgl/FTFont/FTPolygonFontImpl.h0000644000176200001440000000400214100762641020221 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTPolygonFontImpl__ #define __FTPolygonFontImpl__ #include "FTFontImpl.h" class FTGlyph; class FTPolygonFontImpl : public FTFontImpl { friend class FTPolygonFont; protected: FTPolygonFontImpl(FTFont *ftFont, const char* fontFilePath); FTPolygonFontImpl(FTFont *ftFont, const unsigned char *pBufferBytes, size_t bufferSizeInBytes); /** * Set the outset distance for the font. Only implemented by * FTOutlineFont, FTPolygonFont and FTExtrudeFont * * @param depth The outset distance. */ virtual void Outset(float o) { outset = o; } private: /** * The outset distance (front and back) for the font. */ float outset; }; #endif // __FTPolygonFontImpl__ rgl/src/ext/ftgl/FTFont/FTBufferFontImpl.h0000644000176200001440000000541214100762641020011 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTBufferFontImpl__ #define __FTBufferFontImpl__ #include "FTFontImpl.h" class FTGlyph; class FTBuffer; class FTBufferFontImpl : public FTFontImpl { friend class FTBufferFont; protected: FTBufferFontImpl(FTFont *ftFont, const char* fontFilePath); FTBufferFontImpl(FTFont *ftFont, const unsigned char *pBufferBytes, size_t bufferSizeInBytes); virtual ~FTBufferFontImpl(); virtual FTPoint Render(const char *s, const int len, FTPoint position, FTPoint spacing, int renderMode); virtual FTPoint Render(const wchar_t *s, const int len, FTPoint position, FTPoint spacing, int renderMode); virtual bool FaceSize(const unsigned int size, const unsigned int res); private: /** * Create an FTBufferGlyph object for the base class. */ FTGlyph* MakeGlyphImpl(FT_GlyphSlot ftGlyph); /* Internal generic Render() implementation */ template inline FTPoint RenderI(const T *s, const int len, FTPoint position, FTPoint spacing, int mode); /* Pixel buffer */ FTBuffer *buffer; static const int BUFFER_CACHE_SIZE = 16; /* Texture IDs */ GLuint idCache[BUFFER_CACHE_SIZE]; void *stringCache[BUFFER_CACHE_SIZE]; FTBBox bboxCache[BUFFER_CACHE_SIZE]; FTPoint advanceCache[BUFFER_CACHE_SIZE]; int lastString; }; #endif // __FTBufferFontImpl__ rgl/src/ext/ftgl/FTFont/FTFontImpl.h0000644000176200001440000001135314100762641016660 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTFontImpl__ #define __FTFontImpl__ #include "FTGL/ftgl.h" #include "FTFace.h" class FTGlyphContainer; class FTGlyph; class FTFontImpl { friend class FTFont; protected: FTFontImpl(FTFont *ftFont, char const *fontFilePath); FTFontImpl(FTFont *ftFont, const unsigned char *pBufferBytes, size_t bufferSizeInBytes); virtual ~FTFontImpl(); virtual bool Attach(const char* fontFilePath); virtual bool Attach(const unsigned char *pBufferBytes, size_t bufferSizeInBytes); virtual void GlyphLoadFlags(FT_Int flags); virtual bool CharMap(FT_Encoding encoding); virtual unsigned int CharMapCount() const; virtual FT_Encoding* CharMapList(); virtual void UseDisplayList(bool useList); virtual float Ascender() const; virtual float Descender() const; virtual float LineHeight() const; virtual bool FaceSize(const unsigned int size, const unsigned int res); virtual unsigned int FaceSize() const; virtual void Depth(float depth); virtual void Outset(float outset); virtual void Outset(float front, float back); virtual FTBBox BBox(const char *s, const int len, FTPoint, FTPoint); virtual FTBBox BBox(const wchar_t *s, const int len, FTPoint, FTPoint); virtual float Advance(const char *s, const int len, FTPoint); virtual float Advance(const wchar_t *s, const int len, FTPoint); virtual FTPoint Render(const char *s, const int len, FTPoint, FTPoint, int); virtual FTPoint Render(const wchar_t *s, const int len, FTPoint, FTPoint, int); /** * Current face object */ FTFace face; /** * Current size object */ FTSize charSize; /** * Flag to enable or disable the use of Display Lists inside FTGL * true turns ON display lists. * false turns OFF display lists. */ bool useDisplayLists; /** * The default glyph loading flags. */ FT_Int load_flags; /** * Current error code. Zero means no error. */ FT_Error err; private: /** * A link back to the interface of which we are the implementation. */ FTFont *intf; /** * Check that the glyph at chr exist. If not load it. * * @param chr character index * @return true if the glyph can be created. */ bool CheckGlyph(const unsigned int chr); /** * An object that holds a list of glyphs */ FTGlyphContainer* glyphList; /** * Current pen or cursor position; */ FTPoint pen; /* Internal generic BBox() implementation */ template inline FTBBox BBoxI(const T *s, const int len, FTPoint position, FTPoint spacing); /* Internal generic Advance() implementation */ template inline float AdvanceI(const T *s, const int len, FTPoint spacing); /* Internal generic Render() implementation */ template inline FTPoint RenderI(const T *s, const int len, FTPoint position, FTPoint spacing, int mode); }; #endif // __FTFontImpl__ rgl/src/ext/ftgl/FTFont/FTBitmapFont.cpp0000644000176200001440000000577714100762641017543 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTGL/ftgl.h" #include "FTInternals.h" #include "FTBitmapFontImpl.h" // // FTBitmapFont // FTBitmapFont::FTBitmapFont(char const *fontFilePath) : FTFont(new FTBitmapFontImpl(this, fontFilePath)) {} FTBitmapFont::FTBitmapFont(unsigned char const *pBufferBytes, size_t bufferSizeInBytes) : FTFont(new FTBitmapFontImpl(this, pBufferBytes, bufferSizeInBytes)) {} FTBitmapFont::~FTBitmapFont() {} FTGlyph* FTBitmapFont::MakeGlyph(FT_GlyphSlot ftGlyph) { return new FTBitmapGlyph(ftGlyph); } // // FTBitmapFontImpl // template inline FTPoint FTBitmapFontImpl::RenderI(const T* string, const int len, FTPoint position, FTPoint spacing, int renderMode) { // Protect GL_BLEND glPushAttrib(GL_COLOR_BUFFER_BIT); // Protect glPixelStorei() calls (also in FTBitmapGlyphImpl::RenderImpl) glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glDisable(GL_BLEND); FTPoint tmp = FTFontImpl::Render(string, len, position, spacing, renderMode); glPopClientAttrib(); glPopAttrib(); return tmp; } FTPoint FTBitmapFontImpl::Render(const char * string, const int len, FTPoint position, FTPoint spacing, int renderMode) { return RenderI(string, len, position, spacing, renderMode); } FTPoint FTBitmapFontImpl::Render(const wchar_t * string, const int len, FTPoint position, FTPoint spacing, int renderMode) { return RenderI(string, len, position, spacing, renderMode); } rgl/src/ext/ftgl/FTVector.h0000644000176200001440000001163714100762641015237 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTVector__ #define __FTVector__ #include "FTGL/ftgl.h" /** * Provides a non-STL alternative to the STL vector */ template class FTVector { public: typedef FT_VECTOR_ITEM_TYPE value_type; typedef value_type& reference; typedef const value_type& const_reference; typedef value_type* iterator; typedef const value_type* const_iterator; typedef size_t size_type; FTVector() { Capacity = Size = 0; Items = 0; } virtual ~FTVector() { clear(); } FTVector& operator =(const FTVector& v) { reserve(v.capacity()); iterator ptr = begin(); const_iterator vbegin = v.begin(); const_iterator vend = v.end(); while(vbegin != vend) { *ptr++ = *vbegin++; } Size = v.size(); return *this; } size_type size() const { return Size; } size_type capacity() const { return Capacity; } iterator begin() { return Items; } const_iterator begin() const { return Items; } iterator end() { return begin() + size(); } const_iterator end() const { return begin() + size(); } bool empty() const { return size() == 0; } reference operator [](size_type pos) { return(*(begin() + pos)); } const_reference operator [](size_type pos) const { return *(begin() + pos); } void clear() { if(Capacity) { delete [] Items; Capacity = Size = 0; Items = 0; } } void reserve(size_type n) { if(capacity() < n) { expand(n); } } void push_back(const value_type& x) { if(size() == capacity()) { expand(); } (*this)[size()] = x; ++Size; } void resize(size_type n, value_type x) { if(n == size()) { return; } reserve(n); iterator ibegin, iend; if(n >= Size) { ibegin = this->end(); iend = this->begin() + n; } else { ibegin = this->begin() + n; iend = this->end(); } while(ibegin != iend) { *ibegin++ = x; } Size = n; } private: void expand(size_type capacity_hint = 0) { size_type new_capacity = (capacity() == 0) ? 256 : capacity() * 2; if(capacity_hint) { while(new_capacity < capacity_hint) { new_capacity *= 2; } } value_type *new_items = new value_type[new_capacity]; iterator ibegin = this->begin(); iterator iend = this->end(); value_type *ptr = new_items; while(ibegin != iend) { *ptr++ = *ibegin++; } if(Capacity) { delete [] Items; } Items = new_items; Capacity = new_capacity; } size_type Capacity; size_type Size; value_type* Items; }; #endif // __FTVector__ rgl/src/ext/ftgl/FTCharmap.h0000644000176200001440000001220314100762641015336 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTCharmap__ #define __FTCharmap__ #include #include FT_FREETYPE_H #include FT_GLYPH_H #include "FTGL/ftgl.h" #include "FTCharToGlyphIndexMap.h" /** * FTCharmap takes care of specifying the encoding for a font and mapping * character codes to glyph indices. * * It doesn't preprocess all indices, only on an as needed basis. This may * seem like a performance penalty but it is quicker than using the 'raw' * freetype calls and will save significant amounts of memory when dealing * with unicode encoding * * @see "Freetype 2 Documentation" * */ class FTFace; class FTCharmap { public: /** * Constructor */ FTCharmap(FTFace* face); /** * Destructor */ virtual ~FTCharmap(); /** * Queries for the current character map code. * * @return The current character map code. */ FT_Encoding Encoding() const { return ftEncoding; } /** * Sets the character map for the face. If an error occurs the object is not modified. * Valid encodings as at Freetype 2.0.4 * ft_encoding_none * ft_encoding_symbol * ft_encoding_unicode * ft_encoding_latin_2 * ft_encoding_sjis * ft_encoding_gb2312 * ft_encoding_big5 * ft_encoding_wansung * ft_encoding_johab * ft_encoding_adobe_standard * ft_encoding_adobe_expert * ft_encoding_adobe_custom * ft_encoding_apple_roman * * @param encoding the Freetype encoding symbol. See above. * @return true if charmap was valid and set * correctly. */ bool CharMap(FT_Encoding encoding); /** * Get the FTGlyphContainer index of the input character. * * @param characterCode The character code of the requested glyph in * the current encoding eg apple roman. * @return The FTGlyphContainer index for the character or zero * if it wasn't found */ unsigned int GlyphListIndex(const unsigned int characterCode); /** * Get the font glyph index of the input character. * * @param characterCode The character code of the requested glyph in * the current encoding eg apple roman. * @return The glyph index for the character. */ unsigned int FontIndex(const unsigned int characterCode); /** * Set the FTGlyphContainer index of the character code. * * @param characterCode The character code of the requested glyph in * the current encoding eg apple roman. * @param containerIndex The index into the FTGlyphContainer of the * character code. */ void InsertIndex(const unsigned int characterCode, const size_t containerIndex); /** * Queries for errors. * * @return The current error code. Zero means no error. */ FT_Error Error() const { return err; } private: /** * Current character map code. */ FT_Encoding ftEncoding; /** * The current Freetype face. */ const FT_Face ftFace; /** * A structure that maps glyph indices to character codes * * < character code, face glyph index> */ typedef FTCharToGlyphIndexMap CharacterMap; CharacterMap charMap; /** * Precomputed font indices. */ static const unsigned int MAX_PRECOMPUTED = 128; unsigned int charIndexCache[MAX_PRECOMPUTED]; /** * Current error code. */ FT_Error err; }; #endif // __FTCharmap__ rgl/src/ext/ftgl/FTCharmap.cpp0000644000176200001440000000536114100762641015700 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * Copyright (c) 2008 Sam Hocevar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "config.h" #include "FTFace.h" #include "FTCharmap.h" FTCharmap::FTCharmap(FTFace* face) : ftFace(*(face->Face())), err(0) { if(!ftFace->charmap) { if(!ftFace->num_charmaps) { // This face doesn't even have one charmap! err = 0x96; // Invalid_CharMap_Format return; } err = FT_Set_Charmap(ftFace, ftFace->charmaps[0]); } ftEncoding = ftFace->charmap->encoding; for(unsigned int i = 0; i < FTCharmap::MAX_PRECOMPUTED; i++) { charIndexCache[i] = FT_Get_Char_Index(ftFace, i); } } FTCharmap::~FTCharmap() { charMap.clear(); } bool FTCharmap::CharMap(FT_Encoding encoding) { if(ftEncoding == encoding) { err = 0; return true; } err = FT_Select_Charmap(ftFace, encoding); if(!err) { ftEncoding = encoding; charMap.clear(); } return !err; } unsigned int FTCharmap::GlyphListIndex(const unsigned int characterCode) { return static_cast(charMap.find(static_cast(characterCode))); } unsigned int FTCharmap::FontIndex(const unsigned int characterCode) { if(characterCode < FTCharmap::MAX_PRECOMPUTED) { return charIndexCache[characterCode]; } return FT_Get_Char_Index(ftFace, characterCode); } void FTCharmap::InsertIndex(const unsigned int characterCode, const size_t containerIndex) { charMap.insert(characterCode, static_cast(containerIndex)); } rgl/src/ext/ftgl/FTUnicode.h0000644000176200001440000001776714100762641015375 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2008 Daniel Remenak * * Portions derived from ConvertUTF.c Copyright (C) 2001-2004 Unicode, Inc * Unicode, Inc. hereby grants the right to freely use the information * supplied in this file in the creation of products supporting the * Unicode Standard, and to make copies of this file in any form * for internal or external distribution as long as this notice * remains attached. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTUnicode__ #define __FTUnicode__ /** * Provides a way to easily walk multibyte unicode strings in the various * Unicode encodings (UTF-8, UTF-16, UTF-32, UCS-2, and UCS-4). Encodings * with elements larger than one byte must already be in the correct endian * order for the current architecture. */ template class FTUnicodeStringItr { public: /** * Constructor. Also reads the first character and stores it. * * @param string The buffer to iterate. No copy is made. */ FTUnicodeStringItr(const T* string) : curPos(string), nextPos(string) { (*this)++; }; /** * Pre-increment operator. Reads the next unicode character and sets * the state appropriately. * Note - not protected against overruns. */ FTUnicodeStringItr& operator++() { curPos = nextPos; // unicode handling switch (sizeof(T)) { case 1: // UTF-8 // get this character readUTF8(); break; case 2: // UTF-16 readUTF16(); break; case 4: // UTF-32 // fall through default: // error condition really, but give it a shot anyway curChar = *nextPos++; } return *this; } /** * Post-increment operator. Reads the next character and sets * the state appropriately. * Note - not protected against overruns. */ FTUnicodeStringItr operator++(int) { FTUnicodeStringItr temp = *this; ++*this; return temp; } /** * Equality operator. Two FTUnicodeStringItrs are considered equal * if they have the same current buffer and buffer position. */ bool operator==(const FTUnicodeStringItr& right) const { if (curPos == right.getBufferFromHere()) return true; return false; } /** * Dereference operator. * * @return The unicode codepoint of the character currently pointed * to by the FTUnicodeStringItr. */ unsigned int operator*() const { return curChar; } /** * Buffer-fetching getter. You can use this to retreive the buffer * starting at the currently-iterated character for functions which * require a Unicode string as input. */ const T* getBufferFromHere() const { return curPos; } private: /** * Helper function for reading a single UTF8 character from the string. * Updates internal state appropriately. */ void readUTF8(); /** * Helper function for reading a single UTF16 character from the string. * Updates internal state appropriately. */ void readUTF16(); /** * The buffer position of the first element in the current character. */ const T* curPos; /** * The character stored at the current buffer position (prefetched on * increment, so there's no penalty for dereferencing more than once). */ unsigned int curChar; /** * The buffer position of the first element in the next character. */ const T* nextPos; // unicode magic numbers static const char utf8bytes[256]; static const unsigned long offsetsFromUTF8[6]; static const unsigned long highSurrogateStart; static const unsigned long highSurrogateEnd; static const unsigned long lowSurrogateStart; static const unsigned long lowSurrogateEnd; static const unsigned long highSurrogateShift; static const unsigned long lowSurrogateBase; }; /* The first character in a UTF8 sequence indicates how many bytes * to read (among other things) */ template const char FTUnicodeStringItr::utf8bytes[256] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6 }; /* Magic values subtracted from a buffer value during UTF8 conversion. * This table contains as many values as there might be trailing bytes * in a UTF-8 sequence. */ template const unsigned long FTUnicodeStringItr::offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; // get a UTF8 character; leave the tracking pointer at the start of the // next character // not protected against invalid UTF8 template inline void FTUnicodeStringItr::readUTF8() { unsigned int ch = 0; unsigned int extraBytesToRead = utf8bytes[(unsigned char)(*nextPos)]; // falls through switch (extraBytesToRead) { case 6: ch += *nextPos++; ch <<= 6; /* remember, illegal UTF-8 */ case 5: ch += *nextPos++; ch <<= 6; /* remember, illegal UTF-8 */ case 4: ch += *nextPos++; ch <<= 6; case 3: ch += *nextPos++; ch <<= 6; case 2: ch += *nextPos++; ch <<= 6; case 1: ch += *nextPos++; } ch -= offsetsFromUTF8[extraBytesToRead-1]; curChar = ch; } // Magic numbers for UTF-16 conversions template const unsigned long FTUnicodeStringItr::highSurrogateStart = 0xD800; template const unsigned long FTUnicodeStringItr::highSurrogateEnd = 0xDBFF; template const unsigned long FTUnicodeStringItr::lowSurrogateStart = 0xDC00; template const unsigned long FTUnicodeStringItr::lowSurrogateEnd = 0xDFFF; template const unsigned long FTUnicodeStringItr::highSurrogateShift = 10; template const unsigned long FTUnicodeStringItr::lowSurrogateBase = 0x0010000UL; template inline void FTUnicodeStringItr::readUTF16() { unsigned int ch = *nextPos++; // if we have the first half of the surrogate pair if (ch >= highSurrogateStart && ch <= highSurrogateEnd) { unsigned int ch2 = *curPos; // complete the surrogate pair if (ch2 >= lowSurrogateStart && ch2 <= lowSurrogateEnd) { ch = static_cast(((ch - highSurrogateStart) << highSurrogateShift) + (ch2 - lowSurrogateStart) + lowSurrogateBase); ++nextPos; } } curChar = ch; } #endif rgl/src/ext/ftgl/FTLibrary.h0000644000176200001440000000750114100762641015374 0ustar liggesusers/* * FTGL - OpenGL font library * * Copyright (c) 2001-2004 Henry Maddocks * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __FTLibrary__ #define __FTLibrary__ #include #include FT_FREETYPE_H //#include FT_CACHE_H #include "FTGL/ftgl.h" /** * FTLibrary class is the global accessor for the Freetype library. * * This class encapsulates the Freetype Library. This is a singleton class * and ensures that only one FT_Library is in existence at any one time. * All constructors are private therefore clients cannot create or * instantiate this class themselves and must access it's methods via the * static FTLibrary::Instance() function. * * Just because this class returns a valid FTLibrary object * doesn't mean that the Freetype Library has been successfully initialised. * Clients should check for errors. You can initialse the library AND check * for errors using the following code... * err = FTLibrary::Instance().Error(); * * @see "Freetype 2 Documentation" * */ class FTLibrary { public: /** * Global acces point to the single FTLibrary object. * * @return The global FTLibrary object. */ static const FTLibrary& Instance(); /** * Gets a pointer to the native Freetype library. * * @return A handle to a FreeType library instance. */ const FT_Library* const GetLibrary() const { return library; } /** * Queries the library for errors. * * @return The current error code. */ FT_Error Error() const { return err; } /** * Destructor * * Disposes of the Freetype library */ ~FTLibrary(); private: /** * Default constructors. * * Made private to stop clients creating there own FTLibrary * objects. */ FTLibrary(); FTLibrary(const FT_Library&){} FTLibrary& operator=(const FT_Library&) { return *this; } /** * Initialises the Freetype library * * Even though this function indicates success via the return value, * clients can't see this so must check the error codes. This function * is only ever called by the default c_stor * * @return true if the Freetype library was * successfully initialised, false * otherwise. */ bool Initialise(); /** * Freetype library handle. */ FT_Library* library; // FTC_Manager* manager; /** * Current error code. Zero means no error. */ FT_Error err; }; #endif // __FTLibrary__ rgl/src/ext/GLsdk/0000755000176200001440000000000014100762641013432 5ustar liggesusersrgl/src/ext/GLsdk/README0000644000176200001440000000754514100762641014325 0ustar liggesusersThe currently shipping OpenGL32.DLL from Microsoft only has entry points for OpenGL 1.1. If an application wants to use OpenGL {1.2, 1.3, 1.4, 1.5} functions, it has to use wglGetProcAddress() in order to obtain the entry points from the driver. The files in this distribution enable the application pretend that there is full support for OpenGL {1.2/1.3/1.4/1.5} if the underlying implementation supports OpenGL {1.2/1.3/1.4/1.5}. A useful feature of the framework is that it provides a safety layer by initializing each function to a "default" initialization function with matching arguments and return type. On debug builds, the initialization function adds an ASSERT to catch unwitting usage of NULL function pointers by the application. The framework is also readily usable for multi-context and multi-threaded applications, including application code that demonstrates how to achieve this. Additionally, this distribution provides full support for all the extension entry points in glext.h and wglext.h. In order to use this scheme, the application needs to do the following: ===================================================================== For applications that do not create rendering contexts on different devices (e.g. multi-display with different vendors supporting the two displays): 1. Include "glprocs.h" in addition to including "gl.h" 2. Compile "glprocs.c" and ensure that glprocs.obj is linked with the application code. 3. Call OpenGL{1.2,1.3,1.4,1.5} and extension procs after verifying that the implementation has support for the underlying feature. Example: if (supports12) { glDrawRangeElements (.....) } NOTE: The application can call "glGetString(GL_VERSION)" to determine the version of OpenGL supported on a particular implementation. ===================================================================== For aplications that create rendering contexts on different devices, the application has to perform the following additional steps: 1. Allocate memory for _GLextensionProcs in the application data structures for each device. Example: typedef struct { appType appData; _GLextensionProcs extensionProcs; } ContextData; ContextData cdev1, cdev2; 2. Initialize the extension procs. _InitExtensionProcs (&cdev1.extensionProcs); _InitExtensionProcs (&cdev2.extensionProcs); 3. Provide a mechanism for accessing the current device. Example: ContextData *currentContextData; static _inline _GLextensionProcs *_GET_TLS_PROCTABLE(void) { return (¤tContxtData->extensionProcs); } Another Example (when the two different devices are being used on two different contexts): static _inline _GLextensionProcs *_GET_TLS_PROCTABLE(void) { ContextData *tla = GetThreadSpecificData(); return (&tla->extensionProcs); } (NOTE: Aplication has to replace this function in glprocs.h with its own customized function). ===================================================================== This distribution additionally contains the following: Windows Demo Source: -------------------- windemo: demogl.{c|h} - sample initialization, rendering functions and a sample data structure for tracking per-window data (useful for apps. with multiple windows). Makefile:Builds all the demos (singlewin, multiwin, and multithread) singlewin: demo.c: Shows how to use the SDK for an application with a single window. Makefile: Builds the singlewin sample (demo.exe). multiwin: demo.c: Shows how to use the SDK for an application with two windows Makefile: Builds the multiwin sample (demo.exe) multithread: demo.c: Shows how to use the SDK for a multi-threaded application. Makefile: Builds the multithread sample (demo.exe). GLX Demo Source: -------------------- glxdemo: GLX demo similar to the singlewin Windows demo. rgl/src/ext/GLsdk/windemo/0000755000176200001440000000000014100762641015074 5ustar liggesusersrgl/src/ext/GLsdk/windemo/README0000644000176200001440000000253514100762641015761 0ustar liggesusersdemogl.{c,h} - OpenGL rendering routines (this directory. Shared by programs in threee directories below). The following three directories have the same "demo.c" program which uses demogl, but is setup three different ways. singlewin - Window setup to render in a single window. Most normal aplications work this way and don't have do anything special for OpenGL 1.2, 1.3 and extension procs. multiwin - Multiple windows with a single message loop. At any given time, there is only context which is current. The application defines its own method for accessing the proc table (see _APP_PROCTABLE flag in the Makefile). Since there is only window which is current, a global variable can be used to provide reference to the current proc table. multithread - Multiple windows with a multiple message loops using multiple threads. At any given time, there can be multiple current contexts. The application defines its own method for accessing the proc table (see _APP_PROCTABLE flag in the Makefile). However, there can me multiple current contexts on different thread, the application uses thread local storage to define proper access to the current proc table. rgl/src/ext/GLsdk/windemo/demogl.h0000644000176200001440000000514014100762641016514 0ustar liggesusers#ifndef __DEMOGL_H__ #define __DEMOGL_H__ /* ** License Applicability. Except to the extent portions of this file are ** made subject to an alternative license as permitted in the SGI Free ** Software License B, Version 1.1 (the "License"), the contents of this ** file are subject only to the provisions of the License. You may not use ** this file except in compliance with the License. You may obtain a copy ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: ** ** http://oss.sgi.com/projects/FreeB ** ** Note that, as provided in the License, the Software is distributed on an ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. ** ** Original Code. The Original Code is: OpenGL Sample Implementation, ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. ** Copyright in any portions created by third parties is as indicated ** elsewhere herein. All Rights Reserved. ** ** Additional Notice Provisions: This software was created using the ** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has ** not been independently verified as being compliant with the OpenGL(R) ** version 1.2.1 Specification. */ // Define a structure keeping all application data on a per window // basis. typedef struct { // Intialized data char *windowTitle; int xpos; int ypos; int width; // Size of client region int height; int pfdFlags; // Flags for selecting pixel format descriptor // Computed data int hasMultitexture; // Supports multi-texture int hasWinSwapHint; // Supports WinSwapHint int spin; // Rotation angle of triangle per window int texid; // Texture id per window HWND hWnd; // Main window handle. HDC hDC; // Device context HGLRC hRC; // OpenGL context // If we are using multiple renderers in a single process or on // multiple threads, we must keep our function table for // OpenGL 1.2, OpenGL 1.3 and extension functions #ifdef _APP_PROCTABLE _GLextensionProcs extensionProcs; #endif } WindowData; // Extern defintions for rendering functions in demogl.c. void InitializeOpenGL (WindowData *pwdata); void DrawScene (WindowData *pwdata); #endif /* __DEMOGL_H__ */ rgl/src/ext/GLsdk/windemo/Makefile0000644000176200001440000000101514146473376016547 0ustar liggesusersMAKE = $(MAKE) /nologo # Turn off copyright notice all: singlewin.exe multiwin.exe multithread.exe singlewin.exe: @cd singlewin @$(MAKE) /$(MAKEFLAGS) @cd .. multiwin.exe: @cd multiwin @$(MAKE) /$(MAKEFLAGS) @cd .. multithread.exe: @cd multithread @$(MAKE) /$(MAKEFLAGS) @cd .. clean: @cd singlewin @$(MAKE) /$(MAKEFLAGS) clean @cd .. @cd multiwin @$(MAKE) /$(MAKEFLAGS) clean @cd .. @cd multithread @$(MAKE) /$(MAKEFLAGS) clean @cd .. rgl/src/ext/GLsdk/windemo/singlewin/0000755000176200001440000000000014100762641017073 5ustar liggesusersrgl/src/ext/GLsdk/windemo/singlewin/demo.c0000644000176200001440000001673214100762641020174 0ustar liggesusers/* ** License Applicability. Except to the extent portions of this file are ** made subject to an alternative license as permitted in the SGI Free ** Software License B, Version 1.1 (the "License"), the contents of this ** file are subject only to the provisions of the License. You may not use ** this file except in compliance with the License. You may obtain a copy ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: ** ** http://oss.sgi.com/projects/FreeB ** ** Note that, as provided in the License, the Software is distributed on an ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. ** ** Original Code. The Original Code is: OpenGL Sample Implementation, ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. ** Copyright in any portions created by third parties is as indicated ** elsewhere herein. All Rights Reserved. ** ** Additional Notice Provisions: This software was created using the ** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has ** not been independently verified as being compliant with the OpenGL(R) ** version 1.2.1 Specification. */ #include // Required inclusion on windows #include // OpenGL definitions #include #include #include #include "demogl.h" static char szAppName[] = "OpenGL"; HINSTANCE _hInstance; WindowData wdata[] = { {"ICD OpenGL", 50, 250, 200, 200, PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER}, }; int nWnd = sizeof (wdata) / sizeof (wdata[0]);; #define TESTFLAGS (PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | PFD_GENERIC_FORMAT) //======================================================================== // Setup a pixel format for a window, create context and initialize // OpenGL 1.2 procs. void SetupWindow (HWND hWnd, WindowData *pwdata) { int iPixelFormat = 0; int numPixelFmts; PIXELFORMATDESCRIPTOR pfd; int i; pwdata->hDC = GetDC (hWnd); // Create a DC for the window. // Search for a pixel format which matches the flags specified for // the window. numPixelFmts = DescribePixelFormat (pwdata->hDC, 1, sizeof (pfd), NULL); for (i = 0; i < numPixelFmts; i++) { DescribePixelFormat (pwdata->hDC, i+1, sizeof(pfd), &pfd); if ((pfd.dwFlags & TESTFLAGS) == pwdata->pfdFlags) { iPixelFormat = i+1; break; } } if (iPixelFormat == 0) { // Did not find a suitable pixel format assert (0); exit(1); } // Set pixel format for the window if (SetPixelFormat (pwdata->hDC, iPixelFormat, &pfd) == FALSE) { assert (0); exit (1); } // Create a context for the window pwdata->hRC = wglCreateContext (pwdata->hDC); // Bind this context to this thread. Since each thread is working on // each window, we have to do MakeCurrent only once. wglMakeCurrent (pwdata->hDC, pwdata->hRC); // Initialize the OpenGL context. InitializeOpenGL (pwdata); } //======================================================================== // Proc to receive window messages LONG WINAPI WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; WindowData *pwdata; RECT rect; // Obtain the window data for this thread. Note that WM_CREATE cannot // "read" the values in window data since it has not yet been setup until // we have gone through creation/initialization. Also, pwdata as // computed below is incorrect when we receive WM_CREATE msg. if (hWnd == wdata[0].hWnd) { pwdata = &wdata[0]; } else { pwdata = &wdata[1]; } // Process the window message. switch (msg) { case WM_CREATE: SetupWindow (hWnd, ((LPCREATESTRUCT) lParam)->lpCreateParams); return (0); case WM_SIZE: pwdata->width = LOWORD (lParam); pwdata->height = HIWORD (lParam); glViewport (0, 0, pwdata->width, pwdata->height); return 0; case WM_PAINT: BeginPaint (hWnd, &ps); DrawScene(pwdata); // Update the client area EndPaint (hWnd, &ps); return 0; case WM_DESTROY: // Delete the context. wglDeleteContext (pwdata->hRC); PostQuitMessage( 0 ); return 0; } return DefWindowProc (hWnd, msg, wParam, lParam); } //======================================================================== int ThreadMain (int i) { // Create a window for the application. wdata[i].hWnd = CreateWindow( szAppName, // Application name wdata[i].windowTitle, // Window title text WS_OVERLAPPEDWINDOW | // Window style WS_CLIPCHILDREN | // Needed for OpenGL WS_CLIPSIBLINGS, // Needed for OpenGL wdata[i].xpos, wdata[i].ypos, wdata[i].width, wdata[i].height, NULL, // No parent window NULL, // Use the window class menu. _hInstance, // This instance owns this window &wdata[i]); // Application window data structure // Check for window creation if (!wdata[i].hWnd) { assert (0); exit (1); } // Make the window visible & update its client area ShowWindow (wdata[i].hWnd, SW_SHOWNORMAL); UpdateWindow (wdata[i].hWnd); // Send WM_PAINT message return (0); } //======================================================================== // Windows main program. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { WNDCLASS wc; // windows class sruct int i; HANDLE hThread; DWORD IDThread; MSG msg; // message struct _hInstance = hInstance; // Save for later use. // Fill in window class structure with parameters that // describe the main window. wc.style = CS_HREDRAW | CS_VREDRAW; // Class style(s). wc.lpfnWndProc = (WNDPROC)WndProc; // Window Procedure wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; // Owner of this class wc.hIcon = NULL; // Icon name wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Cursor wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // Default color wc.lpszMenuName = NULL; wc.lpszClassName = szAppName; // Name to register as // Register the window class RegisterClass( &wc ); // Create a single window without creating threads. for (i = 0; i < nWnd; i++) { ThreadMain (0); } // Enter the Windows message loop. Get and dispatch messages // until WM_QUIT. while (GetMessage(&msg, // message structure NULL, // handle of window receiving the message 0, // lowest message id to examine 0)) { // highest message id to examine TranslateMessage (&msg); DispatchMessage (&msg); } return (msg.wParam); } rgl/src/ext/GLsdk/windemo/singlewin/Makefile0000644000176200001440000000124114146473376020547 0ustar liggesusersGLSDKDIR = ..\.. INCS = -I$(GLSDKDIR) INCS = $(INCS) -I.. # add windemo directory LIBS = GDI32.lib User32.lib OpenGL32.lib GLU32.lib !if ("$(BLDENV)" == "") CFLAGS = -c LNFLAGS = !else CFLAGS = -c -Od -Zi LNFLAGS = -debug -debugtype:cv -pdbtype:con !endif demo: demo.obj demogl.obj glprocs.obj link demo.obj demogl.obj glprocs.obj $(LIBS) $(LNFLAGS) demo.obj: demo.c ..\demogl.h cl $(CFLAGS) $(INCS) demo.c demogl.obj: ..\demogl.c ..\demogl.h cl $(CFLAGS) $(INCS) ..\demogl.c glprocs.obj: $(GLSDKDIR)\GL\glprocs.c cl $(CFLAGS) $(INCS) $(GLSDKDIR)\GL\glprocs.c clean: @erase demo.obj glprocs.obj demogl.obj demo.exe *.pdb *.ilk > nul rgl/src/ext/GLsdk/windemo/demogl.c0000644000176200001440000001662714100762641016523 0ustar liggesusers/* ** License Applicability. Except to the extent portions of this file are ** made subject to an alternative license as permitted in the SGI Free ** Software License B, Version 1.1 (the "License"), the contents of this ** file are subject only to the provisions of the License. You may not use ** this file except in compliance with the License. You may obtain a copy ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: ** ** http://oss.sgi.com/projects/FreeB ** ** Note that, as provided in the License, the Software is distributed on an ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. ** ** Original Code. The Original Code is: OpenGL Sample Implementation, ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. ** Copyright in any portions created by third parties is as indicated ** elsewhere herein. All Rights Reserved. ** ** Additional Notice Provisions: This software was created using the ** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has ** not been independently verified as being compliant with the OpenGL(R) ** version 1.2.1 Specification. */ #include // Required inclusion on windows #include // OpenGL definitions #include // OpenGL {1.2, 1.3, 1.4, 1.5} and extension functions #include "demogl.h" //==================================================================== // Using strstr for extension search can result in false positives // because of substring matches. Since extension names in the // extension string are separated by spaces, this can be fixed simply // by looking for a space OR the end-of-string character immediately // following the extension we're looking for (by skipping ahead 'len' // characters). //==================================================================== static GLboolean IsExtensionSupported(const GLubyte *extensionStr, const GLubyte *checkExtension) { const GLubyte *s; GLint len; s = extensionStr; len = strlen (checkExtension); while ((s = strstr (s, checkExtension)) != NULL) { s += len; if ((*s == ' ') || (*s == '\0')) { return (GL_TRUE); } } return (GL_FALSE); } //======================================================================== // Initialize the OpenGL context - create textures, check the extensions // supported by the driver etc. void InitializeOpenGL (WindowData *pwdata) { const GLubyte *extstrGL; GLubyte image[] = { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, }; // Setup the extensions extstrGL = glGetString (GL_EXTENSIONS); // Check for WIN_swap_hint extension. if (GL_TRUE == IsExtensionSupported(extstrGL, "GL_WIN_swap_hint")) { pwdata->hasWinSwapHint = TRUE; } // Check for multi-texture extension. if (GL_TRUE == IsExtensionSupported (extstrGL, "GL_ARB_multitexture")) { pwdata->hasMultitexture = TRUE; // Multi-texturing is supported. Create a texture for unit1 and // bind it in MODULATE mode. //========================================================== //========================================================== // Use an extension function without doing anything special! // OpenGL 1.2, OpenGL 1.3 procs can be used similarly - as // long we ensure it is supported - just as we have done // for multi-texturing here. //========================================================== //========================================================== glActiveTextureARB (GL_TEXTURE1_ARB); // Use unit1 glGenTextures (1, &pwdata->texid); glBindTexture (GL_TEXTURE_2D, pwdata->texid); // Bound on unit 1 glTexImage2D (GL_TEXTURE_2D, 0, GL_LUMINANCE, 4, 4, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, image); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable (GL_TEXTURE_2D); } } //======================================================================== void DrawScene (WindowData *pwdata) { // If WIN_swap_hint extension is supported, use it to create GREEN // border around the frame. We render the first frame with GREEN. // The second frame is the actual rendering rectangle - but is // swapped with a smaller swap rectangle. if (pwdata->hasWinSwapHint) { glClearColor (0.0, 1.0, 0.0, 0.0); // GREEN glClear(GL_COLOR_BUFFER_BIT); SwapBuffers (pwdata->hDC); // Setup the swap hint rect for the next frame //========================================================== //========================================================== // Use an extension function without doing anything special! // OpenGL 1.2, OpenGL 1.3 procs can be used similarly - as // long we ensure it is supported - just as we have done // for SwapHint here. //========================================================== //========================================================== glAddSwapHintRectWIN(20, 20, pwdata->width - 40, pwdata->height - 40); } // Render a triangle - multi-textured if ARB_multitexture is supported. glClearColor (0.0, 0.0, 0.0, 0.0); // BLACK glClear(GL_COLOR_BUFFER_BIT); glMatrixMode (GL_MODELVIEW); glLoadIdentity(); glRotatef (pwdata->spin, 0.0, 0.0, 1.0); pwdata->spin += 2; if (pwdata->spin >= 360) { pwdata->spin = 0; } if (pwdata->hasMultitexture) { //========================================================== //========================================================== // Use an extension function without doing anything special! // OpenGL 1.2, OpenGL 1.3 procs can be used similarly - as // long we ensure it is supported - just as we have done // for MultiTexCoord here. //========================================================== //========================================================== glBegin( GL_POLYGON ); glMultiTexCoord2fARB (GL_TEXTURE1_ARB, 0.0, 0.0); glColor3f (1.0, 0.0, 0.0); glVertex3f(0.0, 0.0, 0.0); glMultiTexCoord2fARB (GL_TEXTURE1_ARB, 1.0, 0.0); glColor3f (0.0, 1.0, 0.0); glVertex3f(0.5, 0.0, 0.0); glMultiTexCoord2fARB (GL_TEXTURE1_ARB, 1.0, 1.0); glColor3f (0.0, 0.0, 1.0); glVertex3f(0.5, 0.5, 0.0); glEnd(); } else { glBegin( GL_POLYGON ); glColor3f (1.0, 0.0, 0.0); glVertex3f(0.0, 0.0, 0.0); glColor3f (0.0, 1.0, 0.0); glVertex3f(0.5, 0.0, 0.0); glColor3f (0.0, 0.0, 1.0); glVertex3f(0.5, 0.5, 0.0); glEnd(); } SwapBuffers (pwdata->hDC); } rgl/src/ext/GLsdk/windemo/multiwin/0000755000176200001440000000000014100762641016744 5ustar liggesusersrgl/src/ext/GLsdk/windemo/multiwin/demo.c0000644000176200001440000002372314100762641020043 0ustar liggesusers/* ** License Applicability. Except to the extent portions of this file are ** made subject to an alternative license as permitted in the SGI Free ** Software License B, Version 1.1 (the "License"), the contents of this ** file are subject only to the provisions of the License. You may not use ** this file except in compliance with the License. You may obtain a copy ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: ** ** http://oss.sgi.com/projects/FreeB ** ** Note that, as provided in the License, the Software is distributed on an ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. ** ** Original Code. The Original Code is: OpenGL Sample Implementation, ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. ** Copyright in any portions created by third parties is as indicated ** elsewhere herein. All Rights Reserved. ** ** Additional Notice Provisions: This software was created using the ** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has ** not been independently verified as being compliant with the OpenGL(R) ** version 1.2.1 Specification. */ #include // Required inclusion on windows #include // OpenGL definitions #include #include #include #include "demogl.h" static char szAppName[] = "OpenGL"; HINSTANCE _hInstance; WindowData wdata[] = { {"MS OpenGL", 50, 50, 150, 150, PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | PFD_GENERIC_FORMAT}, {"ICD OpenGL", 50, 250, 200, 200, PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER}, }; int nWnd = sizeof (wdata) / sizeof (wdata[0]);; #define TESTFLAGS (PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | PFD_GENERIC_FORMAT) //****************************************************************** //****************************************************************** WindowData *currentWindowData; // Function to get thread local proc table. _GLextensionProcs *_GET_TLS_PROCTABLE(void) { // Return the pointer to the extension proc table // hanging off the current local data. return (¤tWindowData->extensionProcs); } //****************************************************************** //****************************************************************** //======================================================================== // Setup a pixel format for a window, create context and initialize // OpenGL 1.2 procs. void SetupWindow (HWND hWnd, WindowData *pwdata) { int iPixelFormat = 0; int numPixelFmts; PIXELFORMATDESCRIPTOR pfd; int i; pwdata->hDC = GetDC (hWnd); // Create a DC for the window. // Search for a pixel format which matches the flags specified for // the window. numPixelFmts = DescribePixelFormat (pwdata->hDC, 1, sizeof (pfd), NULL); for (i = 0; i < numPixelFmts; i++) { DescribePixelFormat (pwdata->hDC, i+1, sizeof(pfd), &pfd); if ((pfd.dwFlags & TESTFLAGS) == pwdata->pfdFlags) { iPixelFormat = i+1; break; } } if (iPixelFormat == 0) { // Did not find a suitable pixel format assert (0); exit(1); } // Set pixel format for the window if (SetPixelFormat (pwdata->hDC, iPixelFormat, &pfd) == FALSE) { assert (0); exit (1); } // Create a context for the window pwdata->hRC = wglCreateContext (pwdata->hDC); // Bind this context to this thread. Since each thread is working on // each window, we have to do MakeCurrent only once. wglMakeCurrent (pwdata->hDC, pwdata->hRC); //******************************************************** //******************************************************** // Every time we do MakeCurrent, we must setup the global // ptr to currentWindowData so that we have the correct // proc table for OpenGL functions. currentWindowData = pwdata; //******************************************************** //******************************************************** // Initialize the OpenGL context. InitializeOpenGL (pwdata); } //======================================================================== // Proc to receive window messages LONG WINAPI WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; WindowData *pwdata; RECT rect; // Obtain the window data for this thread. Note that WM_CREATE cannot // "read" the values in window data since it has not yet been setup until // we have gone through creation/initialization. Also, pwdata as // computed below is incorrect when we receive WM_CREATE msg. if (hWnd == wdata[0].hWnd) { pwdata = &wdata[0]; } else { pwdata = &wdata[1]; } // Process the window message. switch (msg) { case WM_CREATE: SetupWindow (hWnd, ((LPCREATESTRUCT) lParam)->lpCreateParams); return (0); case WM_SIZE: pwdata->width = LOWORD (lParam); pwdata->height = HIWORD (lParam); glViewport (0, 0, pwdata->width, pwdata->height); return 0; case WM_PAINT: // Since both the contexts are running on the same thread, // make the context for the current window current // before rendering. wglMakeCurrent (pwdata->hDC, pwdata->hRC); //******************************************************** //******************************************************** // Every time we do MakeCurrent, we must setup the global // ptr to currentWindowData so that we have the correct // proc table for OpenGL functions. currentWindowData = pwdata; //******************************************************** //******************************************************** BeginPaint (hWnd, &ps); DrawScene(pwdata); // Update the client area EndPaint (hWnd, &ps); return 0; case WM_DESTROY: // Delete the context. wglDeleteContext (pwdata->hRC); // In multi-window scenario, post the quit message // only when the number of window becomes zero. nWnd -= 1; if (nWnd == 0) { PostQuitMessage( 0 ); } return 0; } return DefWindowProc (hWnd, msg, wParam, lParam); } //======================================================================== int ThreadMain (int i) { //****************************************************************** //****************************************************************** // Initialize the OpenGL extension proc table for this window data. // (One time intiailization per device context). We do it early // so that even wgl Extensions are correctly available to the thread. _InitExtensionProcs (&wdata[i].extensionProcs); //****************************************************************** //****************************************************************** // Create a window for the application. wdata[i].hWnd = CreateWindow( szAppName, // Application name wdata[i].windowTitle, // Window title text WS_OVERLAPPEDWINDOW | // Window style WS_CLIPCHILDREN | // Needed for OpenGL WS_CLIPSIBLINGS, // Needed for OpenGL wdata[i].xpos, wdata[i].ypos, wdata[i].width, wdata[i].height, NULL, // No parent window NULL, // Use the window class menu. _hInstance, // This instance owns this window &wdata[i]); // Application window data structure // Check for window creation if (!wdata[i].hWnd) { assert (0); exit (1); } // Make the window visible & update its client area ShowWindow (wdata[i].hWnd, SW_SHOWNORMAL); UpdateWindow (wdata[i].hWnd); // Send WM_PAINT message return (0); } //======================================================================== // Windows main program. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { WNDCLASS wc; // windows class sruct int i; HANDLE hThread; DWORD IDThread; MSG msg; // message struct _hInstance = hInstance; // Save for later use. // Fill in window class structure with parameters that // describe the main window. wc.style = CS_HREDRAW | CS_VREDRAW; // Class style(s). wc.lpfnWndProc = (WNDPROC)WndProc; // Window Procedure wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; // Owner of this class wc.hIcon = NULL; // Icon name wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Cursor wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // Default color wc.lpszMenuName = NULL; wc.lpszClassName = szAppName; // Name to register as // Register the window class RegisterClass( &wc ); // Create multiple windows without creating threads. for (i = 0; i < nWnd; i++) { ThreadMain (i); } // Enter the Windows message loop. Get and dispatch messages // until WM_QUIT. while (GetMessage(&msg, // message structure NULL, // handle of window receiving the message 0, // lowest message id to examine 0)) { // highest message id to examine TranslateMessage (&msg); DispatchMessage (&msg); } return (msg.wParam); } rgl/src/ext/GLsdk/windemo/multiwin/Makefile0000644000176200001440000000165514146473376020431 0ustar liggesusersGLSDKDIR = ..\.. INCS = -I$(GLSDKDIR) INCS = $(INCS) -I.. # add demogl directory LIBS = GDI32.lib User32.lib OpenGL32.lib GLU32.lib !if ("$(BLDENV)" == "") CFLAGS = -c LNFLAGS = !else CFLAGS = -c -Od -Zi LNFLAGS = -debug -debugtype:cv -pdbtype:con !endif #********************************************************************* # Since this is a multi-thread/multi-device application, we define # our own proctable. CFLAGS = $(CFLAGS) -D_APP_PROCTABLE #********************************************************************* demo: demo.obj demogl.obj glprocs.obj link demo.obj demogl.obj glprocs.obj $(LIBS) $(LNFLAGS) demo.obj: demo.c ..\demogl.h cl $(CFLAGS) $(INCS) demo.c demogl.obj: ..\demogl.c ..\demogl.h cl $(CFLAGS) $(INCS) ..\demogl.c glprocs.obj: $(GLSDKDIR)\GL\glprocs.c cl $(CFLAGS) $(INCS) $(GLSDKDIR)\GL\glprocs.c clean: @erase demo.obj glprocs.obj demogl.obj demo.exe *.pdb *.ilk > nul rgl/src/ext/GLsdk/windemo/multithread/0000755000176200001440000000000014100762641017416 5ustar liggesusersrgl/src/ext/GLsdk/windemo/multithread/demo.c0000644000176200001440000002576714100762641020527 0ustar liggesusers/* ** License Applicability. Except to the extent portions of this file are ** made subject to an alternative license as permitted in the SGI Free ** Software License B, Version 1.1 (the "License"), the contents of this ** file are subject only to the provisions of the License. You may not use ** this file except in compliance with the License. You may obtain a copy ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: ** ** http://oss.sgi.com/projects/FreeB ** ** Note that, as provided in the License, the Software is distributed on an ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. ** ** Original Code. The Original Code is: OpenGL Sample Implementation, ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. ** Copyright in any portions created by third parties is as indicated ** elsewhere herein. All Rights Reserved. ** ** Additional Notice Provisions: This software was created using the ** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has ** not been independently verified as being compliant with the OpenGL(R) ** version 1.2.1 Specification. */ #include // Required inclusion on windows #include // OpenGL definitions #include #include #include #include "demogl.h" static WNDCLASSEX wcx; static char szAppName[] = "OpenGL"; HINSTANCE _hInstance; WindowData wdata[] = { {"MS OpenGL", 50, 50, 150, 150, PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | PFD_GENERIC_FORMAT}, {"ICD OpenGL", 50, 250, 200, 200, PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER}, }; int nWnd = sizeof (wdata) / sizeof (wdata[0]);; #define TESTFLAGS (PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | PFD_GENERIC_FORMAT) //****************************************************************** //****************************************************************** DWORD tlsIndex; // Index for thread local data. // Function to get thread local proc table. _GLextensionProcs *_GET_TLS_PROCTABLE(void) { WindowData *pwdata; // Get pointer to thread local data. pwdata = TlsGetValue (tlsIndex); // Return the pointer to the extension proc table // hanging off the thread local data. return (&pwdata->extensionProcs); } //****************************************************************** //****************************************************************** //======================================================================== // Setup a pixel format for a window, create context and initialize // OpenGL 1.2 procs. void SetupWindow (HWND hWnd, WindowData *pwdata) { int iPixelFormat = 0; int numPixelFmts; PIXELFORMATDESCRIPTOR pfd; int i; pwdata->hDC = GetDC (hWnd); // Create a DC for the window. // Search for a pixel format which matches the flags specified for // the window. numPixelFmts = DescribePixelFormat (pwdata->hDC, 1, sizeof (pfd), NULL); for (i = 0; i < numPixelFmts; i++) { DescribePixelFormat (pwdata->hDC, i+1, sizeof(pfd), &pfd); if ((pfd.dwFlags & TESTFLAGS) == pwdata->pfdFlags) { iPixelFormat = i+1; break; } } if (iPixelFormat == 0) { // Did not find a suitable pixel format assert (0); exit(1); } // Set pixel format for the window if (SetPixelFormat (pwdata->hDC, iPixelFormat, &pfd) == FALSE) { assert (0); exit (1); } // Create a context for the window pwdata->hRC = wglCreateContext (pwdata->hDC); // Bind this context to this thread. Since each thread is working on // each window, we have to do MakeCurrent only once. wglMakeCurrent (pwdata->hDC, pwdata->hRC); // Initialize the OpenGL context. InitializeOpenGL (pwdata); } //======================================================================== // Proc to receive window messages LONG WINAPI WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; WindowData *pwdata; RECT rect; // Obtain the window data for this thread. Note that WM_CREATE cannot // "read" the values in window data since it has not yet been setup until // we have gone through creation/initialization. pwdata = TlsGetValue (tlsIndex); // Process the window message. switch (msg) { case WM_CREATE: SetupWindow (hWnd, ((LPCREATESTRUCT) lParam)->lpCreateParams); return (0); case WM_SIZE: pwdata->width = LOWORD (lParam); pwdata->height = HIWORD (lParam); glViewport (0, 0, pwdata->width, pwdata->height); return 0; case WM_PAINT: // Since each thread has its own context, we don't have // to do a MakeCurrent for each paint message. BeginPaint (hWnd, &ps); DrawScene(pwdata); // Update the client area EndPaint (hWnd, &ps); return 0; case WM_DESTROY: // Delete the context. wglDeleteContext (pwdata->hRC); PostQuitMessage( 0 ); return 0; } return DefWindowProc (hWnd, msg, wParam, lParam); } //======================================================================== int ThreadMain (void *vi) { int i = (int) vi; MSG msg; // message struct //****************************************************************** //****************************************************************** // Store the windowData for this thread in the thread local data. TlsSetValue (tlsIndex, &wdata[i]); // Initialize the OpenGL extension proc table for this window data. // (One time intiailization per device context). We do it early // so that even wgl Extensions are correctly available to the thread. _InitExtensionProcs (&wdata[i].extensionProcs); //****************************************************************** //****************************************************************** // Fill in the window class structure with parameters // that describe the main window. wcx.cbSize = sizeof(wcx); // size of structure wcx.style = CS_HREDRAW | CS_VREDRAW; // redraw if size changes wcx.lpfnWndProc = WndProc; // points to window procedure wcx.cbClsExtra = 0; // no extra class memory wcx.cbWndExtra = 0; // no extra window memory wcx.hInstance = _hInstance; // handle to instance wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION); // predefined app. icon wcx.hCursor = LoadCursor(NULL, IDC_ARROW); // predefined arrow wcx.hbrBackground = GetStockObject( WHITE_BRUSH); // white background brush wcx.lpszMenuName = NULL; // name of menu resource wcx.lpszClassName = szAppName; // name of window class wcx.hIconSm = LoadImage(_hInstance, // small class icon MAKEINTRESOURCE(5), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); // Register the window class. RegisterClassEx(&wcx); // Create a window for the application. wdata[i].hWnd = CreateWindow( szAppName, // Application name wdata[i].windowTitle, // Window title text WS_OVERLAPPEDWINDOW | // Window style WS_CLIPCHILDREN | // Needed for OpenGL WS_CLIPSIBLINGS, // Needed for OpenGL wdata[i].xpos, wdata[i].ypos, wdata[i].width, wdata[i].height, NULL, // No parent window NULL, // Use the window class menu. _hInstance, // This instance owns this window &wdata[i]); // Application window data structure // Check for window creation if (!wdata[i].hWnd) { assert (0); exit (1); } // Make the window visible & update its client area ShowWindow (wdata[i].hWnd, SW_SHOWNORMAL); UpdateWindow (wdata[i].hWnd); // Send WM_PAINT message // Enter the Windows message loop. Get and dispatch messages // until WM_QUIT. while (GetMessage(&msg, // message structure NULL, // handle of window receiving the message 0, // lowest message id to examine 0)) { // highest message id to examine TranslateMessage (&msg); DispatchMessage (&msg); } UnregisterClass(szAppName, _hInstance); return (msg.wParam); } //======================================================================== // Windows main program. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { WNDCLASS wc; // windows class sruct int i; HANDLE hThread; DWORD IDThread; _hInstance = hInstance; // Save for later use. // Fill in window class structure with parameters that // describe the main window. wc.style = CS_HREDRAW | CS_VREDRAW; // Class style(s). wc.lpfnWndProc = (WNDPROC)WndProc; // Window Procedure wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; // Owner of this class wc.hIcon = NULL; // Icon name wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Cursor wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // Default color wc.lpszMenuName = NULL; wc.lpszClassName = szAppName; // Name to register as // Register the window class RegisterClass( &wc ); //****************************************************************** //****************************************************************** // For multi-threaded applications, allocate a thread local storage // for storing a global for each thread. if ( (tlsIndex = TlsAlloc()) == -1) { assert (0); exit(1); } //****************************************************************** //****************************************************************** for (i = 0; i < nWnd; i++) { hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) ThreadMain, (void *) i, 0, &IDThread); if (hThread == NULL) { assert (0); exit(1); } } // We don't nee this thread anymore since the two threads are // taking care of the two windows independently. However, we // exit the thread and not the process. ExitThread (0); } rgl/src/ext/GLsdk/windemo/multithread/Makefile0000644000176200001440000000172114146473376021075 0ustar liggesusersGLSDKDIR = ..\.. INCS = -I$(GLSDKDIR) INCS = $(INCS) -I.. # add demogl directory LIBS = GDI32.lib User32.lib OpenGL32.lib GLU32.lib # By default build release binaries. !if "$(BLDENV)" == "" CFLAGS = -c LNFLAGS = !else CFLAGS = -c -Od -Zi LNFLAGS = -debug -debugtype:cv -pdbtype:con !endif #********************************************************************* # Since this is a multi-thread/multi-device application, we define # our own proctable. CFLAGS = $(CFLAGS) -D_APP_PROCTABLE #********************************************************************* demo: demo.obj demogl.obj glprocs.obj link demo.obj demogl.obj glprocs.obj $(LIBS) $(LNFLAGS) demo.obj: demo.c ..\demogl.h cl $(CFLAGS) $(INCS) demo.c demogl.obj: ..\demogl.c ..\demogl.h cl $(CFLAGS) $(INCS) ..\demogl.c glprocs.obj: $(GLSDKDIR)\GL\glprocs.c cl $(CFLAGS) $(INCS) $(GLSDKDIR)\GL\glprocs.c clean: @erase demo.obj glprocs.obj demogl.obj demo.exe *.pdb *.ilk > nul rgl/src/ext/GLsdk/glxdemo/0000755000176200001440000000000014100762641015071 5ustar liggesusersrgl/src/ext/GLsdk/glxdemo/demo.c0000644000176200001440000002440514100762641016166 0ustar liggesusers/* ** License Applicability. Except to the extent portions of this file are ** made subject to an alternative license as permitted in the SGI Free ** Software License B, Version 1.1 (the "License"), the contents of this ** file are subject only to the provisions of the License. You may not use ** this file except in compliance with the License. You may obtain a copy ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: ** ** http://oss.sgi.com/projects/FreeB ** ** Note that, as provided in the License, the Software is distributed on an ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. ** ** Original Code. The Original Code is: OpenGL Sample Implementation, ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. ** Copyright in any portions created by third parties is as indicated ** elsewhere herein. All Rights Reserved. ** ** Additional Notice Provisions: This software was created using the ** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has ** not been independently verified as being compliant with the OpenGL(R) ** version 1.2.1 Specification. */ #include #include #include #include #include #include #include #include #include "GL/glprocs.h" /* * Define a structure keeping all application data on a per window * basis. */ typedef struct { /* Intialized data */ char *windowTitle; int xpos; int ypos; int width; /* Size of client region */ int height; int pfdFlags; /* Flags for selecting pixel format descriptor */ /* Computed data */ int hasMultitexture; /* Supports multi-texture */ int hasWinSwapHint; /* Supports WinSwapHint */ int spin; /* Rotation angle of triangle per window */ int texid; /* Texture id per window */ Display *display; GLXContext context; Window window; /* If we are using multiple renderers in a single process or on * multiple threads, we must keep our function table for * OpenGL 1.2, OpenGL 1.3 and extension functions */ #ifdef _APP_PROCTABLE _GLextensionProcs extensionProcs; #endif } WindowData; /* Using strstr for extension search can result in false positives because of substring matches. Since extension names in the extension string are separated by spaces, this can be fixed simply by looking for a space OR the end-of-string character immediately following the extension we're looking for (by skipping ahead 'len' characters). */ static GLboolean IsExtensionSupported(const GLubyte *extensionStr, const GLubyte *checkExtension) { const GLubyte *s; GLint len; s = extensionStr; len = strlen (checkExtension); while ((s = strstr (s, checkExtension)) != NULL) { s += len; if ((*s == ' ') || (*s == '\0')) { return (GL_TRUE); } } return (GL_FALSE); } /* * Initialize the OpenGL context - create textures, check the extensions * supported by the driver etc. */ static void InitializeOpenGL(WindowData *pwdata) { const GLubyte *extstrGL; GLubyte image[] = { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, }; /* Setup the extensions */ extstrGL = glGetString(GL_EXTENSIONS); /* Check for multi-texture extension. */ if (GL_TRUE == IsExtensionSupported (extstrGL, "GL_ARB_multitexture")) { pwdata->hasMultitexture = GL_TRUE; /* Multi-texturing is supported. Create a texture for unit1 and * bind it in MODULATE mode. */ /* ========================================================== * ========================================================== * Use an extension function without doing anything special! * OpenGL 1.2, OpenGL 1.3 procs can be used similarly - as * long we ensure it is supported - just as we have done * for multi-texturing here. * ========================================================== * ========================================================== */ glActiveTextureARB (GL_TEXTURE1_ARB); /* Use unit1 */ glGenTextures (1, &pwdata->texid); glBindTexture (GL_TEXTURE_2D, pwdata->texid); /* Bound on unit 1 */ glTexImage2D (GL_TEXTURE_2D, 0, GL_LUMINANCE, 4, 4, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, image); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable (GL_TEXTURE_2D); } } static void DrawScene(WindowData *pwdata) { /* Render a triangle - multi-textured if ARB_multitexture is supported. */ glClearColor (0.0, 0.0, 0.0, 0.0); /* BLACK */ glClear (GL_COLOR_BUFFER_BIT); glMatrixMode (GL_MODELVIEW); glLoadIdentity(); glRotatef (pwdata->spin, 0.0, 0.0, 1.0); pwdata->spin += 2; if (pwdata->spin >= 360) { pwdata->spin = 0; } if (pwdata->hasMultitexture) { /* * ========================================================== * ========================================================== * Use an extension function without doing anything special! * OpenGL 1.2, OpenGL 1.3 procs can be used similarly - as * long we ensure it is supported - just as we have done * for MultiTexCoord here. * ========================================================== * ========================================================== */ glBegin( GL_POLYGON ); glMultiTexCoord2fARB (GL_TEXTURE1_ARB, 0.0, 0.0); glColor3f (1.0, 0.0, 0.0); glVertex3f(0.0, 0.0, 0.0); glMultiTexCoord2fARB (GL_TEXTURE1_ARB, 1.0, 0.0); glColor3f (0.0, 1.0, 0.0); glVertex3f(0.5, 0.0, 0.0); glMultiTexCoord2fARB (GL_TEXTURE1_ARB, 1.0, 1.0); glColor3f (0.0, 0.0, 1.0); glVertex3f(0.5, 0.5, 0.0); glEnd(); } else { glBegin( GL_POLYGON ); glColor3f (1.0, 0.0, 0.0); glVertex3f(0.0, 0.0, 0.0); glColor3f (0.0, 1.0, 0.0); glVertex3f(0.5, 0.0, 0.0); glColor3f (0.0, 0.0, 1.0); glVertex3f(0.5, 0.5, 0.0); glEnd(); } glXSwapBuffers(pwdata->display, pwdata->window); } /* * Create an RGB OpenGL window. * Return the window and context handles. */ static void MakeWindow( Display *dpy, const char *name, int x, int y, int width, int height, WindowData *winData ) { int attrib[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None }; int scrnum; XSetWindowAttributes attr; unsigned long mask; Window root; Window win; GLXContext ctx; XVisualInfo *visinfo; scrnum = DefaultScreen( dpy ); root = RootWindow( dpy, scrnum ); visinfo = glXChooseVisual( dpy, scrnum, attrib ); if (!visinfo) { printf("Error: couldn't get an RGB, Double-buffered visual\n"); exit(1); } /* window attributes */ attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow( dpy, root, 0, 0, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr ); /* set hints and properties */ { XSizeHints sizehints; sizehints.x = x; sizehints.y = y; sizehints.width = width; sizehints.height = height; sizehints.flags = USSize | USPosition; XSetNormalHints(dpy, win, &sizehints); XSetStandardProperties(dpy, win, name, name, None, (char **)NULL, 0, &sizehints); } ctx = glXCreateContext( dpy, visinfo, NULL, True ); if (!ctx) { printf("Error: glXCreateContext failed\n"); exit(1); } XFree(visinfo); winData->display = dpy; winData->window = win; winData->context = ctx; } static void EventLoop(WindowData *winData) { while (1) { static long mask = StructureNotifyMask | ExposureMask | KeyPressMask; XEvent event; while (XCheckWindowEvent(winData->display, winData->window, mask, &event)) { if (event.xany.window == winData->window) { switch (event.type) { case Expose: DrawScene(winData); break; case ConfigureNotify: glViewport(0, 0, event.xconfigure.width, event.xconfigure.height); break; case KeyPress: { char buffer[10]; int r; r = XLookupString(&event.xkey, buffer, sizeof(buffer), NULL, NULL); if (buffer[0] == 27) { /* escape */ return; } } } } } DrawScene(winData); } } int main(int argc, char *argv[]) { Display *dpy; WindowData winData; dpy = XOpenDisplay(NULL); if (!dpy) { printf("Error: couldn't open default display.\n"); return -1; } MakeWindow(dpy, "glprocs test", 0, 0, 300, 300, &winData); XMapWindow(dpy, winData.window); glXMakeCurrent(dpy, winData.window, winData.context); InitializeOpenGL(&winData); EventLoop(&winData); glXDestroyContext(dpy, winData.context); XDestroyWindow(dpy, winData.window); XCloseDisplay(dpy); return 0; } rgl/src/ext/GLsdk/glxdemo/Makefile0000644000176200001440000000051114146473376016544 0ustar liggesusersCC = gcc CFLAGS = -c -g -Wall -I/usr/include -I.. LIBS = -L/usr/lib -lGL demo: demo.o glprocs.o $(CC) demo.o glprocs.o $(LIBS) -o $@ demo.o: demo.c ../GL/glprocs.h $(CC) $(CFLAGS) demo.c glprocs.o: glprocs.c ../GL/glprocs.h $(CC) $(CFLAGS) glprocs.c glprocs.c: ln -s ../GL/glprocs.c . clean: rm -f *.o demo glprocs.c rgl/src/ext/GLsdk/GL/0000755000176200001440000000000014100762641013734 5ustar liggesusersrgl/src/ext/GLsdk/GL/glprocs.h0000644000176200001440000054064314100762641015572 0ustar liggesusers#ifndef _GLPROCS_H_ #define _GLPROCS_H_ /* ** GLprocs utility for getting function addresses for OpenGL(R) 1.2, ** OpenGL 1.3, OpenGL 1.4, OpenGL 1.5 and OpenGL extension functions. ** ** Version: 1.1 ** ** License Applicability. Except to the extent portions of this file are ** made subject to an alternative license as permitted in the SGI Free ** Software License B, Version 1.1 (the "License"), the contents of this ** file are subject only to the provisions of the License. You may not use ** this file except in compliance with the License. You may obtain a copy ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: ** ** http://oss.sgi.com/projects/FreeB ** ** Note that, as provided in the License, the Software is distributed on an ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. ** ** Original Code. The Original Code is: OpenGL Sample Implementation, ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. ** Copyright in any portions created by third parties is as indicated ** elsewhere herein. All Rights Reserved. ** ** Additional Notice Provisions: This software was created using the ** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has ** not been independently verified as being compliant with the OpenGL(R) ** version 1.2.1 Specification. ** ** Initial version of glprocs.{c,h} contributed by Intel(R) Corporation. */ #ifdef _WIN32 #include "glext.h" #include "wglext.h" #else #include #endif #ifndef _WIN32 /* non-Windows environment */ #ifndef APIENTRY #define APIENTRY #endif #ifdef __GNUC__ #define _inline __inline__ #else #define _inline #endif #endif #ifdef __cplusplus extern "C" { #endif /* Structure of all OpenGL {1.2, 1.3, 1.4, 1.5}, GL extension procs.*/ typedef struct { void (APIENTRY *BlendColor) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); void (APIENTRY *BlendEquation) (GLenum mode); void (APIENTRY *DrawRangeElements) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); void (APIENTRY *ColorTable) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); void (APIENTRY *ColorTableParameterfv) (GLenum target, GLenum pname, const GLfloat *params); void (APIENTRY *ColorTableParameteriv) (GLenum target, GLenum pname, const GLint *params); void (APIENTRY *CopyColorTable) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); void (APIENTRY *GetColorTable) (GLenum target, GLenum format, GLenum type, GLvoid *table); void (APIENTRY *GetColorTableParameterfv) (GLenum target, GLenum pname, GLfloat *params); void (APIENTRY *GetColorTableParameteriv) (GLenum target, GLenum pname, GLint *params); void (APIENTRY *ColorSubTable) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); void (APIENTRY *CopyColorSubTable) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); void (APIENTRY *ConvolutionFilter1D) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); void (APIENTRY *ConvolutionFilter2D) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); void (APIENTRY *ConvolutionParameterf) (GLenum target, GLenum pname, GLfloat params); void (APIENTRY *ConvolutionParameterfv) (GLenum target, GLenum pname, const GLfloat *params); void (APIENTRY *ConvolutionParameteri) (GLenum target, GLenum pname, GLint params); void (APIENTRY *ConvolutionParameteriv) (GLenum target, GLenum pname, const GLint *params); void (APIENTRY *CopyConvolutionFilter1D) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); void (APIENTRY *CopyConvolutionFilter2D) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); void (APIENTRY *GetConvolutionFilter) (GLenum target, GLenum format, GLenum type, GLvoid *image); void (APIENTRY *GetConvolutionParameterfv) (GLenum target, GLenum pname, GLfloat *params); void (APIENTRY *GetConvolutionParameteriv) (GLenum target, GLenum pname, GLint *params); void (APIENTRY *GetSeparableFilter) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); void (APIENTRY *SeparableFilter2D) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); void (APIENTRY *GetHistogram) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); void (APIENTRY *GetHistogramParameterfv) (GLenum target, GLenum pname, GLfloat *params); void (APIENTRY *GetHistogramParameteriv) (GLenum target, GLenum pname, GLint *params); void (APIENTRY *GetMinmax) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); void (APIENTRY *GetMinmaxParameterfv) (GLenum target, GLenum pname, GLfloat *params); void (APIENTRY *GetMinmaxParameteriv) (GLenum target, GLenum pname, GLint *params); void (APIENTRY *Histogram) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); void (APIENTRY *Minmax) (GLenum target, GLenum internalformat, GLboolean sink); void (APIENTRY *ResetHistogram) (GLenum target); void (APIENTRY *ResetMinmax) (GLenum target); void (APIENTRY *TexImage3D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); void (APIENTRY *TexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); void (APIENTRY *CopyTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); void (APIENTRY *ActiveTexture) (GLenum texture); void (APIENTRY *ClientActiveTexture) (GLenum texture); void (APIENTRY *MultiTexCoord1d) (GLenum target, GLdouble s); void (APIENTRY *MultiTexCoord1dv) (GLenum target, const GLdouble *v); void (APIENTRY *MultiTexCoord1f) (GLenum target, GLfloat s); void (APIENTRY *MultiTexCoord1fv) (GLenum target, const GLfloat *v); void (APIENTRY *MultiTexCoord1i) (GLenum target, GLint s); void (APIENTRY *MultiTexCoord1iv) (GLenum target, const GLint *v); void (APIENTRY *MultiTexCoord1s) (GLenum target, GLshort s); void (APIENTRY *MultiTexCoord1sv) (GLenum target, const GLshort *v); void (APIENTRY *MultiTexCoord2d) (GLenum target, GLdouble s, GLdouble t); void (APIENTRY *MultiTexCoord2dv) (GLenum target, const GLdouble *v); void (APIENTRY *MultiTexCoord2f) (GLenum target, GLfloat s, GLfloat t); void (APIENTRY *MultiTexCoord2fv) (GLenum target, const GLfloat *v); void (APIENTRY *MultiTexCoord2i) (GLenum target, GLint s, GLint t); void (APIENTRY *MultiTexCoord2iv) (GLenum target, const GLint *v); void (APIENTRY *MultiTexCoord2s) (GLenum target, GLshort s, GLshort t); void (APIENTRY *MultiTexCoord2sv) (GLenum target, const GLshort *v); void (APIENTRY *MultiTexCoord3d) (GLenum target, GLdouble s, GLdouble t, GLdouble r); void (APIENTRY *MultiTexCoord3dv) (GLenum target, const GLdouble *v); void (APIENTRY *MultiTexCoord3f) (GLenum target, GLfloat s, GLfloat t, GLfloat r); void (APIENTRY *MultiTexCoord3fv) (GLenum target, const GLfloat *v); void (APIENTRY *MultiTexCoord3i) (GLenum target, GLint s, GLint t, GLint r); void (APIENTRY *MultiTexCoord3iv) (GLenum target, const GLint *v); void (APIENTRY *MultiTexCoord3s) (GLenum target, GLshort s, GLshort t, GLshort r); void (APIENTRY *MultiTexCoord3sv) (GLenum target, const GLshort *v); void (APIENTRY *MultiTexCoord4d) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); void (APIENTRY *MultiTexCoord4dv) (GLenum target, const GLdouble *v); void (APIENTRY *MultiTexCoord4f) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); void (APIENTRY *MultiTexCoord4fv) (GLenum target, const GLfloat *v); void (APIENTRY *MultiTexCoord4i) (GLenum target, GLint s, GLint t, GLint r, GLint q); void (APIENTRY *MultiTexCoord4iv) (GLenum target, const GLint *v); void (APIENTRY *MultiTexCoord4s) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); void (APIENTRY *MultiTexCoord4sv) (GLenum target, const GLshort *v); void (APIENTRY *LoadTransposeMatrixf) (const GLfloat *m); void (APIENTRY *LoadTransposeMatrixd) (const GLdouble *m); void (APIENTRY *MultTransposeMatrixf) (const GLfloat *m); void (APIENTRY *MultTransposeMatrixd) (const GLdouble *m); void (APIENTRY *SampleCoverage) (GLclampf value, GLboolean invert); void (APIENTRY *CompressedTexImage3D) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); void (APIENTRY *CompressedTexImage2D) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); void (APIENTRY *CompressedTexImage1D) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); void (APIENTRY *CompressedTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); void (APIENTRY *CompressedTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); void (APIENTRY *CompressedTexSubImage1D) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); void (APIENTRY *GetCompressedTexImage) (GLenum target, GLint level, GLvoid *img); void (APIENTRY *BlendFuncSeparate) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); void (APIENTRY *FogCoordf) (GLfloat coord); void (APIENTRY *FogCoordfv) (const GLfloat *coord); void (APIENTRY *FogCoordd) (GLdouble coord); void (APIENTRY *FogCoorddv) (const GLdouble *coord); void (APIENTRY *FogCoordPointer) (GLenum type, GLsizei stride, const GLvoid *pointer); void (APIENTRY *MultiDrawArrays) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); void (APIENTRY *MultiDrawElements) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); void (APIENTRY *PointParameterf) (GLenum pname, GLfloat param); void (APIENTRY *PointParameterfv) (GLenum pname, const GLfloat *params); void (APIENTRY *PointParameteri) (GLenum pname, GLint param); void (APIENTRY *PointParameteriv) (GLenum pname, const GLint *params); void (APIENTRY *SecondaryColor3b) (GLbyte red, GLbyte green, GLbyte blue); void (APIENTRY *SecondaryColor3bv) (const GLbyte *v); void (APIENTRY *SecondaryColor3d) (GLdouble red, GLdouble green, GLdouble blue); void (APIENTRY *SecondaryColor3dv) (const GLdouble *v); void (APIENTRY *SecondaryColor3f) (GLfloat red, GLfloat green, GLfloat blue); void (APIENTRY *SecondaryColor3fv) (const GLfloat *v); void (APIENTRY *SecondaryColor3i) (GLint red, GLint green, GLint blue); void (APIENTRY *SecondaryColor3iv) (const GLint *v); void (APIENTRY *SecondaryColor3s) (GLshort red, GLshort green, GLshort blue); void (APIENTRY *SecondaryColor3sv) (const GLshort *v); void (APIENTRY *SecondaryColor3ub) (GLubyte red, GLubyte green, GLubyte blue); void (APIENTRY *SecondaryColor3ubv) (const GLubyte *v); void (APIENTRY *SecondaryColor3ui) (GLuint red, GLuint green, GLuint blue); void (APIENTRY *SecondaryColor3uiv) (const GLuint *v); void (APIENTRY *SecondaryColor3us) (GLushort red, GLushort green, GLushort blue); void (APIENTRY *SecondaryColor3usv) (const GLushort *v); void (APIENTRY *SecondaryColorPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); void (APIENTRY *WindowPos2d) (GLdouble x, GLdouble y); void (APIENTRY *WindowPos2dv) (const GLdouble *v); void (APIENTRY *WindowPos2f) (GLfloat x, GLfloat y); void (APIENTRY *WindowPos2fv) (const GLfloat *v); void (APIENTRY *WindowPos2i) (GLint x, GLint y); void (APIENTRY *WindowPos2iv) (const GLint *v); void (APIENTRY *WindowPos2s) (GLshort x, GLshort y); void (APIENTRY *WindowPos2sv) (const GLshort *v); void (APIENTRY *WindowPos3d) (GLdouble x, GLdouble y, GLdouble z); void (APIENTRY *WindowPos3dv) (const GLdouble *v); void (APIENTRY *WindowPos3f) (GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *WindowPos3fv) (const GLfloat *v); void (APIENTRY *WindowPos3i) (GLint x, GLint y, GLint z); void (APIENTRY *WindowPos3iv) (const GLint *v); void (APIENTRY *WindowPos3s) (GLshort x, GLshort y, GLshort z); void (APIENTRY *WindowPos3sv) (const GLshort *v); void (APIENTRY *GenQueries) (GLsizei n, GLuint *ids); void (APIENTRY *DeleteQueries) (GLsizei n, const GLuint *ids); GLboolean (APIENTRY *IsQuery) (GLuint id); void (APIENTRY *BeginQuery) (GLenum target, GLuint id); void (APIENTRY *EndQuery) (GLenum target); void (APIENTRY *GetQueryiv) (GLenum target, GLenum pname, GLint *params); void (APIENTRY *GetQueryObjectiv) (GLuint id, GLenum pname, GLint *params); void (APIENTRY *GetQueryObjectuiv) (GLuint id, GLenum pname, GLuint *params); void (APIENTRY *BindBuffer) (GLenum target, GLuint buffer); void (APIENTRY *DeleteBuffers) (GLsizei n, const GLuint *buffers); void (APIENTRY *GenBuffers) (GLsizei n, GLuint *buffers); GLboolean (APIENTRY *IsBuffer) (GLuint buffer); void (APIENTRY *BufferData) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); void (APIENTRY *BufferSubData) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); void (APIENTRY *GetBufferSubData) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); GLvoid* (APIENTRY *MapBuffer) (GLenum target, GLenum access); GLboolean (APIENTRY *UnmapBuffer) (GLenum target); void (APIENTRY *GetBufferParameteriv) (GLenum target, GLenum pname, GLint *params); void (APIENTRY *GetBufferPointerv) (GLenum target, GLenum pname, GLvoid* *params); void (APIENTRY *ActiveTextureARB) (GLenum texture); void (APIENTRY *ClientActiveTextureARB) (GLenum texture); void (APIENTRY *MultiTexCoord1dARB) (GLenum target, GLdouble s); void (APIENTRY *MultiTexCoord1dvARB) (GLenum target, const GLdouble *v); void (APIENTRY *MultiTexCoord1fARB) (GLenum target, GLfloat s); void (APIENTRY *MultiTexCoord1fvARB) (GLenum target, const GLfloat *v); void (APIENTRY *MultiTexCoord1iARB) (GLenum target, GLint s); void (APIENTRY *MultiTexCoord1ivARB) (GLenum target, const GLint *v); void (APIENTRY *MultiTexCoord1sARB) (GLenum target, GLshort s); void (APIENTRY *MultiTexCoord1svARB) (GLenum target, const GLshort *v); void (APIENTRY *MultiTexCoord2dARB) (GLenum target, GLdouble s, GLdouble t); void (APIENTRY *MultiTexCoord2dvARB) (GLenum target, const GLdouble *v); void (APIENTRY *MultiTexCoord2fARB) (GLenum target, GLfloat s, GLfloat t); void (APIENTRY *MultiTexCoord2fvARB) (GLenum target, const GLfloat *v); void (APIENTRY *MultiTexCoord2iARB) (GLenum target, GLint s, GLint t); void (APIENTRY *MultiTexCoord2ivARB) (GLenum target, const GLint *v); void (APIENTRY *MultiTexCoord2sARB) (GLenum target, GLshort s, GLshort t); void (APIENTRY *MultiTexCoord2svARB) (GLenum target, const GLshort *v); void (APIENTRY *MultiTexCoord3dARB) (GLenum target, GLdouble s, GLdouble t, GLdouble r); void (APIENTRY *MultiTexCoord3dvARB) (GLenum target, const GLdouble *v); void (APIENTRY *MultiTexCoord3fARB) (GLenum target, GLfloat s, GLfloat t, GLfloat r); void (APIENTRY *MultiTexCoord3fvARB) (GLenum target, const GLfloat *v); void (APIENTRY *MultiTexCoord3iARB) (GLenum target, GLint s, GLint t, GLint r); void (APIENTRY *MultiTexCoord3ivARB) (GLenum target, const GLint *v); void (APIENTRY *MultiTexCoord3sARB) (GLenum target, GLshort s, GLshort t, GLshort r); void (APIENTRY *MultiTexCoord3svARB) (GLenum target, const GLshort *v); void (APIENTRY *MultiTexCoord4dARB) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); void (APIENTRY *MultiTexCoord4dvARB) (GLenum target, const GLdouble *v); void (APIENTRY *MultiTexCoord4fARB) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); void (APIENTRY *MultiTexCoord4fvARB) (GLenum target, const GLfloat *v); void (APIENTRY *MultiTexCoord4iARB) (GLenum target, GLint s, GLint t, GLint r, GLint q); void (APIENTRY *MultiTexCoord4ivARB) (GLenum target, const GLint *v); void (APIENTRY *MultiTexCoord4sARB) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); void (APIENTRY *MultiTexCoord4svARB) (GLenum target, const GLshort *v); void (APIENTRY *LoadTransposeMatrixfARB) (const GLfloat *m); void (APIENTRY *LoadTransposeMatrixdARB) (const GLdouble *m); void (APIENTRY *MultTransposeMatrixfARB) (const GLfloat *m); void (APIENTRY *MultTransposeMatrixdARB) (const GLdouble *m); void (APIENTRY *SampleCoverageARB) (GLclampf value, GLboolean invert); void (APIENTRY *CompressedTexImage3DARB) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); void (APIENTRY *CompressedTexImage2DARB) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); void (APIENTRY *CompressedTexImage1DARB) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); void (APIENTRY *CompressedTexSubImage3DARB) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); void (APIENTRY *CompressedTexSubImage2DARB) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); void (APIENTRY *CompressedTexSubImage1DARB) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); void (APIENTRY *GetCompressedTexImageARB) (GLenum target, GLint level, GLvoid *img); void (APIENTRY *PointParameterfARB) (GLenum pname, GLfloat param); void (APIENTRY *PointParameterfvARB) (GLenum pname, const GLfloat *params); void (APIENTRY *WeightbvARB) (GLint size, const GLbyte *weights); void (APIENTRY *WeightsvARB) (GLint size, const GLshort *weights); void (APIENTRY *WeightivARB) (GLint size, const GLint *weights); void (APIENTRY *WeightfvARB) (GLint size, const GLfloat *weights); void (APIENTRY *WeightdvARB) (GLint size, const GLdouble *weights); void (APIENTRY *WeightubvARB) (GLint size, const GLubyte *weights); void (APIENTRY *WeightusvARB) (GLint size, const GLushort *weights); void (APIENTRY *WeightuivARB) (GLint size, const GLuint *weights); void (APIENTRY *WeightPointerARB) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); void (APIENTRY *VertexBlendARB) (GLint count); void (APIENTRY *CurrentPaletteMatrixARB) (GLint index); void (APIENTRY *MatrixIndexubvARB) (GLint size, const GLubyte *indices); void (APIENTRY *MatrixIndexusvARB) (GLint size, const GLushort *indices); void (APIENTRY *MatrixIndexuivARB) (GLint size, const GLuint *indices); void (APIENTRY *MatrixIndexPointerARB) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); void (APIENTRY *WindowPos2dARB) (GLdouble x, GLdouble y); void (APIENTRY *WindowPos2dvARB) (const GLdouble *v); void (APIENTRY *WindowPos2fARB) (GLfloat x, GLfloat y); void (APIENTRY *WindowPos2fvARB) (const GLfloat *v); void (APIENTRY *WindowPos2iARB) (GLint x, GLint y); void (APIENTRY *WindowPos2ivARB) (const GLint *v); void (APIENTRY *WindowPos2sARB) (GLshort x, GLshort y); void (APIENTRY *WindowPos2svARB) (const GLshort *v); void (APIENTRY *WindowPos3dARB) (GLdouble x, GLdouble y, GLdouble z); void (APIENTRY *WindowPos3dvARB) (const GLdouble *v); void (APIENTRY *WindowPos3fARB) (GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *WindowPos3fvARB) (const GLfloat *v); void (APIENTRY *WindowPos3iARB) (GLint x, GLint y, GLint z); void (APIENTRY *WindowPos3ivARB) (const GLint *v); void (APIENTRY *WindowPos3sARB) (GLshort x, GLshort y, GLshort z); void (APIENTRY *WindowPos3svARB) (const GLshort *v); void (APIENTRY *VertexAttrib1dARB) (GLuint index, GLdouble x); void (APIENTRY *VertexAttrib1dvARB) (GLuint index, const GLdouble *v); void (APIENTRY *VertexAttrib1fARB) (GLuint index, GLfloat x); void (APIENTRY *VertexAttrib1fvARB) (GLuint index, const GLfloat *v); void (APIENTRY *VertexAttrib1sARB) (GLuint index, GLshort x); void (APIENTRY *VertexAttrib1svARB) (GLuint index, const GLshort *v); void (APIENTRY *VertexAttrib2dARB) (GLuint index, GLdouble x, GLdouble y); void (APIENTRY *VertexAttrib2dvARB) (GLuint index, const GLdouble *v); void (APIENTRY *VertexAttrib2fARB) (GLuint index, GLfloat x, GLfloat y); void (APIENTRY *VertexAttrib2fvARB) (GLuint index, const GLfloat *v); void (APIENTRY *VertexAttrib2sARB) (GLuint index, GLshort x, GLshort y); void (APIENTRY *VertexAttrib2svARB) (GLuint index, const GLshort *v); void (APIENTRY *VertexAttrib3dARB) (GLuint index, GLdouble x, GLdouble y, GLdouble z); void (APIENTRY *VertexAttrib3dvARB) (GLuint index, const GLdouble *v); void (APIENTRY *VertexAttrib3fARB) (GLuint index, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *VertexAttrib3fvARB) (GLuint index, const GLfloat *v); void (APIENTRY *VertexAttrib3sARB) (GLuint index, GLshort x, GLshort y, GLshort z); void (APIENTRY *VertexAttrib3svARB) (GLuint index, const GLshort *v); void (APIENTRY *VertexAttrib4NbvARB) (GLuint index, const GLbyte *v); void (APIENTRY *VertexAttrib4NivARB) (GLuint index, const GLint *v); void (APIENTRY *VertexAttrib4NsvARB) (GLuint index, const GLshort *v); void (APIENTRY *VertexAttrib4NubARB) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); void (APIENTRY *VertexAttrib4NubvARB) (GLuint index, const GLubyte *v); void (APIENTRY *VertexAttrib4NuivARB) (GLuint index, const GLuint *v); void (APIENTRY *VertexAttrib4NusvARB) (GLuint index, const GLushort *v); void (APIENTRY *VertexAttrib4bvARB) (GLuint index, const GLbyte *v); void (APIENTRY *VertexAttrib4dARB) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); void (APIENTRY *VertexAttrib4dvARB) (GLuint index, const GLdouble *v); void (APIENTRY *VertexAttrib4fARB) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); void (APIENTRY *VertexAttrib4fvARB) (GLuint index, const GLfloat *v); void (APIENTRY *VertexAttrib4ivARB) (GLuint index, const GLint *v); void (APIENTRY *VertexAttrib4sARB) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); void (APIENTRY *VertexAttrib4svARB) (GLuint index, const GLshort *v); void (APIENTRY *VertexAttrib4ubvARB) (GLuint index, const GLubyte *v); void (APIENTRY *VertexAttrib4uivARB) (GLuint index, const GLuint *v); void (APIENTRY *VertexAttrib4usvARB) (GLuint index, const GLushort *v); void (APIENTRY *VertexAttribPointerARB) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); void (APIENTRY *EnableVertexAttribArrayARB) (GLuint index); void (APIENTRY *DisableVertexAttribArrayARB) (GLuint index); void (APIENTRY *ProgramStringARB) (GLenum target, GLenum format, GLsizei len, const GLvoid *string); void (APIENTRY *BindProgramARB) (GLenum target, GLuint program); void (APIENTRY *DeleteProgramsARB) (GLsizei n, const GLuint *programs); void (APIENTRY *GenProgramsARB) (GLsizei n, GLuint *programs); void (APIENTRY *ProgramEnvParameter4dARB) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); void (APIENTRY *ProgramEnvParameter4dvARB) (GLenum target, GLuint index, const GLdouble *params); void (APIENTRY *ProgramEnvParameter4fARB) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); void (APIENTRY *ProgramEnvParameter4fvARB) (GLenum target, GLuint index, const GLfloat *params); void (APIENTRY *ProgramLocalParameter4dARB) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); void (APIENTRY *ProgramLocalParameter4dvARB) (GLenum target, GLuint index, const GLdouble *params); void (APIENTRY *ProgramLocalParameter4fARB) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); void (APIENTRY *ProgramLocalParameter4fvARB) (GLenum target, GLuint index, const GLfloat *params); void (APIENTRY *GetProgramEnvParameterdvARB) (GLenum target, GLuint index, GLdouble *params); void (APIENTRY *GetProgramEnvParameterfvARB) (GLenum target, GLuint index, GLfloat *params); void (APIENTRY *GetProgramLocalParameterdvARB) (GLenum target, GLuint index, GLdouble *params); void (APIENTRY *GetProgramLocalParameterfvARB) (GLenum target, GLuint index, GLfloat *params); void (APIENTRY *GetProgramivARB) (GLenum target, GLenum pname, GLint *params); void (APIENTRY *GetProgramStringARB) (GLenum target, GLenum pname, GLvoid *string); void (APIENTRY *GetVertexAttribdvARB) (GLuint index, GLenum pname, GLdouble *params); void (APIENTRY *GetVertexAttribfvARB) (GLuint index, GLenum pname, GLfloat *params); void (APIENTRY *GetVertexAttribivARB) (GLuint index, GLenum pname, GLint *params); void (APIENTRY *GetVertexAttribPointervARB) (GLuint index, GLenum pname, GLvoid* *pointer); GLboolean (APIENTRY *IsProgramARB) (GLuint program); void (APIENTRY *BindBufferARB) (GLenum target, GLuint buffer); void (APIENTRY *DeleteBuffersARB) (GLsizei n, const GLuint *buffers); void (APIENTRY *GenBuffersARB) (GLsizei n, GLuint *buffers); GLboolean (APIENTRY *IsBufferARB) (GLuint buffer); void (APIENTRY *BufferDataARB) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); void (APIENTRY *BufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); void (APIENTRY *GetBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); GLvoid* (APIENTRY *MapBufferARB) (GLenum target, GLenum access); GLboolean (APIENTRY *UnmapBufferARB) (GLenum target); void (APIENTRY *GetBufferParameterivARB) (GLenum target, GLenum pname, GLint *params); void (APIENTRY *GetBufferPointervARB) (GLenum target, GLenum pname, GLvoid* *params); void (APIENTRY *GenQueriesARB) (GLsizei n, GLuint *ids); void (APIENTRY *DeleteQueriesARB) (GLsizei n, const GLuint *ids); GLboolean (APIENTRY *IsQueryARB) (GLuint id); void (APIENTRY *BeginQueryARB) (GLenum target, GLuint id); void (APIENTRY *EndQueryARB) (GLenum target); void (APIENTRY *GetQueryivARB) (GLenum target, GLenum pname, GLint *params); void (APIENTRY *GetQueryObjectivARB) (GLuint id, GLenum pname, GLint *params); void (APIENTRY *GetQueryObjectuivARB) (GLuint id, GLenum pname, GLuint *params); void (APIENTRY *DeleteObjectARB) (GLhandleARB obj); GLhandleARB (APIENTRY *GetHandleARB) (GLenum pname); void (APIENTRY *DetachObjectARB) (GLhandleARB containerObj, GLhandleARB attachedObj); GLhandleARB (APIENTRY *CreateShaderObjectARB) (GLenum shaderType); void (APIENTRY *ShaderSourceARB) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length); void (APIENTRY *CompileShaderARB) (GLhandleARB shaderObj); GLhandleARB (APIENTRY *CreateProgramObjectARB) (void); void (APIENTRY *AttachObjectARB) (GLhandleARB containerObj, GLhandleARB obj); void (APIENTRY *LinkProgramARB) (GLhandleARB programObj); void (APIENTRY *UseProgramObjectARB) (GLhandleARB programObj); void (APIENTRY *ValidateProgramARB) (GLhandleARB programObj); void (APIENTRY *Uniform1fARB) (GLint location, GLfloat v0); void (APIENTRY *Uniform2fARB) (GLint location, GLfloat v0, GLfloat v1); void (APIENTRY *Uniform3fARB) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); void (APIENTRY *Uniform4fARB) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); void (APIENTRY *Uniform1iARB) (GLint location, GLint v0); void (APIENTRY *Uniform2iARB) (GLint location, GLint v0, GLint v1); void (APIENTRY *Uniform3iARB) (GLint location, GLint v0, GLint v1, GLint v2); void (APIENTRY *Uniform4iARB) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); void (APIENTRY *Uniform1fvARB) (GLint location, GLsizei count, const GLfloat *value); void (APIENTRY *Uniform2fvARB) (GLint location, GLsizei count, const GLfloat *value); void (APIENTRY *Uniform3fvARB) (GLint location, GLsizei count, const GLfloat *value); void (APIENTRY *Uniform4fvARB) (GLint location, GLsizei count, const GLfloat *value); void (APIENTRY *Uniform1ivARB) (GLint location, GLsizei count, const GLint *value); void (APIENTRY *Uniform2ivARB) (GLint location, GLsizei count, const GLint *value); void (APIENTRY *Uniform3ivARB) (GLint location, GLsizei count, const GLint *value); void (APIENTRY *Uniform4ivARB) (GLint location, GLsizei count, const GLint *value); void (APIENTRY *UniformMatrix2fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); void (APIENTRY *UniformMatrix3fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); void (APIENTRY *UniformMatrix4fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); void (APIENTRY *GetObjectParameterfvARB) (GLhandleARB obj, GLenum pname, GLfloat *params); void (APIENTRY *GetObjectParameterivARB) (GLhandleARB obj, GLenum pname, GLint *params); void (APIENTRY *GetInfoLogARB) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); void (APIENTRY *GetAttachedObjectsARB) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); GLint (APIENTRY *GetUniformLocationARB) (GLhandleARB programObj, const GLcharARB *name); void (APIENTRY *GetActiveUniformARB) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); void (APIENTRY *GetUniformfvARB) (GLhandleARB programObj, GLint location, GLfloat *params); void (APIENTRY *GetUniformivARB) (GLhandleARB programObj, GLint location, GLint *params); void (APIENTRY *GetShaderSourceARB) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); void (APIENTRY *BindAttribLocationARB) (GLhandleARB programObj, GLuint index, const GLcharARB *name); void (APIENTRY *GetActiveAttribARB) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); GLint (APIENTRY *GetAttribLocationARB) (GLhandleARB programObj, const GLcharARB *name); void (APIENTRY *BlendColorEXT) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); void (APIENTRY *PolygonOffsetEXT) (GLfloat factor, GLfloat bias); void (APIENTRY *TexImage3DEXT) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); void (APIENTRY *TexSubImage3DEXT) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); void (APIENTRY *GetTexFilterFuncSGIS) (GLenum target, GLenum filter, GLfloat *weights); void (APIENTRY *TexFilterFuncSGIS) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); void (APIENTRY *TexSubImage1DEXT) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); void (APIENTRY *TexSubImage2DEXT) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); void (APIENTRY *CopyTexImage1DEXT) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); void (APIENTRY *CopyTexImage2DEXT) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); void (APIENTRY *CopyTexSubImage1DEXT) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); void (APIENTRY *CopyTexSubImage2DEXT) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); void (APIENTRY *CopyTexSubImage3DEXT) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); void (APIENTRY *GetHistogramEXT) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); void (APIENTRY *GetHistogramParameterfvEXT) (GLenum target, GLenum pname, GLfloat *params); void (APIENTRY *GetHistogramParameterivEXT) (GLenum target, GLenum pname, GLint *params); void (APIENTRY *GetMinmaxEXT) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); void (APIENTRY *GetMinmaxParameterfvEXT) (GLenum target, GLenum pname, GLfloat *params); void (APIENTRY *GetMinmaxParameterivEXT) (GLenum target, GLenum pname, GLint *params); void (APIENTRY *HistogramEXT) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); void (APIENTRY *MinmaxEXT) (GLenum target, GLenum internalformat, GLboolean sink); void (APIENTRY *ResetHistogramEXT) (GLenum target); void (APIENTRY *ResetMinmaxEXT) (GLenum target); void (APIENTRY *ConvolutionFilter1DEXT) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); void (APIENTRY *ConvolutionFilter2DEXT) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); void (APIENTRY *ConvolutionParameterfEXT) (GLenum target, GLenum pname, GLfloat params); void (APIENTRY *ConvolutionParameterfvEXT) (GLenum target, GLenum pname, const GLfloat *params); void (APIENTRY *ConvolutionParameteriEXT) (GLenum target, GLenum pname, GLint params); void (APIENTRY *ConvolutionParameterivEXT) (GLenum target, GLenum pname, const GLint *params); void (APIENTRY *CopyConvolutionFilter1DEXT) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); void (APIENTRY *CopyConvolutionFilter2DEXT) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); void (APIENTRY *GetConvolutionFilterEXT) (GLenum target, GLenum format, GLenum type, GLvoid *image); void (APIENTRY *GetConvolutionParameterfvEXT) (GLenum target, GLenum pname, GLfloat *params); void (APIENTRY *GetConvolutionParameterivEXT) (GLenum target, GLenum pname, GLint *params); void (APIENTRY *GetSeparableFilterEXT) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); void (APIENTRY *SeparableFilter2DEXT) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); void (APIENTRY *ColorTableSGI) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); void (APIENTRY *ColorTableParameterfvSGI) (GLenum target, GLenum pname, const GLfloat *params); void (APIENTRY *ColorTableParameterivSGI) (GLenum target, GLenum pname, const GLint *params); void (APIENTRY *CopyColorTableSGI) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); void (APIENTRY *GetColorTableSGI) (GLenum target, GLenum format, GLenum type, GLvoid *table); void (APIENTRY *GetColorTableParameterfvSGI) (GLenum target, GLenum pname, GLfloat *params); void (APIENTRY *GetColorTableParameterivSGI) (GLenum target, GLenum pname, GLint *params); void (APIENTRY *PixelTexGenSGIX) (GLenum mode); void (APIENTRY *PixelTexGenParameteriSGIS) (GLenum pname, GLint param); void (APIENTRY *PixelTexGenParameterivSGIS) (GLenum pname, const GLint *params); void (APIENTRY *PixelTexGenParameterfSGIS) (GLenum pname, GLfloat param); void (APIENTRY *PixelTexGenParameterfvSGIS) (GLenum pname, const GLfloat *params); void (APIENTRY *GetPixelTexGenParameterivSGIS) (GLenum pname, GLint *params); void (APIENTRY *GetPixelTexGenParameterfvSGIS) (GLenum pname, GLfloat *params); void (APIENTRY *TexImage4DSGIS) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels); void (APIENTRY *TexSubImage4DSGIS) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels); GLboolean (APIENTRY *AreTexturesResidentEXT) (GLsizei n, const GLuint *textures, GLboolean *residences); void (APIENTRY *BindTextureEXT) (GLenum target, GLuint texture); void (APIENTRY *DeleteTexturesEXT) (GLsizei n, const GLuint *textures); void (APIENTRY *GenTexturesEXT) (GLsizei n, GLuint *textures); GLboolean (APIENTRY *IsTextureEXT) (GLuint texture); void (APIENTRY *PrioritizeTexturesEXT) (GLsizei n, const GLuint *textures, const GLclampf *priorities); void (APIENTRY *DetailTexFuncSGIS) (GLenum target, GLsizei n, const GLfloat *points); void (APIENTRY *GetDetailTexFuncSGIS) (GLenum target, GLfloat *points); void (APIENTRY *SharpenTexFuncSGIS) (GLenum target, GLsizei n, const GLfloat *points); void (APIENTRY *GetSharpenTexFuncSGIS) (GLenum target, GLfloat *points); void (APIENTRY *SampleMaskSGIS) (GLclampf value, GLboolean invert); void (APIENTRY *SamplePatternSGIS) (GLenum pattern); void (APIENTRY *ArrayElementEXT) (GLint i); void (APIENTRY *ColorPointerEXT) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); void (APIENTRY *DrawArraysEXT) (GLenum mode, GLint first, GLsizei count); void (APIENTRY *EdgeFlagPointerEXT) (GLsizei stride, GLsizei count, const GLboolean *pointer); void (APIENTRY *GetPointervEXT) (GLenum pname, GLvoid* *params); void (APIENTRY *IndexPointerEXT) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); void (APIENTRY *NormalPointerEXT) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); void (APIENTRY *TexCoordPointerEXT) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); void (APIENTRY *VertexPointerEXT) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); void (APIENTRY *BlendEquationEXT) (GLenum mode); void (APIENTRY *SpriteParameterfSGIX) (GLenum pname, GLfloat param); void (APIENTRY *SpriteParameterfvSGIX) (GLenum pname, const GLfloat *params); void (APIENTRY *SpriteParameteriSGIX) (GLenum pname, GLint param); void (APIENTRY *SpriteParameterivSGIX) (GLenum pname, const GLint *params); void (APIENTRY *PointParameterfEXT) (GLenum pname, GLfloat param); void (APIENTRY *PointParameterfvEXT) (GLenum pname, const GLfloat *params); void (APIENTRY *PointParameterfSGIS) (GLenum pname, GLfloat param); void (APIENTRY *PointParameterfvSGIS) (GLenum pname, const GLfloat *params); GLint (APIENTRY *GetInstrumentsSGIX) (void); void (APIENTRY *InstrumentsBufferSGIX) (GLsizei size, GLint *buffer); GLint (APIENTRY *PollInstrumentsSGIX) (GLint *marker_p); void (APIENTRY *ReadInstrumentsSGIX) (GLint marker); void (APIENTRY *StartInstrumentsSGIX) (void); void (APIENTRY *StopInstrumentsSGIX) (GLint marker); void (APIENTRY *FrameZoomSGIX) (GLint factor); void (APIENTRY *TagSampleBufferSGIX) (void); void (APIENTRY *DeformationMap3dSGIX) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); void (APIENTRY *DeformationMap3fSGIX) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); void (APIENTRY *DeformSGIX) (GLbitfield mask); void (APIENTRY *LoadIdentityDeformationMapSGIX) (GLbitfield mask); void (APIENTRY *ReferencePlaneSGIX) (const GLdouble *equation); void (APIENTRY *FlushRasterSGIX) (void); void (APIENTRY *FogFuncSGIS) (GLsizei n, const GLfloat *points); void (APIENTRY *GetFogFuncSGIS) (GLfloat *points); void (APIENTRY *ImageTransformParameteriHP) (GLenum target, GLenum pname, GLint param); void (APIENTRY *ImageTransformParameterfHP) (GLenum target, GLenum pname, GLfloat param); void (APIENTRY *ImageTransformParameterivHP) (GLenum target, GLenum pname, const GLint *params); void (APIENTRY *ImageTransformParameterfvHP) (GLenum target, GLenum pname, const GLfloat *params); void (APIENTRY *GetImageTransformParameterivHP) (GLenum target, GLenum pname, GLint *params); void (APIENTRY *GetImageTransformParameterfvHP) (GLenum target, GLenum pname, GLfloat *params); void (APIENTRY *ColorSubTableEXT) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); void (APIENTRY *CopyColorSubTableEXT) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); void (APIENTRY *HintPGI) (GLenum target, GLint mode); void (APIENTRY *ColorTableEXT) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); void (APIENTRY *GetColorTableEXT) (GLenum target, GLenum format, GLenum type, GLvoid *data); void (APIENTRY *GetColorTableParameterivEXT) (GLenum target, GLenum pname, GLint *params); void (APIENTRY *GetColorTableParameterfvEXT) (GLenum target, GLenum pname, GLfloat *params); void (APIENTRY *GetListParameterfvSGIX) (GLuint list, GLenum pname, GLfloat *params); void (APIENTRY *GetListParameterivSGIX) (GLuint list, GLenum pname, GLint *params); void (APIENTRY *ListParameterfSGIX) (GLuint list, GLenum pname, GLfloat param); void (APIENTRY *ListParameterfvSGIX) (GLuint list, GLenum pname, const GLfloat *params); void (APIENTRY *ListParameteriSGIX) (GLuint list, GLenum pname, GLint param); void (APIENTRY *ListParameterivSGIX) (GLuint list, GLenum pname, const GLint *params); void (APIENTRY *IndexMaterialEXT) (GLenum face, GLenum mode); void (APIENTRY *IndexFuncEXT) (GLenum func, GLclampf ref); void (APIENTRY *LockArraysEXT) (GLint first, GLsizei count); void (APIENTRY *UnlockArraysEXT) (void); void (APIENTRY *CullParameterdvEXT) (GLenum pname, GLdouble *params); void (APIENTRY *CullParameterfvEXT) (GLenum pname, GLfloat *params); void (APIENTRY *FragmentColorMaterialSGIX) (GLenum face, GLenum mode); void (APIENTRY *FragmentLightfSGIX) (GLenum light, GLenum pname, GLfloat param); void (APIENTRY *FragmentLightfvSGIX) (GLenum light, GLenum pname, const GLfloat *params); void (APIENTRY *FragmentLightiSGIX) (GLenum light, GLenum pname, GLint param); void (APIENTRY *FragmentLightivSGIX) (GLenum light, GLenum pname, const GLint *params); void (APIENTRY *FragmentLightModelfSGIX) (GLenum pname, GLfloat param); void (APIENTRY *FragmentLightModelfvSGIX) (GLenum pname, const GLfloat *params); void (APIENTRY *FragmentLightModeliSGIX) (GLenum pname, GLint param); void (APIENTRY *FragmentLightModelivSGIX) (GLenum pname, const GLint *params); void (APIENTRY *FragmentMaterialfSGIX) (GLenum face, GLenum pname, GLfloat param); void (APIENTRY *FragmentMaterialfvSGIX) (GLenum face, GLenum pname, const GLfloat *params); void (APIENTRY *FragmentMaterialiSGIX) (GLenum face, GLenum pname, GLint param); void (APIENTRY *FragmentMaterialivSGIX) (GLenum face, GLenum pname, const GLint *params); void (APIENTRY *GetFragmentLightfvSGIX) (GLenum light, GLenum pname, GLfloat *params); void (APIENTRY *GetFragmentLightivSGIX) (GLenum light, GLenum pname, GLint *params); void (APIENTRY *GetFragmentMaterialfvSGIX) (GLenum face, GLenum pname, GLfloat *params); void (APIENTRY *GetFragmentMaterialivSGIX) (GLenum face, GLenum pname, GLint *params); void (APIENTRY *LightEnviSGIX) (GLenum pname, GLint param); void (APIENTRY *DrawRangeElementsEXT) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); void (APIENTRY *ApplyTextureEXT) (GLenum mode); void (APIENTRY *TextureLightEXT) (GLenum pname); void (APIENTRY *TextureMaterialEXT) (GLenum face, GLenum mode); void (APIENTRY *AsyncMarkerSGIX) (GLuint marker); GLint (APIENTRY *FinishAsyncSGIX) (GLuint *markerp); GLint (APIENTRY *PollAsyncSGIX) (GLuint *markerp); GLuint (APIENTRY *GenAsyncMarkersSGIX) (GLsizei range); void (APIENTRY *DeleteAsyncMarkersSGIX) (GLuint marker, GLsizei range); GLboolean (APIENTRY *IsAsyncMarkerSGIX) (GLuint marker); void (APIENTRY *VertexPointervINTEL) (GLint size, GLenum type, const GLvoid* *pointer); void (APIENTRY *NormalPointervINTEL) (GLenum type, const GLvoid* *pointer); void (APIENTRY *ColorPointervINTEL) (GLint size, GLenum type, const GLvoid* *pointer); void (APIENTRY *TexCoordPointervINTEL) (GLint size, GLenum type, const GLvoid* *pointer); void (APIENTRY *PixelTransformParameteriEXT) (GLenum target, GLenum pname, GLint param); void (APIENTRY *PixelTransformParameterfEXT) (GLenum target, GLenum pname, GLfloat param); void (APIENTRY *PixelTransformParameterivEXT) (GLenum target, GLenum pname, const GLint *params); void (APIENTRY *PixelTransformParameterfvEXT) (GLenum target, GLenum pname, const GLfloat *params); void (APIENTRY *SecondaryColor3bEXT) (GLbyte red, GLbyte green, GLbyte blue); void (APIENTRY *SecondaryColor3bvEXT) (const GLbyte *v); void (APIENTRY *SecondaryColor3dEXT) (GLdouble red, GLdouble green, GLdouble blue); void (APIENTRY *SecondaryColor3dvEXT) (const GLdouble *v); void (APIENTRY *SecondaryColor3fEXT) (GLfloat red, GLfloat green, GLfloat blue); void (APIENTRY *SecondaryColor3fvEXT) (const GLfloat *v); void (APIENTRY *SecondaryColor3iEXT) (GLint red, GLint green, GLint blue); void (APIENTRY *SecondaryColor3ivEXT) (const GLint *v); void (APIENTRY *SecondaryColor3sEXT) (GLshort red, GLshort green, GLshort blue); void (APIENTRY *SecondaryColor3svEXT) (const GLshort *v); void (APIENTRY *SecondaryColor3ubEXT) (GLubyte red, GLubyte green, GLubyte blue); void (APIENTRY *SecondaryColor3ubvEXT) (const GLubyte *v); void (APIENTRY *SecondaryColor3uiEXT) (GLuint red, GLuint green, GLuint blue); void (APIENTRY *SecondaryColor3uivEXT) (const GLuint *v); void (APIENTRY *SecondaryColor3usEXT) (GLushort red, GLushort green, GLushort blue); void (APIENTRY *SecondaryColor3usvEXT) (const GLushort *v); void (APIENTRY *SecondaryColorPointerEXT) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); void (APIENTRY *TextureNormalEXT) (GLenum mode); void (APIENTRY *MultiDrawArraysEXT) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); void (APIENTRY *MultiDrawElementsEXT) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); void (APIENTRY *FogCoordfEXT) (GLfloat coord); void (APIENTRY *FogCoordfvEXT) (const GLfloat *coord); void (APIENTRY *FogCoorddEXT) (GLdouble coord); void (APIENTRY *FogCoorddvEXT) (const GLdouble *coord); void (APIENTRY *FogCoordPointerEXT) (GLenum type, GLsizei stride, const GLvoid *pointer); void (APIENTRY *Tangent3bEXT) (GLbyte tx, GLbyte ty, GLbyte tz); void (APIENTRY *Tangent3bvEXT) (const GLbyte *v); void (APIENTRY *Tangent3dEXT) (GLdouble tx, GLdouble ty, GLdouble tz); void (APIENTRY *Tangent3dvEXT) (const GLdouble *v); void (APIENTRY *Tangent3fEXT) (GLfloat tx, GLfloat ty, GLfloat tz); void (APIENTRY *Tangent3fvEXT) (const GLfloat *v); void (APIENTRY *Tangent3iEXT) (GLint tx, GLint ty, GLint tz); void (APIENTRY *Tangent3ivEXT) (const GLint *v); void (APIENTRY *Tangent3sEXT) (GLshort tx, GLshort ty, GLshort tz); void (APIENTRY *Tangent3svEXT) (const GLshort *v); void (APIENTRY *Binormal3bEXT) (GLbyte bx, GLbyte by, GLbyte bz); void (APIENTRY *Binormal3bvEXT) (const GLbyte *v); void (APIENTRY *Binormal3dEXT) (GLdouble bx, GLdouble by, GLdouble bz); void (APIENTRY *Binormal3dvEXT) (const GLdouble *v); void (APIENTRY *Binormal3fEXT) (GLfloat bx, GLfloat by, GLfloat bz); void (APIENTRY *Binormal3fvEXT) (const GLfloat *v); void (APIENTRY *Binormal3iEXT) (GLint bx, GLint by, GLint bz); void (APIENTRY *Binormal3ivEXT) (const GLint *v); void (APIENTRY *Binormal3sEXT) (GLshort bx, GLshort by, GLshort bz); void (APIENTRY *Binormal3svEXT) (const GLshort *v); void (APIENTRY *TangentPointerEXT) (GLenum type, GLsizei stride, const GLvoid *pointer); void (APIENTRY *BinormalPointerEXT) (GLenum type, GLsizei stride, const GLvoid *pointer); void (APIENTRY *FinishTextureSUNX) (void); void (APIENTRY *GlobalAlphaFactorbSUN) (GLbyte factor); void (APIENTRY *GlobalAlphaFactorsSUN) (GLshort factor); void (APIENTRY *GlobalAlphaFactoriSUN) (GLint factor); void (APIENTRY *GlobalAlphaFactorfSUN) (GLfloat factor); void (APIENTRY *GlobalAlphaFactordSUN) (GLdouble factor); void (APIENTRY *GlobalAlphaFactorubSUN) (GLubyte factor); void (APIENTRY *GlobalAlphaFactorusSUN) (GLushort factor); void (APIENTRY *GlobalAlphaFactoruiSUN) (GLuint factor); void (APIENTRY *ReplacementCodeuiSUN) (GLuint code); void (APIENTRY *ReplacementCodeusSUN) (GLushort code); void (APIENTRY *ReplacementCodeubSUN) (GLubyte code); void (APIENTRY *ReplacementCodeuivSUN) (const GLuint *code); void (APIENTRY *ReplacementCodeusvSUN) (const GLushort *code); void (APIENTRY *ReplacementCodeubvSUN) (const GLubyte *code); void (APIENTRY *ReplacementCodePointerSUN) (GLenum type, GLsizei stride, const GLvoid* *pointer); void (APIENTRY *Color4ubVertex2fSUN) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); void (APIENTRY *Color4ubVertex2fvSUN) (const GLubyte *c, const GLfloat *v); void (APIENTRY *Color4ubVertex3fSUN) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *Color4ubVertex3fvSUN) (const GLubyte *c, const GLfloat *v); void (APIENTRY *Color3fVertex3fSUN) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *Color3fVertex3fvSUN) (const GLfloat *c, const GLfloat *v); void (APIENTRY *Normal3fVertex3fSUN) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *Normal3fVertex3fvSUN) (const GLfloat *n, const GLfloat *v); void (APIENTRY *Color4fNormal3fVertex3fSUN) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *Color4fNormal3fVertex3fvSUN) (const GLfloat *c, const GLfloat *n, const GLfloat *v); void (APIENTRY *TexCoord2fVertex3fSUN) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *TexCoord2fVertex3fvSUN) (const GLfloat *tc, const GLfloat *v); void (APIENTRY *TexCoord4fVertex4fSUN) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); void (APIENTRY *TexCoord4fVertex4fvSUN) (const GLfloat *tc, const GLfloat *v); void (APIENTRY *TexCoord2fColor4ubVertex3fSUN) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *TexCoord2fColor4ubVertex3fvSUN) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); void (APIENTRY *TexCoord2fColor3fVertex3fSUN) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *TexCoord2fColor3fVertex3fvSUN) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); void (APIENTRY *TexCoord2fNormal3fVertex3fSUN) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *TexCoord2fNormal3fVertex3fvSUN) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); void (APIENTRY *TexCoord2fColor4fNormal3fVertex3fSUN) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *TexCoord2fColor4fNormal3fVertex3fvSUN) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); void (APIENTRY *TexCoord4fColor4fNormal3fVertex4fSUN) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); void (APIENTRY *TexCoord4fColor4fNormal3fVertex4fvSUN) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); void (APIENTRY *ReplacementCodeuiVertex3fSUN) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *ReplacementCodeuiVertex3fvSUN) (const GLuint *rc, const GLfloat *v); void (APIENTRY *ReplacementCodeuiColor4ubVertex3fSUN) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *ReplacementCodeuiColor4ubVertex3fvSUN) (const GLuint *rc, const GLubyte *c, const GLfloat *v); void (APIENTRY *ReplacementCodeuiColor3fVertex3fSUN) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *ReplacementCodeuiColor3fVertex3fvSUN) (const GLuint *rc, const GLfloat *c, const GLfloat *v); void (APIENTRY *ReplacementCodeuiNormal3fVertex3fSUN) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *ReplacementCodeuiNormal3fVertex3fvSUN) (const GLuint *rc, const GLfloat *n, const GLfloat *v); void (APIENTRY *ReplacementCodeuiColor4fNormal3fVertex3fSUN) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *ReplacementCodeuiColor4fNormal3fVertex3fvSUN) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); void (APIENTRY *ReplacementCodeuiTexCoord2fVertex3fSUN) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *ReplacementCodeuiTexCoord2fVertex3fvSUN) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); void (APIENTRY *ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); void (APIENTRY *ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); void (APIENTRY *BlendFuncSeparateEXT) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); void (APIENTRY *BlendFuncSeparateINGR) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); void (APIENTRY *VertexWeightfEXT) (GLfloat weight); void (APIENTRY *VertexWeightfvEXT) (const GLfloat *weight); void (APIENTRY *VertexWeightPointerEXT) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer); void (APIENTRY *FlushVertexArrayRangeNV) (void); void (APIENTRY *VertexArrayRangeNV) (GLsizei length, const GLvoid *pointer); void (APIENTRY *CombinerParameterfvNV) (GLenum pname, const GLfloat *params); void (APIENTRY *CombinerParameterfNV) (GLenum pname, GLfloat param); void (APIENTRY *CombinerParameterivNV) (GLenum pname, const GLint *params); void (APIENTRY *CombinerParameteriNV) (GLenum pname, GLint param); void (APIENTRY *CombinerInputNV) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); void (APIENTRY *CombinerOutputNV) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); void (APIENTRY *FinalCombinerInputNV) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); void (APIENTRY *GetCombinerInputParameterfvNV) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); void (APIENTRY *GetCombinerInputParameterivNV) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); void (APIENTRY *GetCombinerOutputParameterfvNV) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); void (APIENTRY *GetCombinerOutputParameterivNV) (GLenum stage, GLenum portion, GLenum pname, GLint *params); void (APIENTRY *GetFinalCombinerInputParameterfvNV) (GLenum variable, GLenum pname, GLfloat *params); void (APIENTRY *GetFinalCombinerInputParameterivNV) (GLenum variable, GLenum pname, GLint *params); void (APIENTRY *ResizeBuffersMESA) (void); void (APIENTRY *WindowPos2dMESA) (GLdouble x, GLdouble y); void (APIENTRY *WindowPos2dvMESA) (const GLdouble *v); void (APIENTRY *WindowPos2fMESA) (GLfloat x, GLfloat y); void (APIENTRY *WindowPos2fvMESA) (const GLfloat *v); void (APIENTRY *WindowPos2iMESA) (GLint x, GLint y); void (APIENTRY *WindowPos2ivMESA) (const GLint *v); void (APIENTRY *WindowPos2sMESA) (GLshort x, GLshort y); void (APIENTRY *WindowPos2svMESA) (const GLshort *v); void (APIENTRY *WindowPos3dMESA) (GLdouble x, GLdouble y, GLdouble z); void (APIENTRY *WindowPos3dvMESA) (const GLdouble *v); void (APIENTRY *WindowPos3fMESA) (GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *WindowPos3fvMESA) (const GLfloat *v); void (APIENTRY *WindowPos3iMESA) (GLint x, GLint y, GLint z); void (APIENTRY *WindowPos3ivMESA) (const GLint *v); void (APIENTRY *WindowPos3sMESA) (GLshort x, GLshort y, GLshort z); void (APIENTRY *WindowPos3svMESA) (const GLshort *v); void (APIENTRY *WindowPos4dMESA) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); void (APIENTRY *WindowPos4dvMESA) (const GLdouble *v); void (APIENTRY *WindowPos4fMESA) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); void (APIENTRY *WindowPos4fvMESA) (const GLfloat *v); void (APIENTRY *WindowPos4iMESA) (GLint x, GLint y, GLint z, GLint w); void (APIENTRY *WindowPos4ivMESA) (const GLint *v); void (APIENTRY *WindowPos4sMESA) (GLshort x, GLshort y, GLshort z, GLshort w); void (APIENTRY *WindowPos4svMESA) (const GLshort *v); void (APIENTRY *MultiModeDrawArraysIBM) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); void (APIENTRY *MultiModeDrawElementsIBM) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride); void (APIENTRY *ColorPointerListIBM) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); void (APIENTRY *SecondaryColorPointerListIBM) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); void (APIENTRY *EdgeFlagPointerListIBM) (GLint stride, const GLboolean* *pointer, GLint ptrstride); void (APIENTRY *FogCoordPointerListIBM) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); void (APIENTRY *IndexPointerListIBM) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); void (APIENTRY *NormalPointerListIBM) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); void (APIENTRY *TexCoordPointerListIBM) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); void (APIENTRY *VertexPointerListIBM) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); void (APIENTRY *TbufferMask3DFX) (GLuint mask); void (APIENTRY *SampleMaskEXT) (GLclampf value, GLboolean invert); void (APIENTRY *SamplePatternEXT) (GLenum pattern); void (APIENTRY *TextureColorMaskSGIS) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); void (APIENTRY *IglooInterfaceSGIX) (GLenum pname, const GLvoid *params); void (APIENTRY *DeleteFencesNV) (GLsizei n, const GLuint *fences); void (APIENTRY *GenFencesNV) (GLsizei n, GLuint *fences); GLboolean (APIENTRY *IsFenceNV) (GLuint fence); GLboolean (APIENTRY *TestFenceNV) (GLuint fence); void (APIENTRY *GetFenceivNV) (GLuint fence, GLenum pname, GLint *params); void (APIENTRY *FinishFenceNV) (GLuint fence); void (APIENTRY *SetFenceNV) (GLuint fence, GLenum condition); void (APIENTRY *MapControlPointsNV) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points); void (APIENTRY *MapParameterivNV) (GLenum target, GLenum pname, const GLint *params); void (APIENTRY *MapParameterfvNV) (GLenum target, GLenum pname, const GLfloat *params); void (APIENTRY *GetMapControlPointsNV) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points); void (APIENTRY *GetMapParameterivNV) (GLenum target, GLenum pname, GLint *params); void (APIENTRY *GetMapParameterfvNV) (GLenum target, GLenum pname, GLfloat *params); void (APIENTRY *GetMapAttribParameterivNV) (GLenum target, GLuint index, GLenum pname, GLint *params); void (APIENTRY *GetMapAttribParameterfvNV) (GLenum target, GLuint index, GLenum pname, GLfloat *params); void (APIENTRY *EvalMapsNV) (GLenum target, GLenum mode); void (APIENTRY *CombinerStageParameterfvNV) (GLenum stage, GLenum pname, const GLfloat *params); void (APIENTRY *GetCombinerStageParameterfvNV) (GLenum stage, GLenum pname, GLfloat *params); GLboolean (APIENTRY *AreProgramsResidentNV) (GLsizei n, const GLuint *programs, GLboolean *residences); void (APIENTRY *BindProgramNV) (GLenum target, GLuint id); void (APIENTRY *DeleteProgramsNV) (GLsizei n, const GLuint *programs); void (APIENTRY *ExecuteProgramNV) (GLenum target, GLuint id, const GLfloat *params); void (APIENTRY *GenProgramsNV) (GLsizei n, GLuint *programs); void (APIENTRY *GetProgramParameterdvNV) (GLenum target, GLuint index, GLenum pname, GLdouble *params); void (APIENTRY *GetProgramParameterfvNV) (GLenum target, GLuint index, GLenum pname, GLfloat *params); void (APIENTRY *GetProgramivNV) (GLuint id, GLenum pname, GLint *params); void (APIENTRY *GetProgramStringNV) (GLuint id, GLenum pname, GLubyte *program); void (APIENTRY *GetTrackMatrixivNV) (GLenum target, GLuint address, GLenum pname, GLint *params); void (APIENTRY *GetVertexAttribdvNV) (GLuint index, GLenum pname, GLdouble *params); void (APIENTRY *GetVertexAttribfvNV) (GLuint index, GLenum pname, GLfloat *params); void (APIENTRY *GetVertexAttribivNV) (GLuint index, GLenum pname, GLint *params); void (APIENTRY *GetVertexAttribPointervNV) (GLuint index, GLenum pname, GLvoid* *pointer); GLboolean (APIENTRY *IsProgramNV) (GLuint id); void (APIENTRY *LoadProgramNV) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); void (APIENTRY *ProgramParameter4dNV) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); void (APIENTRY *ProgramParameter4dvNV) (GLenum target, GLuint index, const GLdouble *v); void (APIENTRY *ProgramParameter4fNV) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); void (APIENTRY *ProgramParameter4fvNV) (GLenum target, GLuint index, const GLfloat *v); void (APIENTRY *ProgramParameters4dvNV) (GLenum target, GLuint index, GLuint count, const GLdouble *v); void (APIENTRY *ProgramParameters4fvNV) (GLenum target, GLuint index, GLuint count, const GLfloat *v); void (APIENTRY *RequestResidentProgramsNV) (GLsizei n, const GLuint *programs); void (APIENTRY *TrackMatrixNV) (GLenum target, GLuint address, GLenum matrix, GLenum transform); void (APIENTRY *VertexAttribPointerNV) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer); void (APIENTRY *VertexAttrib1dNV) (GLuint index, GLdouble x); void (APIENTRY *VertexAttrib1dvNV) (GLuint index, const GLdouble *v); void (APIENTRY *VertexAttrib1fNV) (GLuint index, GLfloat x); void (APIENTRY *VertexAttrib1fvNV) (GLuint index, const GLfloat *v); void (APIENTRY *VertexAttrib1sNV) (GLuint index, GLshort x); void (APIENTRY *VertexAttrib1svNV) (GLuint index, const GLshort *v); void (APIENTRY *VertexAttrib2dNV) (GLuint index, GLdouble x, GLdouble y); void (APIENTRY *VertexAttrib2dvNV) (GLuint index, const GLdouble *v); void (APIENTRY *VertexAttrib2fNV) (GLuint index, GLfloat x, GLfloat y); void (APIENTRY *VertexAttrib2fvNV) (GLuint index, const GLfloat *v); void (APIENTRY *VertexAttrib2sNV) (GLuint index, GLshort x, GLshort y); void (APIENTRY *VertexAttrib2svNV) (GLuint index, const GLshort *v); void (APIENTRY *VertexAttrib3dNV) (GLuint index, GLdouble x, GLdouble y, GLdouble z); void (APIENTRY *VertexAttrib3dvNV) (GLuint index, const GLdouble *v); void (APIENTRY *VertexAttrib3fNV) (GLuint index, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *VertexAttrib3fvNV) (GLuint index, const GLfloat *v); void (APIENTRY *VertexAttrib3sNV) (GLuint index, GLshort x, GLshort y, GLshort z); void (APIENTRY *VertexAttrib3svNV) (GLuint index, const GLshort *v); void (APIENTRY *VertexAttrib4dNV) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); void (APIENTRY *VertexAttrib4dvNV) (GLuint index, const GLdouble *v); void (APIENTRY *VertexAttrib4fNV) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); void (APIENTRY *VertexAttrib4fvNV) (GLuint index, const GLfloat *v); void (APIENTRY *VertexAttrib4sNV) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); void (APIENTRY *VertexAttrib4svNV) (GLuint index, const GLshort *v); void (APIENTRY *VertexAttrib4ubNV) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); void (APIENTRY *VertexAttrib4ubvNV) (GLuint index, const GLubyte *v); void (APIENTRY *VertexAttribs1dvNV) (GLuint index, GLsizei count, const GLdouble *v); void (APIENTRY *VertexAttribs1fvNV) (GLuint index, GLsizei count, const GLfloat *v); void (APIENTRY *VertexAttribs1svNV) (GLuint index, GLsizei count, const GLshort *v); void (APIENTRY *VertexAttribs2dvNV) (GLuint index, GLsizei count, const GLdouble *v); void (APIENTRY *VertexAttribs2fvNV) (GLuint index, GLsizei count, const GLfloat *v); void (APIENTRY *VertexAttribs2svNV) (GLuint index, GLsizei count, const GLshort *v); void (APIENTRY *VertexAttribs3dvNV) (GLuint index, GLsizei count, const GLdouble *v); void (APIENTRY *VertexAttribs3fvNV) (GLuint index, GLsizei count, const GLfloat *v); void (APIENTRY *VertexAttribs3svNV) (GLuint index, GLsizei count, const GLshort *v); void (APIENTRY *VertexAttribs4dvNV) (GLuint index, GLsizei count, const GLdouble *v); void (APIENTRY *VertexAttribs4fvNV) (GLuint index, GLsizei count, const GLfloat *v); void (APIENTRY *VertexAttribs4svNV) (GLuint index, GLsizei count, const GLshort *v); void (APIENTRY *VertexAttribs4ubvNV) (GLuint index, GLsizei count, const GLubyte *v); void (APIENTRY *TexBumpParameterivATI) (GLenum pname, const GLint *param); void (APIENTRY *TexBumpParameterfvATI) (GLenum pname, const GLfloat *param); void (APIENTRY *GetTexBumpParameterivATI) (GLenum pname, GLint *param); void (APIENTRY *GetTexBumpParameterfvATI) (GLenum pname, GLfloat *param); GLuint (APIENTRY *GenFragmentShadersATI) (GLuint range); void (APIENTRY *BindFragmentShaderATI) (GLuint id); void (APIENTRY *DeleteFragmentShaderATI) (GLuint id); void (APIENTRY *BeginFragmentShaderATI) (void); void (APIENTRY *EndFragmentShaderATI) (void); void (APIENTRY *PassTexCoordATI) (GLuint dst, GLuint coord, GLenum swizzle); void (APIENTRY *SampleMapATI) (GLuint dst, GLuint interp, GLenum swizzle); void (APIENTRY *ColorFragmentOp1ATI) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); void (APIENTRY *ColorFragmentOp2ATI) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); void (APIENTRY *ColorFragmentOp3ATI) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); void (APIENTRY *AlphaFragmentOp1ATI) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); void (APIENTRY *AlphaFragmentOp2ATI) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); void (APIENTRY *AlphaFragmentOp3ATI) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); void (APIENTRY *SetFragmentShaderConstantATI) (GLuint dst, const GLfloat *value); void (APIENTRY *PNTrianglesiATI) (GLenum pname, GLint param); void (APIENTRY *PNTrianglesfATI) (GLenum pname, GLfloat param); GLuint (APIENTRY *NewObjectBufferATI) (GLsizei size, const GLvoid *pointer, GLenum usage); GLboolean (APIENTRY *IsObjectBufferATI) (GLuint buffer); void (APIENTRY *UpdateObjectBufferATI) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve); void (APIENTRY *GetObjectBufferfvATI) (GLuint buffer, GLenum pname, GLfloat *params); void (APIENTRY *GetObjectBufferivATI) (GLuint buffer, GLenum pname, GLint *params); void (APIENTRY *FreeObjectBufferATI) (GLuint buffer); void (APIENTRY *ArrayObjectATI) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); void (APIENTRY *GetArrayObjectfvATI) (GLenum array, GLenum pname, GLfloat *params); void (APIENTRY *GetArrayObjectivATI) (GLenum array, GLenum pname, GLint *params); void (APIENTRY *VariantArrayObjectATI) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); void (APIENTRY *GetVariantArrayObjectfvATI) (GLuint id, GLenum pname, GLfloat *params); void (APIENTRY *GetVariantArrayObjectivATI) (GLuint id, GLenum pname, GLint *params); void (APIENTRY *BeginVertexShaderEXT) (void); void (APIENTRY *EndVertexShaderEXT) (void); void (APIENTRY *BindVertexShaderEXT) (GLuint id); GLuint (APIENTRY *GenVertexShadersEXT) (GLuint range); void (APIENTRY *DeleteVertexShaderEXT) (GLuint id); void (APIENTRY *ShaderOp1EXT) (GLenum op, GLuint res, GLuint arg1); void (APIENTRY *ShaderOp2EXT) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); void (APIENTRY *ShaderOp3EXT) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); void (APIENTRY *SwizzleEXT) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); void (APIENTRY *WriteMaskEXT) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); void (APIENTRY *InsertComponentEXT) (GLuint res, GLuint src, GLuint num); void (APIENTRY *ExtractComponentEXT) (GLuint res, GLuint src, GLuint num); GLuint (APIENTRY *GenSymbolsEXT) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); void (APIENTRY *SetInvariantEXT) (GLuint id, GLenum type, const GLvoid *addr); void (APIENTRY *SetLocalConstantEXT) (GLuint id, GLenum type, const GLvoid *addr); void (APIENTRY *VariantbvEXT) (GLuint id, const GLbyte *addr); void (APIENTRY *VariantsvEXT) (GLuint id, const GLshort *addr); void (APIENTRY *VariantivEXT) (GLuint id, const GLint *addr); void (APIENTRY *VariantfvEXT) (GLuint id, const GLfloat *addr); void (APIENTRY *VariantdvEXT) (GLuint id, const GLdouble *addr); void (APIENTRY *VariantubvEXT) (GLuint id, const GLubyte *addr); void (APIENTRY *VariantusvEXT) (GLuint id, const GLushort *addr); void (APIENTRY *VariantuivEXT) (GLuint id, const GLuint *addr); void (APIENTRY *VariantPointerEXT) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr); void (APIENTRY *EnableVariantClientStateEXT) (GLuint id); void (APIENTRY *DisableVariantClientStateEXT) (GLuint id); GLuint (APIENTRY *BindLightParameterEXT) (GLenum light, GLenum value); GLuint (APIENTRY *BindMaterialParameterEXT) (GLenum face, GLenum value); GLuint (APIENTRY *BindTexGenParameterEXT) (GLenum unit, GLenum coord, GLenum value); GLuint (APIENTRY *BindTextureUnitParameterEXT) (GLenum unit, GLenum value); GLuint (APIENTRY *BindParameterEXT) (GLenum value); GLboolean (APIENTRY *IsVariantEnabledEXT) (GLuint id, GLenum cap); void (APIENTRY *GetVariantBooleanvEXT) (GLuint id, GLenum value, GLboolean *data); void (APIENTRY *GetVariantIntegervEXT) (GLuint id, GLenum value, GLint *data); void (APIENTRY *GetVariantFloatvEXT) (GLuint id, GLenum value, GLfloat *data); void (APIENTRY *GetVariantPointervEXT) (GLuint id, GLenum value, GLvoid* *data); void (APIENTRY *GetInvariantBooleanvEXT) (GLuint id, GLenum value, GLboolean *data); void (APIENTRY *GetInvariantIntegervEXT) (GLuint id, GLenum value, GLint *data); void (APIENTRY *GetInvariantFloatvEXT) (GLuint id, GLenum value, GLfloat *data); void (APIENTRY *GetLocalConstantBooleanvEXT) (GLuint id, GLenum value, GLboolean *data); void (APIENTRY *GetLocalConstantIntegervEXT) (GLuint id, GLenum value, GLint *data); void (APIENTRY *GetLocalConstantFloatvEXT) (GLuint id, GLenum value, GLfloat *data); void (APIENTRY *VertexStream1sATI) (GLenum stream, GLshort x); void (APIENTRY *VertexStream1svATI) (GLenum stream, const GLshort *coords); void (APIENTRY *VertexStream1iATI) (GLenum stream, GLint x); void (APIENTRY *VertexStream1ivATI) (GLenum stream, const GLint *coords); void (APIENTRY *VertexStream1fATI) (GLenum stream, GLfloat x); void (APIENTRY *VertexStream1fvATI) (GLenum stream, const GLfloat *coords); void (APIENTRY *VertexStream1dATI) (GLenum stream, GLdouble x); void (APIENTRY *VertexStream1dvATI) (GLenum stream, const GLdouble *coords); void (APIENTRY *VertexStream2sATI) (GLenum stream, GLshort x, GLshort y); void (APIENTRY *VertexStream2svATI) (GLenum stream, const GLshort *coords); void (APIENTRY *VertexStream2iATI) (GLenum stream, GLint x, GLint y); void (APIENTRY *VertexStream2ivATI) (GLenum stream, const GLint *coords); void (APIENTRY *VertexStream2fATI) (GLenum stream, GLfloat x, GLfloat y); void (APIENTRY *VertexStream2fvATI) (GLenum stream, const GLfloat *coords); void (APIENTRY *VertexStream2dATI) (GLenum stream, GLdouble x, GLdouble y); void (APIENTRY *VertexStream2dvATI) (GLenum stream, const GLdouble *coords); void (APIENTRY *VertexStream3sATI) (GLenum stream, GLshort x, GLshort y, GLshort z); void (APIENTRY *VertexStream3svATI) (GLenum stream, const GLshort *coords); void (APIENTRY *VertexStream3iATI) (GLenum stream, GLint x, GLint y, GLint z); void (APIENTRY *VertexStream3ivATI) (GLenum stream, const GLint *coords); void (APIENTRY *VertexStream3fATI) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY *VertexStream3fvATI) (GLenum stream, const GLfloat *coords); void (APIENTRY *VertexStream3dATI) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); void (APIENTRY *VertexStream3dvATI) (GLenum stream, const GLdouble *coords); void (APIENTRY *VertexStream4sATI) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); void (APIENTRY *VertexStream4svATI) (GLenum stream, const GLshort *coords); void (APIENTRY *VertexStream4iATI) (GLenum stream, GLint x, GLint y, GLint z, GLint w); void (APIENTRY *VertexStream4ivATI) (GLenum stream, const GLint *coords); void (APIENTRY *VertexStream4fATI) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); void (APIENTRY *VertexStream4fvATI) (GLenum stream, const GLfloat *coords); void (APIENTRY *VertexStream4dATI) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); void (APIENTRY *VertexStream4dvATI) (GLenum stream, const GLdouble *coords); void (APIENTRY *NormalStream3bATI) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); void (APIENTRY *NormalStream3bvATI) (GLenum stream, const GLbyte *coords); void (APIENTRY *NormalStream3sATI) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); void (APIENTRY *NormalStream3svATI) (GLenum stream, const GLshort *coords); void (APIENTRY *NormalStream3iATI) (GLenum stream, GLint nx, GLint ny, GLint nz); void (APIENTRY *NormalStream3ivATI) (GLenum stream, const GLint *coords); void (APIENTRY *NormalStream3fATI) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); void (APIENTRY *NormalStream3fvATI) (GLenum stream, const GLfloat *coords); void (APIENTRY *NormalStream3dATI) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); void (APIENTRY *NormalStream3dvATI) (GLenum stream, const GLdouble *coords); void (APIENTRY *ClientActiveVertexStreamATI) (GLenum stream); void (APIENTRY *VertexBlendEnviATI) (GLenum pname, GLint param); void (APIENTRY *VertexBlendEnvfATI) (GLenum pname, GLfloat param); void (APIENTRY *ElementPointerATI) (GLenum type, const GLvoid *pointer); void (APIENTRY *DrawElementArrayATI) (GLenum mode, GLsizei count); void (APIENTRY *DrawRangeElementArrayATI) (GLenum mode, GLuint start, GLuint end, GLsizei count); void (APIENTRY *DrawMeshArraysSUN) (GLenum mode, GLint first, GLsizei count, GLsizei width); void (APIENTRY *GenOcclusionQueriesNV) (GLsizei n, GLuint *ids); void (APIENTRY *DeleteOcclusionQueriesNV) (GLsizei n, const GLuint *ids); GLboolean (APIENTRY *IsOcclusionQueryNV) (GLuint id); void (APIENTRY *BeginOcclusionQueryNV) (GLuint id); void (APIENTRY *EndOcclusionQueryNV) (void); void (APIENTRY *GetOcclusionQueryivNV) (GLuint id, GLenum pname, GLint *params); void (APIENTRY *GetOcclusionQueryuivNV) (GLuint id, GLenum pname, GLuint *params); void (APIENTRY *PointParameteriNV) (GLenum pname, GLint param); void (APIENTRY *PointParameterivNV) (GLenum pname, const GLint *params); void (APIENTRY *ActiveStencilFaceEXT) (GLenum face); void (APIENTRY *ElementPointerAPPLE) (GLenum type, const GLvoid *pointer); void (APIENTRY *DrawElementArrayAPPLE) (GLenum mode, GLint first, GLsizei count); void (APIENTRY *DrawRangeElementArrayAPPLE) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); void (APIENTRY *MultiDrawElementArrayAPPLE) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); void (APIENTRY *MultiDrawRangeElementArrayAPPLE) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); void (APIENTRY *GenFencesAPPLE) (GLsizei n, GLuint *fences); void (APIENTRY *DeleteFencesAPPLE) (GLsizei n, const GLuint *fences); void (APIENTRY *SetFenceAPPLE) (GLuint fence); GLboolean (APIENTRY *IsFenceAPPLE) (GLuint fence); GLboolean (APIENTRY *TestFenceAPPLE) (GLuint fence); void (APIENTRY *FinishFenceAPPLE) (GLuint fence); GLboolean (APIENTRY *TestObjectAPPLE) (GLenum object, GLuint name); void (APIENTRY *FinishObjectAPPLE) (GLenum object, GLint name); void (APIENTRY *BindVertexArrayAPPLE) (GLuint array); void (APIENTRY *DeleteVertexArraysAPPLE) (GLsizei n, const GLuint *arrays); void (APIENTRY *GenVertexArraysAPPLE) (GLsizei n, const GLuint *arrays); GLboolean (APIENTRY *IsVertexArrayAPPLE) (GLuint array); void (APIENTRY *VertexArrayRangeAPPLE) (GLsizei length, GLvoid *pointer); void (APIENTRY *FlushVertexArrayRangeAPPLE) (GLsizei length, GLvoid *pointer); void (APIENTRY *VertexArrayParameteriAPPLE) (GLenum pname, GLint param); void (APIENTRY *DrawBuffersATI) (GLsizei n, const GLenum *bufs); void (APIENTRY *ProgramNamedParameter4fNV) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); void (APIENTRY *ProgramNamedParameter4dNV) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); void (APIENTRY *ProgramNamedParameter4fvNV) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); void (APIENTRY *ProgramNamedParameter4dvNV) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); void (APIENTRY *GetProgramNamedParameterfvNV) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); void (APIENTRY *GetProgramNamedParameterdvNV) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); void (APIENTRY *Vertex2hNV) (GLhalfNV x, GLhalfNV y); void (APIENTRY *Vertex2hvNV) (const GLhalfNV *v); void (APIENTRY *Vertex3hNV) (GLhalfNV x, GLhalfNV y, GLhalfNV z); void (APIENTRY *Vertex3hvNV) (const GLhalfNV *v); void (APIENTRY *Vertex4hNV) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); void (APIENTRY *Vertex4hvNV) (const GLhalfNV *v); void (APIENTRY *Normal3hNV) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); void (APIENTRY *Normal3hvNV) (const GLhalfNV *v); void (APIENTRY *Color3hNV) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); void (APIENTRY *Color3hvNV) (const GLhalfNV *v); void (APIENTRY *Color4hNV) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); void (APIENTRY *Color4hvNV) (const GLhalfNV *v); void (APIENTRY *TexCoord1hNV) (GLhalfNV s); void (APIENTRY *TexCoord1hvNV) (const GLhalfNV *v); void (APIENTRY *TexCoord2hNV) (GLhalfNV s, GLhalfNV t); void (APIENTRY *TexCoord2hvNV) (const GLhalfNV *v); void (APIENTRY *TexCoord3hNV) (GLhalfNV s, GLhalfNV t, GLhalfNV r); void (APIENTRY *TexCoord3hvNV) (const GLhalfNV *v); void (APIENTRY *TexCoord4hNV) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); void (APIENTRY *TexCoord4hvNV) (const GLhalfNV *v); void (APIENTRY *MultiTexCoord1hNV) (GLenum target, GLhalfNV s); void (APIENTRY *MultiTexCoord1hvNV) (GLenum target, const GLhalfNV *v); void (APIENTRY *MultiTexCoord2hNV) (GLenum target, GLhalfNV s, GLhalfNV t); void (APIENTRY *MultiTexCoord2hvNV) (GLenum target, const GLhalfNV *v); void (APIENTRY *MultiTexCoord3hNV) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); void (APIENTRY *MultiTexCoord3hvNV) (GLenum target, const GLhalfNV *v); void (APIENTRY *MultiTexCoord4hNV) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); void (APIENTRY *MultiTexCoord4hvNV) (GLenum target, const GLhalfNV *v); void (APIENTRY *FogCoordhNV) (GLhalfNV fog); void (APIENTRY *FogCoordhvNV) (const GLhalfNV *fog); void (APIENTRY *SecondaryColor3hNV) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); void (APIENTRY *SecondaryColor3hvNV) (const GLhalfNV *v); void (APIENTRY *VertexWeighthNV) (GLhalfNV weight); void (APIENTRY *VertexWeighthvNV) (const GLhalfNV *weight); void (APIENTRY *VertexAttrib1hNV) (GLuint index, GLhalfNV x); void (APIENTRY *VertexAttrib1hvNV) (GLuint index, const GLhalfNV *v); void (APIENTRY *VertexAttrib2hNV) (GLuint index, GLhalfNV x, GLhalfNV y); void (APIENTRY *VertexAttrib2hvNV) (GLuint index, const GLhalfNV *v); void (APIENTRY *VertexAttrib3hNV) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); void (APIENTRY *VertexAttrib3hvNV) (GLuint index, const GLhalfNV *v); void (APIENTRY *VertexAttrib4hNV) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); void (APIENTRY *VertexAttrib4hvNV) (GLuint index, const GLhalfNV *v); void (APIENTRY *VertexAttribs1hvNV) (GLuint index, GLsizei n, const GLhalfNV *v); void (APIENTRY *VertexAttribs2hvNV) (GLuint index, GLsizei n, const GLhalfNV *v); void (APIENTRY *VertexAttribs3hvNV) (GLuint index, GLsizei n, const GLhalfNV *v); void (APIENTRY *VertexAttribs4hvNV) (GLuint index, GLsizei n, const GLhalfNV *v); void (APIENTRY *PixelDataRangeNV) (GLenum target, GLsizei length, GLvoid *pointer); void (APIENTRY *FlushPixelDataRangeNV) (GLenum target); void (APIENTRY *PrimitiveRestartNV) (void); void (APIENTRY *PrimitiveRestartIndexNV) (GLuint index); GLvoid* (APIENTRY *MapObjectBufferATI) (GLuint buffer); void (APIENTRY *UnmapObjectBufferATI) (GLuint buffer); void (APIENTRY *StencilOpSeparateATI) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); void (APIENTRY *StencilFuncSeparateATI) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); void (APIENTRY *VertexAttribArrayObjectATI) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); void (APIENTRY *GetVertexAttribArrayObjectfvATI) (GLuint index, GLenum pname, GLfloat *params); void (APIENTRY *GetVertexAttribArrayObjectivATI) (GLuint index, GLenum pname, GLint *params); void (APIENTRY *DepthBoundsEXT) (GLclampd zmin, GLclampd zmax); void (APIENTRY *BlendEquationSeparateEXT) (GLenum modeRGB, GLenum modeAlpha); void (APIENTRY *AddSwapHintRectWIN) (GLint x, GLint y, GLsizei width, GLsizei height); #ifdef _WIN32 HANDLE (WINAPI *CreateBufferRegionARB) (HDC hDC, int iLayerPlane, UINT uType); VOID (WINAPI *DeleteBufferRegionARB) (HANDLE hRegion); BOOL (WINAPI *SaveBufferRegionARB) (HANDLE hRegion, int x, int y, int width, int height); BOOL (WINAPI *RestoreBufferRegionARB) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); const (WINAPI *GetExtensionsStringARB) (HDC hdc); BOOL (WINAPI *GetPixelFormatAttribivARB) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); BOOL (WINAPI *GetPixelFormatAttribfvARB) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); BOOL (WINAPI *ChoosePixelFormatARB) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); BOOL (WINAPI *MakeContextCurrentARB) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); HDC (WINAPI *GetCurrentReadDCARB) (void); HPBUFFERARB (WINAPI *CreatePbufferARB) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); HDC (WINAPI *GetPbufferDCARB) (HPBUFFERARB hPbuffer); int (WINAPI *ReleasePbufferDCARB) (HPBUFFERARB hPbuffer, HDC hDC); BOOL (WINAPI *DestroyPbufferARB) (HPBUFFERARB hPbuffer); BOOL (WINAPI *QueryPbufferARB) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); BOOL (WINAPI *BindTexImageARB) (HPBUFFERARB hPbuffer, int iBuffer); BOOL (WINAPI *ReleaseTexImageARB) (HPBUFFERARB hPbuffer, int iBuffer); BOOL (WINAPI *SetPbufferAttribARB) (HPBUFFERARB hPbuffer, const int *piAttribList); GLboolean (WINAPI *CreateDisplayColorTableEXT) (GLushort id); GLboolean (WINAPI *LoadDisplayColorTableEXT) (const GLushort *table, GLuint length); GLboolean (WINAPI *BindDisplayColorTableEXT) (GLushort id); VOID (WINAPI *DestroyDisplayColorTableEXT) (GLushort id); const (WINAPI *GetExtensionsStringEXT) (void); BOOL (WINAPI *MakeContextCurrentEXT) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); HDC (WINAPI *GetCurrentReadDCEXT) (void); HPBUFFEREXT (WINAPI *CreatePbufferEXT) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); HDC (WINAPI *GetPbufferDCEXT) (HPBUFFEREXT hPbuffer); int (WINAPI *ReleasePbufferDCEXT) (HPBUFFEREXT hPbuffer, HDC hDC); BOOL (WINAPI *DestroyPbufferEXT) (HPBUFFEREXT hPbuffer); BOOL (WINAPI *QueryPbufferEXT) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); BOOL (WINAPI *GetPixelFormatAttribivEXT) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); BOOL (WINAPI *GetPixelFormatAttribfvEXT) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); BOOL (WINAPI *ChoosePixelFormatEXT) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); BOOL (WINAPI *SwapIntervalEXT) (int interval); int (WINAPI *GetSwapIntervalEXT) (void); void* (WINAPI *AllocateMemoryNV) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); void (WINAPI *FreeMemoryNV) (void); BOOL (WINAPI *GetSyncValuesOML) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); BOOL (WINAPI *GetMscRateOML) (HDC hdc, INT32 *numerator, INT32 *denominator); INT64 (WINAPI *SwapBuffersMscOML) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); INT64 (WINAPI *SwapLayerBuffersMscOML) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); BOOL (WINAPI *WaitForMscOML) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); BOOL (WINAPI *WaitForSbcOML) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); BOOL (WINAPI *GetDigitalVideoParametersI3D) (HDC hDC, int iAttribute, int *piValue); BOOL (WINAPI *SetDigitalVideoParametersI3D) (HDC hDC, int iAttribute, const int *piValue); BOOL (WINAPI *GetGammaTableParametersI3D) (HDC hDC, int iAttribute, int *piValue); BOOL (WINAPI *SetGammaTableParametersI3D) (HDC hDC, int iAttribute, const int *piValue); BOOL (WINAPI *GetGammaTableI3D) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); BOOL (WINAPI *SetGammaTableI3D) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); BOOL (WINAPI *EnableGenlockI3D) (HDC hDC); BOOL (WINAPI *DisableGenlockI3D) (HDC hDC); BOOL (WINAPI *IsEnabledGenlockI3D) (HDC hDC, BOOL *pFlag); BOOL (WINAPI *GenlockSourceI3D) (HDC hDC, UINT uSource); BOOL (WINAPI *GetGenlockSourceI3D) (HDC hDC, UINT *uSource); BOOL (WINAPI *GenlockSourceEdgeI3D) (HDC hDC, UINT uEdge); BOOL (WINAPI *GetGenlockSourceEdgeI3D) (HDC hDC, UINT *uEdge); BOOL (WINAPI *GenlockSampleRateI3D) (HDC hDC, UINT uRate); BOOL (WINAPI *GetGenlockSampleRateI3D) (HDC hDC, UINT *uRate); BOOL (WINAPI *GenlockSourceDelayI3D) (HDC hDC, UINT uDelay); BOOL (WINAPI *GetGenlockSourceDelayI3D) (HDC hDC, UINT *uDelay); BOOL (WINAPI *QueryGenlockMaxSourceDelayI3D) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); LPVOID (WINAPI *CreateImageBufferI3D) (HDC hDC, DWORD dwSize, UINT uFlags); BOOL (WINAPI *DestroyImageBufferI3D) (HDC hDC, LPVOID pAddress); BOOL (WINAPI *AssociateImageBufferEventsI3D) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); BOOL (WINAPI *ReleaseImageBufferEventsI3D) (HDC hDC, const LPVOID *pAddress, UINT count); BOOL (WINAPI *EnableFrameLockI3D) (void); BOOL (WINAPI *DisableFrameLockI3D) (void); BOOL (WINAPI *IsEnabledFrameLockI3D) (BOOL *pFlag); BOOL (WINAPI *QueryFrameLockMasterI3D) (BOOL *pFlag); BOOL (WINAPI *GetFrameUsageI3D) (float *pUsage); BOOL (WINAPI *BeginFrameTrackingI3D) (void); BOOL (WINAPI *EndFrameTrackingI3D) (void); BOOL (WINAPI *QueryFrameTrackingI3D) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); #endif /* _WIN32 */ } _GLextensionProcs; #define glBlendColor (_GET_TLS_PROCTABLE()->BlendColor) #define glBlendEquation (_GET_TLS_PROCTABLE()->BlendEquation) #define glDrawRangeElements (_GET_TLS_PROCTABLE()->DrawRangeElements) #define glColorTable (_GET_TLS_PROCTABLE()->ColorTable) #define glColorTableParameterfv (_GET_TLS_PROCTABLE()->ColorTableParameterfv) #define glColorTableParameteriv (_GET_TLS_PROCTABLE()->ColorTableParameteriv) #define glCopyColorTable (_GET_TLS_PROCTABLE()->CopyColorTable) #define glGetColorTable (_GET_TLS_PROCTABLE()->GetColorTable) #define glGetColorTableParameterfv (_GET_TLS_PROCTABLE()->GetColorTableParameterfv) #define glGetColorTableParameteriv (_GET_TLS_PROCTABLE()->GetColorTableParameteriv) #define glColorSubTable (_GET_TLS_PROCTABLE()->ColorSubTable) #define glCopyColorSubTable (_GET_TLS_PROCTABLE()->CopyColorSubTable) #define glConvolutionFilter1D (_GET_TLS_PROCTABLE()->ConvolutionFilter1D) #define glConvolutionFilter2D (_GET_TLS_PROCTABLE()->ConvolutionFilter2D) #define glConvolutionParameterf (_GET_TLS_PROCTABLE()->ConvolutionParameterf) #define glConvolutionParameterfv (_GET_TLS_PROCTABLE()->ConvolutionParameterfv) #define glConvolutionParameteri (_GET_TLS_PROCTABLE()->ConvolutionParameteri) #define glConvolutionParameteriv (_GET_TLS_PROCTABLE()->ConvolutionParameteriv) #define glCopyConvolutionFilter1D (_GET_TLS_PROCTABLE()->CopyConvolutionFilter1D) #define glCopyConvolutionFilter2D (_GET_TLS_PROCTABLE()->CopyConvolutionFilter2D) #define glGetConvolutionFilter (_GET_TLS_PROCTABLE()->GetConvolutionFilter) #define glGetConvolutionParameterfv (_GET_TLS_PROCTABLE()->GetConvolutionParameterfv) #define glGetConvolutionParameteriv (_GET_TLS_PROCTABLE()->GetConvolutionParameteriv) #define glGetSeparableFilter (_GET_TLS_PROCTABLE()->GetSeparableFilter) #define glSeparableFilter2D (_GET_TLS_PROCTABLE()->SeparableFilter2D) #define glGetHistogram (_GET_TLS_PROCTABLE()->GetHistogram) #define glGetHistogramParameterfv (_GET_TLS_PROCTABLE()->GetHistogramParameterfv) #define glGetHistogramParameteriv (_GET_TLS_PROCTABLE()->GetHistogramParameteriv) #define glGetMinmax (_GET_TLS_PROCTABLE()->GetMinmax) #define glGetMinmaxParameterfv (_GET_TLS_PROCTABLE()->GetMinmaxParameterfv) #define glGetMinmaxParameteriv (_GET_TLS_PROCTABLE()->GetMinmaxParameteriv) #define glHistogram (_GET_TLS_PROCTABLE()->Histogram) #define glMinmax (_GET_TLS_PROCTABLE()->Minmax) #define glResetHistogram (_GET_TLS_PROCTABLE()->ResetHistogram) #define glResetMinmax (_GET_TLS_PROCTABLE()->ResetMinmax) #define glTexImage3D (_GET_TLS_PROCTABLE()->TexImage3D) #define glTexSubImage3D (_GET_TLS_PROCTABLE()->TexSubImage3D) #define glCopyTexSubImage3D (_GET_TLS_PROCTABLE()->CopyTexSubImage3D) #define glActiveTexture (_GET_TLS_PROCTABLE()->ActiveTexture) #define glClientActiveTexture (_GET_TLS_PROCTABLE()->ClientActiveTexture) #define glMultiTexCoord1d (_GET_TLS_PROCTABLE()->MultiTexCoord1d) #define glMultiTexCoord1dv (_GET_TLS_PROCTABLE()->MultiTexCoord1dv) #define glMultiTexCoord1f (_GET_TLS_PROCTABLE()->MultiTexCoord1f) #define glMultiTexCoord1fv (_GET_TLS_PROCTABLE()->MultiTexCoord1fv) #define glMultiTexCoord1i (_GET_TLS_PROCTABLE()->MultiTexCoord1i) #define glMultiTexCoord1iv (_GET_TLS_PROCTABLE()->MultiTexCoord1iv) #define glMultiTexCoord1s (_GET_TLS_PROCTABLE()->MultiTexCoord1s) #define glMultiTexCoord1sv (_GET_TLS_PROCTABLE()->MultiTexCoord1sv) #define glMultiTexCoord2d (_GET_TLS_PROCTABLE()->MultiTexCoord2d) #define glMultiTexCoord2dv (_GET_TLS_PROCTABLE()->MultiTexCoord2dv) #define glMultiTexCoord2f (_GET_TLS_PROCTABLE()->MultiTexCoord2f) #define glMultiTexCoord2fv (_GET_TLS_PROCTABLE()->MultiTexCoord2fv) #define glMultiTexCoord2i (_GET_TLS_PROCTABLE()->MultiTexCoord2i) #define glMultiTexCoord2iv (_GET_TLS_PROCTABLE()->MultiTexCoord2iv) #define glMultiTexCoord2s (_GET_TLS_PROCTABLE()->MultiTexCoord2s) #define glMultiTexCoord2sv (_GET_TLS_PROCTABLE()->MultiTexCoord2sv) #define glMultiTexCoord3d (_GET_TLS_PROCTABLE()->MultiTexCoord3d) #define glMultiTexCoord3dv (_GET_TLS_PROCTABLE()->MultiTexCoord3dv) #define glMultiTexCoord3f (_GET_TLS_PROCTABLE()->MultiTexCoord3f) #define glMultiTexCoord3fv (_GET_TLS_PROCTABLE()->MultiTexCoord3fv) #define glMultiTexCoord3i (_GET_TLS_PROCTABLE()->MultiTexCoord3i) #define glMultiTexCoord3iv (_GET_TLS_PROCTABLE()->MultiTexCoord3iv) #define glMultiTexCoord3s (_GET_TLS_PROCTABLE()->MultiTexCoord3s) #define glMultiTexCoord3sv (_GET_TLS_PROCTABLE()->MultiTexCoord3sv) #define glMultiTexCoord4d (_GET_TLS_PROCTABLE()->MultiTexCoord4d) #define glMultiTexCoord4dv (_GET_TLS_PROCTABLE()->MultiTexCoord4dv) #define glMultiTexCoord4f (_GET_TLS_PROCTABLE()->MultiTexCoord4f) #define glMultiTexCoord4fv (_GET_TLS_PROCTABLE()->MultiTexCoord4fv) #define glMultiTexCoord4i (_GET_TLS_PROCTABLE()->MultiTexCoord4i) #define glMultiTexCoord4iv (_GET_TLS_PROCTABLE()->MultiTexCoord4iv) #define glMultiTexCoord4s (_GET_TLS_PROCTABLE()->MultiTexCoord4s) #define glMultiTexCoord4sv (_GET_TLS_PROCTABLE()->MultiTexCoord4sv) #define glLoadTransposeMatrixf (_GET_TLS_PROCTABLE()->LoadTransposeMatrixf) #define glLoadTransposeMatrixd (_GET_TLS_PROCTABLE()->LoadTransposeMatrixd) #define glMultTransposeMatrixf (_GET_TLS_PROCTABLE()->MultTransposeMatrixf) #define glMultTransposeMatrixd (_GET_TLS_PROCTABLE()->MultTransposeMatrixd) #define glSampleCoverage (_GET_TLS_PROCTABLE()->SampleCoverage) #define glCompressedTexImage3D (_GET_TLS_PROCTABLE()->CompressedTexImage3D) #define glCompressedTexImage2D (_GET_TLS_PROCTABLE()->CompressedTexImage2D) #define glCompressedTexImage1D (_GET_TLS_PROCTABLE()->CompressedTexImage1D) #define glCompressedTexSubImage3D (_GET_TLS_PROCTABLE()->CompressedTexSubImage3D) #define glCompressedTexSubImage2D (_GET_TLS_PROCTABLE()->CompressedTexSubImage2D) #define glCompressedTexSubImage1D (_GET_TLS_PROCTABLE()->CompressedTexSubImage1D) #define glGetCompressedTexImage (_GET_TLS_PROCTABLE()->GetCompressedTexImage) #define glBlendFuncSeparate (_GET_TLS_PROCTABLE()->BlendFuncSeparate) #define glFogCoordf (_GET_TLS_PROCTABLE()->FogCoordf) #define glFogCoordfv (_GET_TLS_PROCTABLE()->FogCoordfv) #define glFogCoordd (_GET_TLS_PROCTABLE()->FogCoordd) #define glFogCoorddv (_GET_TLS_PROCTABLE()->FogCoorddv) #define glFogCoordPointer (_GET_TLS_PROCTABLE()->FogCoordPointer) #define glMultiDrawArrays (_GET_TLS_PROCTABLE()->MultiDrawArrays) #define glMultiDrawElements (_GET_TLS_PROCTABLE()->MultiDrawElements) #define glPointParameterf (_GET_TLS_PROCTABLE()->PointParameterf) #define glPointParameterfv (_GET_TLS_PROCTABLE()->PointParameterfv) #define glPointParameteri (_GET_TLS_PROCTABLE()->PointParameteri) #define glPointParameteriv (_GET_TLS_PROCTABLE()->PointParameteriv) #define glSecondaryColor3b (_GET_TLS_PROCTABLE()->SecondaryColor3b) #define glSecondaryColor3bv (_GET_TLS_PROCTABLE()->SecondaryColor3bv) #define glSecondaryColor3d (_GET_TLS_PROCTABLE()->SecondaryColor3d) #define glSecondaryColor3dv (_GET_TLS_PROCTABLE()->SecondaryColor3dv) #define glSecondaryColor3f (_GET_TLS_PROCTABLE()->SecondaryColor3f) #define glSecondaryColor3fv (_GET_TLS_PROCTABLE()->SecondaryColor3fv) #define glSecondaryColor3i (_GET_TLS_PROCTABLE()->SecondaryColor3i) #define glSecondaryColor3iv (_GET_TLS_PROCTABLE()->SecondaryColor3iv) #define glSecondaryColor3s (_GET_TLS_PROCTABLE()->SecondaryColor3s) #define glSecondaryColor3sv (_GET_TLS_PROCTABLE()->SecondaryColor3sv) #define glSecondaryColor3ub (_GET_TLS_PROCTABLE()->SecondaryColor3ub) #define glSecondaryColor3ubv (_GET_TLS_PROCTABLE()->SecondaryColor3ubv) #define glSecondaryColor3ui (_GET_TLS_PROCTABLE()->SecondaryColor3ui) #define glSecondaryColor3uiv (_GET_TLS_PROCTABLE()->SecondaryColor3uiv) #define glSecondaryColor3us (_GET_TLS_PROCTABLE()->SecondaryColor3us) #define glSecondaryColor3usv (_GET_TLS_PROCTABLE()->SecondaryColor3usv) #define glSecondaryColorPointer (_GET_TLS_PROCTABLE()->SecondaryColorPointer) #define glWindowPos2d (_GET_TLS_PROCTABLE()->WindowPos2d) #define glWindowPos2dv (_GET_TLS_PROCTABLE()->WindowPos2dv) #define glWindowPos2f (_GET_TLS_PROCTABLE()->WindowPos2f) #define glWindowPos2fv (_GET_TLS_PROCTABLE()->WindowPos2fv) #define glWindowPos2i (_GET_TLS_PROCTABLE()->WindowPos2i) #define glWindowPos2iv (_GET_TLS_PROCTABLE()->WindowPos2iv) #define glWindowPos2s (_GET_TLS_PROCTABLE()->WindowPos2s) #define glWindowPos2sv (_GET_TLS_PROCTABLE()->WindowPos2sv) #define glWindowPos3d (_GET_TLS_PROCTABLE()->WindowPos3d) #define glWindowPos3dv (_GET_TLS_PROCTABLE()->WindowPos3dv) #define glWindowPos3f (_GET_TLS_PROCTABLE()->WindowPos3f) #define glWindowPos3fv (_GET_TLS_PROCTABLE()->WindowPos3fv) #define glWindowPos3i (_GET_TLS_PROCTABLE()->WindowPos3i) #define glWindowPos3iv (_GET_TLS_PROCTABLE()->WindowPos3iv) #define glWindowPos3s (_GET_TLS_PROCTABLE()->WindowPos3s) #define glWindowPos3sv (_GET_TLS_PROCTABLE()->WindowPos3sv) #define glGenQueries (_GET_TLS_PROCTABLE()->GenQueries) #define glDeleteQueries (_GET_TLS_PROCTABLE()->DeleteQueries) #define glIsQuery (_GET_TLS_PROCTABLE()->IsQuery) #define glBeginQuery (_GET_TLS_PROCTABLE()->BeginQuery) #define glEndQuery (_GET_TLS_PROCTABLE()->EndQuery) #define glGetQueryiv (_GET_TLS_PROCTABLE()->GetQueryiv) #define glGetQueryObjectiv (_GET_TLS_PROCTABLE()->GetQueryObjectiv) #define glGetQueryObjectuiv (_GET_TLS_PROCTABLE()->GetQueryObjectuiv) #define glBindBuffer (_GET_TLS_PROCTABLE()->BindBuffer) #define glDeleteBuffers (_GET_TLS_PROCTABLE()->DeleteBuffers) #define glGenBuffers (_GET_TLS_PROCTABLE()->GenBuffers) #define glIsBuffer (_GET_TLS_PROCTABLE()->IsBuffer) #define glBufferData (_GET_TLS_PROCTABLE()->BufferData) #define glBufferSubData (_GET_TLS_PROCTABLE()->BufferSubData) #define glGetBufferSubData (_GET_TLS_PROCTABLE()->GetBufferSubData) #define glMapBuffer (_GET_TLS_PROCTABLE()->MapBuffer) #define glUnmapBuffer (_GET_TLS_PROCTABLE()->UnmapBuffer) #define glGetBufferParameteriv (_GET_TLS_PROCTABLE()->GetBufferParameteriv) #define glGetBufferPointerv (_GET_TLS_PROCTABLE()->GetBufferPointerv) #define glActiveTextureARB (_GET_TLS_PROCTABLE()->ActiveTextureARB) #define glClientActiveTextureARB (_GET_TLS_PROCTABLE()->ClientActiveTextureARB) #define glMultiTexCoord1dARB (_GET_TLS_PROCTABLE()->MultiTexCoord1dARB) #define glMultiTexCoord1dvARB (_GET_TLS_PROCTABLE()->MultiTexCoord1dvARB) #define glMultiTexCoord1fARB (_GET_TLS_PROCTABLE()->MultiTexCoord1fARB) #define glMultiTexCoord1fvARB (_GET_TLS_PROCTABLE()->MultiTexCoord1fvARB) #define glMultiTexCoord1iARB (_GET_TLS_PROCTABLE()->MultiTexCoord1iARB) #define glMultiTexCoord1ivARB (_GET_TLS_PROCTABLE()->MultiTexCoord1ivARB) #define glMultiTexCoord1sARB (_GET_TLS_PROCTABLE()->MultiTexCoord1sARB) #define glMultiTexCoord1svARB (_GET_TLS_PROCTABLE()->MultiTexCoord1svARB) #define glMultiTexCoord2dARB (_GET_TLS_PROCTABLE()->MultiTexCoord2dARB) #define glMultiTexCoord2dvARB (_GET_TLS_PROCTABLE()->MultiTexCoord2dvARB) #define glMultiTexCoord2fARB (_GET_TLS_PROCTABLE()->MultiTexCoord2fARB) #define glMultiTexCoord2fvARB (_GET_TLS_PROCTABLE()->MultiTexCoord2fvARB) #define glMultiTexCoord2iARB (_GET_TLS_PROCTABLE()->MultiTexCoord2iARB) #define glMultiTexCoord2ivARB (_GET_TLS_PROCTABLE()->MultiTexCoord2ivARB) #define glMultiTexCoord2sARB (_GET_TLS_PROCTABLE()->MultiTexCoord2sARB) #define glMultiTexCoord2svARB (_GET_TLS_PROCTABLE()->MultiTexCoord2svARB) #define glMultiTexCoord3dARB (_GET_TLS_PROCTABLE()->MultiTexCoord3dARB) #define glMultiTexCoord3dvARB (_GET_TLS_PROCTABLE()->MultiTexCoord3dvARB) #define glMultiTexCoord3fARB (_GET_TLS_PROCTABLE()->MultiTexCoord3fARB) #define glMultiTexCoord3fvARB (_GET_TLS_PROCTABLE()->MultiTexCoord3fvARB) #define glMultiTexCoord3iARB (_GET_TLS_PROCTABLE()->MultiTexCoord3iARB) #define glMultiTexCoord3ivARB (_GET_TLS_PROCTABLE()->MultiTexCoord3ivARB) #define glMultiTexCoord3sARB (_GET_TLS_PROCTABLE()->MultiTexCoord3sARB) #define glMultiTexCoord3svARB (_GET_TLS_PROCTABLE()->MultiTexCoord3svARB) #define glMultiTexCoord4dARB (_GET_TLS_PROCTABLE()->MultiTexCoord4dARB) #define glMultiTexCoord4dvARB (_GET_TLS_PROCTABLE()->MultiTexCoord4dvARB) #define glMultiTexCoord4fARB (_GET_TLS_PROCTABLE()->MultiTexCoord4fARB) #define glMultiTexCoord4fvARB (_GET_TLS_PROCTABLE()->MultiTexCoord4fvARB) #define glMultiTexCoord4iARB (_GET_TLS_PROCTABLE()->MultiTexCoord4iARB) #define glMultiTexCoord4ivARB (_GET_TLS_PROCTABLE()->MultiTexCoord4ivARB) #define glMultiTexCoord4sARB (_GET_TLS_PROCTABLE()->MultiTexCoord4sARB) #define glMultiTexCoord4svARB (_GET_TLS_PROCTABLE()->MultiTexCoord4svARB) #define glLoadTransposeMatrixfARB (_GET_TLS_PROCTABLE()->LoadTransposeMatrixfARB) #define glLoadTransposeMatrixdARB (_GET_TLS_PROCTABLE()->LoadTransposeMatrixdARB) #define glMultTransposeMatrixfARB (_GET_TLS_PROCTABLE()->MultTransposeMatrixfARB) #define glMultTransposeMatrixdARB (_GET_TLS_PROCTABLE()->MultTransposeMatrixdARB) #define glSampleCoverageARB (_GET_TLS_PROCTABLE()->SampleCoverageARB) #define glCompressedTexImage3DARB (_GET_TLS_PROCTABLE()->CompressedTexImage3DARB) #define glCompressedTexImage2DARB (_GET_TLS_PROCTABLE()->CompressedTexImage2DARB) #define glCompressedTexImage1DARB (_GET_TLS_PROCTABLE()->CompressedTexImage1DARB) #define glCompressedTexSubImage3DARB (_GET_TLS_PROCTABLE()->CompressedTexSubImage3DARB) #define glCompressedTexSubImage2DARB (_GET_TLS_PROCTABLE()->CompressedTexSubImage2DARB) #define glCompressedTexSubImage1DARB (_GET_TLS_PROCTABLE()->CompressedTexSubImage1DARB) #define glGetCompressedTexImageARB (_GET_TLS_PROCTABLE()->GetCompressedTexImageARB) #define glPointParameterfARB (_GET_TLS_PROCTABLE()->PointParameterfARB) #define glPointParameterfvARB (_GET_TLS_PROCTABLE()->PointParameterfvARB) #define glWeightbvARB (_GET_TLS_PROCTABLE()->WeightbvARB) #define glWeightsvARB (_GET_TLS_PROCTABLE()->WeightsvARB) #define glWeightivARB (_GET_TLS_PROCTABLE()->WeightivARB) #define glWeightfvARB (_GET_TLS_PROCTABLE()->WeightfvARB) #define glWeightdvARB (_GET_TLS_PROCTABLE()->WeightdvARB) #define glWeightubvARB (_GET_TLS_PROCTABLE()->WeightubvARB) #define glWeightusvARB (_GET_TLS_PROCTABLE()->WeightusvARB) #define glWeightuivARB (_GET_TLS_PROCTABLE()->WeightuivARB) #define glWeightPointerARB (_GET_TLS_PROCTABLE()->WeightPointerARB) #define glVertexBlendARB (_GET_TLS_PROCTABLE()->VertexBlendARB) #define glCurrentPaletteMatrixARB (_GET_TLS_PROCTABLE()->CurrentPaletteMatrixARB) #define glMatrixIndexubvARB (_GET_TLS_PROCTABLE()->MatrixIndexubvARB) #define glMatrixIndexusvARB (_GET_TLS_PROCTABLE()->MatrixIndexusvARB) #define glMatrixIndexuivARB (_GET_TLS_PROCTABLE()->MatrixIndexuivARB) #define glMatrixIndexPointerARB (_GET_TLS_PROCTABLE()->MatrixIndexPointerARB) #define glWindowPos2dARB (_GET_TLS_PROCTABLE()->WindowPos2dARB) #define glWindowPos2dvARB (_GET_TLS_PROCTABLE()->WindowPos2dvARB) #define glWindowPos2fARB (_GET_TLS_PROCTABLE()->WindowPos2fARB) #define glWindowPos2fvARB (_GET_TLS_PROCTABLE()->WindowPos2fvARB) #define glWindowPos2iARB (_GET_TLS_PROCTABLE()->WindowPos2iARB) #define glWindowPos2ivARB (_GET_TLS_PROCTABLE()->WindowPos2ivARB) #define glWindowPos2sARB (_GET_TLS_PROCTABLE()->WindowPos2sARB) #define glWindowPos2svARB (_GET_TLS_PROCTABLE()->WindowPos2svARB) #define glWindowPos3dARB (_GET_TLS_PROCTABLE()->WindowPos3dARB) #define glWindowPos3dvARB (_GET_TLS_PROCTABLE()->WindowPos3dvARB) #define glWindowPos3fARB (_GET_TLS_PROCTABLE()->WindowPos3fARB) #define glWindowPos3fvARB (_GET_TLS_PROCTABLE()->WindowPos3fvARB) #define glWindowPos3iARB (_GET_TLS_PROCTABLE()->WindowPos3iARB) #define glWindowPos3ivARB (_GET_TLS_PROCTABLE()->WindowPos3ivARB) #define glWindowPos3sARB (_GET_TLS_PROCTABLE()->WindowPos3sARB) #define glWindowPos3svARB (_GET_TLS_PROCTABLE()->WindowPos3svARB) #define glVertexAttrib1dARB (_GET_TLS_PROCTABLE()->VertexAttrib1dARB) #define glVertexAttrib1dvARB (_GET_TLS_PROCTABLE()->VertexAttrib1dvARB) #define glVertexAttrib1fARB (_GET_TLS_PROCTABLE()->VertexAttrib1fARB) #define glVertexAttrib1fvARB (_GET_TLS_PROCTABLE()->VertexAttrib1fvARB) #define glVertexAttrib1sARB (_GET_TLS_PROCTABLE()->VertexAttrib1sARB) #define glVertexAttrib1svARB (_GET_TLS_PROCTABLE()->VertexAttrib1svARB) #define glVertexAttrib2dARB (_GET_TLS_PROCTABLE()->VertexAttrib2dARB) #define glVertexAttrib2dvARB (_GET_TLS_PROCTABLE()->VertexAttrib2dvARB) #define glVertexAttrib2fARB (_GET_TLS_PROCTABLE()->VertexAttrib2fARB) #define glVertexAttrib2fvARB (_GET_TLS_PROCTABLE()->VertexAttrib2fvARB) #define glVertexAttrib2sARB (_GET_TLS_PROCTABLE()->VertexAttrib2sARB) #define glVertexAttrib2svARB (_GET_TLS_PROCTABLE()->VertexAttrib2svARB) #define glVertexAttrib3dARB (_GET_TLS_PROCTABLE()->VertexAttrib3dARB) #define glVertexAttrib3dvARB (_GET_TLS_PROCTABLE()->VertexAttrib3dvARB) #define glVertexAttrib3fARB (_GET_TLS_PROCTABLE()->VertexAttrib3fARB) #define glVertexAttrib3fvARB (_GET_TLS_PROCTABLE()->VertexAttrib3fvARB) #define glVertexAttrib3sARB (_GET_TLS_PROCTABLE()->VertexAttrib3sARB) #define glVertexAttrib3svARB (_GET_TLS_PROCTABLE()->VertexAttrib3svARB) #define glVertexAttrib4NbvARB (_GET_TLS_PROCTABLE()->VertexAttrib4NbvARB) #define glVertexAttrib4NivARB (_GET_TLS_PROCTABLE()->VertexAttrib4NivARB) #define glVertexAttrib4NsvARB (_GET_TLS_PROCTABLE()->VertexAttrib4NsvARB) #define glVertexAttrib4NubARB (_GET_TLS_PROCTABLE()->VertexAttrib4NubARB) #define glVertexAttrib4NubvARB (_GET_TLS_PROCTABLE()->VertexAttrib4NubvARB) #define glVertexAttrib4NuivARB (_GET_TLS_PROCTABLE()->VertexAttrib4NuivARB) #define glVertexAttrib4NusvARB (_GET_TLS_PROCTABLE()->VertexAttrib4NusvARB) #define glVertexAttrib4bvARB (_GET_TLS_PROCTABLE()->VertexAttrib4bvARB) #define glVertexAttrib4dARB (_GET_TLS_PROCTABLE()->VertexAttrib4dARB) #define glVertexAttrib4dvARB (_GET_TLS_PROCTABLE()->VertexAttrib4dvARB) #define glVertexAttrib4fARB (_GET_TLS_PROCTABLE()->VertexAttrib4fARB) #define glVertexAttrib4fvARB (_GET_TLS_PROCTABLE()->VertexAttrib4fvARB) #define glVertexAttrib4ivARB (_GET_TLS_PROCTABLE()->VertexAttrib4ivARB) #define glVertexAttrib4sARB (_GET_TLS_PROCTABLE()->VertexAttrib4sARB) #define glVertexAttrib4svARB (_GET_TLS_PROCTABLE()->VertexAttrib4svARB) #define glVertexAttrib4ubvARB (_GET_TLS_PROCTABLE()->VertexAttrib4ubvARB) #define glVertexAttrib4uivARB (_GET_TLS_PROCTABLE()->VertexAttrib4uivARB) #define glVertexAttrib4usvARB (_GET_TLS_PROCTABLE()->VertexAttrib4usvARB) #define glVertexAttribPointerARB (_GET_TLS_PROCTABLE()->VertexAttribPointerARB) #define glEnableVertexAttribArrayARB (_GET_TLS_PROCTABLE()->EnableVertexAttribArrayARB) #define glDisableVertexAttribArrayARB (_GET_TLS_PROCTABLE()->DisableVertexAttribArrayARB) #define glProgramStringARB (_GET_TLS_PROCTABLE()->ProgramStringARB) #define glBindProgramARB (_GET_TLS_PROCTABLE()->BindProgramARB) #define glDeleteProgramsARB (_GET_TLS_PROCTABLE()->DeleteProgramsARB) #define glGenProgramsARB (_GET_TLS_PROCTABLE()->GenProgramsARB) #define glProgramEnvParameter4dARB (_GET_TLS_PROCTABLE()->ProgramEnvParameter4dARB) #define glProgramEnvParameter4dvARB (_GET_TLS_PROCTABLE()->ProgramEnvParameter4dvARB) #define glProgramEnvParameter4fARB (_GET_TLS_PROCTABLE()->ProgramEnvParameter4fARB) #define glProgramEnvParameter4fvARB (_GET_TLS_PROCTABLE()->ProgramEnvParameter4fvARB) #define glProgramLocalParameter4dARB (_GET_TLS_PROCTABLE()->ProgramLocalParameter4dARB) #define glProgramLocalParameter4dvARB (_GET_TLS_PROCTABLE()->ProgramLocalParameter4dvARB) #define glProgramLocalParameter4fARB (_GET_TLS_PROCTABLE()->ProgramLocalParameter4fARB) #define glProgramLocalParameter4fvARB (_GET_TLS_PROCTABLE()->ProgramLocalParameter4fvARB) #define glGetProgramEnvParameterdvARB (_GET_TLS_PROCTABLE()->GetProgramEnvParameterdvARB) #define glGetProgramEnvParameterfvARB (_GET_TLS_PROCTABLE()->GetProgramEnvParameterfvARB) #define glGetProgramLocalParameterdvARB (_GET_TLS_PROCTABLE()->GetProgramLocalParameterdvARB) #define glGetProgramLocalParameterfvARB (_GET_TLS_PROCTABLE()->GetProgramLocalParameterfvARB) #define glGetProgramivARB (_GET_TLS_PROCTABLE()->GetProgramivARB) #define glGetProgramStringARB (_GET_TLS_PROCTABLE()->GetProgramStringARB) #define glGetVertexAttribdvARB (_GET_TLS_PROCTABLE()->GetVertexAttribdvARB) #define glGetVertexAttribfvARB (_GET_TLS_PROCTABLE()->GetVertexAttribfvARB) #define glGetVertexAttribivARB (_GET_TLS_PROCTABLE()->GetVertexAttribivARB) #define glGetVertexAttribPointervARB (_GET_TLS_PROCTABLE()->GetVertexAttribPointervARB) #define glIsProgramARB (_GET_TLS_PROCTABLE()->IsProgramARB) #define glBindBufferARB (_GET_TLS_PROCTABLE()->BindBufferARB) #define glDeleteBuffersARB (_GET_TLS_PROCTABLE()->DeleteBuffersARB) #define glGenBuffersARB (_GET_TLS_PROCTABLE()->GenBuffersARB) #define glIsBufferARB (_GET_TLS_PROCTABLE()->IsBufferARB) #define glBufferDataARB (_GET_TLS_PROCTABLE()->BufferDataARB) #define glBufferSubDataARB (_GET_TLS_PROCTABLE()->BufferSubDataARB) #define glGetBufferSubDataARB (_GET_TLS_PROCTABLE()->GetBufferSubDataARB) #define glMapBufferARB (_GET_TLS_PROCTABLE()->MapBufferARB) #define glUnmapBufferARB (_GET_TLS_PROCTABLE()->UnmapBufferARB) #define glGetBufferParameterivARB (_GET_TLS_PROCTABLE()->GetBufferParameterivARB) #define glGetBufferPointervARB (_GET_TLS_PROCTABLE()->GetBufferPointervARB) #define glGenQueriesARB (_GET_TLS_PROCTABLE()->GenQueriesARB) #define glDeleteQueriesARB (_GET_TLS_PROCTABLE()->DeleteQueriesARB) #define glIsQueryARB (_GET_TLS_PROCTABLE()->IsQueryARB) #define glBeginQueryARB (_GET_TLS_PROCTABLE()->BeginQueryARB) #define glEndQueryARB (_GET_TLS_PROCTABLE()->EndQueryARB) #define glGetQueryivARB (_GET_TLS_PROCTABLE()->GetQueryivARB) #define glGetQueryObjectivARB (_GET_TLS_PROCTABLE()->GetQueryObjectivARB) #define glGetQueryObjectuivARB (_GET_TLS_PROCTABLE()->GetQueryObjectuivARB) #define glDeleteObjectARB (_GET_TLS_PROCTABLE()->DeleteObjectARB) #define glGetHandleARB (_GET_TLS_PROCTABLE()->GetHandleARB) #define glDetachObjectARB (_GET_TLS_PROCTABLE()->DetachObjectARB) #define glCreateShaderObjectARB (_GET_TLS_PROCTABLE()->CreateShaderObjectARB) #define glShaderSourceARB (_GET_TLS_PROCTABLE()->ShaderSourceARB) #define glCompileShaderARB (_GET_TLS_PROCTABLE()->CompileShaderARB) #define glCreateProgramObjectARB (_GET_TLS_PROCTABLE()->CreateProgramObjectARB) #define glAttachObjectARB (_GET_TLS_PROCTABLE()->AttachObjectARB) #define glLinkProgramARB (_GET_TLS_PROCTABLE()->LinkProgramARB) #define glUseProgramObjectARB (_GET_TLS_PROCTABLE()->UseProgramObjectARB) #define glValidateProgramARB (_GET_TLS_PROCTABLE()->ValidateProgramARB) #define glUniform1fARB (_GET_TLS_PROCTABLE()->Uniform1fARB) #define glUniform2fARB (_GET_TLS_PROCTABLE()->Uniform2fARB) #define glUniform3fARB (_GET_TLS_PROCTABLE()->Uniform3fARB) #define glUniform4fARB (_GET_TLS_PROCTABLE()->Uniform4fARB) #define glUniform1iARB (_GET_TLS_PROCTABLE()->Uniform1iARB) #define glUniform2iARB (_GET_TLS_PROCTABLE()->Uniform2iARB) #define glUniform3iARB (_GET_TLS_PROCTABLE()->Uniform3iARB) #define glUniform4iARB (_GET_TLS_PROCTABLE()->Uniform4iARB) #define glUniform1fvARB (_GET_TLS_PROCTABLE()->Uniform1fvARB) #define glUniform2fvARB (_GET_TLS_PROCTABLE()->Uniform2fvARB) #define glUniform3fvARB (_GET_TLS_PROCTABLE()->Uniform3fvARB) #define glUniform4fvARB (_GET_TLS_PROCTABLE()->Uniform4fvARB) #define glUniform1ivARB (_GET_TLS_PROCTABLE()->Uniform1ivARB) #define glUniform2ivARB (_GET_TLS_PROCTABLE()->Uniform2ivARB) #define glUniform3ivARB (_GET_TLS_PROCTABLE()->Uniform3ivARB) #define glUniform4ivARB (_GET_TLS_PROCTABLE()->Uniform4ivARB) #define glUniformMatrix2fvARB (_GET_TLS_PROCTABLE()->UniformMatrix2fvARB) #define glUniformMatrix3fvARB (_GET_TLS_PROCTABLE()->UniformMatrix3fvARB) #define glUniformMatrix4fvARB (_GET_TLS_PROCTABLE()->UniformMatrix4fvARB) #define glGetObjectParameterfvARB (_GET_TLS_PROCTABLE()->GetObjectParameterfvARB) #define glGetObjectParameterivARB (_GET_TLS_PROCTABLE()->GetObjectParameterivARB) #define glGetInfoLogARB (_GET_TLS_PROCTABLE()->GetInfoLogARB) #define glGetAttachedObjectsARB (_GET_TLS_PROCTABLE()->GetAttachedObjectsARB) #define glGetUniformLocationARB (_GET_TLS_PROCTABLE()->GetUniformLocationARB) #define glGetActiveUniformARB (_GET_TLS_PROCTABLE()->GetActiveUniformARB) #define glGetUniformfvARB (_GET_TLS_PROCTABLE()->GetUniformfvARB) #define glGetUniformivARB (_GET_TLS_PROCTABLE()->GetUniformivARB) #define glGetShaderSourceARB (_GET_TLS_PROCTABLE()->GetShaderSourceARB) #define glBindAttribLocationARB (_GET_TLS_PROCTABLE()->BindAttribLocationARB) #define glGetActiveAttribARB (_GET_TLS_PROCTABLE()->GetActiveAttribARB) #define glGetAttribLocationARB (_GET_TLS_PROCTABLE()->GetAttribLocationARB) #define glBlendColorEXT (_GET_TLS_PROCTABLE()->BlendColorEXT) #define glPolygonOffsetEXT (_GET_TLS_PROCTABLE()->PolygonOffsetEXT) #define glTexImage3DEXT (_GET_TLS_PROCTABLE()->TexImage3DEXT) #define glTexSubImage3DEXT (_GET_TLS_PROCTABLE()->TexSubImage3DEXT) #define glGetTexFilterFuncSGIS (_GET_TLS_PROCTABLE()->GetTexFilterFuncSGIS) #define glTexFilterFuncSGIS (_GET_TLS_PROCTABLE()->TexFilterFuncSGIS) #define glTexSubImage1DEXT (_GET_TLS_PROCTABLE()->TexSubImage1DEXT) #define glTexSubImage2DEXT (_GET_TLS_PROCTABLE()->TexSubImage2DEXT) #define glCopyTexImage1DEXT (_GET_TLS_PROCTABLE()->CopyTexImage1DEXT) #define glCopyTexImage2DEXT (_GET_TLS_PROCTABLE()->CopyTexImage2DEXT) #define glCopyTexSubImage1DEXT (_GET_TLS_PROCTABLE()->CopyTexSubImage1DEXT) #define glCopyTexSubImage2DEXT (_GET_TLS_PROCTABLE()->CopyTexSubImage2DEXT) #define glCopyTexSubImage3DEXT (_GET_TLS_PROCTABLE()->CopyTexSubImage3DEXT) #define glGetHistogramEXT (_GET_TLS_PROCTABLE()->GetHistogramEXT) #define glGetHistogramParameterfvEXT (_GET_TLS_PROCTABLE()->GetHistogramParameterfvEXT) #define glGetHistogramParameterivEXT (_GET_TLS_PROCTABLE()->GetHistogramParameterivEXT) #define glGetMinmaxEXT (_GET_TLS_PROCTABLE()->GetMinmaxEXT) #define glGetMinmaxParameterfvEXT (_GET_TLS_PROCTABLE()->GetMinmaxParameterfvEXT) #define glGetMinmaxParameterivEXT (_GET_TLS_PROCTABLE()->GetMinmaxParameterivEXT) #define glHistogramEXT (_GET_TLS_PROCTABLE()->HistogramEXT) #define glMinmaxEXT (_GET_TLS_PROCTABLE()->MinmaxEXT) #define glResetHistogramEXT (_GET_TLS_PROCTABLE()->ResetHistogramEXT) #define glResetMinmaxEXT (_GET_TLS_PROCTABLE()->ResetMinmaxEXT) #define glConvolutionFilter1DEXT (_GET_TLS_PROCTABLE()->ConvolutionFilter1DEXT) #define glConvolutionFilter2DEXT (_GET_TLS_PROCTABLE()->ConvolutionFilter2DEXT) #define glConvolutionParameterfEXT (_GET_TLS_PROCTABLE()->ConvolutionParameterfEXT) #define glConvolutionParameterfvEXT (_GET_TLS_PROCTABLE()->ConvolutionParameterfvEXT) #define glConvolutionParameteriEXT (_GET_TLS_PROCTABLE()->ConvolutionParameteriEXT) #define glConvolutionParameterivEXT (_GET_TLS_PROCTABLE()->ConvolutionParameterivEXT) #define glCopyConvolutionFilter1DEXT (_GET_TLS_PROCTABLE()->CopyConvolutionFilter1DEXT) #define glCopyConvolutionFilter2DEXT (_GET_TLS_PROCTABLE()->CopyConvolutionFilter2DEXT) #define glGetConvolutionFilterEXT (_GET_TLS_PROCTABLE()->GetConvolutionFilterEXT) #define glGetConvolutionParameterfvEXT (_GET_TLS_PROCTABLE()->GetConvolutionParameterfvEXT) #define glGetConvolutionParameterivEXT (_GET_TLS_PROCTABLE()->GetConvolutionParameterivEXT) #define glGetSeparableFilterEXT (_GET_TLS_PROCTABLE()->GetSeparableFilterEXT) #define glSeparableFilter2DEXT (_GET_TLS_PROCTABLE()->SeparableFilter2DEXT) #define glColorTableSGI (_GET_TLS_PROCTABLE()->ColorTableSGI) #define glColorTableParameterfvSGI (_GET_TLS_PROCTABLE()->ColorTableParameterfvSGI) #define glColorTableParameterivSGI (_GET_TLS_PROCTABLE()->ColorTableParameterivSGI) #define glCopyColorTableSGI (_GET_TLS_PROCTABLE()->CopyColorTableSGI) #define glGetColorTableSGI (_GET_TLS_PROCTABLE()->GetColorTableSGI) #define glGetColorTableParameterfvSGI (_GET_TLS_PROCTABLE()->GetColorTableParameterfvSGI) #define glGetColorTableParameterivSGI (_GET_TLS_PROCTABLE()->GetColorTableParameterivSGI) #define glPixelTexGenSGIX (_GET_TLS_PROCTABLE()->PixelTexGenSGIX) #define glPixelTexGenParameteriSGIS (_GET_TLS_PROCTABLE()->PixelTexGenParameteriSGIS) #define glPixelTexGenParameterivSGIS (_GET_TLS_PROCTABLE()->PixelTexGenParameterivSGIS) #define glPixelTexGenParameterfSGIS (_GET_TLS_PROCTABLE()->PixelTexGenParameterfSGIS) #define glPixelTexGenParameterfvSGIS (_GET_TLS_PROCTABLE()->PixelTexGenParameterfvSGIS) #define glGetPixelTexGenParameterivSGIS (_GET_TLS_PROCTABLE()->GetPixelTexGenParameterivSGIS) #define glGetPixelTexGenParameterfvSGIS (_GET_TLS_PROCTABLE()->GetPixelTexGenParameterfvSGIS) #define glTexImage4DSGIS (_GET_TLS_PROCTABLE()->TexImage4DSGIS) #define glTexSubImage4DSGIS (_GET_TLS_PROCTABLE()->TexSubImage4DSGIS) #define glAreTexturesResidentEXT (_GET_TLS_PROCTABLE()->AreTexturesResidentEXT) #define glBindTextureEXT (_GET_TLS_PROCTABLE()->BindTextureEXT) #define glDeleteTexturesEXT (_GET_TLS_PROCTABLE()->DeleteTexturesEXT) #define glGenTexturesEXT (_GET_TLS_PROCTABLE()->GenTexturesEXT) #define glIsTextureEXT (_GET_TLS_PROCTABLE()->IsTextureEXT) #define glPrioritizeTexturesEXT (_GET_TLS_PROCTABLE()->PrioritizeTexturesEXT) #define glDetailTexFuncSGIS (_GET_TLS_PROCTABLE()->DetailTexFuncSGIS) #define glGetDetailTexFuncSGIS (_GET_TLS_PROCTABLE()->GetDetailTexFuncSGIS) #define glSharpenTexFuncSGIS (_GET_TLS_PROCTABLE()->SharpenTexFuncSGIS) #define glGetSharpenTexFuncSGIS (_GET_TLS_PROCTABLE()->GetSharpenTexFuncSGIS) #define glSampleMaskSGIS (_GET_TLS_PROCTABLE()->SampleMaskSGIS) #define glSamplePatternSGIS (_GET_TLS_PROCTABLE()->SamplePatternSGIS) #define glArrayElementEXT (_GET_TLS_PROCTABLE()->ArrayElementEXT) #define glColorPointerEXT (_GET_TLS_PROCTABLE()->ColorPointerEXT) #define glDrawArraysEXT (_GET_TLS_PROCTABLE()->DrawArraysEXT) #define glEdgeFlagPointerEXT (_GET_TLS_PROCTABLE()->EdgeFlagPointerEXT) #define glGetPointervEXT (_GET_TLS_PROCTABLE()->GetPointervEXT) #define glIndexPointerEXT (_GET_TLS_PROCTABLE()->IndexPointerEXT) #define glNormalPointerEXT (_GET_TLS_PROCTABLE()->NormalPointerEXT) #define glTexCoordPointerEXT (_GET_TLS_PROCTABLE()->TexCoordPointerEXT) #define glVertexPointerEXT (_GET_TLS_PROCTABLE()->VertexPointerEXT) #define glBlendEquationEXT (_GET_TLS_PROCTABLE()->BlendEquationEXT) #define glSpriteParameterfSGIX (_GET_TLS_PROCTABLE()->SpriteParameterfSGIX) #define glSpriteParameterfvSGIX (_GET_TLS_PROCTABLE()->SpriteParameterfvSGIX) #define glSpriteParameteriSGIX (_GET_TLS_PROCTABLE()->SpriteParameteriSGIX) #define glSpriteParameterivSGIX (_GET_TLS_PROCTABLE()->SpriteParameterivSGIX) #define glPointParameterfEXT (_GET_TLS_PROCTABLE()->PointParameterfEXT) #define glPointParameterfvEXT (_GET_TLS_PROCTABLE()->PointParameterfvEXT) #define glPointParameterfSGIS (_GET_TLS_PROCTABLE()->PointParameterfSGIS) #define glPointParameterfvSGIS (_GET_TLS_PROCTABLE()->PointParameterfvSGIS) #define glGetInstrumentsSGIX (_GET_TLS_PROCTABLE()->GetInstrumentsSGIX) #define glInstrumentsBufferSGIX (_GET_TLS_PROCTABLE()->InstrumentsBufferSGIX) #define glPollInstrumentsSGIX (_GET_TLS_PROCTABLE()->PollInstrumentsSGIX) #define glReadInstrumentsSGIX (_GET_TLS_PROCTABLE()->ReadInstrumentsSGIX) #define glStartInstrumentsSGIX (_GET_TLS_PROCTABLE()->StartInstrumentsSGIX) #define glStopInstrumentsSGIX (_GET_TLS_PROCTABLE()->StopInstrumentsSGIX) #define glFrameZoomSGIX (_GET_TLS_PROCTABLE()->FrameZoomSGIX) #define glTagSampleBufferSGIX (_GET_TLS_PROCTABLE()->TagSampleBufferSGIX) #define glDeformationMap3dSGIX (_GET_TLS_PROCTABLE()->DeformationMap3dSGIX) #define glDeformationMap3fSGIX (_GET_TLS_PROCTABLE()->DeformationMap3fSGIX) #define glDeformSGIX (_GET_TLS_PROCTABLE()->DeformSGIX) #define glLoadIdentityDeformationMapSGIX (_GET_TLS_PROCTABLE()->LoadIdentityDeformationMapSGIX) #define glReferencePlaneSGIX (_GET_TLS_PROCTABLE()->ReferencePlaneSGIX) #define glFlushRasterSGIX (_GET_TLS_PROCTABLE()->FlushRasterSGIX) #define glFogFuncSGIS (_GET_TLS_PROCTABLE()->FogFuncSGIS) #define glGetFogFuncSGIS (_GET_TLS_PROCTABLE()->GetFogFuncSGIS) #define glImageTransformParameteriHP (_GET_TLS_PROCTABLE()->ImageTransformParameteriHP) #define glImageTransformParameterfHP (_GET_TLS_PROCTABLE()->ImageTransformParameterfHP) #define glImageTransformParameterivHP (_GET_TLS_PROCTABLE()->ImageTransformParameterivHP) #define glImageTransformParameterfvHP (_GET_TLS_PROCTABLE()->ImageTransformParameterfvHP) #define glGetImageTransformParameterivHP (_GET_TLS_PROCTABLE()->GetImageTransformParameterivHP) #define glGetImageTransformParameterfvHP (_GET_TLS_PROCTABLE()->GetImageTransformParameterfvHP) #define glColorSubTableEXT (_GET_TLS_PROCTABLE()->ColorSubTableEXT) #define glCopyColorSubTableEXT (_GET_TLS_PROCTABLE()->CopyColorSubTableEXT) #define glHintPGI (_GET_TLS_PROCTABLE()->HintPGI) #define glColorTableEXT (_GET_TLS_PROCTABLE()->ColorTableEXT) #define glGetColorTableEXT (_GET_TLS_PROCTABLE()->GetColorTableEXT) #define glGetColorTableParameterivEXT (_GET_TLS_PROCTABLE()->GetColorTableParameterivEXT) #define glGetColorTableParameterfvEXT (_GET_TLS_PROCTABLE()->GetColorTableParameterfvEXT) #define glGetListParameterfvSGIX (_GET_TLS_PROCTABLE()->GetListParameterfvSGIX) #define glGetListParameterivSGIX (_GET_TLS_PROCTABLE()->GetListParameterivSGIX) #define glListParameterfSGIX (_GET_TLS_PROCTABLE()->ListParameterfSGIX) #define glListParameterfvSGIX (_GET_TLS_PROCTABLE()->ListParameterfvSGIX) #define glListParameteriSGIX (_GET_TLS_PROCTABLE()->ListParameteriSGIX) #define glListParameterivSGIX (_GET_TLS_PROCTABLE()->ListParameterivSGIX) #define glIndexMaterialEXT (_GET_TLS_PROCTABLE()->IndexMaterialEXT) #define glIndexFuncEXT (_GET_TLS_PROCTABLE()->IndexFuncEXT) #define glLockArraysEXT (_GET_TLS_PROCTABLE()->LockArraysEXT) #define glUnlockArraysEXT (_GET_TLS_PROCTABLE()->UnlockArraysEXT) #define glCullParameterdvEXT (_GET_TLS_PROCTABLE()->CullParameterdvEXT) #define glCullParameterfvEXT (_GET_TLS_PROCTABLE()->CullParameterfvEXT) #define glFragmentColorMaterialSGIX (_GET_TLS_PROCTABLE()->FragmentColorMaterialSGIX) #define glFragmentLightfSGIX (_GET_TLS_PROCTABLE()->FragmentLightfSGIX) #define glFragmentLightfvSGIX (_GET_TLS_PROCTABLE()->FragmentLightfvSGIX) #define glFragmentLightiSGIX (_GET_TLS_PROCTABLE()->FragmentLightiSGIX) #define glFragmentLightivSGIX (_GET_TLS_PROCTABLE()->FragmentLightivSGIX) #define glFragmentLightModelfSGIX (_GET_TLS_PROCTABLE()->FragmentLightModelfSGIX) #define glFragmentLightModelfvSGIX (_GET_TLS_PROCTABLE()->FragmentLightModelfvSGIX) #define glFragmentLightModeliSGIX (_GET_TLS_PROCTABLE()->FragmentLightModeliSGIX) #define glFragmentLightModelivSGIX (_GET_TLS_PROCTABLE()->FragmentLightModelivSGIX) #define glFragmentMaterialfSGIX (_GET_TLS_PROCTABLE()->FragmentMaterialfSGIX) #define glFragmentMaterialfvSGIX (_GET_TLS_PROCTABLE()->FragmentMaterialfvSGIX) #define glFragmentMaterialiSGIX (_GET_TLS_PROCTABLE()->FragmentMaterialiSGIX) #define glFragmentMaterialivSGIX (_GET_TLS_PROCTABLE()->FragmentMaterialivSGIX) #define glGetFragmentLightfvSGIX (_GET_TLS_PROCTABLE()->GetFragmentLightfvSGIX) #define glGetFragmentLightivSGIX (_GET_TLS_PROCTABLE()->GetFragmentLightivSGIX) #define glGetFragmentMaterialfvSGIX (_GET_TLS_PROCTABLE()->GetFragmentMaterialfvSGIX) #define glGetFragmentMaterialivSGIX (_GET_TLS_PROCTABLE()->GetFragmentMaterialivSGIX) #define glLightEnviSGIX (_GET_TLS_PROCTABLE()->LightEnviSGIX) #define glDrawRangeElementsEXT (_GET_TLS_PROCTABLE()->DrawRangeElementsEXT) #define glApplyTextureEXT (_GET_TLS_PROCTABLE()->ApplyTextureEXT) #define glTextureLightEXT (_GET_TLS_PROCTABLE()->TextureLightEXT) #define glTextureMaterialEXT (_GET_TLS_PROCTABLE()->TextureMaterialEXT) #define glAsyncMarkerSGIX (_GET_TLS_PROCTABLE()->AsyncMarkerSGIX) #define glFinishAsyncSGIX (_GET_TLS_PROCTABLE()->FinishAsyncSGIX) #define glPollAsyncSGIX (_GET_TLS_PROCTABLE()->PollAsyncSGIX) #define glGenAsyncMarkersSGIX (_GET_TLS_PROCTABLE()->GenAsyncMarkersSGIX) #define glDeleteAsyncMarkersSGIX (_GET_TLS_PROCTABLE()->DeleteAsyncMarkersSGIX) #define glIsAsyncMarkerSGIX (_GET_TLS_PROCTABLE()->IsAsyncMarkerSGIX) #define glVertexPointervINTEL (_GET_TLS_PROCTABLE()->VertexPointervINTEL) #define glNormalPointervINTEL (_GET_TLS_PROCTABLE()->NormalPointervINTEL) #define glColorPointervINTEL (_GET_TLS_PROCTABLE()->ColorPointervINTEL) #define glTexCoordPointervINTEL (_GET_TLS_PROCTABLE()->TexCoordPointervINTEL) #define glPixelTransformParameteriEXT (_GET_TLS_PROCTABLE()->PixelTransformParameteriEXT) #define glPixelTransformParameterfEXT (_GET_TLS_PROCTABLE()->PixelTransformParameterfEXT) #define glPixelTransformParameterivEXT (_GET_TLS_PROCTABLE()->PixelTransformParameterivEXT) #define glPixelTransformParameterfvEXT (_GET_TLS_PROCTABLE()->PixelTransformParameterfvEXT) #define glSecondaryColor3bEXT (_GET_TLS_PROCTABLE()->SecondaryColor3bEXT) #define glSecondaryColor3bvEXT (_GET_TLS_PROCTABLE()->SecondaryColor3bvEXT) #define glSecondaryColor3dEXT (_GET_TLS_PROCTABLE()->SecondaryColor3dEXT) #define glSecondaryColor3dvEXT (_GET_TLS_PROCTABLE()->SecondaryColor3dvEXT) #define glSecondaryColor3fEXT (_GET_TLS_PROCTABLE()->SecondaryColor3fEXT) #define glSecondaryColor3fvEXT (_GET_TLS_PROCTABLE()->SecondaryColor3fvEXT) #define glSecondaryColor3iEXT (_GET_TLS_PROCTABLE()->SecondaryColor3iEXT) #define glSecondaryColor3ivEXT (_GET_TLS_PROCTABLE()->SecondaryColor3ivEXT) #define glSecondaryColor3sEXT (_GET_TLS_PROCTABLE()->SecondaryColor3sEXT) #define glSecondaryColor3svEXT (_GET_TLS_PROCTABLE()->SecondaryColor3svEXT) #define glSecondaryColor3ubEXT (_GET_TLS_PROCTABLE()->SecondaryColor3ubEXT) #define glSecondaryColor3ubvEXT (_GET_TLS_PROCTABLE()->SecondaryColor3ubvEXT) #define glSecondaryColor3uiEXT (_GET_TLS_PROCTABLE()->SecondaryColor3uiEXT) #define glSecondaryColor3uivEXT (_GET_TLS_PROCTABLE()->SecondaryColor3uivEXT) #define glSecondaryColor3usEXT (_GET_TLS_PROCTABLE()->SecondaryColor3usEXT) #define glSecondaryColor3usvEXT (_GET_TLS_PROCTABLE()->SecondaryColor3usvEXT) #define glSecondaryColorPointerEXT (_GET_TLS_PROCTABLE()->SecondaryColorPointerEXT) #define glTextureNormalEXT (_GET_TLS_PROCTABLE()->TextureNormalEXT) #define glMultiDrawArraysEXT (_GET_TLS_PROCTABLE()->MultiDrawArraysEXT) #define glMultiDrawElementsEXT (_GET_TLS_PROCTABLE()->MultiDrawElementsEXT) #define glFogCoordfEXT (_GET_TLS_PROCTABLE()->FogCoordfEXT) #define glFogCoordfvEXT (_GET_TLS_PROCTABLE()->FogCoordfvEXT) #define glFogCoorddEXT (_GET_TLS_PROCTABLE()->FogCoorddEXT) #define glFogCoorddvEXT (_GET_TLS_PROCTABLE()->FogCoorddvEXT) #define glFogCoordPointerEXT (_GET_TLS_PROCTABLE()->FogCoordPointerEXT) #define glTangent3bEXT (_GET_TLS_PROCTABLE()->Tangent3bEXT) #define glTangent3bvEXT (_GET_TLS_PROCTABLE()->Tangent3bvEXT) #define glTangent3dEXT (_GET_TLS_PROCTABLE()->Tangent3dEXT) #define glTangent3dvEXT (_GET_TLS_PROCTABLE()->Tangent3dvEXT) #define glTangent3fEXT (_GET_TLS_PROCTABLE()->Tangent3fEXT) #define glTangent3fvEXT (_GET_TLS_PROCTABLE()->Tangent3fvEXT) #define glTangent3iEXT (_GET_TLS_PROCTABLE()->Tangent3iEXT) #define glTangent3ivEXT (_GET_TLS_PROCTABLE()->Tangent3ivEXT) #define glTangent3sEXT (_GET_TLS_PROCTABLE()->Tangent3sEXT) #define glTangent3svEXT (_GET_TLS_PROCTABLE()->Tangent3svEXT) #define glBinormal3bEXT (_GET_TLS_PROCTABLE()->Binormal3bEXT) #define glBinormal3bvEXT (_GET_TLS_PROCTABLE()->Binormal3bvEXT) #define glBinormal3dEXT (_GET_TLS_PROCTABLE()->Binormal3dEXT) #define glBinormal3dvEXT (_GET_TLS_PROCTABLE()->Binormal3dvEXT) #define glBinormal3fEXT (_GET_TLS_PROCTABLE()->Binormal3fEXT) #define glBinormal3fvEXT (_GET_TLS_PROCTABLE()->Binormal3fvEXT) #define glBinormal3iEXT (_GET_TLS_PROCTABLE()->Binormal3iEXT) #define glBinormal3ivEXT (_GET_TLS_PROCTABLE()->Binormal3ivEXT) #define glBinormal3sEXT (_GET_TLS_PROCTABLE()->Binormal3sEXT) #define glBinormal3svEXT (_GET_TLS_PROCTABLE()->Binormal3svEXT) #define glTangentPointerEXT (_GET_TLS_PROCTABLE()->TangentPointerEXT) #define glBinormalPointerEXT (_GET_TLS_PROCTABLE()->BinormalPointerEXT) #define glFinishTextureSUNX (_GET_TLS_PROCTABLE()->FinishTextureSUNX) #define glGlobalAlphaFactorbSUN (_GET_TLS_PROCTABLE()->GlobalAlphaFactorbSUN) #define glGlobalAlphaFactorsSUN (_GET_TLS_PROCTABLE()->GlobalAlphaFactorsSUN) #define glGlobalAlphaFactoriSUN (_GET_TLS_PROCTABLE()->GlobalAlphaFactoriSUN) #define glGlobalAlphaFactorfSUN (_GET_TLS_PROCTABLE()->GlobalAlphaFactorfSUN) #define glGlobalAlphaFactordSUN (_GET_TLS_PROCTABLE()->GlobalAlphaFactordSUN) #define glGlobalAlphaFactorubSUN (_GET_TLS_PROCTABLE()->GlobalAlphaFactorubSUN) #define glGlobalAlphaFactorusSUN (_GET_TLS_PROCTABLE()->GlobalAlphaFactorusSUN) #define glGlobalAlphaFactoruiSUN (_GET_TLS_PROCTABLE()->GlobalAlphaFactoruiSUN) #define glReplacementCodeuiSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuiSUN) #define glReplacementCodeusSUN (_GET_TLS_PROCTABLE()->ReplacementCodeusSUN) #define glReplacementCodeubSUN (_GET_TLS_PROCTABLE()->ReplacementCodeubSUN) #define glReplacementCodeuivSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuivSUN) #define glReplacementCodeusvSUN (_GET_TLS_PROCTABLE()->ReplacementCodeusvSUN) #define glReplacementCodeubvSUN (_GET_TLS_PROCTABLE()->ReplacementCodeubvSUN) #define glReplacementCodePointerSUN (_GET_TLS_PROCTABLE()->ReplacementCodePointerSUN) #define glColor4ubVertex2fSUN (_GET_TLS_PROCTABLE()->Color4ubVertex2fSUN) #define glColor4ubVertex2fvSUN (_GET_TLS_PROCTABLE()->Color4ubVertex2fvSUN) #define glColor4ubVertex3fSUN (_GET_TLS_PROCTABLE()->Color4ubVertex3fSUN) #define glColor4ubVertex3fvSUN (_GET_TLS_PROCTABLE()->Color4ubVertex3fvSUN) #define glColor3fVertex3fSUN (_GET_TLS_PROCTABLE()->Color3fVertex3fSUN) #define glColor3fVertex3fvSUN (_GET_TLS_PROCTABLE()->Color3fVertex3fvSUN) #define glNormal3fVertex3fSUN (_GET_TLS_PROCTABLE()->Normal3fVertex3fSUN) #define glNormal3fVertex3fvSUN (_GET_TLS_PROCTABLE()->Normal3fVertex3fvSUN) #define glColor4fNormal3fVertex3fSUN (_GET_TLS_PROCTABLE()->Color4fNormal3fVertex3fSUN) #define glColor4fNormal3fVertex3fvSUN (_GET_TLS_PROCTABLE()->Color4fNormal3fVertex3fvSUN) #define glTexCoord2fVertex3fSUN (_GET_TLS_PROCTABLE()->TexCoord2fVertex3fSUN) #define glTexCoord2fVertex3fvSUN (_GET_TLS_PROCTABLE()->TexCoord2fVertex3fvSUN) #define glTexCoord4fVertex4fSUN (_GET_TLS_PROCTABLE()->TexCoord4fVertex4fSUN) #define glTexCoord4fVertex4fvSUN (_GET_TLS_PROCTABLE()->TexCoord4fVertex4fvSUN) #define glTexCoord2fColor4ubVertex3fSUN (_GET_TLS_PROCTABLE()->TexCoord2fColor4ubVertex3fSUN) #define glTexCoord2fColor4ubVertex3fvSUN (_GET_TLS_PROCTABLE()->TexCoord2fColor4ubVertex3fvSUN) #define glTexCoord2fColor3fVertex3fSUN (_GET_TLS_PROCTABLE()->TexCoord2fColor3fVertex3fSUN) #define glTexCoord2fColor3fVertex3fvSUN (_GET_TLS_PROCTABLE()->TexCoord2fColor3fVertex3fvSUN) #define glTexCoord2fNormal3fVertex3fSUN (_GET_TLS_PROCTABLE()->TexCoord2fNormal3fVertex3fSUN) #define glTexCoord2fNormal3fVertex3fvSUN (_GET_TLS_PROCTABLE()->TexCoord2fNormal3fVertex3fvSUN) #define glTexCoord2fColor4fNormal3fVertex3fSUN (_GET_TLS_PROCTABLE()->TexCoord2fColor4fNormal3fVertex3fSUN) #define glTexCoord2fColor4fNormal3fVertex3fvSUN (_GET_TLS_PROCTABLE()->TexCoord2fColor4fNormal3fVertex3fvSUN) #define glTexCoord4fColor4fNormal3fVertex4fSUN (_GET_TLS_PROCTABLE()->TexCoord4fColor4fNormal3fVertex4fSUN) #define glTexCoord4fColor4fNormal3fVertex4fvSUN (_GET_TLS_PROCTABLE()->TexCoord4fColor4fNormal3fVertex4fvSUN) #define glReplacementCodeuiVertex3fSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuiVertex3fSUN) #define glReplacementCodeuiVertex3fvSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuiVertex3fvSUN) #define glReplacementCodeuiColor4ubVertex3fSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuiColor4ubVertex3fSUN) #define glReplacementCodeuiColor4ubVertex3fvSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuiColor4ubVertex3fvSUN) #define glReplacementCodeuiColor3fVertex3fSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuiColor3fVertex3fSUN) #define glReplacementCodeuiColor3fVertex3fvSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuiColor3fVertex3fvSUN) #define glReplacementCodeuiNormal3fVertex3fSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuiNormal3fVertex3fSUN) #define glReplacementCodeuiNormal3fVertex3fvSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuiNormal3fVertex3fvSUN) #define glReplacementCodeuiColor4fNormal3fVertex3fSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuiColor4fNormal3fVertex3fSUN) #define glReplacementCodeuiColor4fNormal3fVertex3fvSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuiColor4fNormal3fVertex3fvSUN) #define glReplacementCodeuiTexCoord2fVertex3fSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuiTexCoord2fVertex3fSUN) #define glReplacementCodeuiTexCoord2fVertex3fvSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuiTexCoord2fVertex3fvSUN) #define glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN) #define glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN) #define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN) #define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (_GET_TLS_PROCTABLE()->ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN) #define glBlendFuncSeparateEXT (_GET_TLS_PROCTABLE()->BlendFuncSeparateEXT) #define glBlendFuncSeparateINGR (_GET_TLS_PROCTABLE()->BlendFuncSeparateINGR) #define glVertexWeightfEXT (_GET_TLS_PROCTABLE()->VertexWeightfEXT) #define glVertexWeightfvEXT (_GET_TLS_PROCTABLE()->VertexWeightfvEXT) #define glVertexWeightPointerEXT (_GET_TLS_PROCTABLE()->VertexWeightPointerEXT) #define glFlushVertexArrayRangeNV (_GET_TLS_PROCTABLE()->FlushVertexArrayRangeNV) #define glVertexArrayRangeNV (_GET_TLS_PROCTABLE()->VertexArrayRangeNV) #define glCombinerParameterfvNV (_GET_TLS_PROCTABLE()->CombinerParameterfvNV) #define glCombinerParameterfNV (_GET_TLS_PROCTABLE()->CombinerParameterfNV) #define glCombinerParameterivNV (_GET_TLS_PROCTABLE()->CombinerParameterivNV) #define glCombinerParameteriNV (_GET_TLS_PROCTABLE()->CombinerParameteriNV) #define glCombinerInputNV (_GET_TLS_PROCTABLE()->CombinerInputNV) #define glCombinerOutputNV (_GET_TLS_PROCTABLE()->CombinerOutputNV) #define glFinalCombinerInputNV (_GET_TLS_PROCTABLE()->FinalCombinerInputNV) #define glGetCombinerInputParameterfvNV (_GET_TLS_PROCTABLE()->GetCombinerInputParameterfvNV) #define glGetCombinerInputParameterivNV (_GET_TLS_PROCTABLE()->GetCombinerInputParameterivNV) #define glGetCombinerOutputParameterfvNV (_GET_TLS_PROCTABLE()->GetCombinerOutputParameterfvNV) #define glGetCombinerOutputParameterivNV (_GET_TLS_PROCTABLE()->GetCombinerOutputParameterivNV) #define glGetFinalCombinerInputParameterfvNV (_GET_TLS_PROCTABLE()->GetFinalCombinerInputParameterfvNV) #define glGetFinalCombinerInputParameterivNV (_GET_TLS_PROCTABLE()->GetFinalCombinerInputParameterivNV) #define glResizeBuffersMESA (_GET_TLS_PROCTABLE()->ResizeBuffersMESA) #define glWindowPos2dMESA (_GET_TLS_PROCTABLE()->WindowPos2dMESA) #define glWindowPos2dvMESA (_GET_TLS_PROCTABLE()->WindowPos2dvMESA) #define glWindowPos2fMESA (_GET_TLS_PROCTABLE()->WindowPos2fMESA) #define glWindowPos2fvMESA (_GET_TLS_PROCTABLE()->WindowPos2fvMESA) #define glWindowPos2iMESA (_GET_TLS_PROCTABLE()->WindowPos2iMESA) #define glWindowPos2ivMESA (_GET_TLS_PROCTABLE()->WindowPos2ivMESA) #define glWindowPos2sMESA (_GET_TLS_PROCTABLE()->WindowPos2sMESA) #define glWindowPos2svMESA (_GET_TLS_PROCTABLE()->WindowPos2svMESA) #define glWindowPos3dMESA (_GET_TLS_PROCTABLE()->WindowPos3dMESA) #define glWindowPos3dvMESA (_GET_TLS_PROCTABLE()->WindowPos3dvMESA) #define glWindowPos3fMESA (_GET_TLS_PROCTABLE()->WindowPos3fMESA) #define glWindowPos3fvMESA (_GET_TLS_PROCTABLE()->WindowPos3fvMESA) #define glWindowPos3iMESA (_GET_TLS_PROCTABLE()->WindowPos3iMESA) #define glWindowPos3ivMESA (_GET_TLS_PROCTABLE()->WindowPos3ivMESA) #define glWindowPos3sMESA (_GET_TLS_PROCTABLE()->WindowPos3sMESA) #define glWindowPos3svMESA (_GET_TLS_PROCTABLE()->WindowPos3svMESA) #define glWindowPos4dMESA (_GET_TLS_PROCTABLE()->WindowPos4dMESA) #define glWindowPos4dvMESA (_GET_TLS_PROCTABLE()->WindowPos4dvMESA) #define glWindowPos4fMESA (_GET_TLS_PROCTABLE()->WindowPos4fMESA) #define glWindowPos4fvMESA (_GET_TLS_PROCTABLE()->WindowPos4fvMESA) #define glWindowPos4iMESA (_GET_TLS_PROCTABLE()->WindowPos4iMESA) #define glWindowPos4ivMESA (_GET_TLS_PROCTABLE()->WindowPos4ivMESA) #define glWindowPos4sMESA (_GET_TLS_PROCTABLE()->WindowPos4sMESA) #define glWindowPos4svMESA (_GET_TLS_PROCTABLE()->WindowPos4svMESA) #define glMultiModeDrawArraysIBM (_GET_TLS_PROCTABLE()->MultiModeDrawArraysIBM) #define glMultiModeDrawElementsIBM (_GET_TLS_PROCTABLE()->MultiModeDrawElementsIBM) #define glColorPointerListIBM (_GET_TLS_PROCTABLE()->ColorPointerListIBM) #define glSecondaryColorPointerListIBM (_GET_TLS_PROCTABLE()->SecondaryColorPointerListIBM) #define glEdgeFlagPointerListIBM (_GET_TLS_PROCTABLE()->EdgeFlagPointerListIBM) #define glFogCoordPointerListIBM (_GET_TLS_PROCTABLE()->FogCoordPointerListIBM) #define glIndexPointerListIBM (_GET_TLS_PROCTABLE()->IndexPointerListIBM) #define glNormalPointerListIBM (_GET_TLS_PROCTABLE()->NormalPointerListIBM) #define glTexCoordPointerListIBM (_GET_TLS_PROCTABLE()->TexCoordPointerListIBM) #define glVertexPointerListIBM (_GET_TLS_PROCTABLE()->VertexPointerListIBM) #define glTbufferMask3DFX (_GET_TLS_PROCTABLE()->TbufferMask3DFX) #define glSampleMaskEXT (_GET_TLS_PROCTABLE()->SampleMaskEXT) #define glSamplePatternEXT (_GET_TLS_PROCTABLE()->SamplePatternEXT) #define glTextureColorMaskSGIS (_GET_TLS_PROCTABLE()->TextureColorMaskSGIS) #define glIglooInterfaceSGIX (_GET_TLS_PROCTABLE()->IglooInterfaceSGIX) #define glDeleteFencesNV (_GET_TLS_PROCTABLE()->DeleteFencesNV) #define glGenFencesNV (_GET_TLS_PROCTABLE()->GenFencesNV) #define glIsFenceNV (_GET_TLS_PROCTABLE()->IsFenceNV) #define glTestFenceNV (_GET_TLS_PROCTABLE()->TestFenceNV) #define glGetFenceivNV (_GET_TLS_PROCTABLE()->GetFenceivNV) #define glFinishFenceNV (_GET_TLS_PROCTABLE()->FinishFenceNV) #define glSetFenceNV (_GET_TLS_PROCTABLE()->SetFenceNV) #define glMapControlPointsNV (_GET_TLS_PROCTABLE()->MapControlPointsNV) #define glMapParameterivNV (_GET_TLS_PROCTABLE()->MapParameterivNV) #define glMapParameterfvNV (_GET_TLS_PROCTABLE()->MapParameterfvNV) #define glGetMapControlPointsNV (_GET_TLS_PROCTABLE()->GetMapControlPointsNV) #define glGetMapParameterivNV (_GET_TLS_PROCTABLE()->GetMapParameterivNV) #define glGetMapParameterfvNV (_GET_TLS_PROCTABLE()->GetMapParameterfvNV) #define glGetMapAttribParameterivNV (_GET_TLS_PROCTABLE()->GetMapAttribParameterivNV) #define glGetMapAttribParameterfvNV (_GET_TLS_PROCTABLE()->GetMapAttribParameterfvNV) #define glEvalMapsNV (_GET_TLS_PROCTABLE()->EvalMapsNV) #define glCombinerStageParameterfvNV (_GET_TLS_PROCTABLE()->CombinerStageParameterfvNV) #define glGetCombinerStageParameterfvNV (_GET_TLS_PROCTABLE()->GetCombinerStageParameterfvNV) #define glAreProgramsResidentNV (_GET_TLS_PROCTABLE()->AreProgramsResidentNV) #define glBindProgramNV (_GET_TLS_PROCTABLE()->BindProgramNV) #define glDeleteProgramsNV (_GET_TLS_PROCTABLE()->DeleteProgramsNV) #define glExecuteProgramNV (_GET_TLS_PROCTABLE()->ExecuteProgramNV) #define glGenProgramsNV (_GET_TLS_PROCTABLE()->GenProgramsNV) #define glGetProgramParameterdvNV (_GET_TLS_PROCTABLE()->GetProgramParameterdvNV) #define glGetProgramParameterfvNV (_GET_TLS_PROCTABLE()->GetProgramParameterfvNV) #define glGetProgramivNV (_GET_TLS_PROCTABLE()->GetProgramivNV) #define glGetProgramStringNV (_GET_TLS_PROCTABLE()->GetProgramStringNV) #define glGetTrackMatrixivNV (_GET_TLS_PROCTABLE()->GetTrackMatrixivNV) #define glGetVertexAttribdvNV (_GET_TLS_PROCTABLE()->GetVertexAttribdvNV) #define glGetVertexAttribfvNV (_GET_TLS_PROCTABLE()->GetVertexAttribfvNV) #define glGetVertexAttribivNV (_GET_TLS_PROCTABLE()->GetVertexAttribivNV) #define glGetVertexAttribPointervNV (_GET_TLS_PROCTABLE()->GetVertexAttribPointervNV) #define glIsProgramNV (_GET_TLS_PROCTABLE()->IsProgramNV) #define glLoadProgramNV (_GET_TLS_PROCTABLE()->LoadProgramNV) #define glProgramParameter4dNV (_GET_TLS_PROCTABLE()->ProgramParameter4dNV) #define glProgramParameter4dvNV (_GET_TLS_PROCTABLE()->ProgramParameter4dvNV) #define glProgramParameter4fNV (_GET_TLS_PROCTABLE()->ProgramParameter4fNV) #define glProgramParameter4fvNV (_GET_TLS_PROCTABLE()->ProgramParameter4fvNV) #define glProgramParameters4dvNV (_GET_TLS_PROCTABLE()->ProgramParameters4dvNV) #define glProgramParameters4fvNV (_GET_TLS_PROCTABLE()->ProgramParameters4fvNV) #define glRequestResidentProgramsNV (_GET_TLS_PROCTABLE()->RequestResidentProgramsNV) #define glTrackMatrixNV (_GET_TLS_PROCTABLE()->TrackMatrixNV) #define glVertexAttribPointerNV (_GET_TLS_PROCTABLE()->VertexAttribPointerNV) #define glVertexAttrib1dNV (_GET_TLS_PROCTABLE()->VertexAttrib1dNV) #define glVertexAttrib1dvNV (_GET_TLS_PROCTABLE()->VertexAttrib1dvNV) #define glVertexAttrib1fNV (_GET_TLS_PROCTABLE()->VertexAttrib1fNV) #define glVertexAttrib1fvNV (_GET_TLS_PROCTABLE()->VertexAttrib1fvNV) #define glVertexAttrib1sNV (_GET_TLS_PROCTABLE()->VertexAttrib1sNV) #define glVertexAttrib1svNV (_GET_TLS_PROCTABLE()->VertexAttrib1svNV) #define glVertexAttrib2dNV (_GET_TLS_PROCTABLE()->VertexAttrib2dNV) #define glVertexAttrib2dvNV (_GET_TLS_PROCTABLE()->VertexAttrib2dvNV) #define glVertexAttrib2fNV (_GET_TLS_PROCTABLE()->VertexAttrib2fNV) #define glVertexAttrib2fvNV (_GET_TLS_PROCTABLE()->VertexAttrib2fvNV) #define glVertexAttrib2sNV (_GET_TLS_PROCTABLE()->VertexAttrib2sNV) #define glVertexAttrib2svNV (_GET_TLS_PROCTABLE()->VertexAttrib2svNV) #define glVertexAttrib3dNV (_GET_TLS_PROCTABLE()->VertexAttrib3dNV) #define glVertexAttrib3dvNV (_GET_TLS_PROCTABLE()->VertexAttrib3dvNV) #define glVertexAttrib3fNV (_GET_TLS_PROCTABLE()->VertexAttrib3fNV) #define glVertexAttrib3fvNV (_GET_TLS_PROCTABLE()->VertexAttrib3fvNV) #define glVertexAttrib3sNV (_GET_TLS_PROCTABLE()->VertexAttrib3sNV) #define glVertexAttrib3svNV (_GET_TLS_PROCTABLE()->VertexAttrib3svNV) #define glVertexAttrib4dNV (_GET_TLS_PROCTABLE()->VertexAttrib4dNV) #define glVertexAttrib4dvNV (_GET_TLS_PROCTABLE()->VertexAttrib4dvNV) #define glVertexAttrib4fNV (_GET_TLS_PROCTABLE()->VertexAttrib4fNV) #define glVertexAttrib4fvNV (_GET_TLS_PROCTABLE()->VertexAttrib4fvNV) #define glVertexAttrib4sNV (_GET_TLS_PROCTABLE()->VertexAttrib4sNV) #define glVertexAttrib4svNV (_GET_TLS_PROCTABLE()->VertexAttrib4svNV) #define glVertexAttrib4ubNV (_GET_TLS_PROCTABLE()->VertexAttrib4ubNV) #define glVertexAttrib4ubvNV (_GET_TLS_PROCTABLE()->VertexAttrib4ubvNV) #define glVertexAttribs1dvNV (_GET_TLS_PROCTABLE()->VertexAttribs1dvNV) #define glVertexAttribs1fvNV (_GET_TLS_PROCTABLE()->VertexAttribs1fvNV) #define glVertexAttribs1svNV (_GET_TLS_PROCTABLE()->VertexAttribs1svNV) #define glVertexAttribs2dvNV (_GET_TLS_PROCTABLE()->VertexAttribs2dvNV) #define glVertexAttribs2fvNV (_GET_TLS_PROCTABLE()->VertexAttribs2fvNV) #define glVertexAttribs2svNV (_GET_TLS_PROCTABLE()->VertexAttribs2svNV) #define glVertexAttribs3dvNV (_GET_TLS_PROCTABLE()->VertexAttribs3dvNV) #define glVertexAttribs3fvNV (_GET_TLS_PROCTABLE()->VertexAttribs3fvNV) #define glVertexAttribs3svNV (_GET_TLS_PROCTABLE()->VertexAttribs3svNV) #define glVertexAttribs4dvNV (_GET_TLS_PROCTABLE()->VertexAttribs4dvNV) #define glVertexAttribs4fvNV (_GET_TLS_PROCTABLE()->VertexAttribs4fvNV) #define glVertexAttribs4svNV (_GET_TLS_PROCTABLE()->VertexAttribs4svNV) #define glVertexAttribs4ubvNV (_GET_TLS_PROCTABLE()->VertexAttribs4ubvNV) #define glTexBumpParameterivATI (_GET_TLS_PROCTABLE()->TexBumpParameterivATI) #define glTexBumpParameterfvATI (_GET_TLS_PROCTABLE()->TexBumpParameterfvATI) #define glGetTexBumpParameterivATI (_GET_TLS_PROCTABLE()->GetTexBumpParameterivATI) #define glGetTexBumpParameterfvATI (_GET_TLS_PROCTABLE()->GetTexBumpParameterfvATI) #define glGenFragmentShadersATI (_GET_TLS_PROCTABLE()->GenFragmentShadersATI) #define glBindFragmentShaderATI (_GET_TLS_PROCTABLE()->BindFragmentShaderATI) #define glDeleteFragmentShaderATI (_GET_TLS_PROCTABLE()->DeleteFragmentShaderATI) #define glBeginFragmentShaderATI (_GET_TLS_PROCTABLE()->BeginFragmentShaderATI) #define glEndFragmentShaderATI (_GET_TLS_PROCTABLE()->EndFragmentShaderATI) #define glPassTexCoordATI (_GET_TLS_PROCTABLE()->PassTexCoordATI) #define glSampleMapATI (_GET_TLS_PROCTABLE()->SampleMapATI) #define glColorFragmentOp1ATI (_GET_TLS_PROCTABLE()->ColorFragmentOp1ATI) #define glColorFragmentOp2ATI (_GET_TLS_PROCTABLE()->ColorFragmentOp2ATI) #define glColorFragmentOp3ATI (_GET_TLS_PROCTABLE()->ColorFragmentOp3ATI) #define glAlphaFragmentOp1ATI (_GET_TLS_PROCTABLE()->AlphaFragmentOp1ATI) #define glAlphaFragmentOp2ATI (_GET_TLS_PROCTABLE()->AlphaFragmentOp2ATI) #define glAlphaFragmentOp3ATI (_GET_TLS_PROCTABLE()->AlphaFragmentOp3ATI) #define glSetFragmentShaderConstantATI (_GET_TLS_PROCTABLE()->SetFragmentShaderConstantATI) #define glPNTrianglesiATI (_GET_TLS_PROCTABLE()->PNTrianglesiATI) #define glPNTrianglesfATI (_GET_TLS_PROCTABLE()->PNTrianglesfATI) #define glNewObjectBufferATI (_GET_TLS_PROCTABLE()->NewObjectBufferATI) #define glIsObjectBufferATI (_GET_TLS_PROCTABLE()->IsObjectBufferATI) #define glUpdateObjectBufferATI (_GET_TLS_PROCTABLE()->UpdateObjectBufferATI) #define glGetObjectBufferfvATI (_GET_TLS_PROCTABLE()->GetObjectBufferfvATI) #define glGetObjectBufferivATI (_GET_TLS_PROCTABLE()->GetObjectBufferivATI) #define glFreeObjectBufferATI (_GET_TLS_PROCTABLE()->FreeObjectBufferATI) #define glArrayObjectATI (_GET_TLS_PROCTABLE()->ArrayObjectATI) #define glGetArrayObjectfvATI (_GET_TLS_PROCTABLE()->GetArrayObjectfvATI) #define glGetArrayObjectivATI (_GET_TLS_PROCTABLE()->GetArrayObjectivATI) #define glVariantArrayObjectATI (_GET_TLS_PROCTABLE()->VariantArrayObjectATI) #define glGetVariantArrayObjectfvATI (_GET_TLS_PROCTABLE()->GetVariantArrayObjectfvATI) #define glGetVariantArrayObjectivATI (_GET_TLS_PROCTABLE()->GetVariantArrayObjectivATI) #define glBeginVertexShaderEXT (_GET_TLS_PROCTABLE()->BeginVertexShaderEXT) #define glEndVertexShaderEXT (_GET_TLS_PROCTABLE()->EndVertexShaderEXT) #define glBindVertexShaderEXT (_GET_TLS_PROCTABLE()->BindVertexShaderEXT) #define glGenVertexShadersEXT (_GET_TLS_PROCTABLE()->GenVertexShadersEXT) #define glDeleteVertexShaderEXT (_GET_TLS_PROCTABLE()->DeleteVertexShaderEXT) #define glShaderOp1EXT (_GET_TLS_PROCTABLE()->ShaderOp1EXT) #define glShaderOp2EXT (_GET_TLS_PROCTABLE()->ShaderOp2EXT) #define glShaderOp3EXT (_GET_TLS_PROCTABLE()->ShaderOp3EXT) #define glSwizzleEXT (_GET_TLS_PROCTABLE()->SwizzleEXT) #define glWriteMaskEXT (_GET_TLS_PROCTABLE()->WriteMaskEXT) #define glInsertComponentEXT (_GET_TLS_PROCTABLE()->InsertComponentEXT) #define glExtractComponentEXT (_GET_TLS_PROCTABLE()->ExtractComponentEXT) #define glGenSymbolsEXT (_GET_TLS_PROCTABLE()->GenSymbolsEXT) #define glSetInvariantEXT (_GET_TLS_PROCTABLE()->SetInvariantEXT) #define glSetLocalConstantEXT (_GET_TLS_PROCTABLE()->SetLocalConstantEXT) #define glVariantbvEXT (_GET_TLS_PROCTABLE()->VariantbvEXT) #define glVariantsvEXT (_GET_TLS_PROCTABLE()->VariantsvEXT) #define glVariantivEXT (_GET_TLS_PROCTABLE()->VariantivEXT) #define glVariantfvEXT (_GET_TLS_PROCTABLE()->VariantfvEXT) #define glVariantdvEXT (_GET_TLS_PROCTABLE()->VariantdvEXT) #define glVariantubvEXT (_GET_TLS_PROCTABLE()->VariantubvEXT) #define glVariantusvEXT (_GET_TLS_PROCTABLE()->VariantusvEXT) #define glVariantuivEXT (_GET_TLS_PROCTABLE()->VariantuivEXT) #define glVariantPointerEXT (_GET_TLS_PROCTABLE()->VariantPointerEXT) #define glEnableVariantClientStateEXT (_GET_TLS_PROCTABLE()->EnableVariantClientStateEXT) #define glDisableVariantClientStateEXT (_GET_TLS_PROCTABLE()->DisableVariantClientStateEXT) #define glBindLightParameterEXT (_GET_TLS_PROCTABLE()->BindLightParameterEXT) #define glBindMaterialParameterEXT (_GET_TLS_PROCTABLE()->BindMaterialParameterEXT) #define glBindTexGenParameterEXT (_GET_TLS_PROCTABLE()->BindTexGenParameterEXT) #define glBindTextureUnitParameterEXT (_GET_TLS_PROCTABLE()->BindTextureUnitParameterEXT) #define glBindParameterEXT (_GET_TLS_PROCTABLE()->BindParameterEXT) #define glIsVariantEnabledEXT (_GET_TLS_PROCTABLE()->IsVariantEnabledEXT) #define glGetVariantBooleanvEXT (_GET_TLS_PROCTABLE()->GetVariantBooleanvEXT) #define glGetVariantIntegervEXT (_GET_TLS_PROCTABLE()->GetVariantIntegervEXT) #define glGetVariantFloatvEXT (_GET_TLS_PROCTABLE()->GetVariantFloatvEXT) #define glGetVariantPointervEXT (_GET_TLS_PROCTABLE()->GetVariantPointervEXT) #define glGetInvariantBooleanvEXT (_GET_TLS_PROCTABLE()->GetInvariantBooleanvEXT) #define glGetInvariantIntegervEXT (_GET_TLS_PROCTABLE()->GetInvariantIntegervEXT) #define glGetInvariantFloatvEXT (_GET_TLS_PROCTABLE()->GetInvariantFloatvEXT) #define glGetLocalConstantBooleanvEXT (_GET_TLS_PROCTABLE()->GetLocalConstantBooleanvEXT) #define glGetLocalConstantIntegervEXT (_GET_TLS_PROCTABLE()->GetLocalConstantIntegervEXT) #define glGetLocalConstantFloatvEXT (_GET_TLS_PROCTABLE()->GetLocalConstantFloatvEXT) #define glVertexStream1sATI (_GET_TLS_PROCTABLE()->VertexStream1sATI) #define glVertexStream1svATI (_GET_TLS_PROCTABLE()->VertexStream1svATI) #define glVertexStream1iATI (_GET_TLS_PROCTABLE()->VertexStream1iATI) #define glVertexStream1ivATI (_GET_TLS_PROCTABLE()->VertexStream1ivATI) #define glVertexStream1fATI (_GET_TLS_PROCTABLE()->VertexStream1fATI) #define glVertexStream1fvATI (_GET_TLS_PROCTABLE()->VertexStream1fvATI) #define glVertexStream1dATI (_GET_TLS_PROCTABLE()->VertexStream1dATI) #define glVertexStream1dvATI (_GET_TLS_PROCTABLE()->VertexStream1dvATI) #define glVertexStream2sATI (_GET_TLS_PROCTABLE()->VertexStream2sATI) #define glVertexStream2svATI (_GET_TLS_PROCTABLE()->VertexStream2svATI) #define glVertexStream2iATI (_GET_TLS_PROCTABLE()->VertexStream2iATI) #define glVertexStream2ivATI (_GET_TLS_PROCTABLE()->VertexStream2ivATI) #define glVertexStream2fATI (_GET_TLS_PROCTABLE()->VertexStream2fATI) #define glVertexStream2fvATI (_GET_TLS_PROCTABLE()->VertexStream2fvATI) #define glVertexStream2dATI (_GET_TLS_PROCTABLE()->VertexStream2dATI) #define glVertexStream2dvATI (_GET_TLS_PROCTABLE()->VertexStream2dvATI) #define glVertexStream3sATI (_GET_TLS_PROCTABLE()->VertexStream3sATI) #define glVertexStream3svATI (_GET_TLS_PROCTABLE()->VertexStream3svATI) #define glVertexStream3iATI (_GET_TLS_PROCTABLE()->VertexStream3iATI) #define glVertexStream3ivATI (_GET_TLS_PROCTABLE()->VertexStream3ivATI) #define glVertexStream3fATI (_GET_TLS_PROCTABLE()->VertexStream3fATI) #define glVertexStream3fvATI (_GET_TLS_PROCTABLE()->VertexStream3fvATI) #define glVertexStream3dATI (_GET_TLS_PROCTABLE()->VertexStream3dATI) #define glVertexStream3dvATI (_GET_TLS_PROCTABLE()->VertexStream3dvATI) #define glVertexStream4sATI (_GET_TLS_PROCTABLE()->VertexStream4sATI) #define glVertexStream4svATI (_GET_TLS_PROCTABLE()->VertexStream4svATI) #define glVertexStream4iATI (_GET_TLS_PROCTABLE()->VertexStream4iATI) #define glVertexStream4ivATI (_GET_TLS_PROCTABLE()->VertexStream4ivATI) #define glVertexStream4fATI (_GET_TLS_PROCTABLE()->VertexStream4fATI) #define glVertexStream4fvATI (_GET_TLS_PROCTABLE()->VertexStream4fvATI) #define glVertexStream4dATI (_GET_TLS_PROCTABLE()->VertexStream4dATI) #define glVertexStream4dvATI (_GET_TLS_PROCTABLE()->VertexStream4dvATI) #define glNormalStream3bATI (_GET_TLS_PROCTABLE()->NormalStream3bATI) #define glNormalStream3bvATI (_GET_TLS_PROCTABLE()->NormalStream3bvATI) #define glNormalStream3sATI (_GET_TLS_PROCTABLE()->NormalStream3sATI) #define glNormalStream3svATI (_GET_TLS_PROCTABLE()->NormalStream3svATI) #define glNormalStream3iATI (_GET_TLS_PROCTABLE()->NormalStream3iATI) #define glNormalStream3ivATI (_GET_TLS_PROCTABLE()->NormalStream3ivATI) #define glNormalStream3fATI (_GET_TLS_PROCTABLE()->NormalStream3fATI) #define glNormalStream3fvATI (_GET_TLS_PROCTABLE()->NormalStream3fvATI) #define glNormalStream3dATI (_GET_TLS_PROCTABLE()->NormalStream3dATI) #define glNormalStream3dvATI (_GET_TLS_PROCTABLE()->NormalStream3dvATI) #define glClientActiveVertexStreamATI (_GET_TLS_PROCTABLE()->ClientActiveVertexStreamATI) #define glVertexBlendEnviATI (_GET_TLS_PROCTABLE()->VertexBlendEnviATI) #define glVertexBlendEnvfATI (_GET_TLS_PROCTABLE()->VertexBlendEnvfATI) #define glElementPointerATI (_GET_TLS_PROCTABLE()->ElementPointerATI) #define glDrawElementArrayATI (_GET_TLS_PROCTABLE()->DrawElementArrayATI) #define glDrawRangeElementArrayATI (_GET_TLS_PROCTABLE()->DrawRangeElementArrayATI) #define glDrawMeshArraysSUN (_GET_TLS_PROCTABLE()->DrawMeshArraysSUN) #define glGenOcclusionQueriesNV (_GET_TLS_PROCTABLE()->GenOcclusionQueriesNV) #define glDeleteOcclusionQueriesNV (_GET_TLS_PROCTABLE()->DeleteOcclusionQueriesNV) #define glIsOcclusionQueryNV (_GET_TLS_PROCTABLE()->IsOcclusionQueryNV) #define glBeginOcclusionQueryNV (_GET_TLS_PROCTABLE()->BeginOcclusionQueryNV) #define glEndOcclusionQueryNV (_GET_TLS_PROCTABLE()->EndOcclusionQueryNV) #define glGetOcclusionQueryivNV (_GET_TLS_PROCTABLE()->GetOcclusionQueryivNV) #define glGetOcclusionQueryuivNV (_GET_TLS_PROCTABLE()->GetOcclusionQueryuivNV) #define glPointParameteriNV (_GET_TLS_PROCTABLE()->PointParameteriNV) #define glPointParameterivNV (_GET_TLS_PROCTABLE()->PointParameterivNV) #define glActiveStencilFaceEXT (_GET_TLS_PROCTABLE()->ActiveStencilFaceEXT) #define glElementPointerAPPLE (_GET_TLS_PROCTABLE()->ElementPointerAPPLE) #define glDrawElementArrayAPPLE (_GET_TLS_PROCTABLE()->DrawElementArrayAPPLE) #define glDrawRangeElementArrayAPPLE (_GET_TLS_PROCTABLE()->DrawRangeElementArrayAPPLE) #define glMultiDrawElementArrayAPPLE (_GET_TLS_PROCTABLE()->MultiDrawElementArrayAPPLE) #define glMultiDrawRangeElementArrayAPPLE (_GET_TLS_PROCTABLE()->MultiDrawRangeElementArrayAPPLE) #define glGenFencesAPPLE (_GET_TLS_PROCTABLE()->GenFencesAPPLE) #define glDeleteFencesAPPLE (_GET_TLS_PROCTABLE()->DeleteFencesAPPLE) #define glSetFenceAPPLE (_GET_TLS_PROCTABLE()->SetFenceAPPLE) #define glIsFenceAPPLE (_GET_TLS_PROCTABLE()->IsFenceAPPLE) #define glTestFenceAPPLE (_GET_TLS_PROCTABLE()->TestFenceAPPLE) #define glFinishFenceAPPLE (_GET_TLS_PROCTABLE()->FinishFenceAPPLE) #define glTestObjectAPPLE (_GET_TLS_PROCTABLE()->TestObjectAPPLE) #define glFinishObjectAPPLE (_GET_TLS_PROCTABLE()->FinishObjectAPPLE) #define glBindVertexArrayAPPLE (_GET_TLS_PROCTABLE()->BindVertexArrayAPPLE) #define glDeleteVertexArraysAPPLE (_GET_TLS_PROCTABLE()->DeleteVertexArraysAPPLE) #define glGenVertexArraysAPPLE (_GET_TLS_PROCTABLE()->GenVertexArraysAPPLE) #define glIsVertexArrayAPPLE (_GET_TLS_PROCTABLE()->IsVertexArrayAPPLE) #define glVertexArrayRangeAPPLE (_GET_TLS_PROCTABLE()->VertexArrayRangeAPPLE) #define glFlushVertexArrayRangeAPPLE (_GET_TLS_PROCTABLE()->FlushVertexArrayRangeAPPLE) #define glVertexArrayParameteriAPPLE (_GET_TLS_PROCTABLE()->VertexArrayParameteriAPPLE) #define glDrawBuffersATI (_GET_TLS_PROCTABLE()->DrawBuffersATI) #define glProgramNamedParameter4fNV (_GET_TLS_PROCTABLE()->ProgramNamedParameter4fNV) #define glProgramNamedParameter4dNV (_GET_TLS_PROCTABLE()->ProgramNamedParameter4dNV) #define glProgramNamedParameter4fvNV (_GET_TLS_PROCTABLE()->ProgramNamedParameter4fvNV) #define glProgramNamedParameter4dvNV (_GET_TLS_PROCTABLE()->ProgramNamedParameter4dvNV) #define glGetProgramNamedParameterfvNV (_GET_TLS_PROCTABLE()->GetProgramNamedParameterfvNV) #define glGetProgramNamedParameterdvNV (_GET_TLS_PROCTABLE()->GetProgramNamedParameterdvNV) #define glVertex2hNV (_GET_TLS_PROCTABLE()->Vertex2hNV) #define glVertex2hvNV (_GET_TLS_PROCTABLE()->Vertex2hvNV) #define glVertex3hNV (_GET_TLS_PROCTABLE()->Vertex3hNV) #define glVertex3hvNV (_GET_TLS_PROCTABLE()->Vertex3hvNV) #define glVertex4hNV (_GET_TLS_PROCTABLE()->Vertex4hNV) #define glVertex4hvNV (_GET_TLS_PROCTABLE()->Vertex4hvNV) #define glNormal3hNV (_GET_TLS_PROCTABLE()->Normal3hNV) #define glNormal3hvNV (_GET_TLS_PROCTABLE()->Normal3hvNV) #define glColor3hNV (_GET_TLS_PROCTABLE()->Color3hNV) #define glColor3hvNV (_GET_TLS_PROCTABLE()->Color3hvNV) #define glColor4hNV (_GET_TLS_PROCTABLE()->Color4hNV) #define glColor4hvNV (_GET_TLS_PROCTABLE()->Color4hvNV) #define glTexCoord1hNV (_GET_TLS_PROCTABLE()->TexCoord1hNV) #define glTexCoord1hvNV (_GET_TLS_PROCTABLE()->TexCoord1hvNV) #define glTexCoord2hNV (_GET_TLS_PROCTABLE()->TexCoord2hNV) #define glTexCoord2hvNV (_GET_TLS_PROCTABLE()->TexCoord2hvNV) #define glTexCoord3hNV (_GET_TLS_PROCTABLE()->TexCoord3hNV) #define glTexCoord3hvNV (_GET_TLS_PROCTABLE()->TexCoord3hvNV) #define glTexCoord4hNV (_GET_TLS_PROCTABLE()->TexCoord4hNV) #define glTexCoord4hvNV (_GET_TLS_PROCTABLE()->TexCoord4hvNV) #define glMultiTexCoord1hNV (_GET_TLS_PROCTABLE()->MultiTexCoord1hNV) #define glMultiTexCoord1hvNV (_GET_TLS_PROCTABLE()->MultiTexCoord1hvNV) #define glMultiTexCoord2hNV (_GET_TLS_PROCTABLE()->MultiTexCoord2hNV) #define glMultiTexCoord2hvNV (_GET_TLS_PROCTABLE()->MultiTexCoord2hvNV) #define glMultiTexCoord3hNV (_GET_TLS_PROCTABLE()->MultiTexCoord3hNV) #define glMultiTexCoord3hvNV (_GET_TLS_PROCTABLE()->MultiTexCoord3hvNV) #define glMultiTexCoord4hNV (_GET_TLS_PROCTABLE()->MultiTexCoord4hNV) #define glMultiTexCoord4hvNV (_GET_TLS_PROCTABLE()->MultiTexCoord4hvNV) #define glFogCoordhNV (_GET_TLS_PROCTABLE()->FogCoordhNV) #define glFogCoordhvNV (_GET_TLS_PROCTABLE()->FogCoordhvNV) #define glSecondaryColor3hNV (_GET_TLS_PROCTABLE()->SecondaryColor3hNV) #define glSecondaryColor3hvNV (_GET_TLS_PROCTABLE()->SecondaryColor3hvNV) #define glVertexWeighthNV (_GET_TLS_PROCTABLE()->VertexWeighthNV) #define glVertexWeighthvNV (_GET_TLS_PROCTABLE()->VertexWeighthvNV) #define glVertexAttrib1hNV (_GET_TLS_PROCTABLE()->VertexAttrib1hNV) #define glVertexAttrib1hvNV (_GET_TLS_PROCTABLE()->VertexAttrib1hvNV) #define glVertexAttrib2hNV (_GET_TLS_PROCTABLE()->VertexAttrib2hNV) #define glVertexAttrib2hvNV (_GET_TLS_PROCTABLE()->VertexAttrib2hvNV) #define glVertexAttrib3hNV (_GET_TLS_PROCTABLE()->VertexAttrib3hNV) #define glVertexAttrib3hvNV (_GET_TLS_PROCTABLE()->VertexAttrib3hvNV) #define glVertexAttrib4hNV (_GET_TLS_PROCTABLE()->VertexAttrib4hNV) #define glVertexAttrib4hvNV (_GET_TLS_PROCTABLE()->VertexAttrib4hvNV) #define glVertexAttribs1hvNV (_GET_TLS_PROCTABLE()->VertexAttribs1hvNV) #define glVertexAttribs2hvNV (_GET_TLS_PROCTABLE()->VertexAttribs2hvNV) #define glVertexAttribs3hvNV (_GET_TLS_PROCTABLE()->VertexAttribs3hvNV) #define glVertexAttribs4hvNV (_GET_TLS_PROCTABLE()->VertexAttribs4hvNV) #define glPixelDataRangeNV (_GET_TLS_PROCTABLE()->PixelDataRangeNV) #define glFlushPixelDataRangeNV (_GET_TLS_PROCTABLE()->FlushPixelDataRangeNV) #define glPrimitiveRestartNV (_GET_TLS_PROCTABLE()->PrimitiveRestartNV) #define glPrimitiveRestartIndexNV (_GET_TLS_PROCTABLE()->PrimitiveRestartIndexNV) #define glMapObjectBufferATI (_GET_TLS_PROCTABLE()->MapObjectBufferATI) #define glUnmapObjectBufferATI (_GET_TLS_PROCTABLE()->UnmapObjectBufferATI) #define glStencilOpSeparateATI (_GET_TLS_PROCTABLE()->StencilOpSeparateATI) #define glStencilFuncSeparateATI (_GET_TLS_PROCTABLE()->StencilFuncSeparateATI) #define glVertexAttribArrayObjectATI (_GET_TLS_PROCTABLE()->VertexAttribArrayObjectATI) #define glGetVertexAttribArrayObjectfvATI (_GET_TLS_PROCTABLE()->GetVertexAttribArrayObjectfvATI) #define glGetVertexAttribArrayObjectivATI (_GET_TLS_PROCTABLE()->GetVertexAttribArrayObjectivATI) #define glDepthBoundsEXT (_GET_TLS_PROCTABLE()->DepthBoundsEXT) #define glBlendEquationSeparateEXT (_GET_TLS_PROCTABLE()->BlendEquationSeparateEXT) #define glAddSwapHintRectWIN (_GET_TLS_PROCTABLE()->AddSwapHintRectWIN) #ifdef _WIN32 #define wglCreateBufferRegionARB (_GET_TLS_PROCTABLE()->CreateBufferRegionARB) #define wglDeleteBufferRegionARB (_GET_TLS_PROCTABLE()->DeleteBufferRegionARB) #define wglSaveBufferRegionARB (_GET_TLS_PROCTABLE()->SaveBufferRegionARB) #define wglRestoreBufferRegionARB (_GET_TLS_PROCTABLE()->RestoreBufferRegionARB) #define wglGetExtensionsStringARB (_GET_TLS_PROCTABLE()->GetExtensionsStringARB) #define wglGetPixelFormatAttribivARB (_GET_TLS_PROCTABLE()->GetPixelFormatAttribivARB) #define wglGetPixelFormatAttribfvARB (_GET_TLS_PROCTABLE()->GetPixelFormatAttribfvARB) #define wglChoosePixelFormatARB (_GET_TLS_PROCTABLE()->ChoosePixelFormatARB) #define wglMakeContextCurrentARB (_GET_TLS_PROCTABLE()->MakeContextCurrentARB) #define wglGetCurrentReadDCARB (_GET_TLS_PROCTABLE()->GetCurrentReadDCARB) #define wglCreatePbufferARB (_GET_TLS_PROCTABLE()->CreatePbufferARB) #define wglGetPbufferDCARB (_GET_TLS_PROCTABLE()->GetPbufferDCARB) #define wglReleasePbufferDCARB (_GET_TLS_PROCTABLE()->ReleasePbufferDCARB) #define wglDestroyPbufferARB (_GET_TLS_PROCTABLE()->DestroyPbufferARB) #define wglQueryPbufferARB (_GET_TLS_PROCTABLE()->QueryPbufferARB) #define wglBindTexImageARB (_GET_TLS_PROCTABLE()->BindTexImageARB) #define wglReleaseTexImageARB (_GET_TLS_PROCTABLE()->ReleaseTexImageARB) #define wglSetPbufferAttribARB (_GET_TLS_PROCTABLE()->SetPbufferAttribARB) #define wglCreateDisplayColorTableEXT (_GET_TLS_PROCTABLE()->CreateDisplayColorTableEXT) #define wglLoadDisplayColorTableEXT (_GET_TLS_PROCTABLE()->LoadDisplayColorTableEXT) #define wglBindDisplayColorTableEXT (_GET_TLS_PROCTABLE()->BindDisplayColorTableEXT) #define wglDestroyDisplayColorTableEXT (_GET_TLS_PROCTABLE()->DestroyDisplayColorTableEXT) #define wglGetExtensionsStringEXT (_GET_TLS_PROCTABLE()->GetExtensionsStringEXT) #define wglMakeContextCurrentEXT (_GET_TLS_PROCTABLE()->MakeContextCurrentEXT) #define wglGetCurrentReadDCEXT (_GET_TLS_PROCTABLE()->GetCurrentReadDCEXT) #define wglCreatePbufferEXT (_GET_TLS_PROCTABLE()->CreatePbufferEXT) #define wglGetPbufferDCEXT (_GET_TLS_PROCTABLE()->GetPbufferDCEXT) #define wglReleasePbufferDCEXT (_GET_TLS_PROCTABLE()->ReleasePbufferDCEXT) #define wglDestroyPbufferEXT (_GET_TLS_PROCTABLE()->DestroyPbufferEXT) #define wglQueryPbufferEXT (_GET_TLS_PROCTABLE()->QueryPbufferEXT) #define wglGetPixelFormatAttribivEXT (_GET_TLS_PROCTABLE()->GetPixelFormatAttribivEXT) #define wglGetPixelFormatAttribfvEXT (_GET_TLS_PROCTABLE()->GetPixelFormatAttribfvEXT) #define wglChoosePixelFormatEXT (_GET_TLS_PROCTABLE()->ChoosePixelFormatEXT) #define wglSwapIntervalEXT (_GET_TLS_PROCTABLE()->SwapIntervalEXT) #define wglGetSwapIntervalEXT (_GET_TLS_PROCTABLE()->GetSwapIntervalEXT) #define wglAllocateMemoryNV (_GET_TLS_PROCTABLE()->AllocateMemoryNV) #define wglFreeMemoryNV (_GET_TLS_PROCTABLE()->FreeMemoryNV) #define wglGetSyncValuesOML (_GET_TLS_PROCTABLE()->GetSyncValuesOML) #define wglGetMscRateOML (_GET_TLS_PROCTABLE()->GetMscRateOML) #define wglSwapBuffersMscOML (_GET_TLS_PROCTABLE()->SwapBuffersMscOML) #define wglSwapLayerBuffersMscOML (_GET_TLS_PROCTABLE()->SwapLayerBuffersMscOML) #define wglWaitForMscOML (_GET_TLS_PROCTABLE()->WaitForMscOML) #define wglWaitForSbcOML (_GET_TLS_PROCTABLE()->WaitForSbcOML) #define wglGetDigitalVideoParametersI3D (_GET_TLS_PROCTABLE()->GetDigitalVideoParametersI3D) #define wglSetDigitalVideoParametersI3D (_GET_TLS_PROCTABLE()->SetDigitalVideoParametersI3D) #define wglGetGammaTableParametersI3D (_GET_TLS_PROCTABLE()->GetGammaTableParametersI3D) #define wglSetGammaTableParametersI3D (_GET_TLS_PROCTABLE()->SetGammaTableParametersI3D) #define wglGetGammaTableI3D (_GET_TLS_PROCTABLE()->GetGammaTableI3D) #define wglSetGammaTableI3D (_GET_TLS_PROCTABLE()->SetGammaTableI3D) #define wglEnableGenlockI3D (_GET_TLS_PROCTABLE()->EnableGenlockI3D) #define wglDisableGenlockI3D (_GET_TLS_PROCTABLE()->DisableGenlockI3D) #define wglIsEnabledGenlockI3D (_GET_TLS_PROCTABLE()->IsEnabledGenlockI3D) #define wglGenlockSourceI3D (_GET_TLS_PROCTABLE()->GenlockSourceI3D) #define wglGetGenlockSourceI3D (_GET_TLS_PROCTABLE()->GetGenlockSourceI3D) #define wglGenlockSourceEdgeI3D (_GET_TLS_PROCTABLE()->GenlockSourceEdgeI3D) #define wglGetGenlockSourceEdgeI3D (_GET_TLS_PROCTABLE()->GetGenlockSourceEdgeI3D) #define wglGenlockSampleRateI3D (_GET_TLS_PROCTABLE()->GenlockSampleRateI3D) #define wglGetGenlockSampleRateI3D (_GET_TLS_PROCTABLE()->GetGenlockSampleRateI3D) #define wglGenlockSourceDelayI3D (_GET_TLS_PROCTABLE()->GenlockSourceDelayI3D) #define wglGetGenlockSourceDelayI3D (_GET_TLS_PROCTABLE()->GetGenlockSourceDelayI3D) #define wglQueryGenlockMaxSourceDelayI3D (_GET_TLS_PROCTABLE()->QueryGenlockMaxSourceDelayI3D) #define wglCreateImageBufferI3D (_GET_TLS_PROCTABLE()->CreateImageBufferI3D) #define wglDestroyImageBufferI3D (_GET_TLS_PROCTABLE()->DestroyImageBufferI3D) #define wglAssociateImageBufferEventsI3D (_GET_TLS_PROCTABLE()->AssociateImageBufferEventsI3D) #define wglReleaseImageBufferEventsI3D (_GET_TLS_PROCTABLE()->ReleaseImageBufferEventsI3D) #define wglEnableFrameLockI3D (_GET_TLS_PROCTABLE()->EnableFrameLockI3D) #define wglDisableFrameLockI3D (_GET_TLS_PROCTABLE()->DisableFrameLockI3D) #define wglIsEnabledFrameLockI3D (_GET_TLS_PROCTABLE()->IsEnabledFrameLockI3D) #define wglQueryFrameLockMasterI3D (_GET_TLS_PROCTABLE()->QueryFrameLockMasterI3D) #define wglGetFrameUsageI3D (_GET_TLS_PROCTABLE()->GetFrameUsageI3D) #define wglBeginFrameTrackingI3D (_GET_TLS_PROCTABLE()->BeginFrameTrackingI3D) #define wglEndFrameTrackingI3D (_GET_TLS_PROCTABLE()->EndFrameTrackingI3D) #define wglQueryFrameTrackingI3D (_GET_TLS_PROCTABLE()->QueryFrameTrackingI3D) #endif /* _WIN32 */ #ifndef _APP_PROCTABLE /* * Applications can replace the following function with its own function * for accessing thread local proc/context dependent proc table. * The following default function works for most applications which * are using the same device for all their contexts - even if * the contexts are on different threads. */ static _inline _GLextensionProcs *_GET_TLS_PROCTABLE(void) { extern _GLextensionProcs _extensionProcs; return (&_extensionProcs); } #else /* * Application should replace this compiled function with * an inlined function for maximum performance. */ extern _GLextensionProcs *_GET_TLS_PROCTABLE(void); #endif /* * Provide an initialization function for the application * to initialize its own proc tables in case the application * needs to use multiple proc tables. */ static _inline void _InitExtensionProcs(_GLextensionProcs *appProcs) { extern _GLextensionProcs _extensionProcs; *appProcs = _extensionProcs; } #ifdef __cplusplus } #endif #endif /* _GLPROCS_H_ */ rgl/src/ext/GLsdk/GL/glext.h0000644000176200001440000112000114100762641015223 0ustar liggesusers#ifndef __glext_h_ #define __glext_h_ #ifdef __cplusplus extern "C" { #endif /* ** License Applicability. Except to the extent portions of this file are ** made subject to an alternative license as permitted in the SGI Free ** Software License B, Version 1.1 (the "License"), the contents of this ** file are subject only to the provisions of the License. You may not use ** this file except in compliance with the License. You may obtain a copy ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: ** ** http://oss.sgi.com/projects/FreeB ** ** Note that, as provided in the License, the Software is distributed on an ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. ** ** Original Code. The Original Code is: OpenGL Sample Implementation, ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, ** Inc. The Original Code is Copyright (c) 1991-2002 Silicon Graphics, Inc. ** Copyright in any portions created by third parties is as indicated ** elsewhere herein. All Rights Reserved. ** ** Additional Notice Provisions: This software was created using the ** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has ** not been independently verified as being compliant with the OpenGL(R) ** version 1.2.1 Specification. */ #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) #define WIN32_LEAN_AND_MEAN 1 #include #endif #ifndef APIENTRY #define APIENTRY #endif #ifndef APIENTRYP #define APIENTRYP APIENTRY * #endif #ifndef GLAPI #define GLAPI extern #endif /*************************************************************/ /* Header file version number, required by OpenGL ABI for Linux */ /* glext.h last updated 2004/2/23 */ /* Current version at http://oss.sgi.com/projects/ogl-sample/registry/ */ #define GL_GLEXT_VERSION 22 #ifndef GL_VERSION_1_2 #define GL_UNSIGNED_BYTE_3_3_2 0x8032 #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 #define GL_UNSIGNED_INT_8_8_8_8 0x8035 #define GL_UNSIGNED_INT_10_10_10_2 0x8036 #define GL_RESCALE_NORMAL 0x803A #define GL_TEXTURE_BINDING_3D 0x806A #define GL_PACK_SKIP_IMAGES 0x806B #define GL_PACK_IMAGE_HEIGHT 0x806C #define GL_UNPACK_SKIP_IMAGES 0x806D #define GL_UNPACK_IMAGE_HEIGHT 0x806E #define GL_TEXTURE_3D 0x806F #define GL_PROXY_TEXTURE_3D 0x8070 #define GL_TEXTURE_DEPTH 0x8071 #define GL_TEXTURE_WRAP_R 0x8072 #define GL_MAX_3D_TEXTURE_SIZE 0x8073 #define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 #define GL_UNSIGNED_SHORT_5_6_5 0x8363 #define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 #define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 #define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 #define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 #define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 #define GL_BGR 0x80E0 #define GL_BGRA 0x80E1 #define GL_MAX_ELEMENTS_VERTICES 0x80E8 #define GL_MAX_ELEMENTS_INDICES 0x80E9 #define GL_CLAMP_TO_EDGE 0x812F #define GL_TEXTURE_MIN_LOD 0x813A #define GL_TEXTURE_MAX_LOD 0x813B #define GL_TEXTURE_BASE_LEVEL 0x813C #define GL_TEXTURE_MAX_LEVEL 0x813D #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 #define GL_SINGLE_COLOR 0x81F9 #define GL_SEPARATE_SPECULAR_COLOR 0x81FA #define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 #define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 #define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 #define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 #define GL_ALIASED_POINT_SIZE_RANGE 0x846D #define GL_ALIASED_LINE_WIDTH_RANGE 0x846E #endif #ifndef GL_ARB_imaging #define GL_CONSTANT_COLOR 0x8001 #define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 #define GL_CONSTANT_ALPHA 0x8003 #define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 #define GL_BLEND_COLOR 0x8005 #define GL_FUNC_ADD 0x8006 #define GL_MIN 0x8007 #define GL_MAX 0x8008 #define GL_BLEND_EQUATION 0x8009 #define GL_FUNC_SUBTRACT 0x800A #define GL_FUNC_REVERSE_SUBTRACT 0x800B #define GL_CONVOLUTION_1D 0x8010 #define GL_CONVOLUTION_2D 0x8011 #define GL_SEPARABLE_2D 0x8012 #define GL_CONVOLUTION_BORDER_MODE 0x8013 #define GL_CONVOLUTION_FILTER_SCALE 0x8014 #define GL_CONVOLUTION_FILTER_BIAS 0x8015 #define GL_REDUCE 0x8016 #define GL_CONVOLUTION_FORMAT 0x8017 #define GL_CONVOLUTION_WIDTH 0x8018 #define GL_CONVOLUTION_HEIGHT 0x8019 #define GL_MAX_CONVOLUTION_WIDTH 0x801A #define GL_MAX_CONVOLUTION_HEIGHT 0x801B #define GL_POST_CONVOLUTION_RED_SCALE 0x801C #define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D #define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E #define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F #define GL_POST_CONVOLUTION_RED_BIAS 0x8020 #define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 #define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 #define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 #define GL_HISTOGRAM 0x8024 #define GL_PROXY_HISTOGRAM 0x8025 #define GL_HISTOGRAM_WIDTH 0x8026 #define GL_HISTOGRAM_FORMAT 0x8027 #define GL_HISTOGRAM_RED_SIZE 0x8028 #define GL_HISTOGRAM_GREEN_SIZE 0x8029 #define GL_HISTOGRAM_BLUE_SIZE 0x802A #define GL_HISTOGRAM_ALPHA_SIZE 0x802B #define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C #define GL_HISTOGRAM_SINK 0x802D #define GL_MINMAX 0x802E #define GL_MINMAX_FORMAT 0x802F #define GL_MINMAX_SINK 0x8030 #define GL_TABLE_TOO_LARGE 0x8031 #define GL_COLOR_MATRIX 0x80B1 #define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 #define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 #define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 #define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 #define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 #define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 #define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 #define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 #define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA #define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB #define GL_COLOR_TABLE 0x80D0 #define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 #define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 #define GL_PROXY_COLOR_TABLE 0x80D3 #define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 #define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 #define GL_COLOR_TABLE_SCALE 0x80D6 #define GL_COLOR_TABLE_BIAS 0x80D7 #define GL_COLOR_TABLE_FORMAT 0x80D8 #define GL_COLOR_TABLE_WIDTH 0x80D9 #define GL_COLOR_TABLE_RED_SIZE 0x80DA #define GL_COLOR_TABLE_GREEN_SIZE 0x80DB #define GL_COLOR_TABLE_BLUE_SIZE 0x80DC #define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD #define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE #define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF #define GL_CONSTANT_BORDER 0x8151 #define GL_REPLICATE_BORDER 0x8153 #define GL_CONVOLUTION_BORDER_COLOR 0x8154 #endif #ifndef GL_VERSION_1_3 #define GL_TEXTURE0 0x84C0 #define GL_TEXTURE1 0x84C1 #define GL_TEXTURE2 0x84C2 #define GL_TEXTURE3 0x84C3 #define GL_TEXTURE4 0x84C4 #define GL_TEXTURE5 0x84C5 #define GL_TEXTURE6 0x84C6 #define GL_TEXTURE7 0x84C7 #define GL_TEXTURE8 0x84C8 #define GL_TEXTURE9 0x84C9 #define GL_TEXTURE10 0x84CA #define GL_TEXTURE11 0x84CB #define GL_TEXTURE12 0x84CC #define GL_TEXTURE13 0x84CD #define GL_TEXTURE14 0x84CE #define GL_TEXTURE15 0x84CF #define GL_TEXTURE16 0x84D0 #define GL_TEXTURE17 0x84D1 #define GL_TEXTURE18 0x84D2 #define GL_TEXTURE19 0x84D3 #define GL_TEXTURE20 0x84D4 #define GL_TEXTURE21 0x84D5 #define GL_TEXTURE22 0x84D6 #define GL_TEXTURE23 0x84D7 #define GL_TEXTURE24 0x84D8 #define GL_TEXTURE25 0x84D9 #define GL_TEXTURE26 0x84DA #define GL_TEXTURE27 0x84DB #define GL_TEXTURE28 0x84DC #define GL_TEXTURE29 0x84DD #define GL_TEXTURE30 0x84DE #define GL_TEXTURE31 0x84DF #define GL_ACTIVE_TEXTURE 0x84E0 #define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 #define GL_MAX_TEXTURE_UNITS 0x84E2 #define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 #define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 #define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 #define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 #define GL_MULTISAMPLE 0x809D #define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E #define GL_SAMPLE_ALPHA_TO_ONE 0x809F #define GL_SAMPLE_COVERAGE 0x80A0 #define GL_SAMPLE_BUFFERS 0x80A8 #define GL_SAMPLES 0x80A9 #define GL_SAMPLE_COVERAGE_VALUE 0x80AA #define GL_SAMPLE_COVERAGE_INVERT 0x80AB #define GL_MULTISAMPLE_BIT 0x20000000 #define GL_NORMAL_MAP 0x8511 #define GL_REFLECTION_MAP 0x8512 #define GL_TEXTURE_CUBE_MAP 0x8513 #define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 #define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A #define GL_PROXY_TEXTURE_CUBE_MAP 0x851B #define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C #define GL_COMPRESSED_ALPHA 0x84E9 #define GL_COMPRESSED_LUMINANCE 0x84EA #define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB #define GL_COMPRESSED_INTENSITY 0x84EC #define GL_COMPRESSED_RGB 0x84ED #define GL_COMPRESSED_RGBA 0x84EE #define GL_TEXTURE_COMPRESSION_HINT 0x84EF #define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 #define GL_TEXTURE_COMPRESSED 0x86A1 #define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 #define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 #define GL_CLAMP_TO_BORDER 0x812D #define GL_CLAMP_TO_BORDER_SGIS 0x812D #define GL_COMBINE 0x8570 #define GL_COMBINE_RGB 0x8571 #define GL_COMBINE_ALPHA 0x8572 #define GL_SOURCE0_RGB 0x8580 #define GL_SOURCE1_RGB 0x8581 #define GL_SOURCE2_RGB 0x8582 #define GL_SOURCE0_ALPHA 0x8588 #define GL_SOURCE1_ALPHA 0x8589 #define GL_SOURCE2_ALPHA 0x858A #define GL_OPERAND0_RGB 0x8590 #define GL_OPERAND1_RGB 0x8591 #define GL_OPERAND2_RGB 0x8592 #define GL_OPERAND0_ALPHA 0x8598 #define GL_OPERAND1_ALPHA 0x8599 #define GL_OPERAND2_ALPHA 0x859A #define GL_RGB_SCALE 0x8573 #define GL_ADD_SIGNED 0x8574 #define GL_INTERPOLATE 0x8575 #define GL_SUBTRACT 0x84E7 #define GL_CONSTANT 0x8576 #define GL_PRIMARY_COLOR 0x8577 #define GL_PREVIOUS 0x8578 #define GL_DOT3_RGB 0x86AE #define GL_DOT3_RGBA 0x86AF #endif #ifndef GL_VERSION_1_4 #define GL_BLEND_DST_RGB 0x80C8 #define GL_BLEND_SRC_RGB 0x80C9 #define GL_BLEND_DST_ALPHA 0x80CA #define GL_BLEND_SRC_ALPHA 0x80CB #define GL_POINT_SIZE_MIN 0x8126 #define GL_POINT_SIZE_MAX 0x8127 #define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 #define GL_POINT_DISTANCE_ATTENUATION 0x8129 #define GL_GENERATE_MIPMAP 0x8191 #define GL_GENERATE_MIPMAP_HINT 0x8192 #define GL_DEPTH_COMPONENT16 0x81A5 #define GL_DEPTH_COMPONENT24 0x81A6 #define GL_DEPTH_COMPONENT32 0x81A7 #define GL_MIRRORED_REPEAT 0x8370 #define GL_FOG_COORDINATE_SOURCE 0x8450 #define GL_FOG_COORDINATE 0x8451 #define GL_FRAGMENT_DEPTH 0x8452 #define GL_CURRENT_FOG_COORDINATE 0x8453 #define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 #define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 #define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 #define GL_FOG_COORDINATE_ARRAY 0x8457 #define GL_COLOR_SUM 0x8458 #define GL_CURRENT_SECONDARY_COLOR 0x8459 #define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A #define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B #define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C #define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D #define GL_SECONDARY_COLOR_ARRAY 0x845E #define GL_MAX_TEXTURE_LOD_BIAS 0x84FD #define GL_TEXTURE_FILTER_CONTROL 0x8500 #define GL_TEXTURE_LOD_BIAS 0x8501 #define GL_INCR_WRAP 0x8507 #define GL_DECR_WRAP 0x8508 #define GL_TEXTURE_DEPTH_SIZE 0x884A #define GL_DEPTH_TEXTURE_MODE 0x884B #define GL_TEXTURE_COMPARE_MODE 0x884C #define GL_TEXTURE_COMPARE_FUNC 0x884D #define GL_COMPARE_R_TO_TEXTURE 0x884E #endif #ifndef GL_VERSION_1_5 #define GL_BUFFER_SIZE 0x8764 #define GL_BUFFER_USAGE 0x8765 #define GL_QUERY_COUNTER_BITS 0x8864 #define GL_CURRENT_QUERY 0x8865 #define GL_QUERY_RESULT 0x8866 #define GL_QUERY_RESULT_AVAILABLE 0x8867 #define GL_ARRAY_BUFFER 0x8892 #define GL_ELEMENT_ARRAY_BUFFER 0x8893 #define GL_ARRAY_BUFFER_BINDING 0x8894 #define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 #define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 #define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 #define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 #define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 #define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A #define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B #define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C #define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D #define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F #define GL_READ_ONLY 0x88B8 #define GL_WRITE_ONLY 0x88B9 #define GL_READ_WRITE 0x88BA #define GL_BUFFER_ACCESS 0x88BB #define GL_BUFFER_MAPPED 0x88BC #define GL_BUFFER_MAP_POINTER 0x88BD #define GL_STREAM_DRAW 0x88E0 #define GL_STREAM_READ 0x88E1 #define GL_STREAM_COPY 0x88E2 #define GL_STATIC_DRAW 0x88E4 #define GL_STATIC_READ 0x88E5 #define GL_STATIC_COPY 0x88E6 #define GL_DYNAMIC_DRAW 0x88E8 #define GL_DYNAMIC_READ 0x88E9 #define GL_DYNAMIC_COPY 0x88EA #define GL_SAMPLES_PASSED 0x8914 #define GL_FOG_COORD_SOURCE GL_FOG_COORDINATE_SOURCE #define GL_FOG_COORD GL_FOG_COORDINATE #define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE #define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE #define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE #define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER #define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY #define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING #define GL_SRC0_RGB GL_SOURCE0_RGB #define GL_SRC1_RGB GL_SOURCE1_RGB #define GL_SRC2_RGB GL_SOURCE2_RGB #define GL_SRC0_ALPHA GL_SOURCE0_ALPHA #define GL_SRC1_ALPHA GL_SOURCE1_ALPHA #define GL_SRC2_ALPHA GL_SOURCE2_ALPHA #endif #ifndef GL_ARB_multitexture #define GL_TEXTURE0_ARB 0x84C0 #define GL_TEXTURE1_ARB 0x84C1 #define GL_TEXTURE2_ARB 0x84C2 #define GL_TEXTURE3_ARB 0x84C3 #define GL_TEXTURE4_ARB 0x84C4 #define GL_TEXTURE5_ARB 0x84C5 #define GL_TEXTURE6_ARB 0x84C6 #define GL_TEXTURE7_ARB 0x84C7 #define GL_TEXTURE8_ARB 0x84C8 #define GL_TEXTURE9_ARB 0x84C9 #define GL_TEXTURE10_ARB 0x84CA #define GL_TEXTURE11_ARB 0x84CB #define GL_TEXTURE12_ARB 0x84CC #define GL_TEXTURE13_ARB 0x84CD #define GL_TEXTURE14_ARB 0x84CE #define GL_TEXTURE15_ARB 0x84CF #define GL_TEXTURE16_ARB 0x84D0 #define GL_TEXTURE17_ARB 0x84D1 #define GL_TEXTURE18_ARB 0x84D2 #define GL_TEXTURE19_ARB 0x84D3 #define GL_TEXTURE20_ARB 0x84D4 #define GL_TEXTURE21_ARB 0x84D5 #define GL_TEXTURE22_ARB 0x84D6 #define GL_TEXTURE23_ARB 0x84D7 #define GL_TEXTURE24_ARB 0x84D8 #define GL_TEXTURE25_ARB 0x84D9 #define GL_TEXTURE26_ARB 0x84DA #define GL_TEXTURE27_ARB 0x84DB #define GL_TEXTURE28_ARB 0x84DC #define GL_TEXTURE29_ARB 0x84DD #define GL_TEXTURE30_ARB 0x84DE #define GL_TEXTURE31_ARB 0x84DF #define GL_ACTIVE_TEXTURE_ARB 0x84E0 #define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 #define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 #endif #ifndef GL_ARB_transpose_matrix #define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 #define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 #define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 #define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 #endif #ifndef GL_ARB_multisample #define GL_MULTISAMPLE_ARB 0x809D #define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E #define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F #define GL_SAMPLE_COVERAGE_ARB 0x80A0 #define GL_SAMPLE_BUFFERS_ARB 0x80A8 #define GL_SAMPLES_ARB 0x80A9 #define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA #define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB #define GL_MULTISAMPLE_BIT_ARB 0x20000000 #endif #ifndef GL_ARB_texture_env_add #endif #ifndef GL_ARB_texture_cube_map #define GL_NORMAL_MAP_ARB 0x8511 #define GL_REFLECTION_MAP_ARB 0x8512 #define GL_TEXTURE_CUBE_MAP_ARB 0x8513 #define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 #define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A #define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B #define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C #endif #ifndef GL_ARB_texture_compression #define GL_COMPRESSED_ALPHA_ARB 0x84E9 #define GL_COMPRESSED_LUMINANCE_ARB 0x84EA #define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB #define GL_COMPRESSED_INTENSITY_ARB 0x84EC #define GL_COMPRESSED_RGB_ARB 0x84ED #define GL_COMPRESSED_RGBA_ARB 0x84EE #define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF #define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 #define GL_TEXTURE_COMPRESSED_ARB 0x86A1 #define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 #define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 #endif #ifndef GL_ARB_texture_border_clamp #define GL_CLAMP_TO_BORDER_ARB 0x812D #endif #ifndef GL_ARB_point_parameters #define GL_POINT_SIZE_MIN_ARB 0x8126 #define GL_POINT_SIZE_MAX_ARB 0x8127 #define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 #define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 #endif #ifndef GL_ARB_vertex_blend #define GL_MAX_VERTEX_UNITS_ARB 0x86A4 #define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 #define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 #define GL_VERTEX_BLEND_ARB 0x86A7 #define GL_CURRENT_WEIGHT_ARB 0x86A8 #define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 #define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA #define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB #define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC #define GL_WEIGHT_ARRAY_ARB 0x86AD #define GL_MODELVIEW0_ARB 0x1700 #define GL_MODELVIEW1_ARB 0x850A #define GL_MODELVIEW2_ARB 0x8722 #define GL_MODELVIEW3_ARB 0x8723 #define GL_MODELVIEW4_ARB 0x8724 #define GL_MODELVIEW5_ARB 0x8725 #define GL_MODELVIEW6_ARB 0x8726 #define GL_MODELVIEW7_ARB 0x8727 #define GL_MODELVIEW8_ARB 0x8728 #define GL_MODELVIEW9_ARB 0x8729 #define GL_MODELVIEW10_ARB 0x872A #define GL_MODELVIEW11_ARB 0x872B #define GL_MODELVIEW12_ARB 0x872C #define GL_MODELVIEW13_ARB 0x872D #define GL_MODELVIEW14_ARB 0x872E #define GL_MODELVIEW15_ARB 0x872F #define GL_MODELVIEW16_ARB 0x8730 #define GL_MODELVIEW17_ARB 0x8731 #define GL_MODELVIEW18_ARB 0x8732 #define GL_MODELVIEW19_ARB 0x8733 #define GL_MODELVIEW20_ARB 0x8734 #define GL_MODELVIEW21_ARB 0x8735 #define GL_MODELVIEW22_ARB 0x8736 #define GL_MODELVIEW23_ARB 0x8737 #define GL_MODELVIEW24_ARB 0x8738 #define GL_MODELVIEW25_ARB 0x8739 #define GL_MODELVIEW26_ARB 0x873A #define GL_MODELVIEW27_ARB 0x873B #define GL_MODELVIEW28_ARB 0x873C #define GL_MODELVIEW29_ARB 0x873D #define GL_MODELVIEW30_ARB 0x873E #define GL_MODELVIEW31_ARB 0x873F #endif #ifndef GL_ARB_matrix_palette #define GL_MATRIX_PALETTE_ARB 0x8840 #define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 #define GL_MAX_PALETTE_MATRICES_ARB 0x8842 #define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 #define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 #define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 #define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 #define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 #define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 #define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 #endif #ifndef GL_ARB_texture_env_combine #define GL_COMBINE_ARB 0x8570 #define GL_COMBINE_RGB_ARB 0x8571 #define GL_COMBINE_ALPHA_ARB 0x8572 #define GL_SOURCE0_RGB_ARB 0x8580 #define GL_SOURCE1_RGB_ARB 0x8581 #define GL_SOURCE2_RGB_ARB 0x8582 #define GL_SOURCE0_ALPHA_ARB 0x8588 #define GL_SOURCE1_ALPHA_ARB 0x8589 #define GL_SOURCE2_ALPHA_ARB 0x858A #define GL_OPERAND0_RGB_ARB 0x8590 #define GL_OPERAND1_RGB_ARB 0x8591 #define GL_OPERAND2_RGB_ARB 0x8592 #define GL_OPERAND0_ALPHA_ARB 0x8598 #define GL_OPERAND1_ALPHA_ARB 0x8599 #define GL_OPERAND2_ALPHA_ARB 0x859A #define GL_RGB_SCALE_ARB 0x8573 #define GL_ADD_SIGNED_ARB 0x8574 #define GL_INTERPOLATE_ARB 0x8575 #define GL_SUBTRACT_ARB 0x84E7 #define GL_CONSTANT_ARB 0x8576 #define GL_PRIMARY_COLOR_ARB 0x8577 #define GL_PREVIOUS_ARB 0x8578 #endif #ifndef GL_ARB_texture_env_crossbar #endif #ifndef GL_ARB_texture_env_dot3 #define GL_DOT3_RGB_ARB 0x86AE #define GL_DOT3_RGBA_ARB 0x86AF #endif #ifndef GL_ARB_texture_mirrored_repeat #define GL_MIRRORED_REPEAT_ARB 0x8370 #endif #ifndef GL_ARB_depth_texture #define GL_DEPTH_COMPONENT16_ARB 0x81A5 #define GL_DEPTH_COMPONENT24_ARB 0x81A6 #define GL_DEPTH_COMPONENT32_ARB 0x81A7 #define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A #define GL_DEPTH_TEXTURE_MODE_ARB 0x884B #endif #ifndef GL_ARB_shadow #define GL_TEXTURE_COMPARE_MODE_ARB 0x884C #define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D #define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E #endif #ifndef GL_ARB_shadow_ambient #define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF #endif #ifndef GL_ARB_window_pos #endif #ifndef GL_ARB_vertex_program #define GL_COLOR_SUM_ARB 0x8458 #define GL_VERTEX_PROGRAM_ARB 0x8620 #define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 #define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 #define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 #define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 #define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 #define GL_PROGRAM_LENGTH_ARB 0x8627 #define GL_PROGRAM_STRING_ARB 0x8628 #define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E #define GL_MAX_PROGRAM_MATRICES_ARB 0x862F #define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 #define GL_CURRENT_MATRIX_ARB 0x8641 #define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 #define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 #define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 #define GL_PROGRAM_ERROR_POSITION_ARB 0x864B #define GL_PROGRAM_BINDING_ARB 0x8677 #define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 #define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A #define GL_PROGRAM_ERROR_STRING_ARB 0x8874 #define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 #define GL_PROGRAM_FORMAT_ARB 0x8876 #define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 #define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 #define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 #define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 #define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 #define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 #define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 #define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 #define GL_PROGRAM_PARAMETERS_ARB 0x88A8 #define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 #define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA #define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB #define GL_PROGRAM_ATTRIBS_ARB 0x88AC #define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD #define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE #define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF #define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 #define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 #define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 #define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 #define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 #define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 #define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 #define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 #define GL_MATRIX0_ARB 0x88C0 #define GL_MATRIX1_ARB 0x88C1 #define GL_MATRIX2_ARB 0x88C2 #define GL_MATRIX3_ARB 0x88C3 #define GL_MATRIX4_ARB 0x88C4 #define GL_MATRIX5_ARB 0x88C5 #define GL_MATRIX6_ARB 0x88C6 #define GL_MATRIX7_ARB 0x88C7 #define GL_MATRIX8_ARB 0x88C8 #define GL_MATRIX9_ARB 0x88C9 #define GL_MATRIX10_ARB 0x88CA #define GL_MATRIX11_ARB 0x88CB #define GL_MATRIX12_ARB 0x88CC #define GL_MATRIX13_ARB 0x88CD #define GL_MATRIX14_ARB 0x88CE #define GL_MATRIX15_ARB 0x88CF #define GL_MATRIX16_ARB 0x88D0 #define GL_MATRIX17_ARB 0x88D1 #define GL_MATRIX18_ARB 0x88D2 #define GL_MATRIX19_ARB 0x88D3 #define GL_MATRIX20_ARB 0x88D4 #define GL_MATRIX21_ARB 0x88D5 #define GL_MATRIX22_ARB 0x88D6 #define GL_MATRIX23_ARB 0x88D7 #define GL_MATRIX24_ARB 0x88D8 #define GL_MATRIX25_ARB 0x88D9 #define GL_MATRIX26_ARB 0x88DA #define GL_MATRIX27_ARB 0x88DB #define GL_MATRIX28_ARB 0x88DC #define GL_MATRIX29_ARB 0x88DD #define GL_MATRIX30_ARB 0x88DE #define GL_MATRIX31_ARB 0x88DF #endif #ifndef GL_ARB_fragment_program #define GL_FRAGMENT_PROGRAM_ARB 0x8804 #define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 #define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 #define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 #define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 #define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 #define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A #define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B #define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C #define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D #define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E #define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F #define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 #define GL_MAX_TEXTURE_COORDS_ARB 0x8871 #define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 #endif #ifndef GL_ARB_vertex_buffer_object #define GL_BUFFER_SIZE_ARB 0x8764 #define GL_BUFFER_USAGE_ARB 0x8765 #define GL_ARRAY_BUFFER_ARB 0x8892 #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 #define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 #define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 #define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 #define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 #define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 #define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 #define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A #define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B #define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C #define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D #define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F #define GL_READ_ONLY_ARB 0x88B8 #define GL_WRITE_ONLY_ARB 0x88B9 #define GL_READ_WRITE_ARB 0x88BA #define GL_BUFFER_ACCESS_ARB 0x88BB #define GL_BUFFER_MAPPED_ARB 0x88BC #define GL_BUFFER_MAP_POINTER_ARB 0x88BD #define GL_STREAM_DRAW_ARB 0x88E0 #define GL_STREAM_READ_ARB 0x88E1 #define GL_STREAM_COPY_ARB 0x88E2 #define GL_STATIC_DRAW_ARB 0x88E4 #define GL_STATIC_READ_ARB 0x88E5 #define GL_STATIC_COPY_ARB 0x88E6 #define GL_DYNAMIC_DRAW_ARB 0x88E8 #define GL_DYNAMIC_READ_ARB 0x88E9 #define GL_DYNAMIC_COPY_ARB 0x88EA #endif #ifndef GL_ARB_occlusion_query #define GL_QUERY_COUNTER_BITS_ARB 0x8864 #define GL_CURRENT_QUERY_ARB 0x8865 #define GL_QUERY_RESULT_ARB 0x8866 #define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 #define GL_SAMPLES_PASSED_ARB 0x8914 #endif #ifndef GL_ARB_shader_objects #define GL_PROGRAM_OBJECT_ARB 0x8B40 #define GL_SHADER_OBJECT_ARB 0x8B48 #define GL_OBJECT_TYPE_ARB 0x8B4E #define GL_OBJECT_SUBTYPE_ARB 0x8B4F #define GL_FLOAT_VEC2_ARB 0x8B50 #define GL_FLOAT_VEC3_ARB 0x8B51 #define GL_FLOAT_VEC4_ARB 0x8B52 #define GL_INT_VEC2_ARB 0x8B53 #define GL_INT_VEC3_ARB 0x8B54 #define GL_INT_VEC4_ARB 0x8B55 #define GL_BOOL_ARB 0x8B56 #define GL_BOOL_VEC2_ARB 0x8B57 #define GL_BOOL_VEC3_ARB 0x8B58 #define GL_BOOL_VEC4_ARB 0x8B59 #define GL_FLOAT_MAT2_ARB 0x8B5A #define GL_FLOAT_MAT3_ARB 0x8B5B #define GL_FLOAT_MAT4_ARB 0x8B5C #define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 #define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 #define GL_OBJECT_LINK_STATUS_ARB 0x8B82 #define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 #define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 #define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 #define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 #define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 #define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 #endif #ifndef GL_ARB_vertex_shader #define GL_VERTEX_SHADER_ARB 0x8B31 #define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A #define GL_MAX_VARYING_FLOATS_ARB 0x8B4B #define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C #define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D #define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 #define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A #endif #ifndef GL_ARB_fragment_shader #define GL_FRAGMENT_SHADER_ARB 0x8B30 #define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 #endif #ifndef GL_ARB_shading_language_100 #endif #ifndef GL_ARB_texture_non_power_of_two #endif #ifndef GL_ARB_point_sprite #define GL_POINT_SPRITE_ARB 0x8861 #define GL_COORD_REPLACE_ARB 0x8862 #endif #ifndef GL_ARB_fragment_program_shadow #endif #ifndef GL_EXT_abgr #define GL_ABGR_EXT 0x8000 #endif #ifndef GL_EXT_blend_color #define GL_CONSTANT_COLOR_EXT 0x8001 #define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 #define GL_CONSTANT_ALPHA_EXT 0x8003 #define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 #define GL_BLEND_COLOR_EXT 0x8005 #endif #ifndef GL_EXT_polygon_offset #define GL_POLYGON_OFFSET_EXT 0x8037 #define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 #define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 #endif #ifndef GL_EXT_texture #define GL_ALPHA4_EXT 0x803B #define GL_ALPHA8_EXT 0x803C #define GL_ALPHA12_EXT 0x803D #define GL_ALPHA16_EXT 0x803E #define GL_LUMINANCE4_EXT 0x803F #define GL_LUMINANCE8_EXT 0x8040 #define GL_LUMINANCE12_EXT 0x8041 #define GL_LUMINANCE16_EXT 0x8042 #define GL_LUMINANCE4_ALPHA4_EXT 0x8043 #define GL_LUMINANCE6_ALPHA2_EXT 0x8044 #define GL_LUMINANCE8_ALPHA8_EXT 0x8045 #define GL_LUMINANCE12_ALPHA4_EXT 0x8046 #define GL_LUMINANCE12_ALPHA12_EXT 0x8047 #define GL_LUMINANCE16_ALPHA16_EXT 0x8048 #define GL_INTENSITY_EXT 0x8049 #define GL_INTENSITY4_EXT 0x804A #define GL_INTENSITY8_EXT 0x804B #define GL_INTENSITY12_EXT 0x804C #define GL_INTENSITY16_EXT 0x804D #define GL_RGB2_EXT 0x804E #define GL_RGB4_EXT 0x804F #define GL_RGB5_EXT 0x8050 #define GL_RGB8_EXT 0x8051 #define GL_RGB10_EXT 0x8052 #define GL_RGB12_EXT 0x8053 #define GL_RGB16_EXT 0x8054 #define GL_RGBA2_EXT 0x8055 #define GL_RGBA4_EXT 0x8056 #define GL_RGB5_A1_EXT 0x8057 #define GL_RGBA8_EXT 0x8058 #define GL_RGB10_A2_EXT 0x8059 #define GL_RGBA12_EXT 0x805A #define GL_RGBA16_EXT 0x805B #define GL_TEXTURE_RED_SIZE_EXT 0x805C #define GL_TEXTURE_GREEN_SIZE_EXT 0x805D #define GL_TEXTURE_BLUE_SIZE_EXT 0x805E #define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F #define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 #define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 #define GL_REPLACE_EXT 0x8062 #define GL_PROXY_TEXTURE_1D_EXT 0x8063 #define GL_PROXY_TEXTURE_2D_EXT 0x8064 #define GL_TEXTURE_TOO_LARGE_EXT 0x8065 #endif #ifndef GL_EXT_texture3D #define GL_PACK_SKIP_IMAGES_EXT 0x806B #define GL_PACK_IMAGE_HEIGHT_EXT 0x806C #define GL_UNPACK_SKIP_IMAGES_EXT 0x806D #define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E #define GL_TEXTURE_3D_EXT 0x806F #define GL_PROXY_TEXTURE_3D_EXT 0x8070 #define GL_TEXTURE_DEPTH_EXT 0x8071 #define GL_TEXTURE_WRAP_R_EXT 0x8072 #define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 #endif #ifndef GL_SGIS_texture_filter4 #define GL_FILTER4_SGIS 0x8146 #define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 #endif #ifndef GL_EXT_subtexture #endif #ifndef GL_EXT_copy_texture #endif #ifndef GL_EXT_histogram #define GL_HISTOGRAM_EXT 0x8024 #define GL_PROXY_HISTOGRAM_EXT 0x8025 #define GL_HISTOGRAM_WIDTH_EXT 0x8026 #define GL_HISTOGRAM_FORMAT_EXT 0x8027 #define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 #define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 #define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A #define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B #define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C #define GL_HISTOGRAM_SINK_EXT 0x802D #define GL_MINMAX_EXT 0x802E #define GL_MINMAX_FORMAT_EXT 0x802F #define GL_MINMAX_SINK_EXT 0x8030 #define GL_TABLE_TOO_LARGE_EXT 0x8031 #endif #ifndef GL_EXT_convolution #define GL_CONVOLUTION_1D_EXT 0x8010 #define GL_CONVOLUTION_2D_EXT 0x8011 #define GL_SEPARABLE_2D_EXT 0x8012 #define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 #define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 #define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 #define GL_REDUCE_EXT 0x8016 #define GL_CONVOLUTION_FORMAT_EXT 0x8017 #define GL_CONVOLUTION_WIDTH_EXT 0x8018 #define GL_CONVOLUTION_HEIGHT_EXT 0x8019 #define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A #define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B #define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C #define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D #define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E #define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F #define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 #define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 #define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 #define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 #endif #ifndef GL_SGI_color_matrix #define GL_COLOR_MATRIX_SGI 0x80B1 #define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 #define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 #define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 #define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 #define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 #define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 #define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 #define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 #define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA #define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB #endif #ifndef GL_SGI_color_table #define GL_COLOR_TABLE_SGI 0x80D0 #define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 #define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 #define GL_PROXY_COLOR_TABLE_SGI 0x80D3 #define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 #define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 #define GL_COLOR_TABLE_SCALE_SGI 0x80D6 #define GL_COLOR_TABLE_BIAS_SGI 0x80D7 #define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 #define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 #define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA #define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB #define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC #define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD #define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE #define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF #endif #ifndef GL_SGIS_pixel_texture #define GL_PIXEL_TEXTURE_SGIS 0x8353 #define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 #define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 #define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 #endif #ifndef GL_SGIX_pixel_texture #define GL_PIXEL_TEX_GEN_SGIX 0x8139 #define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B #endif #ifndef GL_SGIS_texture4D #define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 #define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 #define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 #define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 #define GL_TEXTURE_4D_SGIS 0x8134 #define GL_PROXY_TEXTURE_4D_SGIS 0x8135 #define GL_TEXTURE_4DSIZE_SGIS 0x8136 #define GL_TEXTURE_WRAP_Q_SGIS 0x8137 #define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 #define GL_TEXTURE_4D_BINDING_SGIS 0x814F #endif #ifndef GL_SGI_texture_color_table #define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC #define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD #endif #ifndef GL_EXT_cmyka #define GL_CMYK_EXT 0x800C #define GL_CMYKA_EXT 0x800D #define GL_PACK_CMYK_HINT_EXT 0x800E #define GL_UNPACK_CMYK_HINT_EXT 0x800F #endif #ifndef GL_EXT_texture_object #define GL_TEXTURE_PRIORITY_EXT 0x8066 #define GL_TEXTURE_RESIDENT_EXT 0x8067 #define GL_TEXTURE_1D_BINDING_EXT 0x8068 #define GL_TEXTURE_2D_BINDING_EXT 0x8069 #define GL_TEXTURE_3D_BINDING_EXT 0x806A #endif #ifndef GL_SGIS_detail_texture #define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 #define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 #define GL_LINEAR_DETAIL_SGIS 0x8097 #define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 #define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 #define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A #define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B #define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C #endif #ifndef GL_SGIS_sharpen_texture #define GL_LINEAR_SHARPEN_SGIS 0x80AD #define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE #define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF #define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 #endif #ifndef GL_EXT_packed_pixels #define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 #define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 #define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 #define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 #define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 #endif #ifndef GL_SGIS_texture_lod #define GL_TEXTURE_MIN_LOD_SGIS 0x813A #define GL_TEXTURE_MAX_LOD_SGIS 0x813B #define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C #define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D #endif #ifndef GL_SGIS_multisample #define GL_MULTISAMPLE_SGIS 0x809D #define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E #define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F #define GL_SAMPLE_MASK_SGIS 0x80A0 #define GL_1PASS_SGIS 0x80A1 #define GL_2PASS_0_SGIS 0x80A2 #define GL_2PASS_1_SGIS 0x80A3 #define GL_4PASS_0_SGIS 0x80A4 #define GL_4PASS_1_SGIS 0x80A5 #define GL_4PASS_2_SGIS 0x80A6 #define GL_4PASS_3_SGIS 0x80A7 #define GL_SAMPLE_BUFFERS_SGIS 0x80A8 #define GL_SAMPLES_SGIS 0x80A9 #define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA #define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB #define GL_SAMPLE_PATTERN_SGIS 0x80AC #endif #ifndef GL_EXT_rescale_normal #define GL_RESCALE_NORMAL_EXT 0x803A #endif #ifndef GL_EXT_vertex_array #define GL_VERTEX_ARRAY_EXT 0x8074 #define GL_NORMAL_ARRAY_EXT 0x8075 #define GL_COLOR_ARRAY_EXT 0x8076 #define GL_INDEX_ARRAY_EXT 0x8077 #define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 #define GL_EDGE_FLAG_ARRAY_EXT 0x8079 #define GL_VERTEX_ARRAY_SIZE_EXT 0x807A #define GL_VERTEX_ARRAY_TYPE_EXT 0x807B #define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C #define GL_VERTEX_ARRAY_COUNT_EXT 0x807D #define GL_NORMAL_ARRAY_TYPE_EXT 0x807E #define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F #define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 #define GL_COLOR_ARRAY_SIZE_EXT 0x8081 #define GL_COLOR_ARRAY_TYPE_EXT 0x8082 #define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 #define GL_COLOR_ARRAY_COUNT_EXT 0x8084 #define GL_INDEX_ARRAY_TYPE_EXT 0x8085 #define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 #define GL_INDEX_ARRAY_COUNT_EXT 0x8087 #define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 #define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 #define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A #define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B #define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C #define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D #define GL_VERTEX_ARRAY_POINTER_EXT 0x808E #define GL_NORMAL_ARRAY_POINTER_EXT 0x808F #define GL_COLOR_ARRAY_POINTER_EXT 0x8090 #define GL_INDEX_ARRAY_POINTER_EXT 0x8091 #define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 #define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 #endif #ifndef GL_EXT_misc_attribute #endif #ifndef GL_SGIS_generate_mipmap #define GL_GENERATE_MIPMAP_SGIS 0x8191 #define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 #endif #ifndef GL_SGIX_clipmap #define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 #define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 #define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 #define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 #define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 #define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 #define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 #define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 #define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 #define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D #define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E #define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F #endif #ifndef GL_SGIX_shadow #define GL_TEXTURE_COMPARE_SGIX 0x819A #define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B #define GL_TEXTURE_LEQUAL_R_SGIX 0x819C #define GL_TEXTURE_GEQUAL_R_SGIX 0x819D #endif #ifndef GL_SGIS_texture_edge_clamp #define GL_CLAMP_TO_EDGE_SGIS 0x812F #endif #ifndef GL_EXT_blend_minmax #define GL_FUNC_ADD_EXT 0x8006 #define GL_MIN_EXT 0x8007 #define GL_MAX_EXT 0x8008 #define GL_BLEND_EQUATION_EXT 0x8009 #endif #ifndef GL_EXT_blend_subtract #define GL_FUNC_SUBTRACT_EXT 0x800A #define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B #endif #ifndef GL_EXT_blend_logic_op #endif #ifndef GL_SGIX_interlace #define GL_INTERLACE_SGIX 0x8094 #endif #ifndef GL_SGIX_pixel_tiles #define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E #define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F #define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 #define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 #define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 #define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 #define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 #define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 #endif #ifndef GL_SGIS_texture_select #define GL_DUAL_ALPHA4_SGIS 0x8110 #define GL_DUAL_ALPHA8_SGIS 0x8111 #define GL_DUAL_ALPHA12_SGIS 0x8112 #define GL_DUAL_ALPHA16_SGIS 0x8113 #define GL_DUAL_LUMINANCE4_SGIS 0x8114 #define GL_DUAL_LUMINANCE8_SGIS 0x8115 #define GL_DUAL_LUMINANCE12_SGIS 0x8116 #define GL_DUAL_LUMINANCE16_SGIS 0x8117 #define GL_DUAL_INTENSITY4_SGIS 0x8118 #define GL_DUAL_INTENSITY8_SGIS 0x8119 #define GL_DUAL_INTENSITY12_SGIS 0x811A #define GL_DUAL_INTENSITY16_SGIS 0x811B #define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C #define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D #define GL_QUAD_ALPHA4_SGIS 0x811E #define GL_QUAD_ALPHA8_SGIS 0x811F #define GL_QUAD_LUMINANCE4_SGIS 0x8120 #define GL_QUAD_LUMINANCE8_SGIS 0x8121 #define GL_QUAD_INTENSITY4_SGIS 0x8122 #define GL_QUAD_INTENSITY8_SGIS 0x8123 #define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 #define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 #endif #ifndef GL_SGIX_sprite #define GL_SPRITE_SGIX 0x8148 #define GL_SPRITE_MODE_SGIX 0x8149 #define GL_SPRITE_AXIS_SGIX 0x814A #define GL_SPRITE_TRANSLATION_SGIX 0x814B #define GL_SPRITE_AXIAL_SGIX 0x814C #define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D #define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E #endif #ifndef GL_SGIX_texture_multi_buffer #define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E #endif #ifndef GL_EXT_point_parameters #define GL_POINT_SIZE_MIN_EXT 0x8126 #define GL_POINT_SIZE_MAX_EXT 0x8127 #define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 #define GL_DISTANCE_ATTENUATION_EXT 0x8129 #endif #ifndef GL_SGIS_point_parameters #define GL_POINT_SIZE_MIN_SGIS 0x8126 #define GL_POINT_SIZE_MAX_SGIS 0x8127 #define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 #define GL_DISTANCE_ATTENUATION_SGIS 0x8129 #endif #ifndef GL_SGIX_instruments #define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 #define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 #endif #ifndef GL_SGIX_texture_scale_bias #define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 #define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A #define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B #define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C #endif #ifndef GL_SGIX_framezoom #define GL_FRAMEZOOM_SGIX 0x818B #define GL_FRAMEZOOM_FACTOR_SGIX 0x818C #define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D #endif #ifndef GL_SGIX_tag_sample_buffer #endif #ifndef GL_FfdMaskSGIX #define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 #define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 #endif #ifndef GL_SGIX_polynomial_ffd #define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 #define GL_TEXTURE_DEFORMATION_SGIX 0x8195 #define GL_DEFORMATIONS_MASK_SGIX 0x8196 #define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 #endif #ifndef GL_SGIX_reference_plane #define GL_REFERENCE_PLANE_SGIX 0x817D #define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E #endif #ifndef GL_SGIX_flush_raster #endif #ifndef GL_SGIX_depth_texture #define GL_DEPTH_COMPONENT16_SGIX 0x81A5 #define GL_DEPTH_COMPONENT24_SGIX 0x81A6 #define GL_DEPTH_COMPONENT32_SGIX 0x81A7 #endif #ifndef GL_SGIS_fog_function #define GL_FOG_FUNC_SGIS 0x812A #define GL_FOG_FUNC_POINTS_SGIS 0x812B #define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C #endif #ifndef GL_SGIX_fog_offset #define GL_FOG_OFFSET_SGIX 0x8198 #define GL_FOG_OFFSET_VALUE_SGIX 0x8199 #endif #ifndef GL_HP_image_transform #define GL_IMAGE_SCALE_X_HP 0x8155 #define GL_IMAGE_SCALE_Y_HP 0x8156 #define GL_IMAGE_TRANSLATE_X_HP 0x8157 #define GL_IMAGE_TRANSLATE_Y_HP 0x8158 #define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 #define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A #define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B #define GL_IMAGE_MAG_FILTER_HP 0x815C #define GL_IMAGE_MIN_FILTER_HP 0x815D #define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E #define GL_CUBIC_HP 0x815F #define GL_AVERAGE_HP 0x8160 #define GL_IMAGE_TRANSFORM_2D_HP 0x8161 #define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 #define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 #endif #ifndef GL_HP_convolution_border_modes #define GL_IGNORE_BORDER_HP 0x8150 #define GL_CONSTANT_BORDER_HP 0x8151 #define GL_REPLICATE_BORDER_HP 0x8153 #define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 #endif #ifndef GL_INGR_palette_buffer #endif #ifndef GL_SGIX_texture_add_env #define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE #endif #ifndef GL_EXT_color_subtable #endif #ifndef GL_PGI_vertex_hints #define GL_VERTEX_DATA_HINT_PGI 0x1A22A #define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B #define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C #define GL_MAX_VERTEX_HINT_PGI 0x1A22D #define GL_COLOR3_BIT_PGI 0x00010000 #define GL_COLOR4_BIT_PGI 0x00020000 #define GL_EDGEFLAG_BIT_PGI 0x00040000 #define GL_INDEX_BIT_PGI 0x00080000 #define GL_MAT_AMBIENT_BIT_PGI 0x00100000 #define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 #define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 #define GL_MAT_EMISSION_BIT_PGI 0x00800000 #define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 #define GL_MAT_SHININESS_BIT_PGI 0x02000000 #define GL_MAT_SPECULAR_BIT_PGI 0x04000000 #define GL_NORMAL_BIT_PGI 0x08000000 #define GL_TEXCOORD1_BIT_PGI 0x10000000 #define GL_TEXCOORD2_BIT_PGI 0x20000000 #define GL_TEXCOORD3_BIT_PGI 0x40000000 #define GL_TEXCOORD4_BIT_PGI 0x80000000 #define GL_VERTEX23_BIT_PGI 0x00000004 #define GL_VERTEX4_BIT_PGI 0x00000008 #endif #ifndef GL_PGI_misc_hints #define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 #define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD #define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE #define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 #define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 #define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 #define GL_ALWAYS_FAST_HINT_PGI 0x1A20C #define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D #define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E #define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F #define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 #define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 #define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 #define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 #define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 #define GL_FULL_STIPPLE_HINT_PGI 0x1A219 #define GL_CLIP_NEAR_HINT_PGI 0x1A220 #define GL_CLIP_FAR_HINT_PGI 0x1A221 #define GL_WIDE_LINE_HINT_PGI 0x1A222 #define GL_BACK_NORMALS_HINT_PGI 0x1A223 #endif #ifndef GL_EXT_paletted_texture #define GL_COLOR_INDEX1_EXT 0x80E2 #define GL_COLOR_INDEX2_EXT 0x80E3 #define GL_COLOR_INDEX4_EXT 0x80E4 #define GL_COLOR_INDEX8_EXT 0x80E5 #define GL_COLOR_INDEX12_EXT 0x80E6 #define GL_COLOR_INDEX16_EXT 0x80E7 #define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED #endif #ifndef GL_EXT_clip_volume_hint #define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 #endif #ifndef GL_SGIX_list_priority #define GL_LIST_PRIORITY_SGIX 0x8182 #endif #ifndef GL_SGIX_ir_instrument1 #define GL_IR_INSTRUMENT1_SGIX 0x817F #endif #ifndef GL_SGIX_calligraphic_fragment #define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 #endif #ifndef GL_SGIX_texture_lod_bias #define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E #define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F #define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 #endif #ifndef GL_SGIX_shadow_ambient #define GL_SHADOW_AMBIENT_SGIX 0x80BF #endif #ifndef GL_EXT_index_texture #endif #ifndef GL_EXT_index_material #define GL_INDEX_MATERIAL_EXT 0x81B8 #define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 #define GL_INDEX_MATERIAL_FACE_EXT 0x81BA #endif #ifndef GL_EXT_index_func #define GL_INDEX_TEST_EXT 0x81B5 #define GL_INDEX_TEST_FUNC_EXT 0x81B6 #define GL_INDEX_TEST_REF_EXT 0x81B7 #endif #ifndef GL_EXT_index_array_formats #define GL_IUI_V2F_EXT 0x81AD #define GL_IUI_V3F_EXT 0x81AE #define GL_IUI_N3F_V2F_EXT 0x81AF #define GL_IUI_N3F_V3F_EXT 0x81B0 #define GL_T2F_IUI_V2F_EXT 0x81B1 #define GL_T2F_IUI_V3F_EXT 0x81B2 #define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 #define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 #endif #ifndef GL_EXT_compiled_vertex_array #define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 #define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 #endif #ifndef GL_EXT_cull_vertex #define GL_CULL_VERTEX_EXT 0x81AA #define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB #define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC #endif #ifndef GL_SGIX_ycrcb #define GL_YCRCB_422_SGIX 0x81BB #define GL_YCRCB_444_SGIX 0x81BC #endif #ifndef GL_SGIX_fragment_lighting #define GL_FRAGMENT_LIGHTING_SGIX 0x8400 #define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 #define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 #define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 #define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 #define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 #define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 #define GL_LIGHT_ENV_MODE_SGIX 0x8407 #define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 #define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 #define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A #define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B #define GL_FRAGMENT_LIGHT0_SGIX 0x840C #define GL_FRAGMENT_LIGHT1_SGIX 0x840D #define GL_FRAGMENT_LIGHT2_SGIX 0x840E #define GL_FRAGMENT_LIGHT3_SGIX 0x840F #define GL_FRAGMENT_LIGHT4_SGIX 0x8410 #define GL_FRAGMENT_LIGHT5_SGIX 0x8411 #define GL_FRAGMENT_LIGHT6_SGIX 0x8412 #define GL_FRAGMENT_LIGHT7_SGIX 0x8413 #endif #ifndef GL_IBM_rasterpos_clip #define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 #endif #ifndef GL_HP_texture_lighting #define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 #define GL_TEXTURE_POST_SPECULAR_HP 0x8168 #define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 #endif #ifndef GL_EXT_draw_range_elements #define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 #define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 #endif #ifndef GL_WIN_phong_shading #define GL_PHONG_WIN 0x80EA #define GL_PHONG_HINT_WIN 0x80EB #endif #ifndef GL_WIN_specular_fog #define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC #endif #ifndef GL_EXT_light_texture #define GL_FRAGMENT_MATERIAL_EXT 0x8349 #define GL_FRAGMENT_NORMAL_EXT 0x834A #define GL_FRAGMENT_COLOR_EXT 0x834C #define GL_ATTENUATION_EXT 0x834D #define GL_SHADOW_ATTENUATION_EXT 0x834E #define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F #define GL_TEXTURE_LIGHT_EXT 0x8350 #define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 #define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 /* reuse GL_FRAGMENT_DEPTH_EXT */ #endif #ifndef GL_SGIX_blend_alpha_minmax #define GL_ALPHA_MIN_SGIX 0x8320 #define GL_ALPHA_MAX_SGIX 0x8321 #endif #ifndef GL_SGIX_impact_pixel_texture #define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 #define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 #define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 #define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 #define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 #define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 #define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A #endif #ifndef GL_EXT_bgra #define GL_BGR_EXT 0x80E0 #define GL_BGRA_EXT 0x80E1 #endif #ifndef GL_SGIX_async #define GL_ASYNC_MARKER_SGIX 0x8329 #endif #ifndef GL_SGIX_async_pixel #define GL_ASYNC_TEX_IMAGE_SGIX 0x835C #define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D #define GL_ASYNC_READ_PIXELS_SGIX 0x835E #define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F #define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 #define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 #endif #ifndef GL_SGIX_async_histogram #define GL_ASYNC_HISTOGRAM_SGIX 0x832C #define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D #endif #ifndef GL_INTEL_texture_scissor #endif #ifndef GL_INTEL_parallel_arrays #define GL_PARALLEL_ARRAYS_INTEL 0x83F4 #define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 #define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 #define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 #define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 #endif #ifndef GL_HP_occlusion_test #define GL_OCCLUSION_TEST_HP 0x8165 #define GL_OCCLUSION_TEST_RESULT_HP 0x8166 #endif #ifndef GL_EXT_pixel_transform #define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 #define GL_PIXEL_MAG_FILTER_EXT 0x8331 #define GL_PIXEL_MIN_FILTER_EXT 0x8332 #define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 #define GL_CUBIC_EXT 0x8334 #define GL_AVERAGE_EXT 0x8335 #define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 #define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 #define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 #endif #ifndef GL_EXT_pixel_transform_color_table #endif #ifndef GL_EXT_shared_texture_palette #define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB #endif #ifndef GL_EXT_separate_specular_color #define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 #define GL_SINGLE_COLOR_EXT 0x81F9 #define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA #endif #ifndef GL_EXT_secondary_color #define GL_COLOR_SUM_EXT 0x8458 #define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 #define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A #define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B #define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C #define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D #define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E #endif #ifndef GL_EXT_texture_perturb_normal #define GL_PERTURB_EXT 0x85AE #define GL_TEXTURE_NORMAL_EXT 0x85AF #endif #ifndef GL_EXT_multi_draw_arrays #endif #ifndef GL_EXT_fog_coord #define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 #define GL_FOG_COORDINATE_EXT 0x8451 #define GL_FRAGMENT_DEPTH_EXT 0x8452 #define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 #define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 #define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 #define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 #define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 #endif #ifndef GL_REND_screen_coordinates #define GL_SCREEN_COORDINATES_REND 0x8490 #define GL_INVERTED_SCREEN_W_REND 0x8491 #endif #ifndef GL_EXT_coordinate_frame #define GL_TANGENT_ARRAY_EXT 0x8439 #define GL_BINORMAL_ARRAY_EXT 0x843A #define GL_CURRENT_TANGENT_EXT 0x843B #define GL_CURRENT_BINORMAL_EXT 0x843C #define GL_TANGENT_ARRAY_TYPE_EXT 0x843E #define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F #define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 #define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 #define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 #define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 #define GL_MAP1_TANGENT_EXT 0x8444 #define GL_MAP2_TANGENT_EXT 0x8445 #define GL_MAP1_BINORMAL_EXT 0x8446 #define GL_MAP2_BINORMAL_EXT 0x8447 #endif #ifndef GL_EXT_texture_env_combine #define GL_COMBINE_EXT 0x8570 #define GL_COMBINE_RGB_EXT 0x8571 #define GL_COMBINE_ALPHA_EXT 0x8572 #define GL_RGB_SCALE_EXT 0x8573 #define GL_ADD_SIGNED_EXT 0x8574 #define GL_INTERPOLATE_EXT 0x8575 #define GL_CONSTANT_EXT 0x8576 #define GL_PRIMARY_COLOR_EXT 0x8577 #define GL_PREVIOUS_EXT 0x8578 #define GL_SOURCE0_RGB_EXT 0x8580 #define GL_SOURCE1_RGB_EXT 0x8581 #define GL_SOURCE2_RGB_EXT 0x8582 #define GL_SOURCE0_ALPHA_EXT 0x8588 #define GL_SOURCE1_ALPHA_EXT 0x8589 #define GL_SOURCE2_ALPHA_EXT 0x858A #define GL_OPERAND0_RGB_EXT 0x8590 #define GL_OPERAND1_RGB_EXT 0x8591 #define GL_OPERAND2_RGB_EXT 0x8592 #define GL_OPERAND0_ALPHA_EXT 0x8598 #define GL_OPERAND1_ALPHA_EXT 0x8599 #define GL_OPERAND2_ALPHA_EXT 0x859A #endif #ifndef GL_APPLE_specular_vector #define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 #endif #ifndef GL_APPLE_transform_hint #define GL_TRANSFORM_HINT_APPLE 0x85B1 #endif #ifndef GL_SGIX_fog_scale #define GL_FOG_SCALE_SGIX 0x81FC #define GL_FOG_SCALE_VALUE_SGIX 0x81FD #endif #ifndef GL_SUNX_constant_data #define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 #define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 #endif #ifndef GL_SUN_global_alpha #define GL_GLOBAL_ALPHA_SUN 0x81D9 #define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA #endif #ifndef GL_SUN_triangle_list #define GL_RESTART_SUN 0x0001 #define GL_REPLACE_MIDDLE_SUN 0x0002 #define GL_REPLACE_OLDEST_SUN 0x0003 #define GL_TRIANGLE_LIST_SUN 0x81D7 #define GL_REPLACEMENT_CODE_SUN 0x81D8 #define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 #define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 #define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 #define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 #define GL_R1UI_V3F_SUN 0x85C4 #define GL_R1UI_C4UB_V3F_SUN 0x85C5 #define GL_R1UI_C3F_V3F_SUN 0x85C6 #define GL_R1UI_N3F_V3F_SUN 0x85C7 #define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 #define GL_R1UI_T2F_V3F_SUN 0x85C9 #define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA #define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB #endif #ifndef GL_SUN_vertex #endif #ifndef GL_EXT_blend_func_separate #define GL_BLEND_DST_RGB_EXT 0x80C8 #define GL_BLEND_SRC_RGB_EXT 0x80C9 #define GL_BLEND_DST_ALPHA_EXT 0x80CA #define GL_BLEND_SRC_ALPHA_EXT 0x80CB #endif #ifndef GL_INGR_color_clamp #define GL_RED_MIN_CLAMP_INGR 0x8560 #define GL_GREEN_MIN_CLAMP_INGR 0x8561 #define GL_BLUE_MIN_CLAMP_INGR 0x8562 #define GL_ALPHA_MIN_CLAMP_INGR 0x8563 #define GL_RED_MAX_CLAMP_INGR 0x8564 #define GL_GREEN_MAX_CLAMP_INGR 0x8565 #define GL_BLUE_MAX_CLAMP_INGR 0x8566 #define GL_ALPHA_MAX_CLAMP_INGR 0x8567 #endif #ifndef GL_INGR_interlace_read #define GL_INTERLACE_READ_INGR 0x8568 #endif #ifndef GL_EXT_stencil_wrap #define GL_INCR_WRAP_EXT 0x8507 #define GL_DECR_WRAP_EXT 0x8508 #endif #ifndef GL_EXT_422_pixels #define GL_422_EXT 0x80CC #define GL_422_REV_EXT 0x80CD #define GL_422_AVERAGE_EXT 0x80CE #define GL_422_REV_AVERAGE_EXT 0x80CF #endif #ifndef GL_NV_texgen_reflection #define GL_NORMAL_MAP_NV 0x8511 #define GL_REFLECTION_MAP_NV 0x8512 #endif #ifndef GL_EXT_texture_cube_map #define GL_NORMAL_MAP_EXT 0x8511 #define GL_REFLECTION_MAP_EXT 0x8512 #define GL_TEXTURE_CUBE_MAP_EXT 0x8513 #define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 #define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A #define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B #define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C #endif #ifndef GL_SUN_convolution_border_modes #define GL_WRAP_BORDER_SUN 0x81D4 #endif #ifndef GL_EXT_texture_env_add #endif #ifndef GL_EXT_texture_lod_bias #define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD #define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 #define GL_TEXTURE_LOD_BIAS_EXT 0x8501 #endif #ifndef GL_EXT_texture_filter_anisotropic #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF #endif #ifndef GL_EXT_vertex_weighting #define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH #define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 #define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX #define GL_MODELVIEW1_MATRIX_EXT 0x8506 #define GL_VERTEX_WEIGHTING_EXT 0x8509 #define GL_MODELVIEW0_EXT GL_MODELVIEW #define GL_MODELVIEW1_EXT 0x850A #define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B #define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C #define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D #define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E #define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F #define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 #endif #ifndef GL_NV_light_max_exponent #define GL_MAX_SHININESS_NV 0x8504 #define GL_MAX_SPOT_EXPONENT_NV 0x8505 #endif #ifndef GL_NV_vertex_array_range #define GL_VERTEX_ARRAY_RANGE_NV 0x851D #define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E #define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F #define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 #define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 #endif #ifndef GL_NV_register_combiners #define GL_REGISTER_COMBINERS_NV 0x8522 #define GL_VARIABLE_A_NV 0x8523 #define GL_VARIABLE_B_NV 0x8524 #define GL_VARIABLE_C_NV 0x8525 #define GL_VARIABLE_D_NV 0x8526 #define GL_VARIABLE_E_NV 0x8527 #define GL_VARIABLE_F_NV 0x8528 #define GL_VARIABLE_G_NV 0x8529 #define GL_CONSTANT_COLOR0_NV 0x852A #define GL_CONSTANT_COLOR1_NV 0x852B #define GL_PRIMARY_COLOR_NV 0x852C #define GL_SECONDARY_COLOR_NV 0x852D #define GL_SPARE0_NV 0x852E #define GL_SPARE1_NV 0x852F #define GL_DISCARD_NV 0x8530 #define GL_E_TIMES_F_NV 0x8531 #define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 #define GL_UNSIGNED_IDENTITY_NV 0x8536 #define GL_UNSIGNED_INVERT_NV 0x8537 #define GL_EXPAND_NORMAL_NV 0x8538 #define GL_EXPAND_NEGATE_NV 0x8539 #define GL_HALF_BIAS_NORMAL_NV 0x853A #define GL_HALF_BIAS_NEGATE_NV 0x853B #define GL_SIGNED_IDENTITY_NV 0x853C #define GL_SIGNED_NEGATE_NV 0x853D #define GL_SCALE_BY_TWO_NV 0x853E #define GL_SCALE_BY_FOUR_NV 0x853F #define GL_SCALE_BY_ONE_HALF_NV 0x8540 #define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 #define GL_COMBINER_INPUT_NV 0x8542 #define GL_COMBINER_MAPPING_NV 0x8543 #define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 #define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 #define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 #define GL_COMBINER_MUX_SUM_NV 0x8547 #define GL_COMBINER_SCALE_NV 0x8548 #define GL_COMBINER_BIAS_NV 0x8549 #define GL_COMBINER_AB_OUTPUT_NV 0x854A #define GL_COMBINER_CD_OUTPUT_NV 0x854B #define GL_COMBINER_SUM_OUTPUT_NV 0x854C #define GL_MAX_GENERAL_COMBINERS_NV 0x854D #define GL_NUM_GENERAL_COMBINERS_NV 0x854E #define GL_COLOR_SUM_CLAMP_NV 0x854F #define GL_COMBINER0_NV 0x8550 #define GL_COMBINER1_NV 0x8551 #define GL_COMBINER2_NV 0x8552 #define GL_COMBINER3_NV 0x8553 #define GL_COMBINER4_NV 0x8554 #define GL_COMBINER5_NV 0x8555 #define GL_COMBINER6_NV 0x8556 #define GL_COMBINER7_NV 0x8557 /* reuse GL_TEXTURE0_ARB */ /* reuse GL_TEXTURE1_ARB */ /* reuse GL_ZERO */ /* reuse GL_NONE */ /* reuse GL_FOG */ #endif #ifndef GL_NV_fog_distance #define GL_FOG_DISTANCE_MODE_NV 0x855A #define GL_EYE_RADIAL_NV 0x855B #define GL_EYE_PLANE_ABSOLUTE_NV 0x855C /* reuse GL_EYE_PLANE */ #endif #ifndef GL_NV_texgen_emboss #define GL_EMBOSS_LIGHT_NV 0x855D #define GL_EMBOSS_CONSTANT_NV 0x855E #define GL_EMBOSS_MAP_NV 0x855F #endif #ifndef GL_NV_blend_square #endif #ifndef GL_NV_texture_env_combine4 #define GL_COMBINE4_NV 0x8503 #define GL_SOURCE3_RGB_NV 0x8583 #define GL_SOURCE3_ALPHA_NV 0x858B #define GL_OPERAND3_RGB_NV 0x8593 #define GL_OPERAND3_ALPHA_NV 0x859B #endif #ifndef GL_MESA_resize_buffers #endif #ifndef GL_MESA_window_pos #endif #ifndef GL_EXT_texture_compression_s3tc #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 #define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 #endif #ifndef GL_IBM_cull_vertex #define GL_CULL_VERTEX_IBM 103050 #endif #ifndef GL_IBM_multimode_draw_arrays #endif #ifndef GL_IBM_vertex_array_lists #define GL_VERTEX_ARRAY_LIST_IBM 103070 #define GL_NORMAL_ARRAY_LIST_IBM 103071 #define GL_COLOR_ARRAY_LIST_IBM 103072 #define GL_INDEX_ARRAY_LIST_IBM 103073 #define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 #define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 #define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 #define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 #define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 #define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 #define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 #define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 #define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 #define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 #define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 #define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 #endif #ifndef GL_SGIX_subsample #define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 #define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 #define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 #define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 #define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 #endif #ifndef GL_SGIX_ycrcb_subsample #endif #ifndef GL_SGIX_ycrcba #define GL_YCRCB_SGIX 0x8318 #define GL_YCRCBA_SGIX 0x8319 #endif #ifndef GL_SGI_depth_pass_instrument #define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 #define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 #define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 #endif #ifndef GL_3DFX_texture_compression_FXT1 #define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 #define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 #endif #ifndef GL_3DFX_multisample #define GL_MULTISAMPLE_3DFX 0x86B2 #define GL_SAMPLE_BUFFERS_3DFX 0x86B3 #define GL_SAMPLES_3DFX 0x86B4 #define GL_MULTISAMPLE_BIT_3DFX 0x20000000 #endif #ifndef GL_3DFX_tbuffer #endif #ifndef GL_EXT_multisample #define GL_MULTISAMPLE_EXT 0x809D #define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E #define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F #define GL_SAMPLE_MASK_EXT 0x80A0 #define GL_1PASS_EXT 0x80A1 #define GL_2PASS_0_EXT 0x80A2 #define GL_2PASS_1_EXT 0x80A3 #define GL_4PASS_0_EXT 0x80A4 #define GL_4PASS_1_EXT 0x80A5 #define GL_4PASS_2_EXT 0x80A6 #define GL_4PASS_3_EXT 0x80A7 #define GL_SAMPLE_BUFFERS_EXT 0x80A8 #define GL_SAMPLES_EXT 0x80A9 #define GL_SAMPLE_MASK_VALUE_EXT 0x80AA #define GL_SAMPLE_MASK_INVERT_EXT 0x80AB #define GL_SAMPLE_PATTERN_EXT 0x80AC #define GL_MULTISAMPLE_BIT_EXT 0x20000000 #endif #ifndef GL_SGIX_vertex_preclip #define GL_VERTEX_PRECLIP_SGIX 0x83EE #define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF #endif #ifndef GL_SGIX_convolution_accuracy #define GL_CONVOLUTION_HINT_SGIX 0x8316 #endif #ifndef GL_SGIX_resample #define GL_PACK_RESAMPLE_SGIX 0x842C #define GL_UNPACK_RESAMPLE_SGIX 0x842D #define GL_RESAMPLE_REPLICATE_SGIX 0x842E #define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F #define GL_RESAMPLE_DECIMATE_SGIX 0x8430 #endif #ifndef GL_SGIS_point_line_texgen #define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 #define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 #define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 #define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 #define GL_EYE_POINT_SGIS 0x81F4 #define GL_OBJECT_POINT_SGIS 0x81F5 #define GL_EYE_LINE_SGIS 0x81F6 #define GL_OBJECT_LINE_SGIS 0x81F7 #endif #ifndef GL_SGIS_texture_color_mask #define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF #endif #ifndef GL_EXT_texture_env_dot3 #define GL_DOT3_RGB_EXT 0x8740 #define GL_DOT3_RGBA_EXT 0x8741 #endif #ifndef GL_ATI_texture_mirror_once #define GL_MIRROR_CLAMP_ATI 0x8742 #define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 #endif #ifndef GL_NV_fence #define GL_ALL_COMPLETED_NV 0x84F2 #define GL_FENCE_STATUS_NV 0x84F3 #define GL_FENCE_CONDITION_NV 0x84F4 #endif #ifndef GL_IBM_texture_mirrored_repeat #define GL_MIRRORED_REPEAT_IBM 0x8370 #endif #ifndef GL_NV_evaluators #define GL_EVAL_2D_NV 0x86C0 #define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 #define GL_MAP_TESSELLATION_NV 0x86C2 #define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 #define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 #define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 #define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 #define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 #define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 #define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 #define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA #define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB #define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC #define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD #define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE #define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF #define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 #define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 #define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 #define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 #define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 #define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 #define GL_MAX_MAP_TESSELLATION_NV 0x86D6 #define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 #endif #ifndef GL_NV_packed_depth_stencil #define GL_DEPTH_STENCIL_NV 0x84F9 #define GL_UNSIGNED_INT_24_8_NV 0x84FA #endif #ifndef GL_NV_register_combiners2 #define GL_PER_STAGE_CONSTANTS_NV 0x8535 #endif #ifndef GL_NV_texture_compression_vtc #endif #ifndef GL_NV_texture_rectangle #define GL_TEXTURE_RECTANGLE_NV 0x84F5 #define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 #define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 #define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 #endif #ifndef GL_NV_texture_shader #define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C #define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D #define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E #define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 #define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA #define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB #define GL_DSDT_MAG_INTENSITY_NV 0x86DC #define GL_SHADER_CONSISTENT_NV 0x86DD #define GL_TEXTURE_SHADER_NV 0x86DE #define GL_SHADER_OPERATION_NV 0x86DF #define GL_CULL_MODES_NV 0x86E0 #define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 #define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 #define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 #define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV #define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV #define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV #define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 #define GL_CONST_EYE_NV 0x86E5 #define GL_PASS_THROUGH_NV 0x86E6 #define GL_CULL_FRAGMENT_NV 0x86E7 #define GL_OFFSET_TEXTURE_2D_NV 0x86E8 #define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 #define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA #define GL_DOT_PRODUCT_NV 0x86EC #define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED #define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE #define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 #define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 #define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 #define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 #define GL_HILO_NV 0x86F4 #define GL_DSDT_NV 0x86F5 #define GL_DSDT_MAG_NV 0x86F6 #define GL_DSDT_MAG_VIB_NV 0x86F7 #define GL_HILO16_NV 0x86F8 #define GL_SIGNED_HILO_NV 0x86F9 #define GL_SIGNED_HILO16_NV 0x86FA #define GL_SIGNED_RGBA_NV 0x86FB #define GL_SIGNED_RGBA8_NV 0x86FC #define GL_SIGNED_RGB_NV 0x86FE #define GL_SIGNED_RGB8_NV 0x86FF #define GL_SIGNED_LUMINANCE_NV 0x8701 #define GL_SIGNED_LUMINANCE8_NV 0x8702 #define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 #define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 #define GL_SIGNED_ALPHA_NV 0x8705 #define GL_SIGNED_ALPHA8_NV 0x8706 #define GL_SIGNED_INTENSITY_NV 0x8707 #define GL_SIGNED_INTENSITY8_NV 0x8708 #define GL_DSDT8_NV 0x8709 #define GL_DSDT8_MAG8_NV 0x870A #define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B #define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C #define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D #define GL_HI_SCALE_NV 0x870E #define GL_LO_SCALE_NV 0x870F #define GL_DS_SCALE_NV 0x8710 #define GL_DT_SCALE_NV 0x8711 #define GL_MAGNITUDE_SCALE_NV 0x8712 #define GL_VIBRANCE_SCALE_NV 0x8713 #define GL_HI_BIAS_NV 0x8714 #define GL_LO_BIAS_NV 0x8715 #define GL_DS_BIAS_NV 0x8716 #define GL_DT_BIAS_NV 0x8717 #define GL_MAGNITUDE_BIAS_NV 0x8718 #define GL_VIBRANCE_BIAS_NV 0x8719 #define GL_TEXTURE_BORDER_VALUES_NV 0x871A #define GL_TEXTURE_HI_SIZE_NV 0x871B #define GL_TEXTURE_LO_SIZE_NV 0x871C #define GL_TEXTURE_DS_SIZE_NV 0x871D #define GL_TEXTURE_DT_SIZE_NV 0x871E #define GL_TEXTURE_MAG_SIZE_NV 0x871F #endif #ifndef GL_NV_texture_shader2 #define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF #endif #ifndef GL_NV_vertex_array_range2 #define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 #endif #ifndef GL_NV_vertex_program #define GL_VERTEX_PROGRAM_NV 0x8620 #define GL_VERTEX_STATE_PROGRAM_NV 0x8621 #define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 #define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 #define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 #define GL_CURRENT_ATTRIB_NV 0x8626 #define GL_PROGRAM_LENGTH_NV 0x8627 #define GL_PROGRAM_STRING_NV 0x8628 #define GL_MODELVIEW_PROJECTION_NV 0x8629 #define GL_IDENTITY_NV 0x862A #define GL_INVERSE_NV 0x862B #define GL_TRANSPOSE_NV 0x862C #define GL_INVERSE_TRANSPOSE_NV 0x862D #define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E #define GL_MAX_TRACK_MATRICES_NV 0x862F #define GL_MATRIX0_NV 0x8630 #define GL_MATRIX1_NV 0x8631 #define GL_MATRIX2_NV 0x8632 #define GL_MATRIX3_NV 0x8633 #define GL_MATRIX4_NV 0x8634 #define GL_MATRIX5_NV 0x8635 #define GL_MATRIX6_NV 0x8636 #define GL_MATRIX7_NV 0x8637 #define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 #define GL_CURRENT_MATRIX_NV 0x8641 #define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 #define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 #define GL_PROGRAM_PARAMETER_NV 0x8644 #define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 #define GL_PROGRAM_TARGET_NV 0x8646 #define GL_PROGRAM_RESIDENT_NV 0x8647 #define GL_TRACK_MATRIX_NV 0x8648 #define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 #define GL_VERTEX_PROGRAM_BINDING_NV 0x864A #define GL_PROGRAM_ERROR_POSITION_NV 0x864B #define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 #define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 #define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 #define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 #define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 #define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 #define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 #define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 #define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 #define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 #define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A #define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B #define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C #define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D #define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E #define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F #define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 #define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 #define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 #define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 #define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 #define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 #define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 #define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 #define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 #define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 #define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A #define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B #define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C #define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D #define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E #define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F #define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 #define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 #define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 #define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 #define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 #define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 #define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 #define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 #define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 #define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 #define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A #define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B #define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C #define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D #define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E #define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F #endif #ifndef GL_SGIX_texture_coordinate_clamp #define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 #define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A #define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B #endif #ifndef GL_SGIX_scalebias_hint #define GL_SCALEBIAS_HINT_SGIX 0x8322 #endif #ifndef GL_OML_interlace #define GL_INTERLACE_OML 0x8980 #define GL_INTERLACE_READ_OML 0x8981 #endif #ifndef GL_OML_subsample #define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 #define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 #endif #ifndef GL_OML_resample #define GL_PACK_RESAMPLE_OML 0x8984 #define GL_UNPACK_RESAMPLE_OML 0x8985 #define GL_RESAMPLE_REPLICATE_OML 0x8986 #define GL_RESAMPLE_ZERO_FILL_OML 0x8987 #define GL_RESAMPLE_AVERAGE_OML 0x8988 #define GL_RESAMPLE_DECIMATE_OML 0x8989 #endif #ifndef GL_NV_copy_depth_to_color #define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E #define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F #endif #ifndef GL_ATI_envmap_bumpmap #define GL_BUMP_ROT_MATRIX_ATI 0x8775 #define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 #define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 #define GL_BUMP_TEX_UNITS_ATI 0x8778 #define GL_DUDV_ATI 0x8779 #define GL_DU8DV8_ATI 0x877A #define GL_BUMP_ENVMAP_ATI 0x877B #define GL_BUMP_TARGET_ATI 0x877C #endif #ifndef GL_ATI_fragment_shader #define GL_FRAGMENT_SHADER_ATI 0x8920 #define GL_REG_0_ATI 0x8921 #define GL_REG_1_ATI 0x8922 #define GL_REG_2_ATI 0x8923 #define GL_REG_3_ATI 0x8924 #define GL_REG_4_ATI 0x8925 #define GL_REG_5_ATI 0x8926 #define GL_REG_6_ATI 0x8927 #define GL_REG_7_ATI 0x8928 #define GL_REG_8_ATI 0x8929 #define GL_REG_9_ATI 0x892A #define GL_REG_10_ATI 0x892B #define GL_REG_11_ATI 0x892C #define GL_REG_12_ATI 0x892D #define GL_REG_13_ATI 0x892E #define GL_REG_14_ATI 0x892F #define GL_REG_15_ATI 0x8930 #define GL_REG_16_ATI 0x8931 #define GL_REG_17_ATI 0x8932 #define GL_REG_18_ATI 0x8933 #define GL_REG_19_ATI 0x8934 #define GL_REG_20_ATI 0x8935 #define GL_REG_21_ATI 0x8936 #define GL_REG_22_ATI 0x8937 #define GL_REG_23_ATI 0x8938 #define GL_REG_24_ATI 0x8939 #define GL_REG_25_ATI 0x893A #define GL_REG_26_ATI 0x893B #define GL_REG_27_ATI 0x893C #define GL_REG_28_ATI 0x893D #define GL_REG_29_ATI 0x893E #define GL_REG_30_ATI 0x893F #define GL_REG_31_ATI 0x8940 #define GL_CON_0_ATI 0x8941 #define GL_CON_1_ATI 0x8942 #define GL_CON_2_ATI 0x8943 #define GL_CON_3_ATI 0x8944 #define GL_CON_4_ATI 0x8945 #define GL_CON_5_ATI 0x8946 #define GL_CON_6_ATI 0x8947 #define GL_CON_7_ATI 0x8948 #define GL_CON_8_ATI 0x8949 #define GL_CON_9_ATI 0x894A #define GL_CON_10_ATI 0x894B #define GL_CON_11_ATI 0x894C #define GL_CON_12_ATI 0x894D #define GL_CON_13_ATI 0x894E #define GL_CON_14_ATI 0x894F #define GL_CON_15_ATI 0x8950 #define GL_CON_16_ATI 0x8951 #define GL_CON_17_ATI 0x8952 #define GL_CON_18_ATI 0x8953 #define GL_CON_19_ATI 0x8954 #define GL_CON_20_ATI 0x8955 #define GL_CON_21_ATI 0x8956 #define GL_CON_22_ATI 0x8957 #define GL_CON_23_ATI 0x8958 #define GL_CON_24_ATI 0x8959 #define GL_CON_25_ATI 0x895A #define GL_CON_26_ATI 0x895B #define GL_CON_27_ATI 0x895C #define GL_CON_28_ATI 0x895D #define GL_CON_29_ATI 0x895E #define GL_CON_30_ATI 0x895F #define GL_CON_31_ATI 0x8960 #define GL_MOV_ATI 0x8961 #define GL_ADD_ATI 0x8963 #define GL_MUL_ATI 0x8964 #define GL_SUB_ATI 0x8965 #define GL_DOT3_ATI 0x8966 #define GL_DOT4_ATI 0x8967 #define GL_MAD_ATI 0x8968 #define GL_LERP_ATI 0x8969 #define GL_CND_ATI 0x896A #define GL_CND0_ATI 0x896B #define GL_DOT2_ADD_ATI 0x896C #define GL_SECONDARY_INTERPOLATOR_ATI 0x896D #define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E #define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F #define GL_NUM_PASSES_ATI 0x8970 #define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 #define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 #define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 #define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 #define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 #define GL_SWIZZLE_STR_ATI 0x8976 #define GL_SWIZZLE_STQ_ATI 0x8977 #define GL_SWIZZLE_STR_DR_ATI 0x8978 #define GL_SWIZZLE_STQ_DQ_ATI 0x8979 #define GL_SWIZZLE_STRQ_ATI 0x897A #define GL_SWIZZLE_STRQ_DQ_ATI 0x897B #define GL_RED_BIT_ATI 0x00000001 #define GL_GREEN_BIT_ATI 0x00000002 #define GL_BLUE_BIT_ATI 0x00000004 #define GL_2X_BIT_ATI 0x00000001 #define GL_4X_BIT_ATI 0x00000002 #define GL_8X_BIT_ATI 0x00000004 #define GL_HALF_BIT_ATI 0x00000008 #define GL_QUARTER_BIT_ATI 0x00000010 #define GL_EIGHTH_BIT_ATI 0x00000020 #define GL_SATURATE_BIT_ATI 0x00000040 #define GL_COMP_BIT_ATI 0x00000002 #define GL_NEGATE_BIT_ATI 0x00000004 #define GL_BIAS_BIT_ATI 0x00000008 #endif #ifndef GL_ATI_pn_triangles #define GL_PN_TRIANGLES_ATI 0x87F0 #define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 #define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 #define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 #define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 #define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 #define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 #define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 #define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 #endif #ifndef GL_ATI_vertex_array_object #define GL_STATIC_ATI 0x8760 #define GL_DYNAMIC_ATI 0x8761 #define GL_PRESERVE_ATI 0x8762 #define GL_DISCARD_ATI 0x8763 #define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 #define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 #define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 #define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 #endif #ifndef GL_EXT_vertex_shader #define GL_VERTEX_SHADER_EXT 0x8780 #define GL_VERTEX_SHADER_BINDING_EXT 0x8781 #define GL_OP_INDEX_EXT 0x8782 #define GL_OP_NEGATE_EXT 0x8783 #define GL_OP_DOT3_EXT 0x8784 #define GL_OP_DOT4_EXT 0x8785 #define GL_OP_MUL_EXT 0x8786 #define GL_OP_ADD_EXT 0x8787 #define GL_OP_MADD_EXT 0x8788 #define GL_OP_FRAC_EXT 0x8789 #define GL_OP_MAX_EXT 0x878A #define GL_OP_MIN_EXT 0x878B #define GL_OP_SET_GE_EXT 0x878C #define GL_OP_SET_LT_EXT 0x878D #define GL_OP_CLAMP_EXT 0x878E #define GL_OP_FLOOR_EXT 0x878F #define GL_OP_ROUND_EXT 0x8790 #define GL_OP_EXP_BASE_2_EXT 0x8791 #define GL_OP_LOG_BASE_2_EXT 0x8792 #define GL_OP_POWER_EXT 0x8793 #define GL_OP_RECIP_EXT 0x8794 #define GL_OP_RECIP_SQRT_EXT 0x8795 #define GL_OP_SUB_EXT 0x8796 #define GL_OP_CROSS_PRODUCT_EXT 0x8797 #define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 #define GL_OP_MOV_EXT 0x8799 #define GL_OUTPUT_VERTEX_EXT 0x879A #define GL_OUTPUT_COLOR0_EXT 0x879B #define GL_OUTPUT_COLOR1_EXT 0x879C #define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D #define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E #define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F #define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 #define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 #define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 #define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 #define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 #define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 #define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 #define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 #define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 #define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 #define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA #define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB #define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC #define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD #define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE #define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF #define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 #define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 #define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 #define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 #define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 #define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 #define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 #define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 #define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 #define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 #define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA #define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB #define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC #define GL_OUTPUT_FOG_EXT 0x87BD #define GL_SCALAR_EXT 0x87BE #define GL_VECTOR_EXT 0x87BF #define GL_MATRIX_EXT 0x87C0 #define GL_VARIANT_EXT 0x87C1 #define GL_INVARIANT_EXT 0x87C2 #define GL_LOCAL_CONSTANT_EXT 0x87C3 #define GL_LOCAL_EXT 0x87C4 #define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 #define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 #define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 #define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 #define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 #define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA #define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB #define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC #define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD #define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE #define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF #define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 #define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 #define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 #define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 #define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 #define GL_X_EXT 0x87D5 #define GL_Y_EXT 0x87D6 #define GL_Z_EXT 0x87D7 #define GL_W_EXT 0x87D8 #define GL_NEGATIVE_X_EXT 0x87D9 #define GL_NEGATIVE_Y_EXT 0x87DA #define GL_NEGATIVE_Z_EXT 0x87DB #define GL_NEGATIVE_W_EXT 0x87DC #define GL_ZERO_EXT 0x87DD #define GL_ONE_EXT 0x87DE #define GL_NEGATIVE_ONE_EXT 0x87DF #define GL_NORMALIZED_RANGE_EXT 0x87E0 #define GL_FULL_RANGE_EXT 0x87E1 #define GL_CURRENT_VERTEX_EXT 0x87E2 #define GL_MVP_MATRIX_EXT 0x87E3 #define GL_VARIANT_VALUE_EXT 0x87E4 #define GL_VARIANT_DATATYPE_EXT 0x87E5 #define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 #define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 #define GL_VARIANT_ARRAY_EXT 0x87E8 #define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 #define GL_INVARIANT_VALUE_EXT 0x87EA #define GL_INVARIANT_DATATYPE_EXT 0x87EB #define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC #define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED #endif #ifndef GL_ATI_vertex_streams #define GL_MAX_VERTEX_STREAMS_ATI 0x876B #define GL_VERTEX_STREAM0_ATI 0x876C #define GL_VERTEX_STREAM1_ATI 0x876D #define GL_VERTEX_STREAM2_ATI 0x876E #define GL_VERTEX_STREAM3_ATI 0x876F #define GL_VERTEX_STREAM4_ATI 0x8770 #define GL_VERTEX_STREAM5_ATI 0x8771 #define GL_VERTEX_STREAM6_ATI 0x8772 #define GL_VERTEX_STREAM7_ATI 0x8773 #define GL_VERTEX_SOURCE_ATI 0x8774 #endif #ifndef GL_ATI_element_array #define GL_ELEMENT_ARRAY_ATI 0x8768 #define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 #define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A #endif #ifndef GL_SUN_mesh_array #define GL_QUAD_MESH_SUN 0x8614 #define GL_TRIANGLE_MESH_SUN 0x8615 #endif #ifndef GL_SUN_slice_accum #define GL_SLICE_ACCUM_SUN 0x85CC #endif #ifndef GL_NV_multisample_filter_hint #define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 #endif #ifndef GL_NV_depth_clamp #define GL_DEPTH_CLAMP_NV 0x864F #endif #ifndef GL_NV_occlusion_query #define GL_PIXEL_COUNTER_BITS_NV 0x8864 #define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 #define GL_PIXEL_COUNT_NV 0x8866 #define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 #endif #ifndef GL_NV_point_sprite #define GL_POINT_SPRITE_NV 0x8861 #define GL_COORD_REPLACE_NV 0x8862 #define GL_POINT_SPRITE_R_MODE_NV 0x8863 #endif #ifndef GL_NV_texture_shader3 #define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 #define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 #define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 #define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 #define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 #define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 #define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 #define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 #define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 #define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 #define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A #define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B #define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C #define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D #define GL_HILO8_NV 0x885E #define GL_SIGNED_HILO8_NV 0x885F #define GL_FORCE_BLUE_TO_ONE_NV 0x8860 #endif #ifndef GL_NV_vertex_program1_1 #endif #ifndef GL_EXT_shadow_funcs #endif #ifndef GL_EXT_stencil_two_side #define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 #define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 #endif #ifndef GL_ATI_text_fragment_shader #define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 #endif #ifndef GL_APPLE_client_storage #define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 #endif #ifndef GL_APPLE_element_array #define GL_ELEMENT_ARRAY_APPLE 0x8768 #define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 #define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A #endif #ifndef GL_APPLE_fence #define GL_DRAW_PIXELS_APPLE 0x8A0A #define GL_FENCE_APPLE 0x8A0B #endif #ifndef GL_APPLE_vertex_array_object #define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 #endif #ifndef GL_APPLE_vertex_array_range #define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D #define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E #define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F #define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 #define GL_STORAGE_CACHED_APPLE 0x85BE #define GL_STORAGE_SHARED_APPLE 0x85BF #endif #ifndef GL_APPLE_ycbcr_422 #define GL_YCBCR_422_APPLE 0x85B9 #define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA #define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB #endif #ifndef GL_S3_s3tc #define GL_RGB_S3TC 0x83A0 #define GL_RGB4_S3TC 0x83A1 #define GL_RGBA_S3TC 0x83A2 #define GL_RGBA4_S3TC 0x83A3 #endif #ifndef GL_ATI_draw_buffers #define GL_MAX_DRAW_BUFFERS_ATI 0x8824 #define GL_DRAW_BUFFER0_ATI 0x8825 #define GL_DRAW_BUFFER1_ATI 0x8826 #define GL_DRAW_BUFFER2_ATI 0x8827 #define GL_DRAW_BUFFER3_ATI 0x8828 #define GL_DRAW_BUFFER4_ATI 0x8829 #define GL_DRAW_BUFFER5_ATI 0x882A #define GL_DRAW_BUFFER6_ATI 0x882B #define GL_DRAW_BUFFER7_ATI 0x882C #define GL_DRAW_BUFFER8_ATI 0x882D #define GL_DRAW_BUFFER9_ATI 0x882E #define GL_DRAW_BUFFER10_ATI 0x882F #define GL_DRAW_BUFFER11_ATI 0x8830 #define GL_DRAW_BUFFER12_ATI 0x8831 #define GL_DRAW_BUFFER13_ATI 0x8832 #define GL_DRAW_BUFFER14_ATI 0x8833 #define GL_DRAW_BUFFER15_ATI 0x8834 #endif #ifndef GL_ATI_texture_env_combine3 #define GL_MODULATE_ADD_ATI 0x8744 #define GL_MODULATE_SIGNED_ADD_ATI 0x8745 #define GL_MODULATE_SUBTRACT_ATI 0x8746 #endif #ifndef GL_ATI_texture_float #define GL_RGBA_FLOAT32_ATI 0x8814 #define GL_RGB_FLOAT32_ATI 0x8815 #define GL_ALPHA_FLOAT32_ATI 0x8816 #define GL_INTENSITY_FLOAT32_ATI 0x8817 #define GL_LUMINANCE_FLOAT32_ATI 0x8818 #define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 #define GL_RGBA_FLOAT16_ATI 0x881A #define GL_RGB_FLOAT16_ATI 0x881B #define GL_ALPHA_FLOAT16_ATI 0x881C #define GL_INTENSITY_FLOAT16_ATI 0x881D #define GL_LUMINANCE_FLOAT16_ATI 0x881E #define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F #endif #ifndef GL_NV_float_buffer #define GL_FLOAT_R_NV 0x8880 #define GL_FLOAT_RG_NV 0x8881 #define GL_FLOAT_RGB_NV 0x8882 #define GL_FLOAT_RGBA_NV 0x8883 #define GL_FLOAT_R16_NV 0x8884 #define GL_FLOAT_R32_NV 0x8885 #define GL_FLOAT_RG16_NV 0x8886 #define GL_FLOAT_RG32_NV 0x8887 #define GL_FLOAT_RGB16_NV 0x8888 #define GL_FLOAT_RGB32_NV 0x8889 #define GL_FLOAT_RGBA16_NV 0x888A #define GL_FLOAT_RGBA32_NV 0x888B #define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C #define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D #define GL_FLOAT_RGBA_MODE_NV 0x888E #endif #ifndef GL_NV_fragment_program #define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 #define GL_FRAGMENT_PROGRAM_NV 0x8870 #define GL_MAX_TEXTURE_COORDS_NV 0x8871 #define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 #define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 #define GL_PROGRAM_ERROR_STRING_NV 0x8874 #endif #ifndef GL_NV_half_float #define GL_HALF_FLOAT_NV 0x140B #endif #ifndef GL_NV_pixel_data_range #define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 #define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 #define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A #define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B #define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C #define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D #endif #ifndef GL_NV_primitive_restart #define GL_PRIMITIVE_RESTART_NV 0x8558 #define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 #endif #ifndef GL_NV_texture_expand_normal #define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F #endif #ifndef GL_NV_vertex_program2 #endif #ifndef GL_ATI_map_object_buffer #endif #ifndef GL_ATI_separate_stencil #define GL_STENCIL_BACK_FUNC_ATI 0x8800 #define GL_STENCIL_BACK_FAIL_ATI 0x8801 #define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 #define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 #endif #ifndef GL_ATI_vertex_attrib_array_object #endif #ifndef GL_EXT_depth_bounds_test #define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 #define GL_DEPTH_BOUNDS_EXT 0x8891 #endif #ifndef GL_EXT_texture_mirror_clamp #define GL_MIRROR_CLAMP_EXT 0x8742 #define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 #define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 #endif #ifndef GL_EXT_blend_equation_separate #define GL_BLEND_EQUATION_RGB_EXT GL_BLEND_EQUATION #define GL_BLEND_EQUATION_ALPHA_EXT 0x883D #endif #ifndef GL_MESA_pack_invert #define GL_PACK_INVERT_MESA 0x8758 #endif #ifndef GL_MESA_ycbcr_texture #define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA #define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB #define GL_YCBCR_MESA 0x8757 #endif /*************************************************************/ #include #ifndef GL_VERSION_1_5 /* GL types for handling large vertex buffer objects */ typedef ptrdiff_t GLintptr; typedef ptrdiff_t GLsizeiptr; #endif #ifndef GL_ARB_vertex_buffer_object /* GL types for handling large vertex buffer objects */ typedef ptrdiff_t GLintptrARB; typedef ptrdiff_t GLsizeiptrARB; #endif #ifndef GL_ARB_shader_objects /* GL types for handling shader object handles and characters */ typedef char GLcharARB; /* native character */ typedef unsigned int GLhandleARB; /* shader object handle */ #endif #ifndef GL_NV_half_float /* GL type for representing NVIDIA "half" floating point type in host memory */ typedef unsigned short GLhalfNV; #endif #ifndef GL_VERSION_1_2 #define GL_VERSION_1_2 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendColor (GLclampf, GLclampf, GLclampf, GLclampf); GLAPI void APIENTRY glBlendEquation (GLenum); GLAPI void APIENTRY glDrawRangeElements (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); GLAPI void APIENTRY glColorTable (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glColorTableParameterfv (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glColorTableParameteriv (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glCopyColorTable (GLenum, GLenum, GLint, GLint, GLsizei); GLAPI void APIENTRY glGetColorTable (GLenum, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetColorTableParameterfv (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetColorTableParameteriv (GLenum, GLenum, GLint *); GLAPI void APIENTRY glColorSubTable (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glCopyColorSubTable (GLenum, GLsizei, GLint, GLint, GLsizei); GLAPI void APIENTRY glConvolutionFilter1D (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glConvolutionFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glConvolutionParameterf (GLenum, GLenum, GLfloat); GLAPI void APIENTRY glConvolutionParameterfv (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glConvolutionParameteri (GLenum, GLenum, GLint); GLAPI void APIENTRY glConvolutionParameteriv (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum, GLenum, GLint, GLint, GLsizei); GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); GLAPI void APIENTRY glGetConvolutionFilter (GLenum, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetSeparableFilter (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); GLAPI void APIENTRY glSeparableFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); GLAPI void APIENTRY glGetHistogram (GLenum, GLboolean, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetHistogramParameterfv (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetHistogramParameteriv (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetMinmax (GLenum, GLboolean, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum, GLenum, GLint *); GLAPI void APIENTRY glHistogram (GLenum, GLsizei, GLenum, GLboolean); GLAPI void APIENTRY glMinmax (GLenum, GLenum, GLboolean); GLAPI void APIENTRY glResetHistogram (GLenum); GLAPI void APIENTRY glResetMinmax (GLenum); GLAPI void APIENTRY glTexImage3D (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glCopyTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target); typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target); typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); #endif #ifndef GL_VERSION_1_3 #define GL_VERSION_1_3 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glActiveTexture (GLenum); GLAPI void APIENTRY glClientActiveTexture (GLenum); GLAPI void APIENTRY glMultiTexCoord1d (GLenum, GLdouble); GLAPI void APIENTRY glMultiTexCoord1dv (GLenum, const GLdouble *); GLAPI void APIENTRY glMultiTexCoord1f (GLenum, GLfloat); GLAPI void APIENTRY glMultiTexCoord1fv (GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexCoord1i (GLenum, GLint); GLAPI void APIENTRY glMultiTexCoord1iv (GLenum, const GLint *); GLAPI void APIENTRY glMultiTexCoord1s (GLenum, GLshort); GLAPI void APIENTRY glMultiTexCoord1sv (GLenum, const GLshort *); GLAPI void APIENTRY glMultiTexCoord2d (GLenum, GLdouble, GLdouble); GLAPI void APIENTRY glMultiTexCoord2dv (GLenum, const GLdouble *); GLAPI void APIENTRY glMultiTexCoord2f (GLenum, GLfloat, GLfloat); GLAPI void APIENTRY glMultiTexCoord2fv (GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexCoord2i (GLenum, GLint, GLint); GLAPI void APIENTRY glMultiTexCoord2iv (GLenum, const GLint *); GLAPI void APIENTRY glMultiTexCoord2s (GLenum, GLshort, GLshort); GLAPI void APIENTRY glMultiTexCoord2sv (GLenum, const GLshort *); GLAPI void APIENTRY glMultiTexCoord3d (GLenum, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glMultiTexCoord3dv (GLenum, const GLdouble *); GLAPI void APIENTRY glMultiTexCoord3f (GLenum, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glMultiTexCoord3fv (GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexCoord3i (GLenum, GLint, GLint, GLint); GLAPI void APIENTRY glMultiTexCoord3iv (GLenum, const GLint *); GLAPI void APIENTRY glMultiTexCoord3s (GLenum, GLshort, GLshort, GLshort); GLAPI void APIENTRY glMultiTexCoord3sv (GLenum, const GLshort *); GLAPI void APIENTRY glMultiTexCoord4d (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glMultiTexCoord4dv (GLenum, const GLdouble *); GLAPI void APIENTRY glMultiTexCoord4f (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glMultiTexCoord4fv (GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexCoord4i (GLenum, GLint, GLint, GLint, GLint); GLAPI void APIENTRY glMultiTexCoord4iv (GLenum, const GLint *); GLAPI void APIENTRY glMultiTexCoord4s (GLenum, GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY glMultiTexCoord4sv (GLenum, const GLshort *); GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *); GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *); GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *); GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *); GLAPI void APIENTRY glSampleCoverage (GLclampf, GLboolean); GLAPI void APIENTRY glCompressedTexImage3D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexImage2D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexImage1D (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glGetCompressedTexImage (GLenum, GLint, GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); #endif #ifndef GL_VERSION_1_4 #define GL_VERSION_1_4 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendFuncSeparate (GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY glFogCoordf (GLfloat); GLAPI void APIENTRY glFogCoordfv (const GLfloat *); GLAPI void APIENTRY glFogCoordd (GLdouble); GLAPI void APIENTRY glFogCoorddv (const GLdouble *); GLAPI void APIENTRY glFogCoordPointer (GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glMultiDrawArrays (GLenum, GLint *, GLsizei *, GLsizei); GLAPI void APIENTRY glMultiDrawElements (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); GLAPI void APIENTRY glPointParameterf (GLenum, GLfloat); GLAPI void APIENTRY glPointParameterfv (GLenum, const GLfloat *); GLAPI void APIENTRY glPointParameteri (GLenum, GLint); GLAPI void APIENTRY glPointParameteriv (GLenum, const GLint *); GLAPI void APIENTRY glSecondaryColor3b (GLbyte, GLbyte, GLbyte); GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *); GLAPI void APIENTRY glSecondaryColor3d (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *); GLAPI void APIENTRY glSecondaryColor3f (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *); GLAPI void APIENTRY glSecondaryColor3i (GLint, GLint, GLint); GLAPI void APIENTRY glSecondaryColor3iv (const GLint *); GLAPI void APIENTRY glSecondaryColor3s (GLshort, GLshort, GLshort); GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *); GLAPI void APIENTRY glSecondaryColor3ub (GLubyte, GLubyte, GLubyte); GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *); GLAPI void APIENTRY glSecondaryColor3ui (GLuint, GLuint, GLuint); GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *); GLAPI void APIENTRY glSecondaryColor3us (GLushort, GLushort, GLushort); GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *); GLAPI void APIENTRY glSecondaryColorPointer (GLint, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glWindowPos2d (GLdouble, GLdouble); GLAPI void APIENTRY glWindowPos2dv (const GLdouble *); GLAPI void APIENTRY glWindowPos2f (GLfloat, GLfloat); GLAPI void APIENTRY glWindowPos2fv (const GLfloat *); GLAPI void APIENTRY glWindowPos2i (GLint, GLint); GLAPI void APIENTRY glWindowPos2iv (const GLint *); GLAPI void APIENTRY glWindowPos2s (GLshort, GLshort); GLAPI void APIENTRY glWindowPos2sv (const GLshort *); GLAPI void APIENTRY glWindowPos3d (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glWindowPos3dv (const GLdouble *); GLAPI void APIENTRY glWindowPos3f (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glWindowPos3fv (const GLfloat *); GLAPI void APIENTRY glWindowPos3i (GLint, GLint, GLint); GLAPI void APIENTRY glWindowPos3iv (const GLint *); GLAPI void APIENTRY glWindowPos3s (GLshort, GLshort, GLshort); GLAPI void APIENTRY glWindowPos3sv (const GLshort *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord); typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord); typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord); typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v); #endif #ifndef GL_VERSION_1_5 #define GL_VERSION_1_5 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGenQueries (GLsizei, GLuint *); GLAPI void APIENTRY glDeleteQueries (GLsizei, const GLuint *); GLAPI GLboolean APIENTRY glIsQuery (GLuint); GLAPI void APIENTRY glBeginQuery (GLenum, GLuint); GLAPI void APIENTRY glEndQuery (GLenum); GLAPI void APIENTRY glGetQueryiv (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetQueryObjectiv (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetQueryObjectuiv (GLuint, GLenum, GLuint *); GLAPI void APIENTRY glBindBuffer (GLenum, GLuint); GLAPI void APIENTRY glDeleteBuffers (GLsizei, const GLuint *); GLAPI void APIENTRY glGenBuffers (GLsizei, GLuint *); GLAPI GLboolean APIENTRY glIsBuffer (GLuint); GLAPI void APIENTRY glBufferData (GLenum, GLsizeiptr, const GLvoid *, GLenum); GLAPI void APIENTRY glBufferSubData (GLenum, GLintptr, GLsizeiptr, const GLvoid *); GLAPI void APIENTRY glGetBufferSubData (GLenum, GLintptr, GLsizeiptr, GLvoid *); GLAPI GLvoid* APIENTRY glMapBuffer (GLenum, GLenum); GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum); GLAPI void APIENTRY glGetBufferParameteriv (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetBufferPointerv (GLenum, GLenum, GLvoid* *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id); typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target); typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* *params); #endif #ifndef GL_ARB_multitexture #define GL_ARB_multitexture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glActiveTextureARB (GLenum); GLAPI void APIENTRY glClientActiveTextureARB (GLenum); GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum, GLdouble); GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum, const GLdouble *); GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum, GLfloat); GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum, GLint); GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum, const GLint *); GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum, GLshort); GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum, const GLshort *); GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum, GLdouble, GLdouble); GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum, const GLdouble *); GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum, GLfloat, GLfloat); GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum, GLint, GLint); GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum, const GLint *); GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum, GLshort, GLshort); GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum, const GLshort *); GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum, const GLdouble *); GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum, GLint, GLint, GLint); GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum, const GLint *); GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum, GLshort, GLshort, GLshort); GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum, const GLshort *); GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum, const GLdouble *); GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *); GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum, GLint, GLint, GLint, GLint); GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum, const GLint *); GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum, GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum, const GLshort *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); #endif #ifndef GL_ARB_transpose_matrix #define GL_ARB_transpose_matrix 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *); GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *); GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *); GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); #endif #ifndef GL_ARB_multisample #define GL_ARB_multisample 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSampleCoverageARB (GLclampf, GLboolean); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); #endif #ifndef GL_ARB_texture_env_add #define GL_ARB_texture_env_add 1 #endif #ifndef GL_ARB_texture_cube_map #define GL_ARB_texture_cube_map 1 #endif #ifndef GL_ARB_texture_compression #define GL_ARB_texture_compression 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum, GLint, GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid *img); #endif #ifndef GL_ARB_texture_border_clamp #define GL_ARB_texture_border_clamp 1 #endif #ifndef GL_ARB_point_parameters #define GL_ARB_point_parameters 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPointParameterfARB (GLenum, GLfloat); GLAPI void APIENTRY glPointParameterfvARB (GLenum, const GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); #endif #ifndef GL_ARB_vertex_blend #define GL_ARB_vertex_blend 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glWeightbvARB (GLint, const GLbyte *); GLAPI void APIENTRY glWeightsvARB (GLint, const GLshort *); GLAPI void APIENTRY glWeightivARB (GLint, const GLint *); GLAPI void APIENTRY glWeightfvARB (GLint, const GLfloat *); GLAPI void APIENTRY glWeightdvARB (GLint, const GLdouble *); GLAPI void APIENTRY glWeightubvARB (GLint, const GLubyte *); GLAPI void APIENTRY glWeightusvARB (GLint, const GLushort *); GLAPI void APIENTRY glWeightuivARB (GLint, const GLuint *); GLAPI void APIENTRY glWeightPointerARB (GLint, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glVertexBlendARB (GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count); #endif #ifndef GL_ARB_matrix_palette #define GL_ARB_matrix_palette 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint); GLAPI void APIENTRY glMatrixIndexubvARB (GLint, const GLubyte *); GLAPI void APIENTRY glMatrixIndexusvARB (GLint, const GLushort *); GLAPI void APIENTRY glMatrixIndexuivARB (GLint, const GLuint *); GLAPI void APIENTRY glMatrixIndexPointerARB (GLint, GLenum, GLsizei, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef GL_ARB_texture_env_combine #define GL_ARB_texture_env_combine 1 #endif #ifndef GL_ARB_texture_env_crossbar #define GL_ARB_texture_env_crossbar 1 #endif #ifndef GL_ARB_texture_env_dot3 #define GL_ARB_texture_env_dot3 1 #endif #ifndef GL_ARB_texture_mirrored_repeat #define GL_ARB_texture_mirrored_repeat 1 #endif #ifndef GL_ARB_depth_texture #define GL_ARB_depth_texture 1 #endif #ifndef GL_ARB_shadow #define GL_ARB_shadow 1 #endif #ifndef GL_ARB_shadow_ambient #define GL_ARB_shadow_ambient 1 #endif #ifndef GL_ARB_window_pos #define GL_ARB_window_pos 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glWindowPos2dARB (GLdouble, GLdouble); GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *); GLAPI void APIENTRY glWindowPos2fARB (GLfloat, GLfloat); GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *); GLAPI void APIENTRY glWindowPos2iARB (GLint, GLint); GLAPI void APIENTRY glWindowPos2ivARB (const GLint *); GLAPI void APIENTRY glWindowPos2sARB (GLshort, GLshort); GLAPI void APIENTRY glWindowPos2svARB (const GLshort *); GLAPI void APIENTRY glWindowPos3dARB (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *); GLAPI void APIENTRY glWindowPos3fARB (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *); GLAPI void APIENTRY glWindowPos3iARB (GLint, GLint, GLint); GLAPI void APIENTRY glWindowPos3ivARB (const GLint *); GLAPI void APIENTRY glWindowPos3sARB (GLshort, GLshort, GLshort); GLAPI void APIENTRY glWindowPos3svARB (const GLshort *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v); #endif #ifndef GL_ARB_vertex_program #define GL_ARB_vertex_program 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexAttrib1dARB (GLuint, GLdouble); GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib1fARB (GLuint, GLfloat); GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib1sARB (GLuint, GLshort); GLAPI void APIENTRY glVertexAttrib1svARB (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib2dARB (GLuint, GLdouble, GLdouble); GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib2fARB (GLuint, GLfloat, GLfloat); GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib2sARB (GLuint, GLshort, GLshort); GLAPI void APIENTRY glVertexAttrib2svARB (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib3dARB (GLuint, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib3fARB (GLuint, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib3sARB (GLuint, GLshort, GLshort, GLshort); GLAPI void APIENTRY glVertexAttrib3svARB (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint, const GLbyte *); GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint, const GLint *); GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint, const GLubyte *); GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint, const GLuint *); GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint, const GLushort *); GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint, const GLbyte *); GLAPI void APIENTRY glVertexAttrib4dARB (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib4fARB (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint, const GLint *); GLAPI void APIENTRY glVertexAttrib4sARB (GLuint, GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY glVertexAttrib4svARB (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint, const GLubyte *); GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint, const GLuint *); GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint, const GLushort *); GLAPI void APIENTRY glVertexAttribPointerARB (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint); GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint); GLAPI void APIENTRY glProgramStringARB (GLenum, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glBindProgramARB (GLenum, GLuint); GLAPI void APIENTRY glDeleteProgramsARB (GLsizei, const GLuint *); GLAPI void APIENTRY glGenProgramsARB (GLsizei, GLuint *); GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum, GLuint, const GLdouble *); GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum, GLuint, const GLfloat *); GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum, GLuint, const GLdouble *); GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum, GLuint, const GLfloat *); GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum, GLuint, GLdouble *); GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum, GLuint, GLfloat *); GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum, GLuint, GLdouble *); GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum, GLuint, GLfloat *); GLAPI void APIENTRY glGetProgramivARB (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetProgramStringARB (GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint, GLenum, GLdouble *); GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetVertexAttribivARB (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint, GLenum, GLvoid* *); GLAPI GLboolean APIENTRY glIsProgramARB (GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string); typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer); typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program); #endif #ifndef GL_ARB_fragment_program #define GL_ARB_fragment_program 1 /* All ARB_fragment_program entry points are shared with ARB_vertex_program. */ #endif #ifndef GL_ARB_vertex_buffer_object #define GL_ARB_vertex_buffer_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindBufferARB (GLenum, GLuint); GLAPI void APIENTRY glDeleteBuffersARB (GLsizei, const GLuint *); GLAPI void APIENTRY glGenBuffersARB (GLsizei, GLuint *); GLAPI GLboolean APIENTRY glIsBufferARB (GLuint); GLAPI void APIENTRY glBufferDataARB (GLenum, GLsizeiptrARB, const GLvoid *, GLenum); GLAPI void APIENTRY glBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *); GLAPI void APIENTRY glGetBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, GLvoid *); GLAPI GLvoid* APIENTRY glMapBufferARB (GLenum, GLenum); GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum); GLAPI void APIENTRY glGetBufferParameterivARB (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target); typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* *params); #endif #ifndef GL_ARB_occlusion_query #define GL_ARB_occlusion_query 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGenQueriesARB (GLsizei, GLuint *); GLAPI void APIENTRY glDeleteQueriesARB (GLsizei, const GLuint *); GLAPI GLboolean APIENTRY glIsQueryARB (GLuint); GLAPI void APIENTRY glBeginQueryARB (GLenum, GLuint); GLAPI void APIENTRY glEndQueryARB (GLenum); GLAPI void APIENTRY glGetQueryivARB (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetQueryObjectivARB (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint, GLenum, GLuint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids); typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids); typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id); typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target); typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params); #endif #ifndef GL_ARB_shader_objects #define GL_ARB_shader_objects 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB); GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum); GLAPI void APIENTRY glDetachObjectARB (GLhandleARB, GLhandleARB); GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum); GLAPI void APIENTRY glShaderSourceARB (GLhandleARB, GLsizei, const GLcharARB* *, const GLint *); GLAPI void APIENTRY glCompileShaderARB (GLhandleARB); GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void); GLAPI void APIENTRY glAttachObjectARB (GLhandleARB, GLhandleARB); GLAPI void APIENTRY glLinkProgramARB (GLhandleARB); GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB); GLAPI void APIENTRY glValidateProgramARB (GLhandleARB); GLAPI void APIENTRY glUniform1fARB (GLint, GLfloat); GLAPI void APIENTRY glUniform2fARB (GLint, GLfloat, GLfloat); GLAPI void APIENTRY glUniform3fARB (GLint, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glUniform4fARB (GLint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glUniform1iARB (GLint, GLint); GLAPI void APIENTRY glUniform2iARB (GLint, GLint, GLint); GLAPI void APIENTRY glUniform3iARB (GLint, GLint, GLint, GLint); GLAPI void APIENTRY glUniform4iARB (GLint, GLint, GLint, GLint, GLint); GLAPI void APIENTRY glUniform1fvARB (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY glUniform2fvARB (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY glUniform3fvARB (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY glUniform4fvARB (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY glUniform1ivARB (GLint, GLsizei, const GLint *); GLAPI void APIENTRY glUniform2ivARB (GLint, GLsizei, const GLint *); GLAPI void APIENTRY glUniform3ivARB (GLint, GLsizei, const GLint *); GLAPI void APIENTRY glUniform4ivARB (GLint, GLsizei, const GLint *); GLAPI void APIENTRY glUniformMatrix2fvARB (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glUniformMatrix3fvARB (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glUniformMatrix4fvARB (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB, GLenum, GLfloat *); GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB, GLenum, GLint *); GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *); GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB, const GLcharARB *); GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB, GLint, GLfloat *); GLAPI void APIENTRY glGetUniformivARB (GLhandleARB, GLint, GLint *); GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname); typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length); typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void); typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params); typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params); typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); #endif #ifndef GL_ARB_vertex_shader #define GL_ARB_vertex_shader 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB, GLuint, const GLcharARB *); GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB, const GLcharARB *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); #endif #ifndef GL_ARB_fragment_shader #define GL_ARB_fragment_shader 1 #endif #ifndef GL_ARB_shading_language_100 #define GL_ARB_shading_language_100 1 #endif #ifndef GL_ARB_texture_non_power_of_two #define GL_ARB_texture_non_power_of_two 1 #endif #ifndef GL_ARB_point_sprite #define GL_ARB_point_sprite 1 #endif #ifndef GL_ARB_fragment_program_shadow #define GL_ARB_fragment_program_shadow 1 #endif #ifndef GL_EXT_abgr #define GL_EXT_abgr 1 #endif #ifndef GL_EXT_blend_color #define GL_EXT_blend_color 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendColorEXT (GLclampf, GLclampf, GLclampf, GLclampf); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); #endif #ifndef GL_EXT_polygon_offset #define GL_EXT_polygon_offset 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat, GLfloat); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); #endif #ifndef GL_EXT_texture #define GL_EXT_texture 1 #endif #ifndef GL_EXT_texture3D #define GL_EXT_texture3D 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexImage3DEXT (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); #endif #ifndef GL_SGIS_texture_filter4 #define GL_SGIS_texture_filter4 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum, GLenum, GLsizei, const GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); #endif #ifndef GL_EXT_subtexture #define GL_EXT_subtexture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexSubImage1DEXT (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); #endif #ifndef GL_EXT_copy_texture #define GL_EXT_copy_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei); GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); #endif #ifndef GL_EXT_histogram #define GL_EXT_histogram 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetHistogramEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetMinmaxEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum, GLenum, GLint *); GLAPI void APIENTRY glHistogramEXT (GLenum, GLsizei, GLenum, GLboolean); GLAPI void APIENTRY glMinmaxEXT (GLenum, GLenum, GLboolean); GLAPI void APIENTRY glResetHistogramEXT (GLenum); GLAPI void APIENTRY glResetMinmaxEXT (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target); #endif #ifndef GL_EXT_convolution #define GL_EXT_convolution 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum, GLenum, GLfloat); GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum, GLenum, GLint); GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum, GLenum, GLint, GLint, GLsizei); GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); #endif #ifndef GL_EXT_color_matrix #define GL_EXT_color_matrix 1 #endif #ifndef GL_SGI_color_table #define GL_SGI_color_table 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorTableSGI (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glColorTableParameterivSGI (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glCopyColorTableSGI (GLenum, GLenum, GLint, GLint, GLsizei); GLAPI void APIENTRY glGetColorTableSGI (GLenum, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum, GLenum, GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); #endif #ifndef GL_SGIX_pixel_texture #define GL_SGIX_pixel_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPixelTexGenSGIX (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); #endif #ifndef GL_SGIS_pixel_texture #define GL_SGIS_pixel_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum, GLint); GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum, const GLint *); GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum, GLfloat); GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum, const GLfloat *); GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum, GLint *); GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); #endif #ifndef GL_SGIS_texture4D #define GL_SGIS_texture4D 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexImage4DSGIS (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels); #endif #ifndef GL_SGI_texture_color_table #define GL_SGI_texture_color_table 1 #endif #ifndef GL_EXT_cmyka #define GL_EXT_cmyka 1 #endif #ifndef GL_EXT_texture_object #define GL_EXT_texture_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei, const GLuint *, GLboolean *); GLAPI void APIENTRY glBindTextureEXT (GLenum, GLuint); GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei, const GLuint *); GLAPI void APIENTRY glGenTexturesEXT (GLsizei, GLuint *); GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint); GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei, const GLuint *, const GLclampf *); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture); typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); #endif #ifndef GL_SGIS_detail_texture #define GL_SGIS_detail_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum, GLsizei, const GLfloat *); GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); #endif #ifndef GL_SGIS_sharpen_texture #define GL_SGIS_sharpen_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum, GLsizei, const GLfloat *); GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); #endif #ifndef GL_EXT_packed_pixels #define GL_EXT_packed_pixels 1 #endif #ifndef GL_SGIS_texture_lod #define GL_SGIS_texture_lod 1 #endif #ifndef GL_SGIS_multisample #define GL_SGIS_multisample 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSampleMaskSGIS (GLclampf, GLboolean); GLAPI void APIENTRY glSamplePatternSGIS (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); #endif #ifndef GL_EXT_rescale_normal #define GL_EXT_rescale_normal 1 #endif #ifndef GL_EXT_vertex_array #define GL_EXT_vertex_array 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glArrayElementEXT (GLint); GLAPI void APIENTRY glColorPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); GLAPI void APIENTRY glDrawArraysEXT (GLenum, GLint, GLsizei); GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei, GLsizei, const GLboolean *); GLAPI void APIENTRY glGetPointervEXT (GLenum, GLvoid* *); GLAPI void APIENTRY glIndexPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); GLAPI void APIENTRY glNormalPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); GLAPI void APIENTRY glTexCoordPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); GLAPI void APIENTRY glVertexPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i); typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params); typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); #endif #ifndef GL_EXT_misc_attribute #define GL_EXT_misc_attribute 1 #endif #ifndef GL_SGIS_generate_mipmap #define GL_SGIS_generate_mipmap 1 #endif #ifndef GL_SGIX_clipmap #define GL_SGIX_clipmap 1 #endif #ifndef GL_SGIX_shadow #define GL_SGIX_shadow 1 #endif #ifndef GL_SGIS_texture_edge_clamp #define GL_SGIS_texture_edge_clamp 1 #endif #ifndef GL_SGIS_texture_border_clamp #define GL_SGIS_texture_border_clamp 1 #endif #ifndef GL_EXT_blend_minmax #define GL_EXT_blend_minmax 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendEquationEXT (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); #endif #ifndef GL_EXT_blend_subtract #define GL_EXT_blend_subtract 1 #endif #ifndef GL_EXT_blend_logic_op #define GL_EXT_blend_logic_op 1 #endif #ifndef GL_SGIX_interlace #define GL_SGIX_interlace 1 #endif #ifndef GL_SGIX_pixel_tiles #define GL_SGIX_pixel_tiles 1 #endif #ifndef GL_SGIX_texture_select #define GL_SGIX_texture_select 1 #endif #ifndef GL_SGIX_sprite #define GL_SGIX_sprite 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum, GLfloat); GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum, const GLfloat *); GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum, GLint); GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum, const GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); #endif #ifndef GL_SGIX_texture_multi_buffer #define GL_SGIX_texture_multi_buffer 1 #endif #ifndef GL_EXT_point_parameters #define GL_EXT_point_parameters 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPointParameterfEXT (GLenum, GLfloat); GLAPI void APIENTRY glPointParameterfvEXT (GLenum, const GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); #endif #ifndef GL_SGIS_point_parameters #define GL_SGIS_point_parameters 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPointParameterfSGIS (GLenum, GLfloat); GLAPI void APIENTRY glPointParameterfvSGIS (GLenum, const GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); #endif #ifndef GL_SGIX_instruments #define GL_SGIX_instruments 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLint APIENTRY glGetInstrumentsSGIX (void); GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei, GLint *); GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *); GLAPI void APIENTRY glReadInstrumentsSGIX (GLint); GLAPI void APIENTRY glStartInstrumentsSGIX (void); GLAPI void APIENTRY glStopInstrumentsSGIX (GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void); typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void); typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); #endif #ifndef GL_SGIX_texture_scale_bias #define GL_SGIX_texture_scale_bias 1 #endif #ifndef GL_SGIX_framezoom #define GL_SGIX_framezoom 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFrameZoomSGIX (GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor); #endif #ifndef GL_SGIX_tag_sample_buffer #define GL_SGIX_tag_sample_buffer 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTagSampleBufferSGIX (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); #endif #ifndef GL_SGIX_polynomial_ffd #define GL_SGIX_polynomial_ffd 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *); GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *); GLAPI void APIENTRY glDeformSGIX (GLbitfield); GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask); typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); #endif #ifndef GL_SGIX_reference_plane #define GL_SGIX_reference_plane 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); #endif #ifndef GL_SGIX_flush_raster #define GL_SGIX_flush_raster 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFlushRasterSGIX (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void); #endif #ifndef GL_SGIX_depth_texture #define GL_SGIX_depth_texture 1 #endif #ifndef GL_SGIS_fog_function #define GL_SGIS_fog_function 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFogFuncSGIS (GLsizei, const GLfloat *); GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points); #endif #ifndef GL_SGIX_fog_offset #define GL_SGIX_fog_offset 1 #endif #ifndef GL_HP_image_transform #define GL_HP_image_transform 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glImageTransformParameteriHP (GLenum, GLenum, GLint); GLAPI void APIENTRY glImageTransformParameterfHP (GLenum, GLenum, GLfloat); GLAPI void APIENTRY glImageTransformParameterivHP (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum, GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); #endif #ifndef GL_HP_convolution_border_modes #define GL_HP_convolution_border_modes 1 #endif #ifndef GL_SGIX_texture_add_env #define GL_SGIX_texture_add_env 1 #endif #ifndef GL_EXT_color_subtable #define GL_EXT_color_subtable 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorSubTableEXT (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum, GLsizei, GLint, GLint, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); #endif #ifndef GL_PGI_vertex_hints #define GL_PGI_vertex_hints 1 #endif #ifndef GL_PGI_misc_hints #define GL_PGI_misc_hints 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glHintPGI (GLenum, GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode); #endif #ifndef GL_EXT_paletted_texture #define GL_EXT_paletted_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorTableEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY glGetColorTableEXT (GLenum, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum, GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); #endif #ifndef GL_EXT_clip_volume_hint #define GL_EXT_clip_volume_hint 1 #endif #ifndef GL_SGIX_list_priority #define GL_SGIX_list_priority 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetListParameterivSGIX (GLuint, GLenum, GLint *); GLAPI void APIENTRY glListParameterfSGIX (GLuint, GLenum, GLfloat); GLAPI void APIENTRY glListParameterfvSGIX (GLuint, GLenum, const GLfloat *); GLAPI void APIENTRY glListParameteriSGIX (GLuint, GLenum, GLint); GLAPI void APIENTRY glListParameterivSGIX (GLuint, GLenum, const GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); #endif #ifndef GL_SGIX_ir_instrument1 #define GL_SGIX_ir_instrument1 1 #endif #ifndef GL_SGIX_calligraphic_fragment #define GL_SGIX_calligraphic_fragment 1 #endif #ifndef GL_SGIX_texture_lod_bias #define GL_SGIX_texture_lod_bias 1 #endif #ifndef GL_SGIX_shadow_ambient #define GL_SGIX_shadow_ambient 1 #endif #ifndef GL_EXT_index_texture #define GL_EXT_index_texture 1 #endif #ifndef GL_EXT_index_material #define GL_EXT_index_material 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glIndexMaterialEXT (GLenum, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); #endif #ifndef GL_EXT_index_func #define GL_EXT_index_func 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glIndexFuncEXT (GLenum, GLclampf); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); #endif #ifndef GL_EXT_index_array_formats #define GL_EXT_index_array_formats 1 #endif #ifndef GL_EXT_compiled_vertex_array #define GL_EXT_compiled_vertex_array 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glLockArraysEXT (GLint, GLsizei); GLAPI void APIENTRY glUnlockArraysEXT (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void); #endif #ifndef GL_EXT_cull_vertex #define GL_EXT_cull_vertex 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCullParameterdvEXT (GLenum, GLdouble *); GLAPI void APIENTRY glCullParameterfvEXT (GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); #endif #ifndef GL_SGIX_ycrcb #define GL_SGIX_ycrcb 1 #endif #ifndef GL_SGIX_fragment_lighting #define GL_SGIX_fragment_lighting 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum, GLenum); GLAPI void APIENTRY glFragmentLightfSGIX (GLenum, GLenum, GLfloat); GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glFragmentLightiSGIX (GLenum, GLenum, GLint); GLAPI void APIENTRY glFragmentLightivSGIX (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum, GLfloat); GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum, const GLfloat *); GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum, GLint); GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum, const GLint *); GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum, GLenum, GLfloat); GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum, GLenum, GLint); GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum, GLenum, GLint *); GLAPI void APIENTRY glLightEnviSGIX (GLenum, GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); #endif #ifndef GL_IBM_rasterpos_clip #define GL_IBM_rasterpos_clip 1 #endif #ifndef GL_HP_texture_lighting #define GL_HP_texture_lighting 1 #endif #ifndef GL_EXT_draw_range_elements #define GL_EXT_draw_range_elements 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); #endif #ifndef GL_WIN_phong_shading #define GL_WIN_phong_shading 1 #endif #ifndef GL_WIN_specular_fog #define GL_WIN_specular_fog 1 #endif #ifndef GL_EXT_light_texture #define GL_EXT_light_texture 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glApplyTextureEXT (GLenum); GLAPI void APIENTRY glTextureLightEXT (GLenum); GLAPI void APIENTRY glTextureMaterialEXT (GLenum, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); #endif #ifndef GL_SGIX_blend_alpha_minmax #define GL_SGIX_blend_alpha_minmax 1 #endif #ifndef GL_EXT_bgra #define GL_EXT_bgra 1 #endif #ifndef GL_SGIX_async #define GL_SGIX_async 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint); GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *); GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *); GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei); GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint, GLsizei); GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker); typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp); typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp); typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); #endif #ifndef GL_SGIX_async_pixel #define GL_SGIX_async_pixel 1 #endif #ifndef GL_SGIX_async_histogram #define GL_SGIX_async_histogram 1 #endif #ifndef GL_INTEL_parallel_arrays #define GL_INTEL_parallel_arrays 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexPointervINTEL (GLint, GLenum, const GLvoid* *); GLAPI void APIENTRY glNormalPointervINTEL (GLenum, const GLvoid* *); GLAPI void APIENTRY glColorPointervINTEL (GLint, GLenum, const GLvoid* *); GLAPI void APIENTRY glTexCoordPointervINTEL (GLint, GLenum, const GLvoid* *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer); typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); #endif #ifndef GL_HP_occlusion_test #define GL_HP_occlusion_test 1 #endif #ifndef GL_EXT_pixel_transform #define GL_EXT_pixel_transform 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum, GLenum, GLint); GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum, GLenum, GLfloat); GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum, GLenum, const GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); #endif #ifndef GL_EXT_pixel_transform_color_table #define GL_EXT_pixel_transform_color_table 1 #endif #ifndef GL_EXT_shared_texture_palette #define GL_EXT_shared_texture_palette 1 #endif #ifndef GL_EXT_separate_specular_color #define GL_EXT_separate_specular_color 1 #endif #ifndef GL_EXT_secondary_color #define GL_EXT_secondary_color 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte, GLbyte, GLbyte); GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *); GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *); GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *); GLAPI void APIENTRY glSecondaryColor3iEXT (GLint, GLint, GLint); GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *); GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort, GLshort, GLshort); GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *); GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte, GLubyte, GLubyte); GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *); GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint, GLuint, GLuint); GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *); GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort, GLushort, GLushort); GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *); GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint, GLenum, GLsizei, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef GL_EXT_texture_perturb_normal #define GL_EXT_texture_perturb_normal 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTextureNormalEXT (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode); #endif #ifndef GL_EXT_multi_draw_arrays #define GL_EXT_multi_draw_arrays 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum, GLint *, GLsizei *, GLsizei); GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); #endif #ifndef GL_EXT_fog_coord #define GL_EXT_fog_coord 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFogCoordfEXT (GLfloat); GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *); GLAPI void APIENTRY glFogCoorddEXT (GLdouble); GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *); GLAPI void APIENTRY glFogCoordPointerEXT (GLenum, GLsizei, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord); typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord); typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef GL_REND_screen_coordinates #define GL_REND_screen_coordinates 1 #endif #ifndef GL_EXT_coordinate_frame #define GL_EXT_coordinate_frame 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTangent3bEXT (GLbyte, GLbyte, GLbyte); GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *); GLAPI void APIENTRY glTangent3dEXT (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *); GLAPI void APIENTRY glTangent3fEXT (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *); GLAPI void APIENTRY glTangent3iEXT (GLint, GLint, GLint); GLAPI void APIENTRY glTangent3ivEXT (const GLint *); GLAPI void APIENTRY glTangent3sEXT (GLshort, GLshort, GLshort); GLAPI void APIENTRY glTangent3svEXT (const GLshort *); GLAPI void APIENTRY glBinormal3bEXT (GLbyte, GLbyte, GLbyte); GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *); GLAPI void APIENTRY glBinormal3dEXT (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *); GLAPI void APIENTRY glBinormal3fEXT (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *); GLAPI void APIENTRY glBinormal3iEXT (GLint, GLint, GLint); GLAPI void APIENTRY glBinormal3ivEXT (const GLint *); GLAPI void APIENTRY glBinormal3sEXT (GLshort, GLshort, GLshort); GLAPI void APIENTRY glBinormal3svEXT (const GLshort *); GLAPI void APIENTRY glTangentPointerEXT (GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glBinormalPointerEXT (GLenum, GLsizei, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v); typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v); typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef GL_EXT_texture_env_combine #define GL_EXT_texture_env_combine 1 #endif #ifndef GL_APPLE_specular_vector #define GL_APPLE_specular_vector 1 #endif #ifndef GL_APPLE_transform_hint #define GL_APPLE_transform_hint 1 #endif #ifndef GL_SGIX_fog_scale #define GL_SGIX_fog_scale 1 #endif #ifndef GL_SUNX_constant_data #define GL_SUNX_constant_data 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFinishTextureSUNX (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void); #endif #ifndef GL_SUN_global_alpha #define GL_SUN_global_alpha 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte); GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort); GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint); GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat); GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble); GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte); GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort); GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); #endif #ifndef GL_SUN_triangle_list #define GL_SUN_triangle_list 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint); GLAPI void APIENTRY glReplacementCodeusSUN (GLushort); GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte); GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *); GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *); GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *); GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum, GLsizei, const GLvoid* *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer); #endif #ifndef GL_SUN_vertex #define GL_SUN_vertex 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat); GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *, const GLfloat *); GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *, const GLfloat *); GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *, const GLfloat *); GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *); GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *, const GLfloat *); GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *, const GLfloat *); GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat, GLfloat, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *, const GLubyte *, const GLfloat *); GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *, const GLfloat *); GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *, const GLubyte *, const GLfloat *); GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); #endif #ifndef GL_EXT_blend_func_separate #define GL_EXT_blend_func_separate 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum, GLenum, GLenum, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); #endif #ifndef GL_INGR_blend_func_separate #define GL_INGR_blend_func_separate 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum, GLenum, GLenum, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); #endif #ifndef GL_INGR_color_clamp #define GL_INGR_color_clamp 1 #endif #ifndef GL_INGR_interlace_read #define GL_INGR_interlace_read 1 #endif #ifndef GL_EXT_stencil_wrap #define GL_EXT_stencil_wrap 1 #endif #ifndef GL_EXT_422_pixels #define GL_EXT_422_pixels 1 #endif #ifndef GL_NV_texgen_reflection #define GL_NV_texgen_reflection 1 #endif #ifndef GL_SUN_convolution_border_modes #define GL_SUN_convolution_border_modes 1 #endif #ifndef GL_EXT_texture_env_add #define GL_EXT_texture_env_add 1 #endif #ifndef GL_EXT_texture_lod_bias #define GL_EXT_texture_lod_bias 1 #endif #ifndef GL_EXT_texture_filter_anisotropic #define GL_EXT_texture_filter_anisotropic 1 #endif #ifndef GL_EXT_vertex_weighting #define GL_EXT_vertex_weighting 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexWeightfEXT (GLfloat); GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *); GLAPI void APIENTRY glVertexWeightPointerEXT (GLsizei, GLenum, GLsizei, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef GL_NV_light_max_exponent #define GL_NV_light_max_exponent 1 #endif #ifndef GL_NV_vertex_array_range #define GL_NV_vertex_array_range 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFlushVertexArrayRangeNV (void); GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid *pointer); #endif #ifndef GL_NV_register_combiners #define GL_NV_register_combiners 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCombinerParameterfvNV (GLenum, const GLfloat *); GLAPI void APIENTRY glCombinerParameterfNV (GLenum, GLfloat); GLAPI void APIENTRY glCombinerParameterivNV (GLenum, const GLint *); GLAPI void APIENTRY glCombinerParameteriNV (GLenum, GLint); GLAPI void APIENTRY glCombinerInputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY glCombinerOutputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean); GLAPI void APIENTRY glFinalCombinerInputNV (GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum, GLenum, GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum, GLenum, GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum, GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum, GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum, GLenum, GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); #endif #ifndef GL_NV_fog_distance #define GL_NV_fog_distance 1 #endif #ifndef GL_NV_texgen_emboss #define GL_NV_texgen_emboss 1 #endif #ifndef GL_NV_blend_square #define GL_NV_blend_square 1 #endif #ifndef GL_NV_texture_env_combine4 #define GL_NV_texture_env_combine4 1 #endif #ifndef GL_MESA_resize_buffers #define GL_MESA_resize_buffers 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glResizeBuffersMESA (void); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void); #endif #ifndef GL_MESA_window_pos #define GL_MESA_window_pos 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glWindowPos2dMESA (GLdouble, GLdouble); GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *); GLAPI void APIENTRY glWindowPos2fMESA (GLfloat, GLfloat); GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *); GLAPI void APIENTRY glWindowPos2iMESA (GLint, GLint); GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *); GLAPI void APIENTRY glWindowPos2sMESA (GLshort, GLshort); GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *); GLAPI void APIENTRY glWindowPos3dMESA (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *); GLAPI void APIENTRY glWindowPos3fMESA (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *); GLAPI void APIENTRY glWindowPos3iMESA (GLint, GLint, GLint); GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *); GLAPI void APIENTRY glWindowPos3sMESA (GLshort, GLshort, GLshort); GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *); GLAPI void APIENTRY glWindowPos4dMESA (GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *); GLAPI void APIENTRY glWindowPos4fMESA (GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *); GLAPI void APIENTRY glWindowPos4iMESA (GLint, GLint, GLint, GLint); GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *); GLAPI void APIENTRY glWindowPos4sMESA (GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); #endif #ifndef GL_IBM_cull_vertex #define GL_IBM_cull_vertex 1 #endif #ifndef GL_IBM_multimode_draw_arrays #define GL_IBM_multimode_draw_arrays 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *, const GLint *, const GLsizei *, GLsizei, GLint); GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *, const GLsizei *, GLenum, const GLvoid* const *, GLsizei, GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride); #endif #ifndef GL_IBM_vertex_array_lists #define GL_IBM_vertex_array_lists 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint, const GLboolean* *, GLint); GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY glIndexPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY glNormalPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY glTexCoordPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY glVertexPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); #endif #ifndef GL_SGIX_subsample #define GL_SGIX_subsample 1 #endif #ifndef GL_SGIX_ycrcba #define GL_SGIX_ycrcba 1 #endif #ifndef GL_SGIX_ycrcb_subsample #define GL_SGIX_ycrcb_subsample 1 #endif #ifndef GL_SGIX_depth_pass_instrument #define GL_SGIX_depth_pass_instrument 1 #endif #ifndef GL_3DFX_texture_compression_FXT1 #define GL_3DFX_texture_compression_FXT1 1 #endif #ifndef GL_3DFX_multisample #define GL_3DFX_multisample 1 #endif #ifndef GL_3DFX_tbuffer #define GL_3DFX_tbuffer 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTbufferMask3DFX (GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); #endif #ifndef GL_EXT_multisample #define GL_EXT_multisample 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSampleMaskEXT (GLclampf, GLboolean); GLAPI void APIENTRY glSamplePatternEXT (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); #endif #ifndef GL_SGIX_vertex_preclip #define GL_SGIX_vertex_preclip 1 #endif #ifndef GL_SGIX_convolution_accuracy #define GL_SGIX_convolution_accuracy 1 #endif #ifndef GL_SGIX_resample #define GL_SGIX_resample 1 #endif #ifndef GL_SGIS_point_line_texgen #define GL_SGIS_point_line_texgen 1 #endif #ifndef GL_SGIS_texture_color_mask #define GL_SGIS_texture_color_mask 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean, GLboolean, GLboolean, GLboolean); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); #endif #ifndef GL_SGIX_igloo_interface #define GL_SGIX_igloo_interface 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum, const GLvoid *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params); #endif #ifndef GL_EXT_texture_env_dot3 #define GL_EXT_texture_env_dot3 1 #endif #ifndef GL_ATI_texture_mirror_once #define GL_ATI_texture_mirror_once 1 #endif #ifndef GL_NV_fence #define GL_NV_fence 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDeleteFencesNV (GLsizei, const GLuint *); GLAPI void APIENTRY glGenFencesNV (GLsizei, GLuint *); GLAPI GLboolean APIENTRY glIsFenceNV (GLuint); GLAPI GLboolean APIENTRY glTestFenceNV (GLuint); GLAPI void APIENTRY glGetFenceivNV (GLuint, GLenum, GLint *); GLAPI void APIENTRY glFinishFenceNV (GLuint); GLAPI void APIENTRY glSetFenceNV (GLuint, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); #endif #ifndef GL_NV_evaluators #define GL_NV_evaluators 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLint, GLint, GLboolean, const GLvoid *); GLAPI void APIENTRY glMapParameterivNV (GLenum, GLenum, const GLint *); GLAPI void APIENTRY glMapParameterfvNV (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glGetMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLboolean, GLvoid *); GLAPI void APIENTRY glGetMapParameterivNV (GLenum, GLenum, GLint *); GLAPI void APIENTRY glGetMapParameterfvNV (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum, GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glEvalMapsNV (GLenum, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points); typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points); typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); #endif #ifndef GL_NV_packed_depth_stencil #define GL_NV_packed_depth_stencil 1 #endif #ifndef GL_NV_register_combiners2 #define GL_NV_register_combiners2 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum, GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); #endif #ifndef GL_NV_texture_compression_vtc #define GL_NV_texture_compression_vtc 1 #endif #ifndef GL_NV_texture_rectangle #define GL_NV_texture_rectangle 1 #endif #ifndef GL_NV_texture_shader #define GL_NV_texture_shader 1 #endif #ifndef GL_NV_texture_shader2 #define GL_NV_texture_shader2 1 #endif #ifndef GL_NV_vertex_array_range2 #define GL_NV_vertex_array_range2 1 #endif #ifndef GL_NV_vertex_program #define GL_NV_vertex_program 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei, const GLuint *, GLboolean *); GLAPI void APIENTRY glBindProgramNV (GLenum, GLuint); GLAPI void APIENTRY glDeleteProgramsNV (GLsizei, const GLuint *); GLAPI void APIENTRY glExecuteProgramNV (GLenum, GLuint, const GLfloat *); GLAPI void APIENTRY glGenProgramsNV (GLsizei, GLuint *); GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum, GLuint, GLenum, GLdouble *); GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetProgramivNV (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetProgramStringNV (GLuint, GLenum, GLubyte *); GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum, GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint, GLenum, GLdouble *); GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetVertexAttribivNV (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint, GLenum, GLvoid* *); GLAPI GLboolean APIENTRY glIsProgramNV (GLuint); GLAPI void APIENTRY glLoadProgramNV (GLenum, GLuint, GLsizei, const GLubyte *); GLAPI void APIENTRY glProgramParameter4dNV (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glProgramParameter4dvNV (GLenum, GLuint, const GLdouble *); GLAPI void APIENTRY glProgramParameter4fNV (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glProgramParameter4fvNV (GLenum, GLuint, const GLfloat *); GLAPI void APIENTRY glProgramParameters4dvNV (GLenum, GLuint, GLuint, const GLdouble *); GLAPI void APIENTRY glProgramParameters4fvNV (GLenum, GLuint, GLuint, const GLfloat *); GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei, const GLuint *); GLAPI void APIENTRY glTrackMatrixNV (GLenum, GLuint, GLenum, GLenum); GLAPI void APIENTRY glVertexAttribPointerNV (GLuint, GLint, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY glVertexAttrib1dNV (GLuint, GLdouble); GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib1fNV (GLuint, GLfloat); GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib1sNV (GLuint, GLshort); GLAPI void APIENTRY glVertexAttrib1svNV (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib2dNV (GLuint, GLdouble, GLdouble); GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib2fNV (GLuint, GLfloat, GLfloat); GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib2sNV (GLuint, GLshort, GLshort); GLAPI void APIENTRY glVertexAttrib2svNV (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib3dNV (GLuint, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib3fNV (GLuint, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib3sNV (GLuint, GLshort, GLshort, GLshort); GLAPI void APIENTRY glVertexAttrib3svNV (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib4dNV (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint, const GLdouble *); GLAPI void APIENTRY glVertexAttrib4fNV (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint, const GLfloat *); GLAPI void APIENTRY glVertexAttrib4sNV (GLuint, GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY glVertexAttrib4svNV (GLuint, const GLshort *); GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint, const GLubyte *); GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint, GLsizei, const GLdouble *); GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint, GLsizei, const GLfloat *); GLAPI void APIENTRY glVertexAttribs1svNV (GLuint, GLsizei, const GLshort *); GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint, GLsizei, const GLdouble *); GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint, GLsizei, const GLfloat *); GLAPI void APIENTRY glVertexAttribs2svNV (GLuint, GLsizei, const GLshort *); GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint, GLsizei, const GLdouble *); GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint, GLsizei, const GLfloat *); GLAPI void APIENTRY glVertexAttribs3svNV (GLuint, GLsizei, const GLshort *); GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint, GLsizei, const GLdouble *); GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint, GLsizei, const GLfloat *); GLAPI void APIENTRY glVertexAttribs4svNV (GLuint, GLsizei, const GLshort *); GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint, GLsizei, const GLubyte *); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id); typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint count, const GLdouble *v); typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint count, const GLfloat *v); typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); #endif #ifndef GL_SGIX_texture_coordinate_clamp #define GL_SGIX_texture_coordinate_clamp 1 #endif #ifndef GL_SGIX_scalebias_hint #define GL_SGIX_scalebias_hint 1 #endif #ifndef GL_OML_interlace #define GL_OML_interlace 1 #endif #ifndef GL_OML_subsample #define GL_OML_subsample 1 #endif #ifndef GL_OML_resample #define GL_OML_resample 1 #endif #ifndef GL_NV_copy_depth_to_color #define GL_NV_copy_depth_to_color 1 #endif #ifndef GL_ATI_envmap_bumpmap #define GL_ATI_envmap_bumpmap 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexBumpParameterivATI (GLenum, const GLint *); GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum, const GLfloat *); GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum, GLint *); GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param); typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param); typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); #endif #ifndef GL_ATI_fragment_shader #define GL_ATI_fragment_shader 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint); GLAPI void APIENTRY glBindFragmentShaderATI (GLuint); GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint); GLAPI void APIENTRY glBeginFragmentShaderATI (void); GLAPI void APIENTRY glEndFragmentShaderATI (void); GLAPI void APIENTRY glPassTexCoordATI (GLuint, GLuint, GLenum); GLAPI void APIENTRY glSampleMapATI (GLuint, GLuint, GLenum); GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint, const GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void); typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void); typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value); #endif #ifndef GL_ATI_pn_triangles #define GL_ATI_pn_triangles 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPNTrianglesiATI (GLenum, GLint); GLAPI void APIENTRY glPNTrianglesfATI (GLenum, GLfloat); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); #endif #ifndef GL_ATI_vertex_array_object #define GL_ATI_vertex_array_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei, const GLvoid *, GLenum); GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint); GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint, GLuint, GLsizei, const GLvoid *, GLenum); GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetObjectBufferivATI (GLuint, GLenum, GLint *); GLAPI void APIENTRY glFreeObjectBufferATI (GLuint); GLAPI void APIENTRY glArrayObjectATI (GLenum, GLint, GLenum, GLsizei, GLuint, GLuint); GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY glGetArrayObjectivATI (GLenum, GLenum, GLint *); GLAPI void APIENTRY glVariantArrayObjectATI (GLuint, GLenum, GLsizei, GLuint, GLuint); GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint, GLenum, GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage); typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve); typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params); #endif #ifndef GL_EXT_vertex_shader #define GL_EXT_vertex_shader 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBeginVertexShaderEXT (void); GLAPI void APIENTRY glEndVertexShaderEXT (void); GLAPI void APIENTRY glBindVertexShaderEXT (GLuint); GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint); GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint); GLAPI void APIENTRY glShaderOp1EXT (GLenum, GLuint, GLuint); GLAPI void APIENTRY glShaderOp2EXT (GLenum, GLuint, GLuint, GLuint); GLAPI void APIENTRY glShaderOp3EXT (GLenum, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY glSwizzleEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY glWriteMaskEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY glInsertComponentEXT (GLuint, GLuint, GLuint); GLAPI void APIENTRY glExtractComponentEXT (GLuint, GLuint, GLuint); GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum, GLenum, GLenum, GLuint); GLAPI void APIENTRY glSetInvariantEXT (GLuint, GLenum, const GLvoid *); GLAPI void APIENTRY glSetLocalConstantEXT (GLuint, GLenum, const GLvoid *); GLAPI void APIENTRY glVariantbvEXT (GLuint, const GLbyte *); GLAPI void APIENTRY glVariantsvEXT (GLuint, const GLshort *); GLAPI void APIENTRY glVariantivEXT (GLuint, const GLint *); GLAPI void APIENTRY glVariantfvEXT (GLuint, const GLfloat *); GLAPI void APIENTRY glVariantdvEXT (GLuint, const GLdouble *); GLAPI void APIENTRY glVariantubvEXT (GLuint, const GLubyte *); GLAPI void APIENTRY glVariantusvEXT (GLuint, const GLushort *); GLAPI void APIENTRY glVariantuivEXT (GLuint, const GLuint *); GLAPI void APIENTRY glVariantPointerEXT (GLuint, GLenum, GLuint, const GLvoid *); GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint); GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint); GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum, GLenum); GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum, GLenum); GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum, GLenum, GLenum); GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum, GLenum); GLAPI GLuint APIENTRY glBindParameterEXT (GLenum); GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint, GLenum); GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint, GLenum, GLboolean *); GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetVariantPointervEXT (GLuint, GLenum, GLvoid* *); GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint, GLenum, GLboolean *); GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint, GLenum, GLboolean *); GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint, GLenum, GLfloat *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void); typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void); typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr); typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr); typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr); typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr); typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr); typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr); typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr); typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr); typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr); typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value); typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* *data); typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); #endif #ifndef GL_ATI_vertex_streams #define GL_ATI_vertex_streams 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexStream1sATI (GLenum, GLshort); GLAPI void APIENTRY glVertexStream1svATI (GLenum, const GLshort *); GLAPI void APIENTRY glVertexStream1iATI (GLenum, GLint); GLAPI void APIENTRY glVertexStream1ivATI (GLenum, const GLint *); GLAPI void APIENTRY glVertexStream1fATI (GLenum, GLfloat); GLAPI void APIENTRY glVertexStream1fvATI (GLenum, const GLfloat *); GLAPI void APIENTRY glVertexStream1dATI (GLenum, GLdouble); GLAPI void APIENTRY glVertexStream1dvATI (GLenum, const GLdouble *); GLAPI void APIENTRY glVertexStream2sATI (GLenum, GLshort, GLshort); GLAPI void APIENTRY glVertexStream2svATI (GLenum, const GLshort *); GLAPI void APIENTRY glVertexStream2iATI (GLenum, GLint, GLint); GLAPI void APIENTRY glVertexStream2ivATI (GLenum, const GLint *); GLAPI void APIENTRY glVertexStream2fATI (GLenum, GLfloat, GLfloat); GLAPI void APIENTRY glVertexStream2fvATI (GLenum, const GLfloat *); GLAPI void APIENTRY glVertexStream2dATI (GLenum, GLdouble, GLdouble); GLAPI void APIENTRY glVertexStream2dvATI (GLenum, const GLdouble *); GLAPI void APIENTRY glVertexStream3sATI (GLenum, GLshort, GLshort, GLshort); GLAPI void APIENTRY glVertexStream3svATI (GLenum, const GLshort *); GLAPI void APIENTRY glVertexStream3iATI (GLenum, GLint, GLint, GLint); GLAPI void APIENTRY glVertexStream3ivATI (GLenum, const GLint *); GLAPI void APIENTRY glVertexStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glVertexStream3fvATI (GLenum, const GLfloat *); GLAPI void APIENTRY glVertexStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glVertexStream3dvATI (GLenum, const GLdouble *); GLAPI void APIENTRY glVertexStream4sATI (GLenum, GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY glVertexStream4svATI (GLenum, const GLshort *); GLAPI void APIENTRY glVertexStream4iATI (GLenum, GLint, GLint, GLint, GLint); GLAPI void APIENTRY glVertexStream4ivATI (GLenum, const GLint *); GLAPI void APIENTRY glVertexStream4fATI (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glVertexStream4fvATI (GLenum, const GLfloat *); GLAPI void APIENTRY glVertexStream4dATI (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glVertexStream4dvATI (GLenum, const GLdouble *); GLAPI void APIENTRY glNormalStream3bATI (GLenum, GLbyte, GLbyte, GLbyte); GLAPI void APIENTRY glNormalStream3bvATI (GLenum, const GLbyte *); GLAPI void APIENTRY glNormalStream3sATI (GLenum, GLshort, GLshort, GLshort); GLAPI void APIENTRY glNormalStream3svATI (GLenum, const GLshort *); GLAPI void APIENTRY glNormalStream3iATI (GLenum, GLint, GLint, GLint); GLAPI void APIENTRY glNormalStream3ivATI (GLenum, const GLint *); GLAPI void APIENTRY glNormalStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glNormalStream3fvATI (GLenum, const GLfloat *); GLAPI void APIENTRY glNormalStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glNormalStream3dvATI (GLenum, const GLdouble *); GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum); GLAPI void APIENTRY glVertexBlendEnviATI (GLenum, GLint); GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum, GLfloat); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); #endif #ifndef GL_ATI_element_array #define GL_ATI_element_array 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glElementPointerATI (GLenum, const GLvoid *); GLAPI void APIENTRY glDrawElementArrayATI (GLenum, GLsizei); GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum, GLuint, GLuint, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer); typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); #endif #ifndef GL_SUN_mesh_array #define GL_SUN_mesh_array 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum, GLint, GLsizei, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); #endif #ifndef GL_SUN_slice_accum #define GL_SUN_slice_accum 1 #endif #ifndef GL_NV_multisample_filter_hint #define GL_NV_multisample_filter_hint 1 #endif #ifndef GL_NV_depth_clamp #define GL_NV_depth_clamp 1 #endif #ifndef GL_NV_occlusion_query #define GL_NV_occlusion_query 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei, GLuint *); GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei, const GLuint *); GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint); GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint); GLAPI void APIENTRY glEndOcclusionQueryNV (void); GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint, GLenum, GLint *); GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint, GLenum, GLuint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void); typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); #endif #ifndef GL_NV_point_sprite #define GL_NV_point_sprite 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPointParameteriNV (GLenum, GLint); GLAPI void APIENTRY glPointParameterivNV (GLenum, const GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params); #endif #ifndef GL_NV_texture_shader3 #define GL_NV_texture_shader3 1 #endif #ifndef GL_NV_vertex_program1_1 #define GL_NV_vertex_program1_1 1 #endif #ifndef GL_EXT_shadow_funcs #define GL_EXT_shadow_funcs 1 #endif #ifndef GL_EXT_stencil_two_side #define GL_EXT_stencil_two_side 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); #endif #ifndef GL_ATI_text_fragment_shader #define GL_ATI_text_fragment_shader 1 #endif #ifndef GL_APPLE_client_storage #define GL_APPLE_client_storage 1 #endif #ifndef GL_APPLE_element_array #define GL_APPLE_element_array 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glElementPointerAPPLE (GLenum, const GLvoid *); GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum, GLint, GLsizei); GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, GLint, GLsizei); GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum, const GLint *, const GLsizei *, GLsizei); GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, const GLint *, const GLsizei *, GLsizei); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer); typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); #endif #ifndef GL_APPLE_fence #define GL_APPLE_fence 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGenFencesAPPLE (GLsizei, GLuint *); GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei, const GLuint *); GLAPI void APIENTRY glSetFenceAPPLE (GLuint); GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint); GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint); GLAPI void APIENTRY glFinishFenceAPPLE (GLuint); GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum, GLuint); GLAPI void APIENTRY glFinishObjectAPPLE (GLenum, GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences); typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences); typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence); typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence); typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence); typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); #endif #ifndef GL_APPLE_vertex_array_object #define GL_APPLE_vertex_array_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint); GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei, const GLuint *); GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei, const GLuint *); GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); #endif #ifndef GL_APPLE_vertex_array_range #define GL_APPLE_vertex_array_range 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei, GLvoid *); GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei, GLvoid *); GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum, GLint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); #endif #ifndef GL_APPLE_ycbcr_422 #define GL_APPLE_ycbcr_422 1 #endif #ifndef GL_S3_s3tc #define GL_S3_s3tc 1 #endif #ifndef GL_ATI_draw_buffers #define GL_ATI_draw_buffers 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawBuffersATI (GLsizei, const GLenum *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs); #endif #ifndef GL_ATI_texture_env_combine3 #define GL_ATI_texture_env_combine3 1 #endif #ifndef GL_ATI_texture_float #define GL_ATI_texture_float 1 #endif #ifndef GL_NV_float_buffer #define GL_NV_float_buffer 1 #endif #ifndef GL_NV_fragment_program #define GL_NV_fragment_program 1 /* Some NV_fragment_program entry points are shared with ARB_vertex_program. */ #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint, GLsizei, const GLubyte *, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint, GLsizei, const GLubyte *, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint, GLsizei, const GLubyte *, const GLfloat *); GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint, GLsizei, const GLubyte *, const GLdouble *); GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint, GLsizei, const GLubyte *, GLfloat *); GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint, GLsizei, const GLubyte *, GLdouble *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); #endif #ifndef GL_NV_half_float #define GL_NV_half_float 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertex2hNV (GLhalfNV, GLhalfNV); GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *); GLAPI void APIENTRY glVertex3hNV (GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *); GLAPI void APIENTRY glVertex4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *); GLAPI void APIENTRY glNormal3hNV (GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *); GLAPI void APIENTRY glColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *); GLAPI void APIENTRY glColor4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *); GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV); GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *); GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV, GLhalfNV); GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *); GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *); GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *); GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum, GLhalfNV); GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum, const GLhalfNV *); GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum, const GLhalfNV *); GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum, const GLhalfNV *); GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum, const GLhalfNV *); GLAPI void APIENTRY glFogCoordhNV (GLhalfNV); GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *); GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *); GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV); GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *); GLAPI void APIENTRY glVertexAttrib1hNV (GLuint, GLhalfNV); GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint, const GLhalfNV *); GLAPI void APIENTRY glVertexAttrib2hNV (GLuint, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint, const GLhalfNV *); GLAPI void APIENTRY glVertexAttrib3hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint, const GLhalfNV *); GLAPI void APIENTRY glVertexAttrib4hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint, const GLhalfNV *); GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint, GLsizei, const GLhalfNV *); GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint, GLsizei, const GLhalfNV *); GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint, GLsizei, const GLhalfNV *); GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint, GLsizei, const GLhalfNV *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s); typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); #endif #ifndef GL_NV_pixel_data_range #define GL_NV_pixel_data_range 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPixelDataRangeNV (GLenum, GLsizei, GLvoid *); GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer); typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); #endif #ifndef GL_NV_primitive_restart #define GL_NV_primitive_restart 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glPrimitiveRestartNV (void); GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void); typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); #endif #ifndef GL_NV_texture_expand_normal #define GL_NV_texture_expand_normal 1 #endif #ifndef GL_NV_vertex_program2 #define GL_NV_vertex_program2 1 #endif #ifndef GL_ATI_map_object_buffer #define GL_ATI_map_object_buffer 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI GLvoid* APIENTRY glMapObjectBufferATI (GLuint); GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef GLvoid* (APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); #endif #ifndef GL_ATI_separate_stencil #define GL_ATI_separate_stencil 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glStencilOpSeparateATI (GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum, GLenum, GLint, GLuint); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); #endif #ifndef GL_ATI_vertex_attrib_array_object #define GL_ATI_vertex_attrib_array_object 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint, GLint, GLenum, GLboolean, GLsizei, GLuint, GLuint); GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint, GLenum, GLint *); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params); #endif #ifndef GL_EXT_depth_bounds_test #define GL_EXT_depth_bounds_test 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDepthBoundsEXT (GLclampd, GLclampd); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); #endif #ifndef GL_EXT_texture_mirror_clamp #define GL_EXT_texture_mirror_clamp 1 #endif #ifndef GL_EXT_blend_equation_separate #define GL_EXT_blend_equation_separate 1 #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum, GLenum); #endif /* GL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); #endif #ifndef GL_MESA_pack_invert #define GL_MESA_pack_invert 1 #endif #ifndef GL_MESA_ycbcr_texture #define GL_MESA_ycbcr_texture 1 #endif #ifndef GL_WIN_swap_hint #define GL_WIN_swap_hint 1 extern void APIENTRY glAddSwapHintRectWIN (GLint, GLint, GLsizei, GLsizei); typedef void (APIENTRY * PFNGLADDSWAPHINTRECTWINPROC) (GLint x, GLint y, GLsizei width, GLsizei height); #endif #ifdef __cplusplus } #endif #endif rgl/src/ext/GLsdk/GL/wglext.h0000644000176200001440000006472714100762641015437 0ustar liggesusers#ifndef __wglext_h_ #define __wglext_h_ #ifdef __cplusplus extern "C" { #endif /* ** License Applicability. Except to the extent portions of this file are ** made subject to an alternative license as permitted in the SGI Free ** Software License B, Version 1.1 (the "License"), the contents of this ** file are subject only to the provisions of the License. You may not use ** this file except in compliance with the License. You may obtain a copy ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: ** ** http://oss.sgi.com/projects/FreeB ** ** Note that, as provided in the License, the Software is distributed on an ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. ** ** Original Code. The Original Code is: OpenGL Sample Implementation, ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, ** Inc. The Original Code is Copyright (c) 1991-2002 Silicon Graphics, Inc. ** Copyright in any portions created by third parties is as indicated ** elsewhere herein. All Rights Reserved. ** ** Additional Notice Provisions: This software was created using the ** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has ** not been independently verified as being compliant with the OpenGL(R) ** version 1.2.1 Specification. */ #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) #define WIN32_LEAN_AND_MEAN 1 #include #endif #ifndef APIENTRY #define APIENTRY #endif #ifndef APIENTRYP #define APIENTRYP APIENTRY * #endif #ifndef GLAPI #define GLAPI extern #endif /*************************************************************/ /* Header file version number */ /* wglext.h last updated 2002/03/22 */ /* Current version at http://oss.sgi.com/projects/ogl-sample/registry/ */ #define WGL_WGLEXT_VERSION 4 #ifndef WGL_ARB_buffer_region #define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 #define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 #define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 #define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 #endif #ifndef WGL_ARB_multisample #define WGL_SAMPLE_BUFFERS_ARB 0x2041 #define WGL_SAMPLES_ARB 0x2042 #endif #ifndef WGL_ARB_extensions_string #endif #ifndef WGL_ARB_pixel_format #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 #define WGL_DRAW_TO_WINDOW_ARB 0x2001 #define WGL_DRAW_TO_BITMAP_ARB 0x2002 #define WGL_ACCELERATION_ARB 0x2003 #define WGL_NEED_PALETTE_ARB 0x2004 #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 #define WGL_SWAP_METHOD_ARB 0x2007 #define WGL_NUMBER_OVERLAYS_ARB 0x2008 #define WGL_NUMBER_UNDERLAYS_ARB 0x2009 #define WGL_TRANSPARENT_ARB 0x200A #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B #define WGL_SHARE_DEPTH_ARB 0x200C #define WGL_SHARE_STENCIL_ARB 0x200D #define WGL_SHARE_ACCUM_ARB 0x200E #define WGL_SUPPORT_GDI_ARB 0x200F #define WGL_SUPPORT_OPENGL_ARB 0x2010 #define WGL_DOUBLE_BUFFER_ARB 0x2011 #define WGL_STEREO_ARB 0x2012 #define WGL_PIXEL_TYPE_ARB 0x2013 #define WGL_COLOR_BITS_ARB 0x2014 #define WGL_RED_BITS_ARB 0x2015 #define WGL_RED_SHIFT_ARB 0x2016 #define WGL_GREEN_BITS_ARB 0x2017 #define WGL_GREEN_SHIFT_ARB 0x2018 #define WGL_BLUE_BITS_ARB 0x2019 #define WGL_BLUE_SHIFT_ARB 0x201A #define WGL_ALPHA_BITS_ARB 0x201B #define WGL_ALPHA_SHIFT_ARB 0x201C #define WGL_ACCUM_BITS_ARB 0x201D #define WGL_ACCUM_RED_BITS_ARB 0x201E #define WGL_ACCUM_GREEN_BITS_ARB 0x201F #define WGL_ACCUM_BLUE_BITS_ARB 0x2020 #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 #define WGL_DEPTH_BITS_ARB 0x2022 #define WGL_STENCIL_BITS_ARB 0x2023 #define WGL_AUX_BUFFERS_ARB 0x2024 #define WGL_NO_ACCELERATION_ARB 0x2025 #define WGL_GENERIC_ACCELERATION_ARB 0x2026 #define WGL_FULL_ACCELERATION_ARB 0x2027 #define WGL_SWAP_EXCHANGE_ARB 0x2028 #define WGL_SWAP_COPY_ARB 0x2029 #define WGL_SWAP_UNDEFINED_ARB 0x202A #define WGL_TYPE_RGBA_ARB 0x202B #define WGL_TYPE_COLORINDEX_ARB 0x202C #endif #ifndef WGL_ARB_make_current_read #define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 #define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 #endif #ifndef WGL_ARB_pbuffer #define WGL_DRAW_TO_PBUFFER_ARB 0x202D #define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E #define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F #define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 #define WGL_PBUFFER_LARGEST_ARB 0x2033 #define WGL_PBUFFER_WIDTH_ARB 0x2034 #define WGL_PBUFFER_HEIGHT_ARB 0x2035 #define WGL_PBUFFER_LOST_ARB 0x2036 #endif #ifndef WGL_ARB_render_texture #define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 #define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 #define WGL_TEXTURE_FORMAT_ARB 0x2072 #define WGL_TEXTURE_TARGET_ARB 0x2073 #define WGL_MIPMAP_TEXTURE_ARB 0x2074 #define WGL_TEXTURE_RGB_ARB 0x2075 #define WGL_TEXTURE_RGBA_ARB 0x2076 #define WGL_NO_TEXTURE_ARB 0x2077 #define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 #define WGL_TEXTURE_1D_ARB 0x2079 #define WGL_TEXTURE_2D_ARB 0x207A #define WGL_MIPMAP_LEVEL_ARB 0x207B #define WGL_CUBE_MAP_FACE_ARB 0x207C #define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E #define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 #define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 #define WGL_FRONT_LEFT_ARB 0x2083 #define WGL_FRONT_RIGHT_ARB 0x2084 #define WGL_BACK_LEFT_ARB 0x2085 #define WGL_BACK_RIGHT_ARB 0x2086 #define WGL_AUX0_ARB 0x2087 #define WGL_AUX1_ARB 0x2088 #define WGL_AUX2_ARB 0x2089 #define WGL_AUX3_ARB 0x208A #define WGL_AUX4_ARB 0x208B #define WGL_AUX5_ARB 0x208C #define WGL_AUX6_ARB 0x208D #define WGL_AUX7_ARB 0x208E #define WGL_AUX8_ARB 0x208F #define WGL_AUX9_ARB 0x2090 #endif #ifndef WGL_EXT_make_current_read #define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 #endif #ifndef WGL_EXT_pixel_format #define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 #define WGL_DRAW_TO_WINDOW_EXT 0x2001 #define WGL_DRAW_TO_BITMAP_EXT 0x2002 #define WGL_ACCELERATION_EXT 0x2003 #define WGL_NEED_PALETTE_EXT 0x2004 #define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 #define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 #define WGL_SWAP_METHOD_EXT 0x2007 #define WGL_NUMBER_OVERLAYS_EXT 0x2008 #define WGL_NUMBER_UNDERLAYS_EXT 0x2009 #define WGL_TRANSPARENT_EXT 0x200A #define WGL_TRANSPARENT_VALUE_EXT 0x200B #define WGL_SHARE_DEPTH_EXT 0x200C #define WGL_SHARE_STENCIL_EXT 0x200D #define WGL_SHARE_ACCUM_EXT 0x200E #define WGL_SUPPORT_GDI_EXT 0x200F #define WGL_SUPPORT_OPENGL_EXT 0x2010 #define WGL_DOUBLE_BUFFER_EXT 0x2011 #define WGL_STEREO_EXT 0x2012 #define WGL_PIXEL_TYPE_EXT 0x2013 #define WGL_COLOR_BITS_EXT 0x2014 #define WGL_RED_BITS_EXT 0x2015 #define WGL_RED_SHIFT_EXT 0x2016 #define WGL_GREEN_BITS_EXT 0x2017 #define WGL_GREEN_SHIFT_EXT 0x2018 #define WGL_BLUE_BITS_EXT 0x2019 #define WGL_BLUE_SHIFT_EXT 0x201A #define WGL_ALPHA_BITS_EXT 0x201B #define WGL_ALPHA_SHIFT_EXT 0x201C #define WGL_ACCUM_BITS_EXT 0x201D #define WGL_ACCUM_RED_BITS_EXT 0x201E #define WGL_ACCUM_GREEN_BITS_EXT 0x201F #define WGL_ACCUM_BLUE_BITS_EXT 0x2020 #define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 #define WGL_DEPTH_BITS_EXT 0x2022 #define WGL_STENCIL_BITS_EXT 0x2023 #define WGL_AUX_BUFFERS_EXT 0x2024 #define WGL_NO_ACCELERATION_EXT 0x2025 #define WGL_GENERIC_ACCELERATION_EXT 0x2026 #define WGL_FULL_ACCELERATION_EXT 0x2027 #define WGL_SWAP_EXCHANGE_EXT 0x2028 #define WGL_SWAP_COPY_EXT 0x2029 #define WGL_SWAP_UNDEFINED_EXT 0x202A #define WGL_TYPE_RGBA_EXT 0x202B #define WGL_TYPE_COLORINDEX_EXT 0x202C #endif #ifndef WGL_EXT_pbuffer #define WGL_DRAW_TO_PBUFFER_EXT 0x202D #define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E #define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F #define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 #define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 #define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 #define WGL_PBUFFER_LARGEST_EXT 0x2033 #define WGL_PBUFFER_WIDTH_EXT 0x2034 #define WGL_PBUFFER_HEIGHT_EXT 0x2035 #endif #ifndef WGL_EXT_depth_float #define WGL_DEPTH_FLOAT_EXT 0x2040 #endif #ifndef WGL_3DFX_multisample #define WGL_SAMPLE_BUFFERS_3DFX 0x2060 #define WGL_SAMPLES_3DFX 0x2061 #endif #ifndef WGL_EXT_multisample #define WGL_SAMPLE_BUFFERS_EXT 0x2041 #define WGL_SAMPLES_EXT 0x2042 #endif #ifndef WGL_I3D_digital_video_control #define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 #define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 #define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 #define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 #endif #ifndef WGL_I3D_gamma #define WGL_GAMMA_TABLE_SIZE_I3D 0x204E #define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F #endif #ifndef WGL_I3D_genlock #define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 #define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045 #define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046 #define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047 #define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 #define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 #define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A #define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B #define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C #endif #ifndef WGL_I3D_image_buffer #define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 #define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 #endif #ifndef WGL_I3D_swap_frame_lock #endif #ifndef WGL_NV_render_depth_texture #define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 #define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 #define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 #define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 #define WGL_DEPTH_COMPONENT_NV 0x20A7 #endif #ifndef WGL_NV_render_texture_rectangle #define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 #define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 #define WGL_TEXTURE_RECTANGLE_NV 0x20A2 #endif #ifndef WGL_NV_float_buffer #define WGL_FLOAT_COMPONENTS_NV 0x20B0 #define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 #define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 #define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 #define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 #define WGL_TEXTURE_FLOAT_R_NV 0x20B5 #define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 #define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 #define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 #endif /*************************************************************/ #ifndef WGL_ARB_pbuffer DECLARE_HANDLE(HPBUFFERARB); #endif #ifndef WGL_EXT_pbuffer DECLARE_HANDLE(HPBUFFEREXT); #endif #ifndef WGL_ARB_buffer_region #define WGL_ARB_buffer_region 1 #ifdef WGL_WGLEXT_PROTOTYPES extern HANDLE WINAPI wglCreateBufferRegionARB (HDC, int, UINT); extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE); extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE, int, int, int, int); extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE, int, int, int, int, int, int); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); #endif #ifndef WGL_ARB_multisample #define WGL_ARB_multisample 1 #endif #ifndef WGL_ARB_extensions_string #define WGL_ARB_extensions_string 1 #ifdef WGL_WGLEXT_PROTOTYPES extern const char * WINAPI wglGetExtensionsStringARB (HDC); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); #endif #ifndef WGL_ARB_pixel_format #define WGL_ARB_pixel_format 1 #ifdef WGL_WGLEXT_PROTOTYPES extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC, int, int, UINT, const int *, int *); extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC, int, int, UINT, const int *, FLOAT *); extern BOOL WINAPI wglChoosePixelFormatARB (HDC, const int *, const FLOAT *, UINT, int *, UINT *); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); #endif #ifndef WGL_ARB_make_current_read #define WGL_ARB_make_current_read 1 #ifdef WGL_WGLEXT_PROTOTYPES extern BOOL WINAPI wglMakeContextCurrentARB (HDC, HDC, HGLRC); extern HDC WINAPI wglGetCurrentReadDCARB (void); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); #endif #ifndef WGL_ARB_pbuffer #define WGL_ARB_pbuffer 1 #ifdef WGL_WGLEXT_PROTOTYPES extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC, int, int, int, const int *); extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB); extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB, HDC); extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB); extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB, int, int *); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); #endif #ifndef WGL_ARB_render_texture #define WGL_ARB_render_texture 1 #ifdef WGL_WGLEXT_PROTOTYPES extern BOOL WINAPI wglBindTexImageARB (HPBUFFERARB, int); extern BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB, int); extern BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB, const int *); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList); #endif #ifndef WGL_EXT_display_color_table #define WGL_EXT_display_color_table 1 #ifdef WGL_WGLEXT_PROTOTYPES extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort); extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *, GLuint); extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort); extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length); typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); #endif #ifndef WGL_EXT_extensions_string #define WGL_EXT_extensions_string 1 #ifdef WGL_WGLEXT_PROTOTYPES extern const char * WINAPI wglGetExtensionsStringEXT (void); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); #endif #ifndef WGL_EXT_make_current_read #define WGL_EXT_make_current_read 1 #ifdef WGL_WGLEXT_PROTOTYPES extern BOOL WINAPI wglMakeContextCurrentEXT (HDC, HDC, HGLRC); extern HDC WINAPI wglGetCurrentReadDCEXT (void); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void); #endif #ifndef WGL_EXT_pbuffer #define WGL_EXT_pbuffer 1 #ifdef WGL_WGLEXT_PROTOTYPES extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC, int, int, int, const int *); extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT); extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT, HDC); extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT); extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT, int, int *); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); #endif #ifndef WGL_EXT_pixel_format #define WGL_EXT_pixel_format 1 #ifdef WGL_WGLEXT_PROTOTYPES extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC, int, int, UINT, int *, int *); extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC, int, int, UINT, int *, FLOAT *); extern BOOL WINAPI wglChoosePixelFormatEXT (HDC, const int *, const FLOAT *, UINT, int *, UINT *); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); #endif #ifndef WGL_EXT_swap_control #define WGL_EXT_swap_control 1 #ifdef WGL_WGLEXT_PROTOTYPES extern BOOL WINAPI wglSwapIntervalEXT (int); extern int WINAPI wglGetSwapIntervalEXT (void); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); #endif #ifndef WGL_EXT_depth_float #define WGL_EXT_depth_float 1 #endif #ifndef WGL_NV_vertex_array_range #define WGL_NV_vertex_array_range 1 #ifdef WGL_WGLEXT_PROTOTYPES extern void* WINAPI wglAllocateMemoryNV (GLsizei, GLfloat, GLfloat, GLfloat); extern void WINAPI wglFreeMemoryNV (void *); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); #endif #ifndef WGL_3DFX_multisample #define WGL_3DFX_multisample 1 #endif #ifndef WGL_EXT_multisample #define WGL_EXT_multisample 1 #endif #ifndef WGL_OML_sync_control #define WGL_OML_sync_control 1 #ifdef WGL_WGLEXT_PROTOTYPES extern BOOL WINAPI wglGetSyncValuesOML (HDC, INT64 *, INT64 *, INT64 *); extern BOOL WINAPI wglGetMscRateOML (HDC, INT32 *, INT32 *); extern INT64 WINAPI wglSwapBuffersMscOML (HDC, INT64, INT64, INT64); extern INT64 WINAPI wglSwapLayerBuffersMscOML (HDC, int, INT64, INT64, INT64); extern BOOL WINAPI wglWaitForMscOML (HDC, INT64, INT64, INT64, INT64 *, INT64 *, INT64 *); extern BOOL WINAPI wglWaitForSbcOML (HDC, INT64, INT64 *, INT64 *, INT64 *); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator); typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); #endif #ifndef WGL_I3D_digital_video_control #define WGL_I3D_digital_video_control 1 #ifdef WGL_WGLEXT_PROTOTYPES extern BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC, int, int *); extern BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC, int, const int *); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); #endif #ifndef WGL_I3D_gamma #define WGL_I3D_gamma 1 #ifdef WGL_WGLEXT_PROTOTYPES extern BOOL WINAPI wglGetGammaTableParametersI3D (HDC, int, int *); extern BOOL WINAPI wglSetGammaTableParametersI3D (HDC, int, const int *); extern BOOL WINAPI wglGetGammaTableI3D (HDC, int, USHORT *, USHORT *, USHORT *); extern BOOL WINAPI wglSetGammaTableI3D (HDC, int, const USHORT *, const USHORT *, const USHORT *); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); #endif #ifndef WGL_I3D_genlock #define WGL_I3D_genlock 1 #ifdef WGL_WGLEXT_PROTOTYPES extern BOOL WINAPI wglEnableGenlockI3D (HDC); extern BOOL WINAPI wglDisableGenlockI3D (HDC); extern BOOL WINAPI wglIsEnabledGenlockI3D (HDC, BOOL *); extern BOOL WINAPI wglGenlockSourceI3D (HDC, UINT); extern BOOL WINAPI wglGetGenlockSourceI3D (HDC, UINT *); extern BOOL WINAPI wglGenlockSourceEdgeI3D (HDC, UINT); extern BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC, UINT *); extern BOOL WINAPI wglGenlockSampleRateI3D (HDC, UINT); extern BOOL WINAPI wglGetGenlockSampleRateI3D (HDC, UINT *); extern BOOL WINAPI wglGenlockSourceDelayI3D (HDC, UINT); extern BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC, UINT *); extern BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC, UINT *, UINT *); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag); typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource); typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge); typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate); typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay); typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); #endif #ifndef WGL_I3D_image_buffer #define WGL_I3D_image_buffer 1 #ifdef WGL_WGLEXT_PROTOTYPES extern LPVOID WINAPI wglCreateImageBufferI3D (HDC, DWORD, UINT); extern BOOL WINAPI wglDestroyImageBufferI3D (HDC, LPVOID); extern BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC, const HANDLE *, const LPVOID *, const DWORD *, UINT); extern BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC, const LPVOID *, UINT); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count); #endif #ifndef WGL_I3D_swap_frame_lock #define WGL_I3D_swap_frame_lock 1 #ifdef WGL_WGLEXT_PROTOTYPES extern BOOL WINAPI wglEnableFrameLockI3D (void); extern BOOL WINAPI wglDisableFrameLockI3D (void); extern BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *); extern BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void); typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void); typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag); typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag); #endif #ifndef WGL_I3D_swap_frame_usage #define WGL_I3D_swap_frame_usage 1 #ifdef WGL_WGLEXT_PROTOTYPES extern BOOL WINAPI wglGetFrameUsageI3D (float *); extern BOOL WINAPI wglBeginFrameTrackingI3D (void); extern BOOL WINAPI wglEndFrameTrackingI3D (void); extern BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *, DWORD *, float *); #endif /* WGL_WGLEXT_PROTOTYPES */ typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage); typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); #endif #ifdef __cplusplus } #endif #endif rgl/src/ext/GLsdk/GL/glprocs.c0000644000176200001440000125250714100762641015565 0ustar liggesusers/* ** GLprocs utility for getting function addresses for OpenGL(R) 1.2, ** OpenGL 1.3, OpenGL 1.4, OpenGL 1.5 and OpenGL extension functions. ** ** Version: 1.1 ** ** License Applicability. Except to the extent portions of this file are ** made subject to an alternative license as permitted in the SGI Free ** Software License B, Version 1.1 (the "License"), the contents of this ** file are subject only to the provisions of the License. You may not use ** this file except in compliance with the License. You may obtain a copy ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: ** ** http://oss.sgi.com/projects/FreeB ** ** Note that, as provided in the License, the Software is distributed on an ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. ** ** Original Code. The Original Code is: OpenGL Sample Implementation, ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. ** Copyright in any portions created by third parties is as indicated ** elsewhere herein. All Rights Reserved. ** ** Additional Notice Provisions: This software was created using the ** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has ** not been independently verified as being compliant with the OpenGL(R) ** version 1.2.1 Specification. ** ** Initial version of glprocs.{c,h} contributed by Intel(R) Corporation. */ #include #include #ifdef _WIN32 #include #include "gl.h" /* Include local "gl.h". Don't include vc32 . */ #include "glprocs.h" #else /* GLX */ #include #include #include #define wglGetProcAddress glXGetProcAddressARB #endif #define _ASSERT(a) assert(a) static void APIENTRY InitBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { void *extproc; extproc = (void *) wglGetProcAddress("glBlendColor"); if (extproc == NULL) { _ASSERT(0); return; } glBlendColor = extproc; glBlendColor(red, green, blue, alpha); } static void APIENTRY InitBlendEquation (GLenum mode) { void *extproc; extproc = (void *) wglGetProcAddress("glBlendEquation"); if (extproc == NULL) { _ASSERT(0); return; } glBlendEquation = extproc; glBlendEquation(mode); } static void APIENTRY InitDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) { void *extproc; extproc = (void *) wglGetProcAddress("glDrawRangeElements"); if (extproc == NULL) { _ASSERT(0); return; } glDrawRangeElements = extproc; glDrawRangeElements(mode, start, end, count, type, indices); } static void APIENTRY InitColorTable (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table) { void *extproc; extproc = (void *) wglGetProcAddress("glColorTable"); if (extproc == NULL) { _ASSERT(0); return; } glColorTable = extproc; glColorTable(target, internalformat, width, format, type, table); } static void APIENTRY InitColorTableParameterfv (GLenum target, GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glColorTableParameterfv"); if (extproc == NULL) { _ASSERT(0); return; } glColorTableParameterfv = extproc; glColorTableParameterfv(target, pname, params); } static void APIENTRY InitColorTableParameteriv (GLenum target, GLenum pname, const GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glColorTableParameteriv"); if (extproc == NULL) { _ASSERT(0); return; } glColorTableParameteriv = extproc; glColorTableParameteriv(target, pname, params); } static void APIENTRY InitCopyColorTable (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) { void *extproc; extproc = (void *) wglGetProcAddress("glCopyColorTable"); if (extproc == NULL) { _ASSERT(0); return; } glCopyColorTable = extproc; glCopyColorTable(target, internalformat, x, y, width); } static void APIENTRY InitGetColorTable (GLenum target, GLenum format, GLenum type, GLvoid *table) { void *extproc; extproc = (void *) wglGetProcAddress("glGetColorTable"); if (extproc == NULL) { _ASSERT(0); return; } glGetColorTable = extproc; glGetColorTable(target, format, type, table); } static void APIENTRY InitGetColorTableParameterfv (GLenum target, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetColorTableParameterfv"); if (extproc == NULL) { _ASSERT(0); return; } glGetColorTableParameterfv = extproc; glGetColorTableParameterfv(target, pname, params); } static void APIENTRY InitGetColorTableParameteriv (GLenum target, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetColorTableParameteriv"); if (extproc == NULL) { _ASSERT(0); return; } glGetColorTableParameteriv = extproc; glGetColorTableParameteriv(target, pname, params); } static void APIENTRY InitColorSubTable (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glColorSubTable"); if (extproc == NULL) { _ASSERT(0); return; } glColorSubTable = extproc; glColorSubTable(target, start, count, format, type, data); } static void APIENTRY InitCopyColorSubTable (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width) { void *extproc; extproc = (void *) wglGetProcAddress("glCopyColorSubTable"); if (extproc == NULL) { _ASSERT(0); return; } glCopyColorSubTable = extproc; glCopyColorSubTable(target, start, x, y, width); } static void APIENTRY InitConvolutionFilter1D (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image) { void *extproc; extproc = (void *) wglGetProcAddress("glConvolutionFilter1D"); if (extproc == NULL) { _ASSERT(0); return; } glConvolutionFilter1D = extproc; glConvolutionFilter1D(target, internalformat, width, format, type, image); } static void APIENTRY InitConvolutionFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image) { void *extproc; extproc = (void *) wglGetProcAddress("glConvolutionFilter2D"); if (extproc == NULL) { _ASSERT(0); return; } glConvolutionFilter2D = extproc; glConvolutionFilter2D(target, internalformat, width, height, format, type, image); } static void APIENTRY InitConvolutionParameterf (GLenum target, GLenum pname, GLfloat params) { void *extproc; extproc = (void *) wglGetProcAddress("glConvolutionParameterf"); if (extproc == NULL) { _ASSERT(0); return; } glConvolutionParameterf = extproc; glConvolutionParameterf(target, pname, params); } static void APIENTRY InitConvolutionParameterfv (GLenum target, GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glConvolutionParameterfv"); if (extproc == NULL) { _ASSERT(0); return; } glConvolutionParameterfv = extproc; glConvolutionParameterfv(target, pname, params); } static void APIENTRY InitConvolutionParameteri (GLenum target, GLenum pname, GLint params) { void *extproc; extproc = (void *) wglGetProcAddress("glConvolutionParameteri"); if (extproc == NULL) { _ASSERT(0); return; } glConvolutionParameteri = extproc; glConvolutionParameteri(target, pname, params); } static void APIENTRY InitConvolutionParameteriv (GLenum target, GLenum pname, const GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glConvolutionParameteriv"); if (extproc == NULL) { _ASSERT(0); return; } glConvolutionParameteriv = extproc; glConvolutionParameteriv(target, pname, params); } static void APIENTRY InitCopyConvolutionFilter1D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) { void *extproc; extproc = (void *) wglGetProcAddress("glCopyConvolutionFilter1D"); if (extproc == NULL) { _ASSERT(0); return; } glCopyConvolutionFilter1D = extproc; glCopyConvolutionFilter1D(target, internalformat, x, y, width); } static void APIENTRY InitCopyConvolutionFilter2D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height) { void *extproc; extproc = (void *) wglGetProcAddress("glCopyConvolutionFilter2D"); if (extproc == NULL) { _ASSERT(0); return; } glCopyConvolutionFilter2D = extproc; glCopyConvolutionFilter2D(target, internalformat, x, y, width, height); } static void APIENTRY InitGetConvolutionFilter (GLenum target, GLenum format, GLenum type, GLvoid *image) { void *extproc; extproc = (void *) wglGetProcAddress("glGetConvolutionFilter"); if (extproc == NULL) { _ASSERT(0); return; } glGetConvolutionFilter = extproc; glGetConvolutionFilter(target, format, type, image); } static void APIENTRY InitGetConvolutionParameterfv (GLenum target, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetConvolutionParameterfv"); if (extproc == NULL) { _ASSERT(0); return; } glGetConvolutionParameterfv = extproc; glGetConvolutionParameterfv(target, pname, params); } static void APIENTRY InitGetConvolutionParameteriv (GLenum target, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetConvolutionParameteriv"); if (extproc == NULL) { _ASSERT(0); return; } glGetConvolutionParameteriv = extproc; glGetConvolutionParameteriv(target, pname, params); } static void APIENTRY InitGetSeparableFilter (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span) { void *extproc; extproc = (void *) wglGetProcAddress("glGetSeparableFilter"); if (extproc == NULL) { _ASSERT(0); return; } glGetSeparableFilter = extproc; glGetSeparableFilter(target, format, type, row, column, span); } static void APIENTRY InitSeparableFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column) { void *extproc; extproc = (void *) wglGetProcAddress("glSeparableFilter2D"); if (extproc == NULL) { _ASSERT(0); return; } glSeparableFilter2D = extproc; glSeparableFilter2D(target, internalformat, width, height, format, type, row, column); } static void APIENTRY InitGetHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values) { void *extproc; extproc = (void *) wglGetProcAddress("glGetHistogram"); if (extproc == NULL) { _ASSERT(0); return; } glGetHistogram = extproc; glGetHistogram(target, reset, format, type, values); } static void APIENTRY InitGetHistogramParameterfv (GLenum target, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetHistogramParameterfv"); if (extproc == NULL) { _ASSERT(0); return; } glGetHistogramParameterfv = extproc; glGetHistogramParameterfv(target, pname, params); } static void APIENTRY InitGetHistogramParameteriv (GLenum target, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetHistogramParameteriv"); if (extproc == NULL) { _ASSERT(0); return; } glGetHistogramParameteriv = extproc; glGetHistogramParameteriv(target, pname, params); } static void APIENTRY InitGetMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values) { void *extproc; extproc = (void *) wglGetProcAddress("glGetMinmax"); if (extproc == NULL) { _ASSERT(0); return; } glGetMinmax = extproc; glGetMinmax(target, reset, format, type, values); } static void APIENTRY InitGetMinmaxParameterfv (GLenum target, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetMinmaxParameterfv"); if (extproc == NULL) { _ASSERT(0); return; } glGetMinmaxParameterfv = extproc; glGetMinmaxParameterfv(target, pname, params); } static void APIENTRY InitGetMinmaxParameteriv (GLenum target, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetMinmaxParameteriv"); if (extproc == NULL) { _ASSERT(0); return; } glGetMinmaxParameteriv = extproc; glGetMinmaxParameteriv(target, pname, params); } static void APIENTRY InitHistogram (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink) { void *extproc; extproc = (void *) wglGetProcAddress("glHistogram"); if (extproc == NULL) { _ASSERT(0); return; } glHistogram = extproc; glHistogram(target, width, internalformat, sink); } static void APIENTRY InitMinmax (GLenum target, GLenum internalformat, GLboolean sink) { void *extproc; extproc = (void *) wglGetProcAddress("glMinmax"); if (extproc == NULL) { _ASSERT(0); return; } glMinmax = extproc; glMinmax(target, internalformat, sink); } static void APIENTRY InitResetHistogram (GLenum target) { void *extproc; extproc = (void *) wglGetProcAddress("glResetHistogram"); if (extproc == NULL) { _ASSERT(0); return; } glResetHistogram = extproc; glResetHistogram(target); } static void APIENTRY InitResetMinmax (GLenum target) { void *extproc; extproc = (void *) wglGetProcAddress("glResetMinmax"); if (extproc == NULL) { _ASSERT(0); return; } glResetMinmax = extproc; glResetMinmax(target); } static void APIENTRY InitTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { void *extproc; extproc = (void *) wglGetProcAddress("glTexImage3D"); if (extproc == NULL) { _ASSERT(0); return; } glTexImage3D = extproc; glTexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels); } static void APIENTRY InitTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) { void *extproc; extproc = (void *) wglGetProcAddress("glTexSubImage3D"); if (extproc == NULL) { _ASSERT(0); return; } glTexSubImage3D = extproc; glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); } static void APIENTRY InitCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) { void *extproc; extproc = (void *) wglGetProcAddress("glCopyTexSubImage3D"); if (extproc == NULL) { _ASSERT(0); return; } glCopyTexSubImage3D = extproc; glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height); } static void APIENTRY InitActiveTexture (GLenum texture) { void *extproc; extproc = (void *) wglGetProcAddress("glActiveTexture"); if (extproc == NULL) { _ASSERT(0); return; } glActiveTexture = extproc; glActiveTexture(texture); } static void APIENTRY InitClientActiveTexture (GLenum texture) { void *extproc; extproc = (void *) wglGetProcAddress("glClientActiveTexture"); if (extproc == NULL) { _ASSERT(0); return; } glClientActiveTexture = extproc; glClientActiveTexture(texture); } static void APIENTRY InitMultiTexCoord1d (GLenum target, GLdouble s) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1d"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1d = extproc; glMultiTexCoord1d(target, s); } static void APIENTRY InitMultiTexCoord1dv (GLenum target, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1dv"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1dv = extproc; glMultiTexCoord1dv(target, v); } static void APIENTRY InitMultiTexCoord1f (GLenum target, GLfloat s) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1f"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1f = extproc; glMultiTexCoord1f(target, s); } static void APIENTRY InitMultiTexCoord1fv (GLenum target, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1fv"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1fv = extproc; glMultiTexCoord1fv(target, v); } static void APIENTRY InitMultiTexCoord1i (GLenum target, GLint s) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1i"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1i = extproc; glMultiTexCoord1i(target, s); } static void APIENTRY InitMultiTexCoord1iv (GLenum target, const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1iv"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1iv = extproc; glMultiTexCoord1iv(target, v); } static void APIENTRY InitMultiTexCoord1s (GLenum target, GLshort s) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1s"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1s = extproc; glMultiTexCoord1s(target, s); } static void APIENTRY InitMultiTexCoord1sv (GLenum target, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1sv"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1sv = extproc; glMultiTexCoord1sv(target, v); } static void APIENTRY InitMultiTexCoord2d (GLenum target, GLdouble s, GLdouble t) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2d"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2d = extproc; glMultiTexCoord2d(target, s, t); } static void APIENTRY InitMultiTexCoord2dv (GLenum target, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2dv"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2dv = extproc; glMultiTexCoord2dv(target, v); } static void APIENTRY InitMultiTexCoord2f (GLenum target, GLfloat s, GLfloat t) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2f"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2f = extproc; glMultiTexCoord2f(target, s, t); } static void APIENTRY InitMultiTexCoord2fv (GLenum target, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2fv"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2fv = extproc; glMultiTexCoord2fv(target, v); } static void APIENTRY InitMultiTexCoord2i (GLenum target, GLint s, GLint t) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2i"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2i = extproc; glMultiTexCoord2i(target, s, t); } static void APIENTRY InitMultiTexCoord2iv (GLenum target, const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2iv"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2iv = extproc; glMultiTexCoord2iv(target, v); } static void APIENTRY InitMultiTexCoord2s (GLenum target, GLshort s, GLshort t) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2s"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2s = extproc; glMultiTexCoord2s(target, s, t); } static void APIENTRY InitMultiTexCoord2sv (GLenum target, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2sv"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2sv = extproc; glMultiTexCoord2sv(target, v); } static void APIENTRY InitMultiTexCoord3d (GLenum target, GLdouble s, GLdouble t, GLdouble r) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3d"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3d = extproc; glMultiTexCoord3d(target, s, t, r); } static void APIENTRY InitMultiTexCoord3dv (GLenum target, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3dv"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3dv = extproc; glMultiTexCoord3dv(target, v); } static void APIENTRY InitMultiTexCoord3f (GLenum target, GLfloat s, GLfloat t, GLfloat r) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3f"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3f = extproc; glMultiTexCoord3f(target, s, t, r); } static void APIENTRY InitMultiTexCoord3fv (GLenum target, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3fv"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3fv = extproc; glMultiTexCoord3fv(target, v); } static void APIENTRY InitMultiTexCoord3i (GLenum target, GLint s, GLint t, GLint r) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3i"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3i = extproc; glMultiTexCoord3i(target, s, t, r); } static void APIENTRY InitMultiTexCoord3iv (GLenum target, const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3iv"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3iv = extproc; glMultiTexCoord3iv(target, v); } static void APIENTRY InitMultiTexCoord3s (GLenum target, GLshort s, GLshort t, GLshort r) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3s"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3s = extproc; glMultiTexCoord3s(target, s, t, r); } static void APIENTRY InitMultiTexCoord3sv (GLenum target, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3sv"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3sv = extproc; glMultiTexCoord3sv(target, v); } static void APIENTRY InitMultiTexCoord4d (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4d"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4d = extproc; glMultiTexCoord4d(target, s, t, r, q); } static void APIENTRY InitMultiTexCoord4dv (GLenum target, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4dv"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4dv = extproc; glMultiTexCoord4dv(target, v); } static void APIENTRY InitMultiTexCoord4f (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4f"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4f = extproc; glMultiTexCoord4f(target, s, t, r, q); } static void APIENTRY InitMultiTexCoord4fv (GLenum target, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4fv"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4fv = extproc; glMultiTexCoord4fv(target, v); } static void APIENTRY InitMultiTexCoord4i (GLenum target, GLint s, GLint t, GLint r, GLint q) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4i"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4i = extproc; glMultiTexCoord4i(target, s, t, r, q); } static void APIENTRY InitMultiTexCoord4iv (GLenum target, const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4iv"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4iv = extproc; glMultiTexCoord4iv(target, v); } static void APIENTRY InitMultiTexCoord4s (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4s"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4s = extproc; glMultiTexCoord4s(target, s, t, r, q); } static void APIENTRY InitMultiTexCoord4sv (GLenum target, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4sv"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4sv = extproc; glMultiTexCoord4sv(target, v); } static void APIENTRY InitLoadTransposeMatrixf (const GLfloat *m) { void *extproc; extproc = (void *) wglGetProcAddress("glLoadTransposeMatrixf"); if (extproc == NULL) { _ASSERT(0); return; } glLoadTransposeMatrixf = extproc; glLoadTransposeMatrixf(m); } static void APIENTRY InitLoadTransposeMatrixd (const GLdouble *m) { void *extproc; extproc = (void *) wglGetProcAddress("glLoadTransposeMatrixd"); if (extproc == NULL) { _ASSERT(0); return; } glLoadTransposeMatrixd = extproc; glLoadTransposeMatrixd(m); } static void APIENTRY InitMultTransposeMatrixf (const GLfloat *m) { void *extproc; extproc = (void *) wglGetProcAddress("glMultTransposeMatrixf"); if (extproc == NULL) { _ASSERT(0); return; } glMultTransposeMatrixf = extproc; glMultTransposeMatrixf(m); } static void APIENTRY InitMultTransposeMatrixd (const GLdouble *m) { void *extproc; extproc = (void *) wglGetProcAddress("glMultTransposeMatrixd"); if (extproc == NULL) { _ASSERT(0); return; } glMultTransposeMatrixd = extproc; glMultTransposeMatrixd(m); } static void APIENTRY InitSampleCoverage (GLclampf value, GLboolean invert) { void *extproc; extproc = (void *) wglGetProcAddress("glSampleCoverage"); if (extproc == NULL) { _ASSERT(0); return; } glSampleCoverage = extproc; glSampleCoverage(value, invert); } static void APIENTRY InitCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glCompressedTexImage3D"); if (extproc == NULL) { _ASSERT(0); return; } glCompressedTexImage3D = extproc; glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data); } static void APIENTRY InitCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glCompressedTexImage2D"); if (extproc == NULL) { _ASSERT(0); return; } glCompressedTexImage2D = extproc; glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data); } static void APIENTRY InitCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glCompressedTexImage1D"); if (extproc == NULL) { _ASSERT(0); return; } glCompressedTexImage1D = extproc; glCompressedTexImage1D(target, level, internalformat, width, border, imageSize, data); } static void APIENTRY InitCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glCompressedTexSubImage3D"); if (extproc == NULL) { _ASSERT(0); return; } glCompressedTexSubImage3D = extproc; glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); } static void APIENTRY InitCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glCompressedTexSubImage2D"); if (extproc == NULL) { _ASSERT(0); return; } glCompressedTexSubImage2D = extproc; glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data); } static void APIENTRY InitCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glCompressedTexSubImage1D"); if (extproc == NULL) { _ASSERT(0); return; } glCompressedTexSubImage1D = extproc; glCompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, data); } static void APIENTRY InitGetCompressedTexImage (GLenum target, GLint level, GLvoid *img) { void *extproc; extproc = (void *) wglGetProcAddress("glGetCompressedTexImage"); if (extproc == NULL) { _ASSERT(0); return; } glGetCompressedTexImage = extproc; glGetCompressedTexImage(target, level, img); } static void APIENTRY InitBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) { void *extproc; extproc = (void *) wglGetProcAddress("glBlendFuncSeparate"); if (extproc == NULL) { _ASSERT(0); return; } glBlendFuncSeparate = extproc; glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); } static void APIENTRY InitFogCoordf (GLfloat coord) { void *extproc; extproc = (void *) wglGetProcAddress("glFogCoordf"); if (extproc == NULL) { _ASSERT(0); return; } glFogCoordf = extproc; glFogCoordf(coord); } static void APIENTRY InitFogCoordfv (const GLfloat *coord) { void *extproc; extproc = (void *) wglGetProcAddress("glFogCoordfv"); if (extproc == NULL) { _ASSERT(0); return; } glFogCoordfv = extproc; glFogCoordfv(coord); } static void APIENTRY InitFogCoordd (GLdouble coord) { void *extproc; extproc = (void *) wglGetProcAddress("glFogCoordd"); if (extproc == NULL) { _ASSERT(0); return; } glFogCoordd = extproc; glFogCoordd(coord); } static void APIENTRY InitFogCoorddv (const GLdouble *coord) { void *extproc; extproc = (void *) wglGetProcAddress("glFogCoorddv"); if (extproc == NULL) { _ASSERT(0); return; } glFogCoorddv = extproc; glFogCoorddv(coord); } static void APIENTRY InitFogCoordPointer (GLenum type, GLsizei stride, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glFogCoordPointer"); if (extproc == NULL) { _ASSERT(0); return; } glFogCoordPointer = extproc; glFogCoordPointer(type, stride, pointer); } static void APIENTRY InitMultiDrawArrays (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiDrawArrays"); if (extproc == NULL) { _ASSERT(0); return; } glMultiDrawArrays = extproc; glMultiDrawArrays(mode, first, count, primcount); } static void APIENTRY InitMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiDrawElements"); if (extproc == NULL) { _ASSERT(0); return; } glMultiDrawElements = extproc; glMultiDrawElements(mode, count, type, indices, primcount); } static void APIENTRY InitPointParameterf (GLenum pname, GLfloat param) { void *extproc; extproc = (void *) wglGetProcAddress("glPointParameterf"); if (extproc == NULL) { _ASSERT(0); return; } glPointParameterf = extproc; glPointParameterf(pname, param); } static void APIENTRY InitPointParameterfv (GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glPointParameterfv"); if (extproc == NULL) { _ASSERT(0); return; } glPointParameterfv = extproc; glPointParameterfv(pname, params); } static void APIENTRY InitPointParameteri (GLenum pname, GLint param) { void *extproc; extproc = (void *) wglGetProcAddress("glPointParameteri"); if (extproc == NULL) { _ASSERT(0); return; } glPointParameteri = extproc; glPointParameteri(pname, param); } static void APIENTRY InitPointParameteriv (GLenum pname, const GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glPointParameteriv"); if (extproc == NULL) { _ASSERT(0); return; } glPointParameteriv = extproc; glPointParameteriv(pname, params); } static void APIENTRY InitSecondaryColor3b (GLbyte red, GLbyte green, GLbyte blue) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3b"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3b = extproc; glSecondaryColor3b(red, green, blue); } static void APIENTRY InitSecondaryColor3bv (const GLbyte *v) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3bv"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3bv = extproc; glSecondaryColor3bv(v); } static void APIENTRY InitSecondaryColor3d (GLdouble red, GLdouble green, GLdouble blue) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3d"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3d = extproc; glSecondaryColor3d(red, green, blue); } static void APIENTRY InitSecondaryColor3dv (const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3dv"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3dv = extproc; glSecondaryColor3dv(v); } static void APIENTRY InitSecondaryColor3f (GLfloat red, GLfloat green, GLfloat blue) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3f"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3f = extproc; glSecondaryColor3f(red, green, blue); } static void APIENTRY InitSecondaryColor3fv (const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3fv"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3fv = extproc; glSecondaryColor3fv(v); } static void APIENTRY InitSecondaryColor3i (GLint red, GLint green, GLint blue) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3i"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3i = extproc; glSecondaryColor3i(red, green, blue); } static void APIENTRY InitSecondaryColor3iv (const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3iv"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3iv = extproc; glSecondaryColor3iv(v); } static void APIENTRY InitSecondaryColor3s (GLshort red, GLshort green, GLshort blue) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3s"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3s = extproc; glSecondaryColor3s(red, green, blue); } static void APIENTRY InitSecondaryColor3sv (const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3sv"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3sv = extproc; glSecondaryColor3sv(v); } static void APIENTRY InitSecondaryColor3ub (GLubyte red, GLubyte green, GLubyte blue) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3ub"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3ub = extproc; glSecondaryColor3ub(red, green, blue); } static void APIENTRY InitSecondaryColor3ubv (const GLubyte *v) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3ubv"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3ubv = extproc; glSecondaryColor3ubv(v); } static void APIENTRY InitSecondaryColor3ui (GLuint red, GLuint green, GLuint blue) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3ui"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3ui = extproc; glSecondaryColor3ui(red, green, blue); } static void APIENTRY InitSecondaryColor3uiv (const GLuint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3uiv"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3uiv = extproc; glSecondaryColor3uiv(v); } static void APIENTRY InitSecondaryColor3us (GLushort red, GLushort green, GLushort blue) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3us"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3us = extproc; glSecondaryColor3us(red, green, blue); } static void APIENTRY InitSecondaryColor3usv (const GLushort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3usv"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3usv = extproc; glSecondaryColor3usv(v); } static void APIENTRY InitSecondaryColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColorPointer"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColorPointer = extproc; glSecondaryColorPointer(size, type, stride, pointer); } static void APIENTRY InitWindowPos2d (GLdouble x, GLdouble y) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2d"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2d = extproc; glWindowPos2d(x, y); } static void APIENTRY InitWindowPos2dv (const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2dv"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2dv = extproc; glWindowPos2dv(v); } static void APIENTRY InitWindowPos2f (GLfloat x, GLfloat y) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2f"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2f = extproc; glWindowPos2f(x, y); } static void APIENTRY InitWindowPos2fv (const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2fv"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2fv = extproc; glWindowPos2fv(v); } static void APIENTRY InitWindowPos2i (GLint x, GLint y) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2i"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2i = extproc; glWindowPos2i(x, y); } static void APIENTRY InitWindowPos2iv (const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2iv"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2iv = extproc; glWindowPos2iv(v); } static void APIENTRY InitWindowPos2s (GLshort x, GLshort y) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2s"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2s = extproc; glWindowPos2s(x, y); } static void APIENTRY InitWindowPos2sv (const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2sv"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2sv = extproc; glWindowPos2sv(v); } static void APIENTRY InitWindowPos3d (GLdouble x, GLdouble y, GLdouble z) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3d"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3d = extproc; glWindowPos3d(x, y, z); } static void APIENTRY InitWindowPos3dv (const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3dv"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3dv = extproc; glWindowPos3dv(v); } static void APIENTRY InitWindowPos3f (GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3f"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3f = extproc; glWindowPos3f(x, y, z); } static void APIENTRY InitWindowPos3fv (const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3fv"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3fv = extproc; glWindowPos3fv(v); } static void APIENTRY InitWindowPos3i (GLint x, GLint y, GLint z) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3i"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3i = extproc; glWindowPos3i(x, y, z); } static void APIENTRY InitWindowPos3iv (const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3iv"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3iv = extproc; glWindowPos3iv(v); } static void APIENTRY InitWindowPos3s (GLshort x, GLshort y, GLshort z) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3s"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3s = extproc; glWindowPos3s(x, y, z); } static void APIENTRY InitWindowPos3sv (const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3sv"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3sv = extproc; glWindowPos3sv(v); } static void APIENTRY InitGenQueries (GLsizei n, GLuint *ids) { void *extproc; extproc = (void *) wglGetProcAddress("glGenQueries"); if (extproc == NULL) { _ASSERT(0); return; } glGenQueries = extproc; glGenQueries(n, ids); } static void APIENTRY InitDeleteQueries (GLsizei n, const GLuint *ids) { void *extproc; extproc = (void *) wglGetProcAddress("glDeleteQueries"); if (extproc == NULL) { _ASSERT(0); return; } glDeleteQueries = extproc; glDeleteQueries(n, ids); } static GLboolean APIENTRY InitIsQuery (GLuint id) { void *extproc; extproc = (void *) wglGetProcAddress("glIsQuery"); if (extproc == NULL) { _ASSERT(0); return 0; } glIsQuery = extproc; return glIsQuery(id); } static void APIENTRY InitBeginQuery (GLenum target, GLuint id) { void *extproc; extproc = (void *) wglGetProcAddress("glBeginQuery"); if (extproc == NULL) { _ASSERT(0); return; } glBeginQuery = extproc; glBeginQuery(target, id); } static void APIENTRY InitEndQuery (GLenum target) { void *extproc; extproc = (void *) wglGetProcAddress("glEndQuery"); if (extproc == NULL) { _ASSERT(0); return; } glEndQuery = extproc; glEndQuery(target); } static void APIENTRY InitGetQueryiv (GLenum target, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetQueryiv"); if (extproc == NULL) { _ASSERT(0); return; } glGetQueryiv = extproc; glGetQueryiv(target, pname, params); } static void APIENTRY InitGetQueryObjectiv (GLuint id, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetQueryObjectiv"); if (extproc == NULL) { _ASSERT(0); return; } glGetQueryObjectiv = extproc; glGetQueryObjectiv(id, pname, params); } static void APIENTRY InitGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetQueryObjectuiv"); if (extproc == NULL) { _ASSERT(0); return; } glGetQueryObjectuiv = extproc; glGetQueryObjectuiv(id, pname, params); } static void APIENTRY InitBindBuffer (GLenum target, GLuint buffer) { void *extproc; extproc = (void *) wglGetProcAddress("glBindBuffer"); if (extproc == NULL) { _ASSERT(0); return; } glBindBuffer = extproc; glBindBuffer(target, buffer); } static void APIENTRY InitDeleteBuffers (GLsizei n, const GLuint *buffers) { void *extproc; extproc = (void *) wglGetProcAddress("glDeleteBuffers"); if (extproc == NULL) { _ASSERT(0); return; } glDeleteBuffers = extproc; glDeleteBuffers(n, buffers); } static void APIENTRY InitGenBuffers (GLsizei n, GLuint *buffers) { void *extproc; extproc = (void *) wglGetProcAddress("glGenBuffers"); if (extproc == NULL) { _ASSERT(0); return; } glGenBuffers = extproc; glGenBuffers(n, buffers); } static GLboolean APIENTRY InitIsBuffer (GLuint buffer) { void *extproc; extproc = (void *) wglGetProcAddress("glIsBuffer"); if (extproc == NULL) { _ASSERT(0); return 0; } glIsBuffer = extproc; return glIsBuffer(buffer); } static void APIENTRY InitBufferData (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) { void *extproc; extproc = (void *) wglGetProcAddress("glBufferData"); if (extproc == NULL) { _ASSERT(0); return; } glBufferData = extproc; glBufferData(target, size, data, usage); } static void APIENTRY InitBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glBufferSubData"); if (extproc == NULL) { _ASSERT(0); return; } glBufferSubData = extproc; glBufferSubData(target, offset, size, data); } static void APIENTRY InitGetBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glGetBufferSubData"); if (extproc == NULL) { _ASSERT(0); return; } glGetBufferSubData = extproc; glGetBufferSubData(target, offset, size, data); } static GLvoid* APIENTRY InitMapBuffer (GLenum target, GLenum access) { void *extproc; extproc = (void *) wglGetProcAddress("glMapBuffer"); if (extproc == NULL) { _ASSERT(0); return 0; } glMapBuffer = extproc; return glMapBuffer(target, access); } static GLboolean APIENTRY InitUnmapBuffer (GLenum target) { void *extproc; extproc = (void *) wglGetProcAddress("glUnmapBuffer"); if (extproc == NULL) { _ASSERT(0); return 0; } glUnmapBuffer = extproc; return glUnmapBuffer(target); } static void APIENTRY InitGetBufferParameteriv (GLenum target, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetBufferParameteriv"); if (extproc == NULL) { _ASSERT(0); return; } glGetBufferParameteriv = extproc; glGetBufferParameteriv(target, pname, params); } static void APIENTRY InitGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetBufferPointerv"); if (extproc == NULL) { _ASSERT(0); return; } glGetBufferPointerv = extproc; glGetBufferPointerv(target, pname, params); } static void APIENTRY InitActiveTextureARB (GLenum texture) { void *extproc; extproc = (void *) wglGetProcAddress("glActiveTextureARB"); if (extproc == NULL) { _ASSERT(0); return; } glActiveTextureARB = extproc; glActiveTextureARB(texture); } static void APIENTRY InitClientActiveTextureARB (GLenum texture) { void *extproc; extproc = (void *) wglGetProcAddress("glClientActiveTextureARB"); if (extproc == NULL) { _ASSERT(0); return; } glClientActiveTextureARB = extproc; glClientActiveTextureARB(texture); } static void APIENTRY InitMultiTexCoord1dARB (GLenum target, GLdouble s) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1dARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1dARB = extproc; glMultiTexCoord1dARB(target, s); } static void APIENTRY InitMultiTexCoord1dvARB (GLenum target, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1dvARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1dvARB = extproc; glMultiTexCoord1dvARB(target, v); } static void APIENTRY InitMultiTexCoord1fARB (GLenum target, GLfloat s) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1fARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1fARB = extproc; glMultiTexCoord1fARB(target, s); } static void APIENTRY InitMultiTexCoord1fvARB (GLenum target, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1fvARB = extproc; glMultiTexCoord1fvARB(target, v); } static void APIENTRY InitMultiTexCoord1iARB (GLenum target, GLint s) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1iARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1iARB = extproc; glMultiTexCoord1iARB(target, s); } static void APIENTRY InitMultiTexCoord1ivARB (GLenum target, const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1ivARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1ivARB = extproc; glMultiTexCoord1ivARB(target, v); } static void APIENTRY InitMultiTexCoord1sARB (GLenum target, GLshort s) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1sARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1sARB = extproc; glMultiTexCoord1sARB(target, s); } static void APIENTRY InitMultiTexCoord1svARB (GLenum target, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1svARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1svARB = extproc; glMultiTexCoord1svARB(target, v); } static void APIENTRY InitMultiTexCoord2dARB (GLenum target, GLdouble s, GLdouble t) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2dARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2dARB = extproc; glMultiTexCoord2dARB(target, s, t); } static void APIENTRY InitMultiTexCoord2dvARB (GLenum target, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2dvARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2dvARB = extproc; glMultiTexCoord2dvARB(target, v); } static void APIENTRY InitMultiTexCoord2fARB (GLenum target, GLfloat s, GLfloat t) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2fARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2fARB = extproc; glMultiTexCoord2fARB(target, s, t); } static void APIENTRY InitMultiTexCoord2fvARB (GLenum target, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2fvARB = extproc; glMultiTexCoord2fvARB(target, v); } static void APIENTRY InitMultiTexCoord2iARB (GLenum target, GLint s, GLint t) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2iARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2iARB = extproc; glMultiTexCoord2iARB(target, s, t); } static void APIENTRY InitMultiTexCoord2ivARB (GLenum target, const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2ivARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2ivARB = extproc; glMultiTexCoord2ivARB(target, v); } static void APIENTRY InitMultiTexCoord2sARB (GLenum target, GLshort s, GLshort t) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2sARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2sARB = extproc; glMultiTexCoord2sARB(target, s, t); } static void APIENTRY InitMultiTexCoord2svARB (GLenum target, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2svARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2svARB = extproc; glMultiTexCoord2svARB(target, v); } static void APIENTRY InitMultiTexCoord3dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3dARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3dARB = extproc; glMultiTexCoord3dARB(target, s, t, r); } static void APIENTRY InitMultiTexCoord3dvARB (GLenum target, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3dvARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3dvARB = extproc; glMultiTexCoord3dvARB(target, v); } static void APIENTRY InitMultiTexCoord3fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3fARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3fARB = extproc; glMultiTexCoord3fARB(target, s, t, r); } static void APIENTRY InitMultiTexCoord3fvARB (GLenum target, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3fvARB = extproc; glMultiTexCoord3fvARB(target, v); } static void APIENTRY InitMultiTexCoord3iARB (GLenum target, GLint s, GLint t, GLint r) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3iARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3iARB = extproc; glMultiTexCoord3iARB(target, s, t, r); } static void APIENTRY InitMultiTexCoord3ivARB (GLenum target, const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3ivARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3ivARB = extproc; glMultiTexCoord3ivARB(target, v); } static void APIENTRY InitMultiTexCoord3sARB (GLenum target, GLshort s, GLshort t, GLshort r) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3sARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3sARB = extproc; glMultiTexCoord3sARB(target, s, t, r); } static void APIENTRY InitMultiTexCoord3svARB (GLenum target, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3svARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3svARB = extproc; glMultiTexCoord3svARB(target, v); } static void APIENTRY InitMultiTexCoord4dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4dARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4dARB = extproc; glMultiTexCoord4dARB(target, s, t, r, q); } static void APIENTRY InitMultiTexCoord4dvARB (GLenum target, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4dvARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4dvARB = extproc; glMultiTexCoord4dvARB(target, v); } static void APIENTRY InitMultiTexCoord4fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4fARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4fARB = extproc; glMultiTexCoord4fARB(target, s, t, r, q); } static void APIENTRY InitMultiTexCoord4fvARB (GLenum target, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4fvARB = extproc; glMultiTexCoord4fvARB(target, v); } static void APIENTRY InitMultiTexCoord4iARB (GLenum target, GLint s, GLint t, GLint r, GLint q) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4iARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4iARB = extproc; glMultiTexCoord4iARB(target, s, t, r, q); } static void APIENTRY InitMultiTexCoord4ivARB (GLenum target, const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4ivARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4ivARB = extproc; glMultiTexCoord4ivARB(target, v); } static void APIENTRY InitMultiTexCoord4sARB (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4sARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4sARB = extproc; glMultiTexCoord4sARB(target, s, t, r, q); } static void APIENTRY InitMultiTexCoord4svARB (GLenum target, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4svARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4svARB = extproc; glMultiTexCoord4svARB(target, v); } static void APIENTRY InitLoadTransposeMatrixfARB (const GLfloat *m) { void *extproc; extproc = (void *) wglGetProcAddress("glLoadTransposeMatrixfARB"); if (extproc == NULL) { _ASSERT(0); return; } glLoadTransposeMatrixfARB = extproc; glLoadTransposeMatrixfARB(m); } static void APIENTRY InitLoadTransposeMatrixdARB (const GLdouble *m) { void *extproc; extproc = (void *) wglGetProcAddress("glLoadTransposeMatrixdARB"); if (extproc == NULL) { _ASSERT(0); return; } glLoadTransposeMatrixdARB = extproc; glLoadTransposeMatrixdARB(m); } static void APIENTRY InitMultTransposeMatrixfARB (const GLfloat *m) { void *extproc; extproc = (void *) wglGetProcAddress("glMultTransposeMatrixfARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultTransposeMatrixfARB = extproc; glMultTransposeMatrixfARB(m); } static void APIENTRY InitMultTransposeMatrixdARB (const GLdouble *m) { void *extproc; extproc = (void *) wglGetProcAddress("glMultTransposeMatrixdARB"); if (extproc == NULL) { _ASSERT(0); return; } glMultTransposeMatrixdARB = extproc; glMultTransposeMatrixdARB(m); } static void APIENTRY InitSampleCoverageARB (GLclampf value, GLboolean invert) { void *extproc; extproc = (void *) wglGetProcAddress("glSampleCoverageARB"); if (extproc == NULL) { _ASSERT(0); return; } glSampleCoverageARB = extproc; glSampleCoverageARB(value, invert); } static void APIENTRY InitCompressedTexImage3DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glCompressedTexImage3DARB"); if (extproc == NULL) { _ASSERT(0); return; } glCompressedTexImage3DARB = extproc; glCompressedTexImage3DARB(target, level, internalformat, width, height, depth, border, imageSize, data); } static void APIENTRY InitCompressedTexImage2DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glCompressedTexImage2DARB"); if (extproc == NULL) { _ASSERT(0); return; } glCompressedTexImage2DARB = extproc; glCompressedTexImage2DARB(target, level, internalformat, width, height, border, imageSize, data); } static void APIENTRY InitCompressedTexImage1DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glCompressedTexImage1DARB"); if (extproc == NULL) { _ASSERT(0); return; } glCompressedTexImage1DARB = extproc; glCompressedTexImage1DARB(target, level, internalformat, width, border, imageSize, data); } static void APIENTRY InitCompressedTexSubImage3DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glCompressedTexSubImage3DARB"); if (extproc == NULL) { _ASSERT(0); return; } glCompressedTexSubImage3DARB = extproc; glCompressedTexSubImage3DARB(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); } static void APIENTRY InitCompressedTexSubImage2DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glCompressedTexSubImage2DARB"); if (extproc == NULL) { _ASSERT(0); return; } glCompressedTexSubImage2DARB = extproc; glCompressedTexSubImage2DARB(target, level, xoffset, yoffset, width, height, format, imageSize, data); } static void APIENTRY InitCompressedTexSubImage1DARB (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glCompressedTexSubImage1DARB"); if (extproc == NULL) { _ASSERT(0); return; } glCompressedTexSubImage1DARB = extproc; glCompressedTexSubImage1DARB(target, level, xoffset, width, format, imageSize, data); } static void APIENTRY InitGetCompressedTexImageARB (GLenum target, GLint level, GLvoid *img) { void *extproc; extproc = (void *) wglGetProcAddress("glGetCompressedTexImageARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetCompressedTexImageARB = extproc; glGetCompressedTexImageARB(target, level, img); } static void APIENTRY InitPointParameterfARB (GLenum pname, GLfloat param) { void *extproc; extproc = (void *) wglGetProcAddress("glPointParameterfARB"); if (extproc == NULL) { _ASSERT(0); return; } glPointParameterfARB = extproc; glPointParameterfARB(pname, param); } static void APIENTRY InitPointParameterfvARB (GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glPointParameterfvARB"); if (extproc == NULL) { _ASSERT(0); return; } glPointParameterfvARB = extproc; glPointParameterfvARB(pname, params); } static void APIENTRY InitWeightbvARB (GLint size, const GLbyte *weights) { void *extproc; extproc = (void *) wglGetProcAddress("glWeightbvARB"); if (extproc == NULL) { _ASSERT(0); return; } glWeightbvARB = extproc; glWeightbvARB(size, weights); } static void APIENTRY InitWeightsvARB (GLint size, const GLshort *weights) { void *extproc; extproc = (void *) wglGetProcAddress("glWeightsvARB"); if (extproc == NULL) { _ASSERT(0); return; } glWeightsvARB = extproc; glWeightsvARB(size, weights); } static void APIENTRY InitWeightivARB (GLint size, const GLint *weights) { void *extproc; extproc = (void *) wglGetProcAddress("glWeightivARB"); if (extproc == NULL) { _ASSERT(0); return; } glWeightivARB = extproc; glWeightivARB(size, weights); } static void APIENTRY InitWeightfvARB (GLint size, const GLfloat *weights) { void *extproc; extproc = (void *) wglGetProcAddress("glWeightfvARB"); if (extproc == NULL) { _ASSERT(0); return; } glWeightfvARB = extproc; glWeightfvARB(size, weights); } static void APIENTRY InitWeightdvARB (GLint size, const GLdouble *weights) { void *extproc; extproc = (void *) wglGetProcAddress("glWeightdvARB"); if (extproc == NULL) { _ASSERT(0); return; } glWeightdvARB = extproc; glWeightdvARB(size, weights); } static void APIENTRY InitWeightubvARB (GLint size, const GLubyte *weights) { void *extproc; extproc = (void *) wglGetProcAddress("glWeightubvARB"); if (extproc == NULL) { _ASSERT(0); return; } glWeightubvARB = extproc; glWeightubvARB(size, weights); } static void APIENTRY InitWeightusvARB (GLint size, const GLushort *weights) { void *extproc; extproc = (void *) wglGetProcAddress("glWeightusvARB"); if (extproc == NULL) { _ASSERT(0); return; } glWeightusvARB = extproc; glWeightusvARB(size, weights); } static void APIENTRY InitWeightuivARB (GLint size, const GLuint *weights) { void *extproc; extproc = (void *) wglGetProcAddress("glWeightuivARB"); if (extproc == NULL) { _ASSERT(0); return; } glWeightuivARB = extproc; glWeightuivARB(size, weights); } static void APIENTRY InitWeightPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glWeightPointerARB"); if (extproc == NULL) { _ASSERT(0); return; } glWeightPointerARB = extproc; glWeightPointerARB(size, type, stride, pointer); } static void APIENTRY InitVertexBlendARB (GLint count) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexBlendARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexBlendARB = extproc; glVertexBlendARB(count); } static void APIENTRY InitCurrentPaletteMatrixARB (GLint index) { void *extproc; extproc = (void *) wglGetProcAddress("glCurrentPaletteMatrixARB"); if (extproc == NULL) { _ASSERT(0); return; } glCurrentPaletteMatrixARB = extproc; glCurrentPaletteMatrixARB(index); } static void APIENTRY InitMatrixIndexubvARB (GLint size, const GLubyte *indices) { void *extproc; extproc = (void *) wglGetProcAddress("glMatrixIndexubvARB"); if (extproc == NULL) { _ASSERT(0); return; } glMatrixIndexubvARB = extproc; glMatrixIndexubvARB(size, indices); } static void APIENTRY InitMatrixIndexusvARB (GLint size, const GLushort *indices) { void *extproc; extproc = (void *) wglGetProcAddress("glMatrixIndexusvARB"); if (extproc == NULL) { _ASSERT(0); return; } glMatrixIndexusvARB = extproc; glMatrixIndexusvARB(size, indices); } static void APIENTRY InitMatrixIndexuivARB (GLint size, const GLuint *indices) { void *extproc; extproc = (void *) wglGetProcAddress("glMatrixIndexuivARB"); if (extproc == NULL) { _ASSERT(0); return; } glMatrixIndexuivARB = extproc; glMatrixIndexuivARB(size, indices); } static void APIENTRY InitMatrixIndexPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glMatrixIndexPointerARB"); if (extproc == NULL) { _ASSERT(0); return; } glMatrixIndexPointerARB = extproc; glMatrixIndexPointerARB(size, type, stride, pointer); } static void APIENTRY InitWindowPos2dARB (GLdouble x, GLdouble y) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2dARB"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2dARB = extproc; glWindowPos2dARB(x, y); } static void APIENTRY InitWindowPos2dvARB (const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2dvARB"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2dvARB = extproc; glWindowPos2dvARB(v); } static void APIENTRY InitWindowPos2fARB (GLfloat x, GLfloat y) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2fARB"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2fARB = extproc; glWindowPos2fARB(x, y); } static void APIENTRY InitWindowPos2fvARB (const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2fvARB = extproc; glWindowPos2fvARB(v); } static void APIENTRY InitWindowPos2iARB (GLint x, GLint y) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2iARB"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2iARB = extproc; glWindowPos2iARB(x, y); } static void APIENTRY InitWindowPos2ivARB (const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2ivARB"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2ivARB = extproc; glWindowPos2ivARB(v); } static void APIENTRY InitWindowPos2sARB (GLshort x, GLshort y) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2sARB"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2sARB = extproc; glWindowPos2sARB(x, y); } static void APIENTRY InitWindowPos2svARB (const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2svARB"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2svARB = extproc; glWindowPos2svARB(v); } static void APIENTRY InitWindowPos3dARB (GLdouble x, GLdouble y, GLdouble z) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3dARB"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3dARB = extproc; glWindowPos3dARB(x, y, z); } static void APIENTRY InitWindowPos3dvARB (const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3dvARB"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3dvARB = extproc; glWindowPos3dvARB(v); } static void APIENTRY InitWindowPos3fARB (GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3fARB"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3fARB = extproc; glWindowPos3fARB(x, y, z); } static void APIENTRY InitWindowPos3fvARB (const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3fvARB = extproc; glWindowPos3fvARB(v); } static void APIENTRY InitWindowPos3iARB (GLint x, GLint y, GLint z) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3iARB"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3iARB = extproc; glWindowPos3iARB(x, y, z); } static void APIENTRY InitWindowPos3ivARB (const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3ivARB"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3ivARB = extproc; glWindowPos3ivARB(v); } static void APIENTRY InitWindowPos3sARB (GLshort x, GLshort y, GLshort z) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3sARB"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3sARB = extproc; glWindowPos3sARB(x, y, z); } static void APIENTRY InitWindowPos3svARB (const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3svARB"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3svARB = extproc; glWindowPos3svARB(v); } static void APIENTRY InitVertexAttrib1dARB (GLuint index, GLdouble x) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib1dARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib1dARB = extproc; glVertexAttrib1dARB(index, x); } static void APIENTRY InitVertexAttrib1dvARB (GLuint index, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib1dvARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib1dvARB = extproc; glVertexAttrib1dvARB(index, v); } static void APIENTRY InitVertexAttrib1fARB (GLuint index, GLfloat x) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib1fARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib1fARB = extproc; glVertexAttrib1fARB(index, x); } static void APIENTRY InitVertexAttrib1fvARB (GLuint index, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib1fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib1fvARB = extproc; glVertexAttrib1fvARB(index, v); } static void APIENTRY InitVertexAttrib1sARB (GLuint index, GLshort x) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib1sARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib1sARB = extproc; glVertexAttrib1sARB(index, x); } static void APIENTRY InitVertexAttrib1svARB (GLuint index, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib1svARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib1svARB = extproc; glVertexAttrib1svARB(index, v); } static void APIENTRY InitVertexAttrib2dARB (GLuint index, GLdouble x, GLdouble y) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib2dARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib2dARB = extproc; glVertexAttrib2dARB(index, x, y); } static void APIENTRY InitVertexAttrib2dvARB (GLuint index, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib2dvARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib2dvARB = extproc; glVertexAttrib2dvARB(index, v); } static void APIENTRY InitVertexAttrib2fARB (GLuint index, GLfloat x, GLfloat y) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib2fARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib2fARB = extproc; glVertexAttrib2fARB(index, x, y); } static void APIENTRY InitVertexAttrib2fvARB (GLuint index, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib2fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib2fvARB = extproc; glVertexAttrib2fvARB(index, v); } static void APIENTRY InitVertexAttrib2sARB (GLuint index, GLshort x, GLshort y) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib2sARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib2sARB = extproc; glVertexAttrib2sARB(index, x, y); } static void APIENTRY InitVertexAttrib2svARB (GLuint index, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib2svARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib2svARB = extproc; glVertexAttrib2svARB(index, v); } static void APIENTRY InitVertexAttrib3dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib3dARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib3dARB = extproc; glVertexAttrib3dARB(index, x, y, z); } static void APIENTRY InitVertexAttrib3dvARB (GLuint index, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib3dvARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib3dvARB = extproc; glVertexAttrib3dvARB(index, v); } static void APIENTRY InitVertexAttrib3fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib3fARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib3fARB = extproc; glVertexAttrib3fARB(index, x, y, z); } static void APIENTRY InitVertexAttrib3fvARB (GLuint index, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib3fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib3fvARB = extproc; glVertexAttrib3fvARB(index, v); } static void APIENTRY InitVertexAttrib3sARB (GLuint index, GLshort x, GLshort y, GLshort z) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib3sARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib3sARB = extproc; glVertexAttrib3sARB(index, x, y, z); } static void APIENTRY InitVertexAttrib3svARB (GLuint index, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib3svARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib3svARB = extproc; glVertexAttrib3svARB(index, v); } static void APIENTRY InitVertexAttrib4NbvARB (GLuint index, const GLbyte *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4NbvARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4NbvARB = extproc; glVertexAttrib4NbvARB(index, v); } static void APIENTRY InitVertexAttrib4NivARB (GLuint index, const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4NivARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4NivARB = extproc; glVertexAttrib4NivARB(index, v); } static void APIENTRY InitVertexAttrib4NsvARB (GLuint index, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4NsvARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4NsvARB = extproc; glVertexAttrib4NsvARB(index, v); } static void APIENTRY InitVertexAttrib4NubARB (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4NubARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4NubARB = extproc; glVertexAttrib4NubARB(index, x, y, z, w); } static void APIENTRY InitVertexAttrib4NubvARB (GLuint index, const GLubyte *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4NubvARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4NubvARB = extproc; glVertexAttrib4NubvARB(index, v); } static void APIENTRY InitVertexAttrib4NuivARB (GLuint index, const GLuint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4NuivARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4NuivARB = extproc; glVertexAttrib4NuivARB(index, v); } static void APIENTRY InitVertexAttrib4NusvARB (GLuint index, const GLushort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4NusvARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4NusvARB = extproc; glVertexAttrib4NusvARB(index, v); } static void APIENTRY InitVertexAttrib4bvARB (GLuint index, const GLbyte *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4bvARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4bvARB = extproc; glVertexAttrib4bvARB(index, v); } static void APIENTRY InitVertexAttrib4dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4dARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4dARB = extproc; glVertexAttrib4dARB(index, x, y, z, w); } static void APIENTRY InitVertexAttrib4dvARB (GLuint index, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4dvARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4dvARB = extproc; glVertexAttrib4dvARB(index, v); } static void APIENTRY InitVertexAttrib4fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4fARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4fARB = extproc; glVertexAttrib4fARB(index, x, y, z, w); } static void APIENTRY InitVertexAttrib4fvARB (GLuint index, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4fvARB = extproc; glVertexAttrib4fvARB(index, v); } static void APIENTRY InitVertexAttrib4ivARB (GLuint index, const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4ivARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4ivARB = extproc; glVertexAttrib4ivARB(index, v); } static void APIENTRY InitVertexAttrib4sARB (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4sARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4sARB = extproc; glVertexAttrib4sARB(index, x, y, z, w); } static void APIENTRY InitVertexAttrib4svARB (GLuint index, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4svARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4svARB = extproc; glVertexAttrib4svARB(index, v); } static void APIENTRY InitVertexAttrib4ubvARB (GLuint index, const GLubyte *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4ubvARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4ubvARB = extproc; glVertexAttrib4ubvARB(index, v); } static void APIENTRY InitVertexAttrib4uivARB (GLuint index, const GLuint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4uivARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4uivARB = extproc; glVertexAttrib4uivARB(index, v); } static void APIENTRY InitVertexAttrib4usvARB (GLuint index, const GLushort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4usvARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4usvARB = extproc; glVertexAttrib4usvARB(index, v); } static void APIENTRY InitVertexAttribPointerARB (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribPointerARB"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribPointerARB = extproc; glVertexAttribPointerARB(index, size, type, normalized, stride, pointer); } static void APIENTRY InitEnableVertexAttribArrayARB (GLuint index) { void *extproc; extproc = (void *) wglGetProcAddress("glEnableVertexAttribArrayARB"); if (extproc == NULL) { _ASSERT(0); return; } glEnableVertexAttribArrayARB = extproc; glEnableVertexAttribArrayARB(index); } static void APIENTRY InitDisableVertexAttribArrayARB (GLuint index) { void *extproc; extproc = (void *) wglGetProcAddress("glDisableVertexAttribArrayARB"); if (extproc == NULL) { _ASSERT(0); return; } glDisableVertexAttribArrayARB = extproc; glDisableVertexAttribArrayARB(index); } static void APIENTRY InitProgramStringARB (GLenum target, GLenum format, GLsizei len, const GLvoid *string) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramStringARB"); if (extproc == NULL) { _ASSERT(0); return; } glProgramStringARB = extproc; glProgramStringARB(target, format, len, string); } static void APIENTRY InitBindProgramARB (GLenum target, GLuint program) { void *extproc; extproc = (void *) wglGetProcAddress("glBindProgramARB"); if (extproc == NULL) { _ASSERT(0); return; } glBindProgramARB = extproc; glBindProgramARB(target, program); } static void APIENTRY InitDeleteProgramsARB (GLsizei n, const GLuint *programs) { void *extproc; extproc = (void *) wglGetProcAddress("glDeleteProgramsARB"); if (extproc == NULL) { _ASSERT(0); return; } glDeleteProgramsARB = extproc; glDeleteProgramsARB(n, programs); } static void APIENTRY InitGenProgramsARB (GLsizei n, GLuint *programs) { void *extproc; extproc = (void *) wglGetProcAddress("glGenProgramsARB"); if (extproc == NULL) { _ASSERT(0); return; } glGenProgramsARB = extproc; glGenProgramsARB(n, programs); } static void APIENTRY InitProgramEnvParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramEnvParameter4dARB"); if (extproc == NULL) { _ASSERT(0); return; } glProgramEnvParameter4dARB = extproc; glProgramEnvParameter4dARB(target, index, x, y, z, w); } static void APIENTRY InitProgramEnvParameter4dvARB (GLenum target, GLuint index, const GLdouble *params) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramEnvParameter4dvARB"); if (extproc == NULL) { _ASSERT(0); return; } glProgramEnvParameter4dvARB = extproc; glProgramEnvParameter4dvARB(target, index, params); } static void APIENTRY InitProgramEnvParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramEnvParameter4fARB"); if (extproc == NULL) { _ASSERT(0); return; } glProgramEnvParameter4fARB = extproc; glProgramEnvParameter4fARB(target, index, x, y, z, w); } static void APIENTRY InitProgramEnvParameter4fvARB (GLenum target, GLuint index, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramEnvParameter4fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glProgramEnvParameter4fvARB = extproc; glProgramEnvParameter4fvARB(target, index, params); } static void APIENTRY InitProgramLocalParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramLocalParameter4dARB"); if (extproc == NULL) { _ASSERT(0); return; } glProgramLocalParameter4dARB = extproc; glProgramLocalParameter4dARB(target, index, x, y, z, w); } static void APIENTRY InitProgramLocalParameter4dvARB (GLenum target, GLuint index, const GLdouble *params) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramLocalParameter4dvARB"); if (extproc == NULL) { _ASSERT(0); return; } glProgramLocalParameter4dvARB = extproc; glProgramLocalParameter4dvARB(target, index, params); } static void APIENTRY InitProgramLocalParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramLocalParameter4fARB"); if (extproc == NULL) { _ASSERT(0); return; } glProgramLocalParameter4fARB = extproc; glProgramLocalParameter4fARB(target, index, x, y, z, w); } static void APIENTRY InitProgramLocalParameter4fvARB (GLenum target, GLuint index, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramLocalParameter4fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glProgramLocalParameter4fvARB = extproc; glProgramLocalParameter4fvARB(target, index, params); } static void APIENTRY InitGetProgramEnvParameterdvARB (GLenum target, GLuint index, GLdouble *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetProgramEnvParameterdvARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetProgramEnvParameterdvARB = extproc; glGetProgramEnvParameterdvARB(target, index, params); } static void APIENTRY InitGetProgramEnvParameterfvARB (GLenum target, GLuint index, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetProgramEnvParameterfvARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetProgramEnvParameterfvARB = extproc; glGetProgramEnvParameterfvARB(target, index, params); } static void APIENTRY InitGetProgramLocalParameterdvARB (GLenum target, GLuint index, GLdouble *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetProgramLocalParameterdvARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetProgramLocalParameterdvARB = extproc; glGetProgramLocalParameterdvARB(target, index, params); } static void APIENTRY InitGetProgramLocalParameterfvARB (GLenum target, GLuint index, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetProgramLocalParameterfvARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetProgramLocalParameterfvARB = extproc; glGetProgramLocalParameterfvARB(target, index, params); } static void APIENTRY InitGetProgramivARB (GLenum target, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetProgramivARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetProgramivARB = extproc; glGetProgramivARB(target, pname, params); } static void APIENTRY InitGetProgramStringARB (GLenum target, GLenum pname, GLvoid *string) { void *extproc; extproc = (void *) wglGetProcAddress("glGetProgramStringARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetProgramStringARB = extproc; glGetProgramStringARB(target, pname, string); } static void APIENTRY InitGetVertexAttribdvARB (GLuint index, GLenum pname, GLdouble *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetVertexAttribdvARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetVertexAttribdvARB = extproc; glGetVertexAttribdvARB(index, pname, params); } static void APIENTRY InitGetVertexAttribfvARB (GLuint index, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetVertexAttribfvARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetVertexAttribfvARB = extproc; glGetVertexAttribfvARB(index, pname, params); } static void APIENTRY InitGetVertexAttribivARB (GLuint index, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetVertexAttribivARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetVertexAttribivARB = extproc; glGetVertexAttribivARB(index, pname, params); } static void APIENTRY InitGetVertexAttribPointervARB (GLuint index, GLenum pname, GLvoid* *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glGetVertexAttribPointervARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetVertexAttribPointervARB = extproc; glGetVertexAttribPointervARB(index, pname, pointer); } static GLboolean APIENTRY InitIsProgramARB (GLuint program) { void *extproc; extproc = (void *) wglGetProcAddress("glIsProgramARB"); if (extproc == NULL) { _ASSERT(0); return 0; } glIsProgramARB = extproc; return glIsProgramARB(program); } static void APIENTRY InitBindBufferARB (GLenum target, GLuint buffer) { void *extproc; extproc = (void *) wglGetProcAddress("glBindBufferARB"); if (extproc == NULL) { _ASSERT(0); return; } glBindBufferARB = extproc; glBindBufferARB(target, buffer); } static void APIENTRY InitDeleteBuffersARB (GLsizei n, const GLuint *buffers) { void *extproc; extproc = (void *) wglGetProcAddress("glDeleteBuffersARB"); if (extproc == NULL) { _ASSERT(0); return; } glDeleteBuffersARB = extproc; glDeleteBuffersARB(n, buffers); } static void APIENTRY InitGenBuffersARB (GLsizei n, GLuint *buffers) { void *extproc; extproc = (void *) wglGetProcAddress("glGenBuffersARB"); if (extproc == NULL) { _ASSERT(0); return; } glGenBuffersARB = extproc; glGenBuffersARB(n, buffers); } static GLboolean APIENTRY InitIsBufferARB (GLuint buffer) { void *extproc; extproc = (void *) wglGetProcAddress("glIsBufferARB"); if (extproc == NULL) { _ASSERT(0); return 0; } glIsBufferARB = extproc; return glIsBufferARB(buffer); } static void APIENTRY InitBufferDataARB (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) { void *extproc; extproc = (void *) wglGetProcAddress("glBufferDataARB"); if (extproc == NULL) { _ASSERT(0); return; } glBufferDataARB = extproc; glBufferDataARB(target, size, data, usage); } static void APIENTRY InitBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glBufferSubDataARB"); if (extproc == NULL) { _ASSERT(0); return; } glBufferSubDataARB = extproc; glBufferSubDataARB(target, offset, size, data); } static void APIENTRY InitGetBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glGetBufferSubDataARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetBufferSubDataARB = extproc; glGetBufferSubDataARB(target, offset, size, data); } static GLvoid* APIENTRY InitMapBufferARB (GLenum target, GLenum access) { void *extproc; extproc = (void *) wglGetProcAddress("glMapBufferARB"); if (extproc == NULL) { _ASSERT(0); return 0; } glMapBufferARB = extproc; return glMapBufferARB(target, access); } static GLboolean APIENTRY InitUnmapBufferARB (GLenum target) { void *extproc; extproc = (void *) wglGetProcAddress("glUnmapBufferARB"); if (extproc == NULL) { _ASSERT(0); return 0; } glUnmapBufferARB = extproc; return glUnmapBufferARB(target); } static void APIENTRY InitGetBufferParameterivARB (GLenum target, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetBufferParameterivARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetBufferParameterivARB = extproc; glGetBufferParameterivARB(target, pname, params); } static void APIENTRY InitGetBufferPointervARB (GLenum target, GLenum pname, GLvoid* *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetBufferPointervARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetBufferPointervARB = extproc; glGetBufferPointervARB(target, pname, params); } static void APIENTRY InitGenQueriesARB (GLsizei n, GLuint *ids) { void *extproc; extproc = (void *) wglGetProcAddress("glGenQueriesARB"); if (extproc == NULL) { _ASSERT(0); return; } glGenQueriesARB = extproc; glGenQueriesARB(n, ids); } static void APIENTRY InitDeleteQueriesARB (GLsizei n, const GLuint *ids) { void *extproc; extproc = (void *) wglGetProcAddress("glDeleteQueriesARB"); if (extproc == NULL) { _ASSERT(0); return; } glDeleteQueriesARB = extproc; glDeleteQueriesARB(n, ids); } static GLboolean APIENTRY InitIsQueryARB (GLuint id) { void *extproc; extproc = (void *) wglGetProcAddress("glIsQueryARB"); if (extproc == NULL) { _ASSERT(0); return 0; } glIsQueryARB = extproc; return glIsQueryARB(id); } static void APIENTRY InitBeginQueryARB (GLenum target, GLuint id) { void *extproc; extproc = (void *) wglGetProcAddress("glBeginQueryARB"); if (extproc == NULL) { _ASSERT(0); return; } glBeginQueryARB = extproc; glBeginQueryARB(target, id); } static void APIENTRY InitEndQueryARB (GLenum target) { void *extproc; extproc = (void *) wglGetProcAddress("glEndQueryARB"); if (extproc == NULL) { _ASSERT(0); return; } glEndQueryARB = extproc; glEndQueryARB(target); } static void APIENTRY InitGetQueryivARB (GLenum target, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetQueryivARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetQueryivARB = extproc; glGetQueryivARB(target, pname, params); } static void APIENTRY InitGetQueryObjectivARB (GLuint id, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetQueryObjectivARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetQueryObjectivARB = extproc; glGetQueryObjectivARB(id, pname, params); } static void APIENTRY InitGetQueryObjectuivARB (GLuint id, GLenum pname, GLuint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetQueryObjectuivARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetQueryObjectuivARB = extproc; glGetQueryObjectuivARB(id, pname, params); } static void APIENTRY InitDeleteObjectARB (GLhandleARB obj) { void *extproc; extproc = (void *) wglGetProcAddress("glDeleteObjectARB"); if (extproc == NULL) { _ASSERT(0); return; } glDeleteObjectARB = extproc; glDeleteObjectARB(obj); } static GLhandleARB APIENTRY InitGetHandleARB (GLenum pname) { void *extproc; extproc = (void *) wglGetProcAddress("glGetHandleARB"); if (extproc == NULL) { _ASSERT(0); return 0; } glGetHandleARB = extproc; return glGetHandleARB(pname); } static void APIENTRY InitDetachObjectARB (GLhandleARB containerObj, GLhandleARB attachedObj) { void *extproc; extproc = (void *) wglGetProcAddress("glDetachObjectARB"); if (extproc == NULL) { _ASSERT(0); return; } glDetachObjectARB = extproc; glDetachObjectARB(containerObj, attachedObj); } static GLhandleARB APIENTRY InitCreateShaderObjectARB (GLenum shaderType) { void *extproc; extproc = (void *) wglGetProcAddress("glCreateShaderObjectARB"); if (extproc == NULL) { _ASSERT(0); return 0; } glCreateShaderObjectARB = extproc; return glCreateShaderObjectARB(shaderType); } static void APIENTRY InitShaderSourceARB (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length) { void *extproc; extproc = (void *) wglGetProcAddress("glShaderSourceARB"); if (extproc == NULL) { _ASSERT(0); return; } glShaderSourceARB = extproc; glShaderSourceARB(shaderObj, count, string, length); } static void APIENTRY InitCompileShaderARB (GLhandleARB shaderObj) { void *extproc; extproc = (void *) wglGetProcAddress("glCompileShaderARB"); if (extproc == NULL) { _ASSERT(0); return; } glCompileShaderARB = extproc; glCompileShaderARB(shaderObj); } static GLhandleARB APIENTRY InitCreateProgramObjectARB (void) { void *extproc; extproc = (void *) wglGetProcAddress("glCreateProgramObjectARB"); if (extproc == NULL) { _ASSERT(0); return 0; } glCreateProgramObjectARB = extproc; return glCreateProgramObjectARB(); } static void APIENTRY InitAttachObjectARB (GLhandleARB containerObj, GLhandleARB obj) { void *extproc; extproc = (void *) wglGetProcAddress("glAttachObjectARB"); if (extproc == NULL) { _ASSERT(0); return; } glAttachObjectARB = extproc; glAttachObjectARB(containerObj, obj); } static void APIENTRY InitLinkProgramARB (GLhandleARB programObj) { void *extproc; extproc = (void *) wglGetProcAddress("glLinkProgramARB"); if (extproc == NULL) { _ASSERT(0); return; } glLinkProgramARB = extproc; glLinkProgramARB(programObj); } static void APIENTRY InitUseProgramObjectARB (GLhandleARB programObj) { void *extproc; extproc = (void *) wglGetProcAddress("glUseProgramObjectARB"); if (extproc == NULL) { _ASSERT(0); return; } glUseProgramObjectARB = extproc; glUseProgramObjectARB(programObj); } static void APIENTRY InitValidateProgramARB (GLhandleARB programObj) { void *extproc; extproc = (void *) wglGetProcAddress("glValidateProgramARB"); if (extproc == NULL) { _ASSERT(0); return; } glValidateProgramARB = extproc; glValidateProgramARB(programObj); } static void APIENTRY InitUniform1fARB (GLint location, GLfloat v0) { void *extproc; extproc = (void *) wglGetProcAddress("glUniform1fARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniform1fARB = extproc; glUniform1fARB(location, v0); } static void APIENTRY InitUniform2fARB (GLint location, GLfloat v0, GLfloat v1) { void *extproc; extproc = (void *) wglGetProcAddress("glUniform2fARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniform2fARB = extproc; glUniform2fARB(location, v0, v1); } static void APIENTRY InitUniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2) { void *extproc; extproc = (void *) wglGetProcAddress("glUniform3fARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniform3fARB = extproc; glUniform3fARB(location, v0, v1, v2); } static void APIENTRY InitUniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) { void *extproc; extproc = (void *) wglGetProcAddress("glUniform4fARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniform4fARB = extproc; glUniform4fARB(location, v0, v1, v2, v3); } static void APIENTRY InitUniform1iARB (GLint location, GLint v0) { void *extproc; extproc = (void *) wglGetProcAddress("glUniform1iARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniform1iARB = extproc; glUniform1iARB(location, v0); } static void APIENTRY InitUniform2iARB (GLint location, GLint v0, GLint v1) { void *extproc; extproc = (void *) wglGetProcAddress("glUniform2iARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniform2iARB = extproc; glUniform2iARB(location, v0, v1); } static void APIENTRY InitUniform3iARB (GLint location, GLint v0, GLint v1, GLint v2) { void *extproc; extproc = (void *) wglGetProcAddress("glUniform3iARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniform3iARB = extproc; glUniform3iARB(location, v0, v1, v2); } static void APIENTRY InitUniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3) { void *extproc; extproc = (void *) wglGetProcAddress("glUniform4iARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniform4iARB = extproc; glUniform4iARB(location, v0, v1, v2, v3); } static void APIENTRY InitUniform1fvARB (GLint location, GLsizei count, const GLfloat *value) { void *extproc; extproc = (void *) wglGetProcAddress("glUniform1fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniform1fvARB = extproc; glUniform1fvARB(location, count, value); } static void APIENTRY InitUniform2fvARB (GLint location, GLsizei count, const GLfloat *value) { void *extproc; extproc = (void *) wglGetProcAddress("glUniform2fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniform2fvARB = extproc; glUniform2fvARB(location, count, value); } static void APIENTRY InitUniform3fvARB (GLint location, GLsizei count, const GLfloat *value) { void *extproc; extproc = (void *) wglGetProcAddress("glUniform3fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniform3fvARB = extproc; glUniform3fvARB(location, count, value); } static void APIENTRY InitUniform4fvARB (GLint location, GLsizei count, const GLfloat *value) { void *extproc; extproc = (void *) wglGetProcAddress("glUniform4fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniform4fvARB = extproc; glUniform4fvARB(location, count, value); } static void APIENTRY InitUniform1ivARB (GLint location, GLsizei count, const GLint *value) { void *extproc; extproc = (void *) wglGetProcAddress("glUniform1ivARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniform1ivARB = extproc; glUniform1ivARB(location, count, value); } static void APIENTRY InitUniform2ivARB (GLint location, GLsizei count, const GLint *value) { void *extproc; extproc = (void *) wglGetProcAddress("glUniform2ivARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniform2ivARB = extproc; glUniform2ivARB(location, count, value); } static void APIENTRY InitUniform3ivARB (GLint location, GLsizei count, const GLint *value) { void *extproc; extproc = (void *) wglGetProcAddress("glUniform3ivARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniform3ivARB = extproc; glUniform3ivARB(location, count, value); } static void APIENTRY InitUniform4ivARB (GLint location, GLsizei count, const GLint *value) { void *extproc; extproc = (void *) wglGetProcAddress("glUniform4ivARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniform4ivARB = extproc; glUniform4ivARB(location, count, value); } static void APIENTRY InitUniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { void *extproc; extproc = (void *) wglGetProcAddress("glUniformMatrix2fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniformMatrix2fvARB = extproc; glUniformMatrix2fvARB(location, count, transpose, value); } static void APIENTRY InitUniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { void *extproc; extproc = (void *) wglGetProcAddress("glUniformMatrix3fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniformMatrix3fvARB = extproc; glUniformMatrix3fvARB(location, count, transpose, value); } static void APIENTRY InitUniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { void *extproc; extproc = (void *) wglGetProcAddress("glUniformMatrix4fvARB"); if (extproc == NULL) { _ASSERT(0); return; } glUniformMatrix4fvARB = extproc; glUniformMatrix4fvARB(location, count, transpose, value); } static void APIENTRY InitGetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetObjectParameterfvARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetObjectParameterfvARB = extproc; glGetObjectParameterfvARB(obj, pname, params); } static void APIENTRY InitGetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetObjectParameterivARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetObjectParameterivARB = extproc; glGetObjectParameterivARB(obj, pname, params); } static void APIENTRY InitGetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog) { void *extproc; extproc = (void *) wglGetProcAddress("glGetInfoLogARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetInfoLogARB = extproc; glGetInfoLogARB(obj, maxLength, length, infoLog); } static void APIENTRY InitGetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj) { void *extproc; extproc = (void *) wglGetProcAddress("glGetAttachedObjectsARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetAttachedObjectsARB = extproc; glGetAttachedObjectsARB(containerObj, maxCount, count, obj); } static GLint APIENTRY InitGetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name) { void *extproc; extproc = (void *) wglGetProcAddress("glGetUniformLocationARB"); if (extproc == NULL) { _ASSERT(0); return 0; } glGetUniformLocationARB = extproc; return glGetUniformLocationARB(programObj, name); } static void APIENTRY InitGetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name) { void *extproc; extproc = (void *) wglGetProcAddress("glGetActiveUniformARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetActiveUniformARB = extproc; glGetActiveUniformARB(programObj, index, maxLength, length, size, type, name); } static void APIENTRY InitGetUniformfvARB (GLhandleARB programObj, GLint location, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetUniformfvARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetUniformfvARB = extproc; glGetUniformfvARB(programObj, location, params); } static void APIENTRY InitGetUniformivARB (GLhandleARB programObj, GLint location, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetUniformivARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetUniformivARB = extproc; glGetUniformivARB(programObj, location, params); } static void APIENTRY InitGetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source) { void *extproc; extproc = (void *) wglGetProcAddress("glGetShaderSourceARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetShaderSourceARB = extproc; glGetShaderSourceARB(obj, maxLength, length, source); } static void APIENTRY InitBindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharARB *name) { void *extproc; extproc = (void *) wglGetProcAddress("glBindAttribLocationARB"); if (extproc == NULL) { _ASSERT(0); return; } glBindAttribLocationARB = extproc; glBindAttribLocationARB(programObj, index, name); } static void APIENTRY InitGetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name) { void *extproc; extproc = (void *) wglGetProcAddress("glGetActiveAttribARB"); if (extproc == NULL) { _ASSERT(0); return; } glGetActiveAttribARB = extproc; glGetActiveAttribARB(programObj, index, maxLength, length, size, type, name); } static GLint APIENTRY InitGetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name) { void *extproc; extproc = (void *) wglGetProcAddress("glGetAttribLocationARB"); if (extproc == NULL) { _ASSERT(0); return 0; } glGetAttribLocationARB = extproc; return glGetAttribLocationARB(programObj, name); } static void APIENTRY InitBlendColorEXT (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { void *extproc; extproc = (void *) wglGetProcAddress("glBlendColorEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBlendColorEXT = extproc; glBlendColorEXT(red, green, blue, alpha); } static void APIENTRY InitPolygonOffsetEXT (GLfloat factor, GLfloat bias) { void *extproc; extproc = (void *) wglGetProcAddress("glPolygonOffsetEXT"); if (extproc == NULL) { _ASSERT(0); return; } glPolygonOffsetEXT = extproc; glPolygonOffsetEXT(factor, bias); } static void APIENTRY InitTexImage3DEXT (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { void *extproc; extproc = (void *) wglGetProcAddress("glTexImage3DEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTexImage3DEXT = extproc; glTexImage3DEXT(target, level, internalformat, width, height, depth, border, format, type, pixels); } static void APIENTRY InitTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) { void *extproc; extproc = (void *) wglGetProcAddress("glTexSubImage3DEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTexSubImage3DEXT = extproc; glTexSubImage3DEXT(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); } static void APIENTRY InitGetTexFilterFuncSGIS (GLenum target, GLenum filter, GLfloat *weights) { void *extproc; extproc = (void *) wglGetProcAddress("glGetTexFilterFuncSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glGetTexFilterFuncSGIS = extproc; glGetTexFilterFuncSGIS(target, filter, weights); } static void APIENTRY InitTexFilterFuncSGIS (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights) { void *extproc; extproc = (void *) wglGetProcAddress("glTexFilterFuncSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glTexFilterFuncSGIS = extproc; glTexFilterFuncSGIS(target, filter, n, weights); } static void APIENTRY InitTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels) { void *extproc; extproc = (void *) wglGetProcAddress("glTexSubImage1DEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTexSubImage1DEXT = extproc; glTexSubImage1DEXT(target, level, xoffset, width, format, type, pixels); } static void APIENTRY InitTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) { void *extproc; extproc = (void *) wglGetProcAddress("glTexSubImage2DEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTexSubImage2DEXT = extproc; glTexSubImage2DEXT(target, level, xoffset, yoffset, width, height, format, type, pixels); } static void APIENTRY InitCopyTexImage1DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) { void *extproc; extproc = (void *) wglGetProcAddress("glCopyTexImage1DEXT"); if (extproc == NULL) { _ASSERT(0); return; } glCopyTexImage1DEXT = extproc; glCopyTexImage1DEXT(target, level, internalformat, x, y, width, border); } static void APIENTRY InitCopyTexImage2DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { void *extproc; extproc = (void *) wglGetProcAddress("glCopyTexImage2DEXT"); if (extproc == NULL) { _ASSERT(0); return; } glCopyTexImage2DEXT = extproc; glCopyTexImage2DEXT(target, level, internalformat, x, y, width, height, border); } static void APIENTRY InitCopyTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { void *extproc; extproc = (void *) wglGetProcAddress("glCopyTexSubImage1DEXT"); if (extproc == NULL) { _ASSERT(0); return; } glCopyTexSubImage1DEXT = extproc; glCopyTexSubImage1DEXT(target, level, xoffset, x, y, width); } static void APIENTRY InitCopyTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { void *extproc; extproc = (void *) wglGetProcAddress("glCopyTexSubImage2DEXT"); if (extproc == NULL) { _ASSERT(0); return; } glCopyTexSubImage2DEXT = extproc; glCopyTexSubImage2DEXT(target, level, xoffset, yoffset, x, y, width, height); } static void APIENTRY InitCopyTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) { void *extproc; extproc = (void *) wglGetProcAddress("glCopyTexSubImage3DEXT"); if (extproc == NULL) { _ASSERT(0); return; } glCopyTexSubImage3DEXT = extproc; glCopyTexSubImage3DEXT(target, level, xoffset, yoffset, zoffset, x, y, width, height); } static void APIENTRY InitGetHistogramEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values) { void *extproc; extproc = (void *) wglGetProcAddress("glGetHistogramEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetHistogramEXT = extproc; glGetHistogramEXT(target, reset, format, type, values); } static void APIENTRY InitGetHistogramParameterfvEXT (GLenum target, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetHistogramParameterfvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetHistogramParameterfvEXT = extproc; glGetHistogramParameterfvEXT(target, pname, params); } static void APIENTRY InitGetHistogramParameterivEXT (GLenum target, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetHistogramParameterivEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetHistogramParameterivEXT = extproc; glGetHistogramParameterivEXT(target, pname, params); } static void APIENTRY InitGetMinmaxEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values) { void *extproc; extproc = (void *) wglGetProcAddress("glGetMinmaxEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetMinmaxEXT = extproc; glGetMinmaxEXT(target, reset, format, type, values); } static void APIENTRY InitGetMinmaxParameterfvEXT (GLenum target, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetMinmaxParameterfvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetMinmaxParameterfvEXT = extproc; glGetMinmaxParameterfvEXT(target, pname, params); } static void APIENTRY InitGetMinmaxParameterivEXT (GLenum target, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetMinmaxParameterivEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetMinmaxParameterivEXT = extproc; glGetMinmaxParameterivEXT(target, pname, params); } static void APIENTRY InitHistogramEXT (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink) { void *extproc; extproc = (void *) wglGetProcAddress("glHistogramEXT"); if (extproc == NULL) { _ASSERT(0); return; } glHistogramEXT = extproc; glHistogramEXT(target, width, internalformat, sink); } static void APIENTRY InitMinmaxEXT (GLenum target, GLenum internalformat, GLboolean sink) { void *extproc; extproc = (void *) wglGetProcAddress("glMinmaxEXT"); if (extproc == NULL) { _ASSERT(0); return; } glMinmaxEXT = extproc; glMinmaxEXT(target, internalformat, sink); } static void APIENTRY InitResetHistogramEXT (GLenum target) { void *extproc; extproc = (void *) wglGetProcAddress("glResetHistogramEXT"); if (extproc == NULL) { _ASSERT(0); return; } glResetHistogramEXT = extproc; glResetHistogramEXT(target); } static void APIENTRY InitResetMinmaxEXT (GLenum target) { void *extproc; extproc = (void *) wglGetProcAddress("glResetMinmaxEXT"); if (extproc == NULL) { _ASSERT(0); return; } glResetMinmaxEXT = extproc; glResetMinmaxEXT(target); } static void APIENTRY InitConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image) { void *extproc; extproc = (void *) wglGetProcAddress("glConvolutionFilter1DEXT"); if (extproc == NULL) { _ASSERT(0); return; } glConvolutionFilter1DEXT = extproc; glConvolutionFilter1DEXT(target, internalformat, width, format, type, image); } static void APIENTRY InitConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image) { void *extproc; extproc = (void *) wglGetProcAddress("glConvolutionFilter2DEXT"); if (extproc == NULL) { _ASSERT(0); return; } glConvolutionFilter2DEXT = extproc; glConvolutionFilter2DEXT(target, internalformat, width, height, format, type, image); } static void APIENTRY InitConvolutionParameterfEXT (GLenum target, GLenum pname, GLfloat params) { void *extproc; extproc = (void *) wglGetProcAddress("glConvolutionParameterfEXT"); if (extproc == NULL) { _ASSERT(0); return; } glConvolutionParameterfEXT = extproc; glConvolutionParameterfEXT(target, pname, params); } static void APIENTRY InitConvolutionParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glConvolutionParameterfvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glConvolutionParameterfvEXT = extproc; glConvolutionParameterfvEXT(target, pname, params); } static void APIENTRY InitConvolutionParameteriEXT (GLenum target, GLenum pname, GLint params) { void *extproc; extproc = (void *) wglGetProcAddress("glConvolutionParameteriEXT"); if (extproc == NULL) { _ASSERT(0); return; } glConvolutionParameteriEXT = extproc; glConvolutionParameteriEXT(target, pname, params); } static void APIENTRY InitConvolutionParameterivEXT (GLenum target, GLenum pname, const GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glConvolutionParameterivEXT"); if (extproc == NULL) { _ASSERT(0); return; } glConvolutionParameterivEXT = extproc; glConvolutionParameterivEXT(target, pname, params); } static void APIENTRY InitCopyConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) { void *extproc; extproc = (void *) wglGetProcAddress("glCopyConvolutionFilter1DEXT"); if (extproc == NULL) { _ASSERT(0); return; } glCopyConvolutionFilter1DEXT = extproc; glCopyConvolutionFilter1DEXT(target, internalformat, x, y, width); } static void APIENTRY InitCopyConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height) { void *extproc; extproc = (void *) wglGetProcAddress("glCopyConvolutionFilter2DEXT"); if (extproc == NULL) { _ASSERT(0); return; } glCopyConvolutionFilter2DEXT = extproc; glCopyConvolutionFilter2DEXT(target, internalformat, x, y, width, height); } static void APIENTRY InitGetConvolutionFilterEXT (GLenum target, GLenum format, GLenum type, GLvoid *image) { void *extproc; extproc = (void *) wglGetProcAddress("glGetConvolutionFilterEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetConvolutionFilterEXT = extproc; glGetConvolutionFilterEXT(target, format, type, image); } static void APIENTRY InitGetConvolutionParameterfvEXT (GLenum target, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetConvolutionParameterfvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetConvolutionParameterfvEXT = extproc; glGetConvolutionParameterfvEXT(target, pname, params); } static void APIENTRY InitGetConvolutionParameterivEXT (GLenum target, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetConvolutionParameterivEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetConvolutionParameterivEXT = extproc; glGetConvolutionParameterivEXT(target, pname, params); } static void APIENTRY InitGetSeparableFilterEXT (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span) { void *extproc; extproc = (void *) wglGetProcAddress("glGetSeparableFilterEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetSeparableFilterEXT = extproc; glGetSeparableFilterEXT(target, format, type, row, column, span); } static void APIENTRY InitSeparableFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column) { void *extproc; extproc = (void *) wglGetProcAddress("glSeparableFilter2DEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSeparableFilter2DEXT = extproc; glSeparableFilter2DEXT(target, internalformat, width, height, format, type, row, column); } static void APIENTRY InitColorTableSGI (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table) { void *extproc; extproc = (void *) wglGetProcAddress("glColorTableSGI"); if (extproc == NULL) { _ASSERT(0); return; } glColorTableSGI = extproc; glColorTableSGI(target, internalformat, width, format, type, table); } static void APIENTRY InitColorTableParameterfvSGI (GLenum target, GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glColorTableParameterfvSGI"); if (extproc == NULL) { _ASSERT(0); return; } glColorTableParameterfvSGI = extproc; glColorTableParameterfvSGI(target, pname, params); } static void APIENTRY InitColorTableParameterivSGI (GLenum target, GLenum pname, const GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glColorTableParameterivSGI"); if (extproc == NULL) { _ASSERT(0); return; } glColorTableParameterivSGI = extproc; glColorTableParameterivSGI(target, pname, params); } static void APIENTRY InitCopyColorTableSGI (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) { void *extproc; extproc = (void *) wglGetProcAddress("glCopyColorTableSGI"); if (extproc == NULL) { _ASSERT(0); return; } glCopyColorTableSGI = extproc; glCopyColorTableSGI(target, internalformat, x, y, width); } static void APIENTRY InitGetColorTableSGI (GLenum target, GLenum format, GLenum type, GLvoid *table) { void *extproc; extproc = (void *) wglGetProcAddress("glGetColorTableSGI"); if (extproc == NULL) { _ASSERT(0); return; } glGetColorTableSGI = extproc; glGetColorTableSGI(target, format, type, table); } static void APIENTRY InitGetColorTableParameterfvSGI (GLenum target, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetColorTableParameterfvSGI"); if (extproc == NULL) { _ASSERT(0); return; } glGetColorTableParameterfvSGI = extproc; glGetColorTableParameterfvSGI(target, pname, params); } static void APIENTRY InitGetColorTableParameterivSGI (GLenum target, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetColorTableParameterivSGI"); if (extproc == NULL) { _ASSERT(0); return; } glGetColorTableParameterivSGI = extproc; glGetColorTableParameterivSGI(target, pname, params); } static void APIENTRY InitPixelTexGenSGIX (GLenum mode) { void *extproc; extproc = (void *) wglGetProcAddress("glPixelTexGenSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glPixelTexGenSGIX = extproc; glPixelTexGenSGIX(mode); } static void APIENTRY InitPixelTexGenParameteriSGIS (GLenum pname, GLint param) { void *extproc; extproc = (void *) wglGetProcAddress("glPixelTexGenParameteriSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glPixelTexGenParameteriSGIS = extproc; glPixelTexGenParameteriSGIS(pname, param); } static void APIENTRY InitPixelTexGenParameterivSGIS (GLenum pname, const GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glPixelTexGenParameterivSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glPixelTexGenParameterivSGIS = extproc; glPixelTexGenParameterivSGIS(pname, params); } static void APIENTRY InitPixelTexGenParameterfSGIS (GLenum pname, GLfloat param) { void *extproc; extproc = (void *) wglGetProcAddress("glPixelTexGenParameterfSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glPixelTexGenParameterfSGIS = extproc; glPixelTexGenParameterfSGIS(pname, param); } static void APIENTRY InitPixelTexGenParameterfvSGIS (GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glPixelTexGenParameterfvSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glPixelTexGenParameterfvSGIS = extproc; glPixelTexGenParameterfvSGIS(pname, params); } static void APIENTRY InitGetPixelTexGenParameterivSGIS (GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetPixelTexGenParameterivSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glGetPixelTexGenParameterivSGIS = extproc; glGetPixelTexGenParameterivSGIS(pname, params); } static void APIENTRY InitGetPixelTexGenParameterfvSGIS (GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetPixelTexGenParameterfvSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glGetPixelTexGenParameterfvSGIS = extproc; glGetPixelTexGenParameterfvSGIS(pname, params); } static void APIENTRY InitTexImage4DSGIS (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { void *extproc; extproc = (void *) wglGetProcAddress("glTexImage4DSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glTexImage4DSGIS = extproc; glTexImage4DSGIS(target, level, internalformat, width, height, depth, size4d, border, format, type, pixels); } static void APIENTRY InitTexSubImage4DSGIS (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels) { void *extproc; extproc = (void *) wglGetProcAddress("glTexSubImage4DSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glTexSubImage4DSGIS = extproc; glTexSubImage4DSGIS(target, level, xoffset, yoffset, zoffset, woffset, width, height, depth, size4d, format, type, pixels); } static GLboolean APIENTRY InitAreTexturesResidentEXT (GLsizei n, const GLuint *textures, GLboolean *residences) { void *extproc; extproc = (void *) wglGetProcAddress("glAreTexturesResidentEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } glAreTexturesResidentEXT = extproc; return glAreTexturesResidentEXT(n, textures, residences); } static void APIENTRY InitBindTextureEXT (GLenum target, GLuint texture) { void *extproc; extproc = (void *) wglGetProcAddress("glBindTextureEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBindTextureEXT = extproc; glBindTextureEXT(target, texture); } static void APIENTRY InitDeleteTexturesEXT (GLsizei n, const GLuint *textures) { void *extproc; extproc = (void *) wglGetProcAddress("glDeleteTexturesEXT"); if (extproc == NULL) { _ASSERT(0); return; } glDeleteTexturesEXT = extproc; glDeleteTexturesEXT(n, textures); } static void APIENTRY InitGenTexturesEXT (GLsizei n, GLuint *textures) { void *extproc; extproc = (void *) wglGetProcAddress("glGenTexturesEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGenTexturesEXT = extproc; glGenTexturesEXT(n, textures); } static GLboolean APIENTRY InitIsTextureEXT (GLuint texture) { void *extproc; extproc = (void *) wglGetProcAddress("glIsTextureEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } glIsTextureEXT = extproc; return glIsTextureEXT(texture); } static void APIENTRY InitPrioritizeTexturesEXT (GLsizei n, const GLuint *textures, const GLclampf *priorities) { void *extproc; extproc = (void *) wglGetProcAddress("glPrioritizeTexturesEXT"); if (extproc == NULL) { _ASSERT(0); return; } glPrioritizeTexturesEXT = extproc; glPrioritizeTexturesEXT(n, textures, priorities); } static void APIENTRY InitDetailTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points) { void *extproc; extproc = (void *) wglGetProcAddress("glDetailTexFuncSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glDetailTexFuncSGIS = extproc; glDetailTexFuncSGIS(target, n, points); } static void APIENTRY InitGetDetailTexFuncSGIS (GLenum target, GLfloat *points) { void *extproc; extproc = (void *) wglGetProcAddress("glGetDetailTexFuncSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glGetDetailTexFuncSGIS = extproc; glGetDetailTexFuncSGIS(target, points); } static void APIENTRY InitSharpenTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points) { void *extproc; extproc = (void *) wglGetProcAddress("glSharpenTexFuncSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glSharpenTexFuncSGIS = extproc; glSharpenTexFuncSGIS(target, n, points); } static void APIENTRY InitGetSharpenTexFuncSGIS (GLenum target, GLfloat *points) { void *extproc; extproc = (void *) wglGetProcAddress("glGetSharpenTexFuncSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glGetSharpenTexFuncSGIS = extproc; glGetSharpenTexFuncSGIS(target, points); } static void APIENTRY InitSampleMaskSGIS (GLclampf value, GLboolean invert) { void *extproc; extproc = (void *) wglGetProcAddress("glSampleMaskSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glSampleMaskSGIS = extproc; glSampleMaskSGIS(value, invert); } static void APIENTRY InitSamplePatternSGIS (GLenum pattern) { void *extproc; extproc = (void *) wglGetProcAddress("glSamplePatternSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glSamplePatternSGIS = extproc; glSamplePatternSGIS(pattern); } static void APIENTRY InitArrayElementEXT (GLint i) { void *extproc; extproc = (void *) wglGetProcAddress("glArrayElementEXT"); if (extproc == NULL) { _ASSERT(0); return; } glArrayElementEXT = extproc; glArrayElementEXT(i); } static void APIENTRY InitColorPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glColorPointerEXT"); if (extproc == NULL) { _ASSERT(0); return; } glColorPointerEXT = extproc; glColorPointerEXT(size, type, stride, count, pointer); } static void APIENTRY InitDrawArraysEXT (GLenum mode, GLint first, GLsizei count) { void *extproc; extproc = (void *) wglGetProcAddress("glDrawArraysEXT"); if (extproc == NULL) { _ASSERT(0); return; } glDrawArraysEXT = extproc; glDrawArraysEXT(mode, first, count); } static void APIENTRY InitEdgeFlagPointerEXT (GLsizei stride, GLsizei count, const GLboolean *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glEdgeFlagPointerEXT"); if (extproc == NULL) { _ASSERT(0); return; } glEdgeFlagPointerEXT = extproc; glEdgeFlagPointerEXT(stride, count, pointer); } static void APIENTRY InitGetPointervEXT (GLenum pname, GLvoid* *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetPointervEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetPointervEXT = extproc; glGetPointervEXT(pname, params); } static void APIENTRY InitIndexPointerEXT (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glIndexPointerEXT"); if (extproc == NULL) { _ASSERT(0); return; } glIndexPointerEXT = extproc; glIndexPointerEXT(type, stride, count, pointer); } static void APIENTRY InitNormalPointerEXT (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glNormalPointerEXT"); if (extproc == NULL) { _ASSERT(0); return; } glNormalPointerEXT = extproc; glNormalPointerEXT(type, stride, count, pointer); } static void APIENTRY InitTexCoordPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoordPointerEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoordPointerEXT = extproc; glTexCoordPointerEXT(size, type, stride, count, pointer); } static void APIENTRY InitVertexPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexPointerEXT"); if (extproc == NULL) { _ASSERT(0); return; } glVertexPointerEXT = extproc; glVertexPointerEXT(size, type, stride, count, pointer); } static void APIENTRY InitBlendEquationEXT (GLenum mode) { void *extproc; extproc = (void *) wglGetProcAddress("glBlendEquationEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBlendEquationEXT = extproc; glBlendEquationEXT(mode); } static void APIENTRY InitSpriteParameterfSGIX (GLenum pname, GLfloat param) { void *extproc; extproc = (void *) wglGetProcAddress("glSpriteParameterfSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glSpriteParameterfSGIX = extproc; glSpriteParameterfSGIX(pname, param); } static void APIENTRY InitSpriteParameterfvSGIX (GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glSpriteParameterfvSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glSpriteParameterfvSGIX = extproc; glSpriteParameterfvSGIX(pname, params); } static void APIENTRY InitSpriteParameteriSGIX (GLenum pname, GLint param) { void *extproc; extproc = (void *) wglGetProcAddress("glSpriteParameteriSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glSpriteParameteriSGIX = extproc; glSpriteParameteriSGIX(pname, param); } static void APIENTRY InitSpriteParameterivSGIX (GLenum pname, const GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glSpriteParameterivSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glSpriteParameterivSGIX = extproc; glSpriteParameterivSGIX(pname, params); } static void APIENTRY InitPointParameterfEXT (GLenum pname, GLfloat param) { void *extproc; extproc = (void *) wglGetProcAddress("glPointParameterfEXT"); if (extproc == NULL) { _ASSERT(0); return; } glPointParameterfEXT = extproc; glPointParameterfEXT(pname, param); } static void APIENTRY InitPointParameterfvEXT (GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glPointParameterfvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glPointParameterfvEXT = extproc; glPointParameterfvEXT(pname, params); } static void APIENTRY InitPointParameterfSGIS (GLenum pname, GLfloat param) { void *extproc; extproc = (void *) wglGetProcAddress("glPointParameterfSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glPointParameterfSGIS = extproc; glPointParameterfSGIS(pname, param); } static void APIENTRY InitPointParameterfvSGIS (GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glPointParameterfvSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glPointParameterfvSGIS = extproc; glPointParameterfvSGIS(pname, params); } static GLint APIENTRY InitGetInstrumentsSGIX (void) { void *extproc; extproc = (void *) wglGetProcAddress("glGetInstrumentsSGIX"); if (extproc == NULL) { _ASSERT(0); return 0; } glGetInstrumentsSGIX = extproc; return glGetInstrumentsSGIX(); } static void APIENTRY InitInstrumentsBufferSGIX (GLsizei size, GLint *buffer) { void *extproc; extproc = (void *) wglGetProcAddress("glInstrumentsBufferSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glInstrumentsBufferSGIX = extproc; glInstrumentsBufferSGIX(size, buffer); } static GLint APIENTRY InitPollInstrumentsSGIX (GLint *marker_p) { void *extproc; extproc = (void *) wglGetProcAddress("glPollInstrumentsSGIX"); if (extproc == NULL) { _ASSERT(0); return 0; } glPollInstrumentsSGIX = extproc; return glPollInstrumentsSGIX(marker_p); } static void APIENTRY InitReadInstrumentsSGIX (GLint marker) { void *extproc; extproc = (void *) wglGetProcAddress("glReadInstrumentsSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glReadInstrumentsSGIX = extproc; glReadInstrumentsSGIX(marker); } static void APIENTRY InitStartInstrumentsSGIX (void) { void *extproc; extproc = (void *) wglGetProcAddress("glStartInstrumentsSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glStartInstrumentsSGIX = extproc; glStartInstrumentsSGIX(); } static void APIENTRY InitStopInstrumentsSGIX (GLint marker) { void *extproc; extproc = (void *) wglGetProcAddress("glStopInstrumentsSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glStopInstrumentsSGIX = extproc; glStopInstrumentsSGIX(marker); } static void APIENTRY InitFrameZoomSGIX (GLint factor) { void *extproc; extproc = (void *) wglGetProcAddress("glFrameZoomSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glFrameZoomSGIX = extproc; glFrameZoomSGIX(factor); } static void APIENTRY InitTagSampleBufferSGIX (void) { void *extproc; extproc = (void *) wglGetProcAddress("glTagSampleBufferSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glTagSampleBufferSGIX = extproc; glTagSampleBufferSGIX(); } static void APIENTRY InitDeformationMap3dSGIX (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points) { void *extproc; extproc = (void *) wglGetProcAddress("glDeformationMap3dSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glDeformationMap3dSGIX = extproc; glDeformationMap3dSGIX(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, w1, w2, wstride, worder, points); } static void APIENTRY InitDeformationMap3fSGIX (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points) { void *extproc; extproc = (void *) wglGetProcAddress("glDeformationMap3fSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glDeformationMap3fSGIX = extproc; glDeformationMap3fSGIX(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, w1, w2, wstride, worder, points); } static void APIENTRY InitDeformSGIX (GLbitfield mask) { void *extproc; extproc = (void *) wglGetProcAddress("glDeformSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glDeformSGIX = extproc; glDeformSGIX(mask); } static void APIENTRY InitLoadIdentityDeformationMapSGIX (GLbitfield mask) { void *extproc; extproc = (void *) wglGetProcAddress("glLoadIdentityDeformationMapSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glLoadIdentityDeformationMapSGIX = extproc; glLoadIdentityDeformationMapSGIX(mask); } static void APIENTRY InitReferencePlaneSGIX (const GLdouble *equation) { void *extproc; extproc = (void *) wglGetProcAddress("glReferencePlaneSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glReferencePlaneSGIX = extproc; glReferencePlaneSGIX(equation); } static void APIENTRY InitFlushRasterSGIX (void) { void *extproc; extproc = (void *) wglGetProcAddress("glFlushRasterSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glFlushRasterSGIX = extproc; glFlushRasterSGIX(); } static void APIENTRY InitFogFuncSGIS (GLsizei n, const GLfloat *points) { void *extproc; extproc = (void *) wglGetProcAddress("glFogFuncSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glFogFuncSGIS = extproc; glFogFuncSGIS(n, points); } static void APIENTRY InitGetFogFuncSGIS (GLfloat *points) { void *extproc; extproc = (void *) wglGetProcAddress("glGetFogFuncSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glGetFogFuncSGIS = extproc; glGetFogFuncSGIS(points); } static void APIENTRY InitImageTransformParameteriHP (GLenum target, GLenum pname, GLint param) { void *extproc; extproc = (void *) wglGetProcAddress("glImageTransformParameteriHP"); if (extproc == NULL) { _ASSERT(0); return; } glImageTransformParameteriHP = extproc; glImageTransformParameteriHP(target, pname, param); } static void APIENTRY InitImageTransformParameterfHP (GLenum target, GLenum pname, GLfloat param) { void *extproc; extproc = (void *) wglGetProcAddress("glImageTransformParameterfHP"); if (extproc == NULL) { _ASSERT(0); return; } glImageTransformParameterfHP = extproc; glImageTransformParameterfHP(target, pname, param); } static void APIENTRY InitImageTransformParameterivHP (GLenum target, GLenum pname, const GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glImageTransformParameterivHP"); if (extproc == NULL) { _ASSERT(0); return; } glImageTransformParameterivHP = extproc; glImageTransformParameterivHP(target, pname, params); } static void APIENTRY InitImageTransformParameterfvHP (GLenum target, GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glImageTransformParameterfvHP"); if (extproc == NULL) { _ASSERT(0); return; } glImageTransformParameterfvHP = extproc; glImageTransformParameterfvHP(target, pname, params); } static void APIENTRY InitGetImageTransformParameterivHP (GLenum target, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetImageTransformParameterivHP"); if (extproc == NULL) { _ASSERT(0); return; } glGetImageTransformParameterivHP = extproc; glGetImageTransformParameterivHP(target, pname, params); } static void APIENTRY InitGetImageTransformParameterfvHP (GLenum target, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetImageTransformParameterfvHP"); if (extproc == NULL) { _ASSERT(0); return; } glGetImageTransformParameterfvHP = extproc; glGetImageTransformParameterfvHP(target, pname, params); } static void APIENTRY InitColorSubTableEXT (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glColorSubTableEXT"); if (extproc == NULL) { _ASSERT(0); return; } glColorSubTableEXT = extproc; glColorSubTableEXT(target, start, count, format, type, data); } static void APIENTRY InitCopyColorSubTableEXT (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width) { void *extproc; extproc = (void *) wglGetProcAddress("glCopyColorSubTableEXT"); if (extproc == NULL) { _ASSERT(0); return; } glCopyColorSubTableEXT = extproc; glCopyColorSubTableEXT(target, start, x, y, width); } static void APIENTRY InitHintPGI (GLenum target, GLint mode) { void *extproc; extproc = (void *) wglGetProcAddress("glHintPGI"); if (extproc == NULL) { _ASSERT(0); return; } glHintPGI = extproc; glHintPGI(target, mode); } static void APIENTRY InitColorTableEXT (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table) { void *extproc; extproc = (void *) wglGetProcAddress("glColorTableEXT"); if (extproc == NULL) { _ASSERT(0); return; } glColorTableEXT = extproc; glColorTableEXT(target, internalFormat, width, format, type, table); } static void APIENTRY InitGetColorTableEXT (GLenum target, GLenum format, GLenum type, GLvoid *data) { void *extproc; extproc = (void *) wglGetProcAddress("glGetColorTableEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetColorTableEXT = extproc; glGetColorTableEXT(target, format, type, data); } static void APIENTRY InitGetColorTableParameterivEXT (GLenum target, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetColorTableParameterivEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetColorTableParameterivEXT = extproc; glGetColorTableParameterivEXT(target, pname, params); } static void APIENTRY InitGetColorTableParameterfvEXT (GLenum target, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetColorTableParameterfvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetColorTableParameterfvEXT = extproc; glGetColorTableParameterfvEXT(target, pname, params); } static void APIENTRY InitGetListParameterfvSGIX (GLuint list, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetListParameterfvSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glGetListParameterfvSGIX = extproc; glGetListParameterfvSGIX(list, pname, params); } static void APIENTRY InitGetListParameterivSGIX (GLuint list, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetListParameterivSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glGetListParameterivSGIX = extproc; glGetListParameterivSGIX(list, pname, params); } static void APIENTRY InitListParameterfSGIX (GLuint list, GLenum pname, GLfloat param) { void *extproc; extproc = (void *) wglGetProcAddress("glListParameterfSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glListParameterfSGIX = extproc; glListParameterfSGIX(list, pname, param); } static void APIENTRY InitListParameterfvSGIX (GLuint list, GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glListParameterfvSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glListParameterfvSGIX = extproc; glListParameterfvSGIX(list, pname, params); } static void APIENTRY InitListParameteriSGIX (GLuint list, GLenum pname, GLint param) { void *extproc; extproc = (void *) wglGetProcAddress("glListParameteriSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glListParameteriSGIX = extproc; glListParameteriSGIX(list, pname, param); } static void APIENTRY InitListParameterivSGIX (GLuint list, GLenum pname, const GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glListParameterivSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glListParameterivSGIX = extproc; glListParameterivSGIX(list, pname, params); } static void APIENTRY InitIndexMaterialEXT (GLenum face, GLenum mode) { void *extproc; extproc = (void *) wglGetProcAddress("glIndexMaterialEXT"); if (extproc == NULL) { _ASSERT(0); return; } glIndexMaterialEXT = extproc; glIndexMaterialEXT(face, mode); } static void APIENTRY InitIndexFuncEXT (GLenum func, GLclampf ref) { void *extproc; extproc = (void *) wglGetProcAddress("glIndexFuncEXT"); if (extproc == NULL) { _ASSERT(0); return; } glIndexFuncEXT = extproc; glIndexFuncEXT(func, ref); } static void APIENTRY InitLockArraysEXT (GLint first, GLsizei count) { void *extproc; extproc = (void *) wglGetProcAddress("glLockArraysEXT"); if (extproc == NULL) { _ASSERT(0); return; } glLockArraysEXT = extproc; glLockArraysEXT(first, count); } static void APIENTRY InitUnlockArraysEXT (void) { void *extproc; extproc = (void *) wglGetProcAddress("glUnlockArraysEXT"); if (extproc == NULL) { _ASSERT(0); return; } glUnlockArraysEXT = extproc; glUnlockArraysEXT(); } static void APIENTRY InitCullParameterdvEXT (GLenum pname, GLdouble *params) { void *extproc; extproc = (void *) wglGetProcAddress("glCullParameterdvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glCullParameterdvEXT = extproc; glCullParameterdvEXT(pname, params); } static void APIENTRY InitCullParameterfvEXT (GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glCullParameterfvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glCullParameterfvEXT = extproc; glCullParameterfvEXT(pname, params); } static void APIENTRY InitFragmentColorMaterialSGIX (GLenum face, GLenum mode) { void *extproc; extproc = (void *) wglGetProcAddress("glFragmentColorMaterialSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glFragmentColorMaterialSGIX = extproc; glFragmentColorMaterialSGIX(face, mode); } static void APIENTRY InitFragmentLightfSGIX (GLenum light, GLenum pname, GLfloat param) { void *extproc; extproc = (void *) wglGetProcAddress("glFragmentLightfSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glFragmentLightfSGIX = extproc; glFragmentLightfSGIX(light, pname, param); } static void APIENTRY InitFragmentLightfvSGIX (GLenum light, GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glFragmentLightfvSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glFragmentLightfvSGIX = extproc; glFragmentLightfvSGIX(light, pname, params); } static void APIENTRY InitFragmentLightiSGIX (GLenum light, GLenum pname, GLint param) { void *extproc; extproc = (void *) wglGetProcAddress("glFragmentLightiSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glFragmentLightiSGIX = extproc; glFragmentLightiSGIX(light, pname, param); } static void APIENTRY InitFragmentLightivSGIX (GLenum light, GLenum pname, const GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glFragmentLightivSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glFragmentLightivSGIX = extproc; glFragmentLightivSGIX(light, pname, params); } static void APIENTRY InitFragmentLightModelfSGIX (GLenum pname, GLfloat param) { void *extproc; extproc = (void *) wglGetProcAddress("glFragmentLightModelfSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glFragmentLightModelfSGIX = extproc; glFragmentLightModelfSGIX(pname, param); } static void APIENTRY InitFragmentLightModelfvSGIX (GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glFragmentLightModelfvSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glFragmentLightModelfvSGIX = extproc; glFragmentLightModelfvSGIX(pname, params); } static void APIENTRY InitFragmentLightModeliSGIX (GLenum pname, GLint param) { void *extproc; extproc = (void *) wglGetProcAddress("glFragmentLightModeliSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glFragmentLightModeliSGIX = extproc; glFragmentLightModeliSGIX(pname, param); } static void APIENTRY InitFragmentLightModelivSGIX (GLenum pname, const GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glFragmentLightModelivSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glFragmentLightModelivSGIX = extproc; glFragmentLightModelivSGIX(pname, params); } static void APIENTRY InitFragmentMaterialfSGIX (GLenum face, GLenum pname, GLfloat param) { void *extproc; extproc = (void *) wglGetProcAddress("glFragmentMaterialfSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glFragmentMaterialfSGIX = extproc; glFragmentMaterialfSGIX(face, pname, param); } static void APIENTRY InitFragmentMaterialfvSGIX (GLenum face, GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glFragmentMaterialfvSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glFragmentMaterialfvSGIX = extproc; glFragmentMaterialfvSGIX(face, pname, params); } static void APIENTRY InitFragmentMaterialiSGIX (GLenum face, GLenum pname, GLint param) { void *extproc; extproc = (void *) wglGetProcAddress("glFragmentMaterialiSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glFragmentMaterialiSGIX = extproc; glFragmentMaterialiSGIX(face, pname, param); } static void APIENTRY InitFragmentMaterialivSGIX (GLenum face, GLenum pname, const GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glFragmentMaterialivSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glFragmentMaterialivSGIX = extproc; glFragmentMaterialivSGIX(face, pname, params); } static void APIENTRY InitGetFragmentLightfvSGIX (GLenum light, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetFragmentLightfvSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glGetFragmentLightfvSGIX = extproc; glGetFragmentLightfvSGIX(light, pname, params); } static void APIENTRY InitGetFragmentLightivSGIX (GLenum light, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetFragmentLightivSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glGetFragmentLightivSGIX = extproc; glGetFragmentLightivSGIX(light, pname, params); } static void APIENTRY InitGetFragmentMaterialfvSGIX (GLenum face, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetFragmentMaterialfvSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glGetFragmentMaterialfvSGIX = extproc; glGetFragmentMaterialfvSGIX(face, pname, params); } static void APIENTRY InitGetFragmentMaterialivSGIX (GLenum face, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetFragmentMaterialivSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glGetFragmentMaterialivSGIX = extproc; glGetFragmentMaterialivSGIX(face, pname, params); } static void APIENTRY InitLightEnviSGIX (GLenum pname, GLint param) { void *extproc; extproc = (void *) wglGetProcAddress("glLightEnviSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glLightEnviSGIX = extproc; glLightEnviSGIX(pname, param); } static void APIENTRY InitDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) { void *extproc; extproc = (void *) wglGetProcAddress("glDrawRangeElementsEXT"); if (extproc == NULL) { _ASSERT(0); return; } glDrawRangeElementsEXT = extproc; glDrawRangeElementsEXT(mode, start, end, count, type, indices); } static void APIENTRY InitApplyTextureEXT (GLenum mode) { void *extproc; extproc = (void *) wglGetProcAddress("glApplyTextureEXT"); if (extproc == NULL) { _ASSERT(0); return; } glApplyTextureEXT = extproc; glApplyTextureEXT(mode); } static void APIENTRY InitTextureLightEXT (GLenum pname) { void *extproc; extproc = (void *) wglGetProcAddress("glTextureLightEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTextureLightEXT = extproc; glTextureLightEXT(pname); } static void APIENTRY InitTextureMaterialEXT (GLenum face, GLenum mode) { void *extproc; extproc = (void *) wglGetProcAddress("glTextureMaterialEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTextureMaterialEXT = extproc; glTextureMaterialEXT(face, mode); } static void APIENTRY InitAsyncMarkerSGIX (GLuint marker) { void *extproc; extproc = (void *) wglGetProcAddress("glAsyncMarkerSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glAsyncMarkerSGIX = extproc; glAsyncMarkerSGIX(marker); } static GLint APIENTRY InitFinishAsyncSGIX (GLuint *markerp) { void *extproc; extproc = (void *) wglGetProcAddress("glFinishAsyncSGIX"); if (extproc == NULL) { _ASSERT(0); return 0; } glFinishAsyncSGIX = extproc; return glFinishAsyncSGIX(markerp); } static GLint APIENTRY InitPollAsyncSGIX (GLuint *markerp) { void *extproc; extproc = (void *) wglGetProcAddress("glPollAsyncSGIX"); if (extproc == NULL) { _ASSERT(0); return 0; } glPollAsyncSGIX = extproc; return glPollAsyncSGIX(markerp); } static GLuint APIENTRY InitGenAsyncMarkersSGIX (GLsizei range) { void *extproc; extproc = (void *) wglGetProcAddress("glGenAsyncMarkersSGIX"); if (extproc == NULL) { _ASSERT(0); return 0; } glGenAsyncMarkersSGIX = extproc; return glGenAsyncMarkersSGIX(range); } static void APIENTRY InitDeleteAsyncMarkersSGIX (GLuint marker, GLsizei range) { void *extproc; extproc = (void *) wglGetProcAddress("glDeleteAsyncMarkersSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glDeleteAsyncMarkersSGIX = extproc; glDeleteAsyncMarkersSGIX(marker, range); } static GLboolean APIENTRY InitIsAsyncMarkerSGIX (GLuint marker) { void *extproc; extproc = (void *) wglGetProcAddress("glIsAsyncMarkerSGIX"); if (extproc == NULL) { _ASSERT(0); return 0; } glIsAsyncMarkerSGIX = extproc; return glIsAsyncMarkerSGIX(marker); } static void APIENTRY InitVertexPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexPointervINTEL"); if (extproc == NULL) { _ASSERT(0); return; } glVertexPointervINTEL = extproc; glVertexPointervINTEL(size, type, pointer); } static void APIENTRY InitNormalPointervINTEL (GLenum type, const GLvoid* *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glNormalPointervINTEL"); if (extproc == NULL) { _ASSERT(0); return; } glNormalPointervINTEL = extproc; glNormalPointervINTEL(type, pointer); } static void APIENTRY InitColorPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glColorPointervINTEL"); if (extproc == NULL) { _ASSERT(0); return; } glColorPointervINTEL = extproc; glColorPointervINTEL(size, type, pointer); } static void APIENTRY InitTexCoordPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoordPointervINTEL"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoordPointervINTEL = extproc; glTexCoordPointervINTEL(size, type, pointer); } static void APIENTRY InitPixelTransformParameteriEXT (GLenum target, GLenum pname, GLint param) { void *extproc; extproc = (void *) wglGetProcAddress("glPixelTransformParameteriEXT"); if (extproc == NULL) { _ASSERT(0); return; } glPixelTransformParameteriEXT = extproc; glPixelTransformParameteriEXT(target, pname, param); } static void APIENTRY InitPixelTransformParameterfEXT (GLenum target, GLenum pname, GLfloat param) { void *extproc; extproc = (void *) wglGetProcAddress("glPixelTransformParameterfEXT"); if (extproc == NULL) { _ASSERT(0); return; } glPixelTransformParameterfEXT = extproc; glPixelTransformParameterfEXT(target, pname, param); } static void APIENTRY InitPixelTransformParameterivEXT (GLenum target, GLenum pname, const GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glPixelTransformParameterivEXT"); if (extproc == NULL) { _ASSERT(0); return; } glPixelTransformParameterivEXT = extproc; glPixelTransformParameterivEXT(target, pname, params); } static void APIENTRY InitPixelTransformParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glPixelTransformParameterfvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glPixelTransformParameterfvEXT = extproc; glPixelTransformParameterfvEXT(target, pname, params); } static void APIENTRY InitSecondaryColor3bEXT (GLbyte red, GLbyte green, GLbyte blue) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3bEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3bEXT = extproc; glSecondaryColor3bEXT(red, green, blue); } static void APIENTRY InitSecondaryColor3bvEXT (const GLbyte *v) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3bvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3bvEXT = extproc; glSecondaryColor3bvEXT(v); } static void APIENTRY InitSecondaryColor3dEXT (GLdouble red, GLdouble green, GLdouble blue) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3dEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3dEXT = extproc; glSecondaryColor3dEXT(red, green, blue); } static void APIENTRY InitSecondaryColor3dvEXT (const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3dvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3dvEXT = extproc; glSecondaryColor3dvEXT(v); } static void APIENTRY InitSecondaryColor3fEXT (GLfloat red, GLfloat green, GLfloat blue) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3fEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3fEXT = extproc; glSecondaryColor3fEXT(red, green, blue); } static void APIENTRY InitSecondaryColor3fvEXT (const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3fvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3fvEXT = extproc; glSecondaryColor3fvEXT(v); } static void APIENTRY InitSecondaryColor3iEXT (GLint red, GLint green, GLint blue) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3iEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3iEXT = extproc; glSecondaryColor3iEXT(red, green, blue); } static void APIENTRY InitSecondaryColor3ivEXT (const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3ivEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3ivEXT = extproc; glSecondaryColor3ivEXT(v); } static void APIENTRY InitSecondaryColor3sEXT (GLshort red, GLshort green, GLshort blue) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3sEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3sEXT = extproc; glSecondaryColor3sEXT(red, green, blue); } static void APIENTRY InitSecondaryColor3svEXT (const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3svEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3svEXT = extproc; glSecondaryColor3svEXT(v); } static void APIENTRY InitSecondaryColor3ubEXT (GLubyte red, GLubyte green, GLubyte blue) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3ubEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3ubEXT = extproc; glSecondaryColor3ubEXT(red, green, blue); } static void APIENTRY InitSecondaryColor3ubvEXT (const GLubyte *v) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3ubvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3ubvEXT = extproc; glSecondaryColor3ubvEXT(v); } static void APIENTRY InitSecondaryColor3uiEXT (GLuint red, GLuint green, GLuint blue) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3uiEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3uiEXT = extproc; glSecondaryColor3uiEXT(red, green, blue); } static void APIENTRY InitSecondaryColor3uivEXT (const GLuint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3uivEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3uivEXT = extproc; glSecondaryColor3uivEXT(v); } static void APIENTRY InitSecondaryColor3usEXT (GLushort red, GLushort green, GLushort blue) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3usEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3usEXT = extproc; glSecondaryColor3usEXT(red, green, blue); } static void APIENTRY InitSecondaryColor3usvEXT (const GLushort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3usvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3usvEXT = extproc; glSecondaryColor3usvEXT(v); } static void APIENTRY InitSecondaryColorPointerEXT (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColorPointerEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColorPointerEXT = extproc; glSecondaryColorPointerEXT(size, type, stride, pointer); } static void APIENTRY InitTextureNormalEXT (GLenum mode) { void *extproc; extproc = (void *) wglGetProcAddress("glTextureNormalEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTextureNormalEXT = extproc; glTextureNormalEXT(mode); } static void APIENTRY InitMultiDrawArraysEXT (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiDrawArraysEXT"); if (extproc == NULL) { _ASSERT(0); return; } glMultiDrawArraysEXT = extproc; glMultiDrawArraysEXT(mode, first, count, primcount); } static void APIENTRY InitMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiDrawElementsEXT"); if (extproc == NULL) { _ASSERT(0); return; } glMultiDrawElementsEXT = extproc; glMultiDrawElementsEXT(mode, count, type, indices, primcount); } static void APIENTRY InitFogCoordfEXT (GLfloat coord) { void *extproc; extproc = (void *) wglGetProcAddress("glFogCoordfEXT"); if (extproc == NULL) { _ASSERT(0); return; } glFogCoordfEXT = extproc; glFogCoordfEXT(coord); } static void APIENTRY InitFogCoordfvEXT (const GLfloat *coord) { void *extproc; extproc = (void *) wglGetProcAddress("glFogCoordfvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glFogCoordfvEXT = extproc; glFogCoordfvEXT(coord); } static void APIENTRY InitFogCoorddEXT (GLdouble coord) { void *extproc; extproc = (void *) wglGetProcAddress("glFogCoorddEXT"); if (extproc == NULL) { _ASSERT(0); return; } glFogCoorddEXT = extproc; glFogCoorddEXT(coord); } static void APIENTRY InitFogCoorddvEXT (const GLdouble *coord) { void *extproc; extproc = (void *) wglGetProcAddress("glFogCoorddvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glFogCoorddvEXT = extproc; glFogCoorddvEXT(coord); } static void APIENTRY InitFogCoordPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glFogCoordPointerEXT"); if (extproc == NULL) { _ASSERT(0); return; } glFogCoordPointerEXT = extproc; glFogCoordPointerEXT(type, stride, pointer); } static void APIENTRY InitTangent3bEXT (GLbyte tx, GLbyte ty, GLbyte tz) { void *extproc; extproc = (void *) wglGetProcAddress("glTangent3bEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTangent3bEXT = extproc; glTangent3bEXT(tx, ty, tz); } static void APIENTRY InitTangent3bvEXT (const GLbyte *v) { void *extproc; extproc = (void *) wglGetProcAddress("glTangent3bvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTangent3bvEXT = extproc; glTangent3bvEXT(v); } static void APIENTRY InitTangent3dEXT (GLdouble tx, GLdouble ty, GLdouble tz) { void *extproc; extproc = (void *) wglGetProcAddress("glTangent3dEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTangent3dEXT = extproc; glTangent3dEXT(tx, ty, tz); } static void APIENTRY InitTangent3dvEXT (const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glTangent3dvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTangent3dvEXT = extproc; glTangent3dvEXT(v); } static void APIENTRY InitTangent3fEXT (GLfloat tx, GLfloat ty, GLfloat tz) { void *extproc; extproc = (void *) wglGetProcAddress("glTangent3fEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTangent3fEXT = extproc; glTangent3fEXT(tx, ty, tz); } static void APIENTRY InitTangent3fvEXT (const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glTangent3fvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTangent3fvEXT = extproc; glTangent3fvEXT(v); } static void APIENTRY InitTangent3iEXT (GLint tx, GLint ty, GLint tz) { void *extproc; extproc = (void *) wglGetProcAddress("glTangent3iEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTangent3iEXT = extproc; glTangent3iEXT(tx, ty, tz); } static void APIENTRY InitTangent3ivEXT (const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glTangent3ivEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTangent3ivEXT = extproc; glTangent3ivEXT(v); } static void APIENTRY InitTangent3sEXT (GLshort tx, GLshort ty, GLshort tz) { void *extproc; extproc = (void *) wglGetProcAddress("glTangent3sEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTangent3sEXT = extproc; glTangent3sEXT(tx, ty, tz); } static void APIENTRY InitTangent3svEXT (const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glTangent3svEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTangent3svEXT = extproc; glTangent3svEXT(v); } static void APIENTRY InitBinormal3bEXT (GLbyte bx, GLbyte by, GLbyte bz) { void *extproc; extproc = (void *) wglGetProcAddress("glBinormal3bEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBinormal3bEXT = extproc; glBinormal3bEXT(bx, by, bz); } static void APIENTRY InitBinormal3bvEXT (const GLbyte *v) { void *extproc; extproc = (void *) wglGetProcAddress("glBinormal3bvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBinormal3bvEXT = extproc; glBinormal3bvEXT(v); } static void APIENTRY InitBinormal3dEXT (GLdouble bx, GLdouble by, GLdouble bz) { void *extproc; extproc = (void *) wglGetProcAddress("glBinormal3dEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBinormal3dEXT = extproc; glBinormal3dEXT(bx, by, bz); } static void APIENTRY InitBinormal3dvEXT (const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glBinormal3dvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBinormal3dvEXT = extproc; glBinormal3dvEXT(v); } static void APIENTRY InitBinormal3fEXT (GLfloat bx, GLfloat by, GLfloat bz) { void *extproc; extproc = (void *) wglGetProcAddress("glBinormal3fEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBinormal3fEXT = extproc; glBinormal3fEXT(bx, by, bz); } static void APIENTRY InitBinormal3fvEXT (const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glBinormal3fvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBinormal3fvEXT = extproc; glBinormal3fvEXT(v); } static void APIENTRY InitBinormal3iEXT (GLint bx, GLint by, GLint bz) { void *extproc; extproc = (void *) wglGetProcAddress("glBinormal3iEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBinormal3iEXT = extproc; glBinormal3iEXT(bx, by, bz); } static void APIENTRY InitBinormal3ivEXT (const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glBinormal3ivEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBinormal3ivEXT = extproc; glBinormal3ivEXT(v); } static void APIENTRY InitBinormal3sEXT (GLshort bx, GLshort by, GLshort bz) { void *extproc; extproc = (void *) wglGetProcAddress("glBinormal3sEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBinormal3sEXT = extproc; glBinormal3sEXT(bx, by, bz); } static void APIENTRY InitBinormal3svEXT (const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glBinormal3svEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBinormal3svEXT = extproc; glBinormal3svEXT(v); } static void APIENTRY InitTangentPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glTangentPointerEXT"); if (extproc == NULL) { _ASSERT(0); return; } glTangentPointerEXT = extproc; glTangentPointerEXT(type, stride, pointer); } static void APIENTRY InitBinormalPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glBinormalPointerEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBinormalPointerEXT = extproc; glBinormalPointerEXT(type, stride, pointer); } static void APIENTRY InitFinishTextureSUNX (void) { void *extproc; extproc = (void *) wglGetProcAddress("glFinishTextureSUNX"); if (extproc == NULL) { _ASSERT(0); return; } glFinishTextureSUNX = extproc; glFinishTextureSUNX(); } static void APIENTRY InitGlobalAlphaFactorbSUN (GLbyte factor) { void *extproc; extproc = (void *) wglGetProcAddress("glGlobalAlphaFactorbSUN"); if (extproc == NULL) { _ASSERT(0); return; } glGlobalAlphaFactorbSUN = extproc; glGlobalAlphaFactorbSUN(factor); } static void APIENTRY InitGlobalAlphaFactorsSUN (GLshort factor) { void *extproc; extproc = (void *) wglGetProcAddress("glGlobalAlphaFactorsSUN"); if (extproc == NULL) { _ASSERT(0); return; } glGlobalAlphaFactorsSUN = extproc; glGlobalAlphaFactorsSUN(factor); } static void APIENTRY InitGlobalAlphaFactoriSUN (GLint factor) { void *extproc; extproc = (void *) wglGetProcAddress("glGlobalAlphaFactoriSUN"); if (extproc == NULL) { _ASSERT(0); return; } glGlobalAlphaFactoriSUN = extproc; glGlobalAlphaFactoriSUN(factor); } static void APIENTRY InitGlobalAlphaFactorfSUN (GLfloat factor) { void *extproc; extproc = (void *) wglGetProcAddress("glGlobalAlphaFactorfSUN"); if (extproc == NULL) { _ASSERT(0); return; } glGlobalAlphaFactorfSUN = extproc; glGlobalAlphaFactorfSUN(factor); } static void APIENTRY InitGlobalAlphaFactordSUN (GLdouble factor) { void *extproc; extproc = (void *) wglGetProcAddress("glGlobalAlphaFactordSUN"); if (extproc == NULL) { _ASSERT(0); return; } glGlobalAlphaFactordSUN = extproc; glGlobalAlphaFactordSUN(factor); } static void APIENTRY InitGlobalAlphaFactorubSUN (GLubyte factor) { void *extproc; extproc = (void *) wglGetProcAddress("glGlobalAlphaFactorubSUN"); if (extproc == NULL) { _ASSERT(0); return; } glGlobalAlphaFactorubSUN = extproc; glGlobalAlphaFactorubSUN(factor); } static void APIENTRY InitGlobalAlphaFactorusSUN (GLushort factor) { void *extproc; extproc = (void *) wglGetProcAddress("glGlobalAlphaFactorusSUN"); if (extproc == NULL) { _ASSERT(0); return; } glGlobalAlphaFactorusSUN = extproc; glGlobalAlphaFactorusSUN(factor); } static void APIENTRY InitGlobalAlphaFactoruiSUN (GLuint factor) { void *extproc; extproc = (void *) wglGetProcAddress("glGlobalAlphaFactoruiSUN"); if (extproc == NULL) { _ASSERT(0); return; } glGlobalAlphaFactoruiSUN = extproc; glGlobalAlphaFactoruiSUN(factor); } static void APIENTRY InitReplacementCodeuiSUN (GLuint code) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuiSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuiSUN = extproc; glReplacementCodeuiSUN(code); } static void APIENTRY InitReplacementCodeusSUN (GLushort code) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeusSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeusSUN = extproc; glReplacementCodeusSUN(code); } static void APIENTRY InitReplacementCodeubSUN (GLubyte code) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeubSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeubSUN = extproc; glReplacementCodeubSUN(code); } static void APIENTRY InitReplacementCodeuivSUN (const GLuint *code) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuivSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuivSUN = extproc; glReplacementCodeuivSUN(code); } static void APIENTRY InitReplacementCodeusvSUN (const GLushort *code) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeusvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeusvSUN = extproc; glReplacementCodeusvSUN(code); } static void APIENTRY InitReplacementCodeubvSUN (const GLubyte *code) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeubvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeubvSUN = extproc; glReplacementCodeubvSUN(code); } static void APIENTRY InitReplacementCodePointerSUN (GLenum type, GLsizei stride, const GLvoid* *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodePointerSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodePointerSUN = extproc; glReplacementCodePointerSUN(type, stride, pointer); } static void APIENTRY InitColor4ubVertex2fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y) { void *extproc; extproc = (void *) wglGetProcAddress("glColor4ubVertex2fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glColor4ubVertex2fSUN = extproc; glColor4ubVertex2fSUN(r, g, b, a, x, y); } static void APIENTRY InitColor4ubVertex2fvSUN (const GLubyte *c, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glColor4ubVertex2fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glColor4ubVertex2fvSUN = extproc; glColor4ubVertex2fvSUN(c, v); } static void APIENTRY InitColor4ubVertex3fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glColor4ubVertex3fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glColor4ubVertex3fSUN = extproc; glColor4ubVertex3fSUN(r, g, b, a, x, y, z); } static void APIENTRY InitColor4ubVertex3fvSUN (const GLubyte *c, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glColor4ubVertex3fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glColor4ubVertex3fvSUN = extproc; glColor4ubVertex3fvSUN(c, v); } static void APIENTRY InitColor3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glColor3fVertex3fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glColor3fVertex3fSUN = extproc; glColor3fVertex3fSUN(r, g, b, x, y, z); } static void APIENTRY InitColor3fVertex3fvSUN (const GLfloat *c, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glColor3fVertex3fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glColor3fVertex3fvSUN = extproc; glColor3fVertex3fvSUN(c, v); } static void APIENTRY InitNormal3fVertex3fSUN (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glNormal3fVertex3fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glNormal3fVertex3fSUN = extproc; glNormal3fVertex3fSUN(nx, ny, nz, x, y, z); } static void APIENTRY InitNormal3fVertex3fvSUN (const GLfloat *n, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glNormal3fVertex3fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glNormal3fVertex3fvSUN = extproc; glNormal3fVertex3fvSUN(n, v); } static void APIENTRY InitColor4fNormal3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glColor4fNormal3fVertex3fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glColor4fNormal3fVertex3fSUN = extproc; glColor4fNormal3fVertex3fSUN(r, g, b, a, nx, ny, nz, x, y, z); } static void APIENTRY InitColor4fNormal3fVertex3fvSUN (const GLfloat *c, const GLfloat *n, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glColor4fNormal3fVertex3fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glColor4fNormal3fVertex3fvSUN = extproc; glColor4fNormal3fVertex3fvSUN(c, n, v); } static void APIENTRY InitTexCoord2fVertex3fSUN (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord2fVertex3fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord2fVertex3fSUN = extproc; glTexCoord2fVertex3fSUN(s, t, x, y, z); } static void APIENTRY InitTexCoord2fVertex3fvSUN (const GLfloat *tc, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord2fVertex3fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord2fVertex3fvSUN = extproc; glTexCoord2fVertex3fvSUN(tc, v); } static void APIENTRY InitTexCoord4fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord4fVertex4fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord4fVertex4fSUN = extproc; glTexCoord4fVertex4fSUN(s, t, p, q, x, y, z, w); } static void APIENTRY InitTexCoord4fVertex4fvSUN (const GLfloat *tc, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord4fVertex4fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord4fVertex4fvSUN = extproc; glTexCoord4fVertex4fvSUN(tc, v); } static void APIENTRY InitTexCoord2fColor4ubVertex3fSUN (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord2fColor4ubVertex3fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord2fColor4ubVertex3fSUN = extproc; glTexCoord2fColor4ubVertex3fSUN(s, t, r, g, b, a, x, y, z); } static void APIENTRY InitTexCoord2fColor4ubVertex3fvSUN (const GLfloat *tc, const GLubyte *c, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord2fColor4ubVertex3fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord2fColor4ubVertex3fvSUN = extproc; glTexCoord2fColor4ubVertex3fvSUN(tc, c, v); } static void APIENTRY InitTexCoord2fColor3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord2fColor3fVertex3fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord2fColor3fVertex3fSUN = extproc; glTexCoord2fColor3fVertex3fSUN(s, t, r, g, b, x, y, z); } static void APIENTRY InitTexCoord2fColor3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord2fColor3fVertex3fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord2fColor3fVertex3fvSUN = extproc; glTexCoord2fColor3fVertex3fvSUN(tc, c, v); } static void APIENTRY InitTexCoord2fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord2fNormal3fVertex3fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord2fNormal3fVertex3fSUN = extproc; glTexCoord2fNormal3fVertex3fSUN(s, t, nx, ny, nz, x, y, z); } static void APIENTRY InitTexCoord2fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *n, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord2fNormal3fVertex3fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord2fNormal3fVertex3fvSUN = extproc; glTexCoord2fNormal3fVertex3fvSUN(tc, n, v); } static void APIENTRY InitTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord2fColor4fNormal3fVertex3fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord2fColor4fNormal3fVertex3fSUN = extproc; glTexCoord2fColor4fNormal3fVertex3fSUN(s, t, r, g, b, a, nx, ny, nz, x, y, z); } static void APIENTRY InitTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord2fColor4fNormal3fVertex3fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord2fColor4fNormal3fVertex3fvSUN = extproc; glTexCoord2fColor4fNormal3fVertex3fvSUN(tc, c, n, v); } static void APIENTRY InitTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord4fColor4fNormal3fVertex4fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord4fColor4fNormal3fVertex4fSUN = extproc; glTexCoord4fColor4fNormal3fVertex4fSUN(s, t, p, q, r, g, b, a, nx, ny, nz, x, y, z, w); } static void APIENTRY InitTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord4fColor4fNormal3fVertex4fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord4fColor4fNormal3fVertex4fvSUN = extproc; glTexCoord4fColor4fNormal3fVertex4fvSUN(tc, c, n, v); } static void APIENTRY InitReplacementCodeuiVertex3fSUN (GLuint rc, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuiVertex3fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuiVertex3fSUN = extproc; glReplacementCodeuiVertex3fSUN(rc, x, y, z); } static void APIENTRY InitReplacementCodeuiVertex3fvSUN (const GLuint *rc, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuiVertex3fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuiVertex3fvSUN = extproc; glReplacementCodeuiVertex3fvSUN(rc, v); } static void APIENTRY InitReplacementCodeuiColor4ubVertex3fSUN (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuiColor4ubVertex3fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuiColor4ubVertex3fSUN = extproc; glReplacementCodeuiColor4ubVertex3fSUN(rc, r, g, b, a, x, y, z); } static void APIENTRY InitReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *rc, const GLubyte *c, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuiColor4ubVertex3fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuiColor4ubVertex3fvSUN = extproc; glReplacementCodeuiColor4ubVertex3fvSUN(rc, c, v); } static void APIENTRY InitReplacementCodeuiColor3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuiColor3fVertex3fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuiColor3fVertex3fSUN = extproc; glReplacementCodeuiColor3fVertex3fSUN(rc, r, g, b, x, y, z); } static void APIENTRY InitReplacementCodeuiColor3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuiColor3fVertex3fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuiColor3fVertex3fvSUN = extproc; glReplacementCodeuiColor3fVertex3fvSUN(rc, c, v); } static void APIENTRY InitReplacementCodeuiNormal3fVertex3fSUN (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuiNormal3fVertex3fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuiNormal3fVertex3fSUN = extproc; glReplacementCodeuiNormal3fVertex3fSUN(rc, nx, ny, nz, x, y, z); } static void APIENTRY InitReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *n, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuiNormal3fVertex3fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuiNormal3fVertex3fvSUN = extproc; glReplacementCodeuiNormal3fVertex3fvSUN(rc, n, v); } static void APIENTRY InitReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuiColor4fNormal3fVertex3fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuiColor4fNormal3fVertex3fSUN = extproc; glReplacementCodeuiColor4fNormal3fVertex3fSUN(rc, r, g, b, a, nx, ny, nz, x, y, z); } static void APIENTRY InitReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuiColor4fNormal3fVertex3fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuiColor4fNormal3fVertex3fvSUN = extproc; glReplacementCodeuiColor4fNormal3fVertex3fvSUN(rc, c, n, v); } static void APIENTRY InitReplacementCodeuiTexCoord2fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuiTexCoord2fVertex3fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuiTexCoord2fVertex3fSUN = extproc; glReplacementCodeuiTexCoord2fVertex3fSUN(rc, s, t, x, y, z); } static void APIENTRY InitReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuiTexCoord2fVertex3fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuiTexCoord2fVertex3fvSUN = extproc; glReplacementCodeuiTexCoord2fVertex3fvSUN(rc, tc, v); } static void APIENTRY InitReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = extproc; glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN(rc, s, t, nx, ny, nz, x, y, z); } static void APIENTRY InitReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = extproc; glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN(rc, tc, n, v); } static void APIENTRY InitReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = extproc; glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN(rc, s, t, r, g, b, a, nx, ny, nz, x, y, z); } static void APIENTRY InitReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN"); if (extproc == NULL) { _ASSERT(0); return; } glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = extproc; glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN(rc, tc, c, n, v); } static void APIENTRY InitBlendFuncSeparateEXT (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) { void *extproc; extproc = (void *) wglGetProcAddress("glBlendFuncSeparateEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBlendFuncSeparateEXT = extproc; glBlendFuncSeparateEXT(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); } static void APIENTRY InitBlendFuncSeparateINGR (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) { void *extproc; extproc = (void *) wglGetProcAddress("glBlendFuncSeparateINGR"); if (extproc == NULL) { _ASSERT(0); return; } glBlendFuncSeparateINGR = extproc; glBlendFuncSeparateINGR(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); } static void APIENTRY InitVertexWeightfEXT (GLfloat weight) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexWeightfEXT"); if (extproc == NULL) { _ASSERT(0); return; } glVertexWeightfEXT = extproc; glVertexWeightfEXT(weight); } static void APIENTRY InitVertexWeightfvEXT (const GLfloat *weight) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexWeightfvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glVertexWeightfvEXT = extproc; glVertexWeightfvEXT(weight); } static void APIENTRY InitVertexWeightPointerEXT (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexWeightPointerEXT"); if (extproc == NULL) { _ASSERT(0); return; } glVertexWeightPointerEXT = extproc; glVertexWeightPointerEXT(size, type, stride, pointer); } static void APIENTRY InitFlushVertexArrayRangeNV (void) { void *extproc; extproc = (void *) wglGetProcAddress("glFlushVertexArrayRangeNV"); if (extproc == NULL) { _ASSERT(0); return; } glFlushVertexArrayRangeNV = extproc; glFlushVertexArrayRangeNV(); } static void APIENTRY InitVertexArrayRangeNV (GLsizei length, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexArrayRangeNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexArrayRangeNV = extproc; glVertexArrayRangeNV(length, pointer); } static void APIENTRY InitCombinerParameterfvNV (GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glCombinerParameterfvNV"); if (extproc == NULL) { _ASSERT(0); return; } glCombinerParameterfvNV = extproc; glCombinerParameterfvNV(pname, params); } static void APIENTRY InitCombinerParameterfNV (GLenum pname, GLfloat param) { void *extproc; extproc = (void *) wglGetProcAddress("glCombinerParameterfNV"); if (extproc == NULL) { _ASSERT(0); return; } glCombinerParameterfNV = extproc; glCombinerParameterfNV(pname, param); } static void APIENTRY InitCombinerParameterivNV (GLenum pname, const GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glCombinerParameterivNV"); if (extproc == NULL) { _ASSERT(0); return; } glCombinerParameterivNV = extproc; glCombinerParameterivNV(pname, params); } static void APIENTRY InitCombinerParameteriNV (GLenum pname, GLint param) { void *extproc; extproc = (void *) wglGetProcAddress("glCombinerParameteriNV"); if (extproc == NULL) { _ASSERT(0); return; } glCombinerParameteriNV = extproc; glCombinerParameteriNV(pname, param); } static void APIENTRY InitCombinerInputNV (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage) { void *extproc; extproc = (void *) wglGetProcAddress("glCombinerInputNV"); if (extproc == NULL) { _ASSERT(0); return; } glCombinerInputNV = extproc; glCombinerInputNV(stage, portion, variable, input, mapping, componentUsage); } static void APIENTRY InitCombinerOutputNV (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum) { void *extproc; extproc = (void *) wglGetProcAddress("glCombinerOutputNV"); if (extproc == NULL) { _ASSERT(0); return; } glCombinerOutputNV = extproc; glCombinerOutputNV(stage, portion, abOutput, cdOutput, sumOutput, scale, bias, abDotProduct, cdDotProduct, muxSum); } static void APIENTRY InitFinalCombinerInputNV (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage) { void *extproc; extproc = (void *) wglGetProcAddress("glFinalCombinerInputNV"); if (extproc == NULL) { _ASSERT(0); return; } glFinalCombinerInputNV = extproc; glFinalCombinerInputNV(variable, input, mapping, componentUsage); } static void APIENTRY InitGetCombinerInputParameterfvNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetCombinerInputParameterfvNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetCombinerInputParameterfvNV = extproc; glGetCombinerInputParameterfvNV(stage, portion, variable, pname, params); } static void APIENTRY InitGetCombinerInputParameterivNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetCombinerInputParameterivNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetCombinerInputParameterivNV = extproc; glGetCombinerInputParameterivNV(stage, portion, variable, pname, params); } static void APIENTRY InitGetCombinerOutputParameterfvNV (GLenum stage, GLenum portion, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetCombinerOutputParameterfvNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetCombinerOutputParameterfvNV = extproc; glGetCombinerOutputParameterfvNV(stage, portion, pname, params); } static void APIENTRY InitGetCombinerOutputParameterivNV (GLenum stage, GLenum portion, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetCombinerOutputParameterivNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetCombinerOutputParameterivNV = extproc; glGetCombinerOutputParameterivNV(stage, portion, pname, params); } static void APIENTRY InitGetFinalCombinerInputParameterfvNV (GLenum variable, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetFinalCombinerInputParameterfvNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetFinalCombinerInputParameterfvNV = extproc; glGetFinalCombinerInputParameterfvNV(variable, pname, params); } static void APIENTRY InitGetFinalCombinerInputParameterivNV (GLenum variable, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetFinalCombinerInputParameterivNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetFinalCombinerInputParameterivNV = extproc; glGetFinalCombinerInputParameterivNV(variable, pname, params); } static void APIENTRY InitResizeBuffersMESA (void) { void *extproc; extproc = (void *) wglGetProcAddress("glResizeBuffersMESA"); if (extproc == NULL) { _ASSERT(0); return; } glResizeBuffersMESA = extproc; glResizeBuffersMESA(); } static void APIENTRY InitWindowPos2dMESA (GLdouble x, GLdouble y) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2dMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2dMESA = extproc; glWindowPos2dMESA(x, y); } static void APIENTRY InitWindowPos2dvMESA (const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2dvMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2dvMESA = extproc; glWindowPos2dvMESA(v); } static void APIENTRY InitWindowPos2fMESA (GLfloat x, GLfloat y) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2fMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2fMESA = extproc; glWindowPos2fMESA(x, y); } static void APIENTRY InitWindowPos2fvMESA (const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2fvMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2fvMESA = extproc; glWindowPos2fvMESA(v); } static void APIENTRY InitWindowPos2iMESA (GLint x, GLint y) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2iMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2iMESA = extproc; glWindowPos2iMESA(x, y); } static void APIENTRY InitWindowPos2ivMESA (const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2ivMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2ivMESA = extproc; glWindowPos2ivMESA(v); } static void APIENTRY InitWindowPos2sMESA (GLshort x, GLshort y) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2sMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2sMESA = extproc; glWindowPos2sMESA(x, y); } static void APIENTRY InitWindowPos2svMESA (const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos2svMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos2svMESA = extproc; glWindowPos2svMESA(v); } static void APIENTRY InitWindowPos3dMESA (GLdouble x, GLdouble y, GLdouble z) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3dMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3dMESA = extproc; glWindowPos3dMESA(x, y, z); } static void APIENTRY InitWindowPos3dvMESA (const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3dvMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3dvMESA = extproc; glWindowPos3dvMESA(v); } static void APIENTRY InitWindowPos3fMESA (GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3fMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3fMESA = extproc; glWindowPos3fMESA(x, y, z); } static void APIENTRY InitWindowPos3fvMESA (const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3fvMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3fvMESA = extproc; glWindowPos3fvMESA(v); } static void APIENTRY InitWindowPos3iMESA (GLint x, GLint y, GLint z) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3iMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3iMESA = extproc; glWindowPos3iMESA(x, y, z); } static void APIENTRY InitWindowPos3ivMESA (const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3ivMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3ivMESA = extproc; glWindowPos3ivMESA(v); } static void APIENTRY InitWindowPos3sMESA (GLshort x, GLshort y, GLshort z) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3sMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3sMESA = extproc; glWindowPos3sMESA(x, y, z); } static void APIENTRY InitWindowPos3svMESA (const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos3svMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos3svMESA = extproc; glWindowPos3svMESA(v); } static void APIENTRY InitWindowPos4dMESA (GLdouble x, GLdouble y, GLdouble z, GLdouble w) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos4dMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos4dMESA = extproc; glWindowPos4dMESA(x, y, z, w); } static void APIENTRY InitWindowPos4dvMESA (const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos4dvMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos4dvMESA = extproc; glWindowPos4dvMESA(v); } static void APIENTRY InitWindowPos4fMESA (GLfloat x, GLfloat y, GLfloat z, GLfloat w) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos4fMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos4fMESA = extproc; glWindowPos4fMESA(x, y, z, w); } static void APIENTRY InitWindowPos4fvMESA (const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos4fvMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos4fvMESA = extproc; glWindowPos4fvMESA(v); } static void APIENTRY InitWindowPos4iMESA (GLint x, GLint y, GLint z, GLint w) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos4iMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos4iMESA = extproc; glWindowPos4iMESA(x, y, z, w); } static void APIENTRY InitWindowPos4ivMESA (const GLint *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos4ivMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos4ivMESA = extproc; glWindowPos4ivMESA(v); } static void APIENTRY InitWindowPos4sMESA (GLshort x, GLshort y, GLshort z, GLshort w) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos4sMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos4sMESA = extproc; glWindowPos4sMESA(x, y, z, w); } static void APIENTRY InitWindowPos4svMESA (const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glWindowPos4svMESA"); if (extproc == NULL) { _ASSERT(0); return; } glWindowPos4svMESA = extproc; glWindowPos4svMESA(v); } static void APIENTRY InitMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiModeDrawArraysIBM"); if (extproc == NULL) { _ASSERT(0); return; } glMultiModeDrawArraysIBM = extproc; glMultiModeDrawArraysIBM(mode, first, count, primcount, modestride); } static void APIENTRY InitMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiModeDrawElementsIBM"); if (extproc == NULL) { _ASSERT(0); return; } glMultiModeDrawElementsIBM = extproc; glMultiModeDrawElementsIBM(mode, count, type, indices, primcount, modestride); } static void APIENTRY InitColorPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride) { void *extproc; extproc = (void *) wglGetProcAddress("glColorPointerListIBM"); if (extproc == NULL) { _ASSERT(0); return; } glColorPointerListIBM = extproc; glColorPointerListIBM(size, type, stride, pointer, ptrstride); } static void APIENTRY InitSecondaryColorPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColorPointerListIBM"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColorPointerListIBM = extproc; glSecondaryColorPointerListIBM(size, type, stride, pointer, ptrstride); } static void APIENTRY InitEdgeFlagPointerListIBM (GLint stride, const GLboolean* *pointer, GLint ptrstride) { void *extproc; extproc = (void *) wglGetProcAddress("glEdgeFlagPointerListIBM"); if (extproc == NULL) { _ASSERT(0); return; } glEdgeFlagPointerListIBM = extproc; glEdgeFlagPointerListIBM(stride, pointer, ptrstride); } static void APIENTRY InitFogCoordPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride) { void *extproc; extproc = (void *) wglGetProcAddress("glFogCoordPointerListIBM"); if (extproc == NULL) { _ASSERT(0); return; } glFogCoordPointerListIBM = extproc; glFogCoordPointerListIBM(type, stride, pointer, ptrstride); } static void APIENTRY InitIndexPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride) { void *extproc; extproc = (void *) wglGetProcAddress("glIndexPointerListIBM"); if (extproc == NULL) { _ASSERT(0); return; } glIndexPointerListIBM = extproc; glIndexPointerListIBM(type, stride, pointer, ptrstride); } static void APIENTRY InitNormalPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride) { void *extproc; extproc = (void *) wglGetProcAddress("glNormalPointerListIBM"); if (extproc == NULL) { _ASSERT(0); return; } glNormalPointerListIBM = extproc; glNormalPointerListIBM(type, stride, pointer, ptrstride); } static void APIENTRY InitTexCoordPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoordPointerListIBM"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoordPointerListIBM = extproc; glTexCoordPointerListIBM(size, type, stride, pointer, ptrstride); } static void APIENTRY InitVertexPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexPointerListIBM"); if (extproc == NULL) { _ASSERT(0); return; } glVertexPointerListIBM = extproc; glVertexPointerListIBM(size, type, stride, pointer, ptrstride); } static void APIENTRY InitTbufferMask3DFX (GLuint mask) { void *extproc; extproc = (void *) wglGetProcAddress("glTbufferMask3DFX"); if (extproc == NULL) { _ASSERT(0); return; } glTbufferMask3DFX = extproc; glTbufferMask3DFX(mask); } static void APIENTRY InitSampleMaskEXT (GLclampf value, GLboolean invert) { void *extproc; extproc = (void *) wglGetProcAddress("glSampleMaskEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSampleMaskEXT = extproc; glSampleMaskEXT(value, invert); } static void APIENTRY InitSamplePatternEXT (GLenum pattern) { void *extproc; extproc = (void *) wglGetProcAddress("glSamplePatternEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSamplePatternEXT = extproc; glSamplePatternEXT(pattern); } static void APIENTRY InitTextureColorMaskSGIS (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { void *extproc; extproc = (void *) wglGetProcAddress("glTextureColorMaskSGIS"); if (extproc == NULL) { _ASSERT(0); return; } glTextureColorMaskSGIS = extproc; glTextureColorMaskSGIS(red, green, blue, alpha); } static void APIENTRY InitIglooInterfaceSGIX (GLenum pname, const GLvoid *params) { void *extproc; extproc = (void *) wglGetProcAddress("glIglooInterfaceSGIX"); if (extproc == NULL) { _ASSERT(0); return; } glIglooInterfaceSGIX = extproc; glIglooInterfaceSGIX(pname, params); } static void APIENTRY InitDeleteFencesNV (GLsizei n, const GLuint *fences) { void *extproc; extproc = (void *) wglGetProcAddress("glDeleteFencesNV"); if (extproc == NULL) { _ASSERT(0); return; } glDeleteFencesNV = extproc; glDeleteFencesNV(n, fences); } static void APIENTRY InitGenFencesNV (GLsizei n, GLuint *fences) { void *extproc; extproc = (void *) wglGetProcAddress("glGenFencesNV"); if (extproc == NULL) { _ASSERT(0); return; } glGenFencesNV = extproc; glGenFencesNV(n, fences); } static GLboolean APIENTRY InitIsFenceNV (GLuint fence) { void *extproc; extproc = (void *) wglGetProcAddress("glIsFenceNV"); if (extproc == NULL) { _ASSERT(0); return 0; } glIsFenceNV = extproc; return glIsFenceNV(fence); } static GLboolean APIENTRY InitTestFenceNV (GLuint fence) { void *extproc; extproc = (void *) wglGetProcAddress("glTestFenceNV"); if (extproc == NULL) { _ASSERT(0); return 0; } glTestFenceNV = extproc; return glTestFenceNV(fence); } static void APIENTRY InitGetFenceivNV (GLuint fence, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetFenceivNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetFenceivNV = extproc; glGetFenceivNV(fence, pname, params); } static void APIENTRY InitFinishFenceNV (GLuint fence) { void *extproc; extproc = (void *) wglGetProcAddress("glFinishFenceNV"); if (extproc == NULL) { _ASSERT(0); return; } glFinishFenceNV = extproc; glFinishFenceNV(fence); } static void APIENTRY InitSetFenceNV (GLuint fence, GLenum condition) { void *extproc; extproc = (void *) wglGetProcAddress("glSetFenceNV"); if (extproc == NULL) { _ASSERT(0); return; } glSetFenceNV = extproc; glSetFenceNV(fence, condition); } static void APIENTRY InitMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points) { void *extproc; extproc = (void *) wglGetProcAddress("glMapControlPointsNV"); if (extproc == NULL) { _ASSERT(0); return; } glMapControlPointsNV = extproc; glMapControlPointsNV(target, index, type, ustride, vstride, uorder, vorder, packed, points); } static void APIENTRY InitMapParameterivNV (GLenum target, GLenum pname, const GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glMapParameterivNV"); if (extproc == NULL) { _ASSERT(0); return; } glMapParameterivNV = extproc; glMapParameterivNV(target, pname, params); } static void APIENTRY InitMapParameterfvNV (GLenum target, GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glMapParameterfvNV"); if (extproc == NULL) { _ASSERT(0); return; } glMapParameterfvNV = extproc; glMapParameterfvNV(target, pname, params); } static void APIENTRY InitGetMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points) { void *extproc; extproc = (void *) wglGetProcAddress("glGetMapControlPointsNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetMapControlPointsNV = extproc; glGetMapControlPointsNV(target, index, type, ustride, vstride, packed, points); } static void APIENTRY InitGetMapParameterivNV (GLenum target, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetMapParameterivNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetMapParameterivNV = extproc; glGetMapParameterivNV(target, pname, params); } static void APIENTRY InitGetMapParameterfvNV (GLenum target, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetMapParameterfvNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetMapParameterfvNV = extproc; glGetMapParameterfvNV(target, pname, params); } static void APIENTRY InitGetMapAttribParameterivNV (GLenum target, GLuint index, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetMapAttribParameterivNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetMapAttribParameterivNV = extproc; glGetMapAttribParameterivNV(target, index, pname, params); } static void APIENTRY InitGetMapAttribParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetMapAttribParameterfvNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetMapAttribParameterfvNV = extproc; glGetMapAttribParameterfvNV(target, index, pname, params); } static void APIENTRY InitEvalMapsNV (GLenum target, GLenum mode) { void *extproc; extproc = (void *) wglGetProcAddress("glEvalMapsNV"); if (extproc == NULL) { _ASSERT(0); return; } glEvalMapsNV = extproc; glEvalMapsNV(target, mode); } static void APIENTRY InitCombinerStageParameterfvNV (GLenum stage, GLenum pname, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glCombinerStageParameterfvNV"); if (extproc == NULL) { _ASSERT(0); return; } glCombinerStageParameterfvNV = extproc; glCombinerStageParameterfvNV(stage, pname, params); } static void APIENTRY InitGetCombinerStageParameterfvNV (GLenum stage, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetCombinerStageParameterfvNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetCombinerStageParameterfvNV = extproc; glGetCombinerStageParameterfvNV(stage, pname, params); } static GLboolean APIENTRY InitAreProgramsResidentNV (GLsizei n, const GLuint *programs, GLboolean *residences) { void *extproc; extproc = (void *) wglGetProcAddress("glAreProgramsResidentNV"); if (extproc == NULL) { _ASSERT(0); return 0; } glAreProgramsResidentNV = extproc; return glAreProgramsResidentNV(n, programs, residences); } static void APIENTRY InitBindProgramNV (GLenum target, GLuint id) { void *extproc; extproc = (void *) wglGetProcAddress("glBindProgramNV"); if (extproc == NULL) { _ASSERT(0); return; } glBindProgramNV = extproc; glBindProgramNV(target, id); } static void APIENTRY InitDeleteProgramsNV (GLsizei n, const GLuint *programs) { void *extproc; extproc = (void *) wglGetProcAddress("glDeleteProgramsNV"); if (extproc == NULL) { _ASSERT(0); return; } glDeleteProgramsNV = extproc; glDeleteProgramsNV(n, programs); } static void APIENTRY InitExecuteProgramNV (GLenum target, GLuint id, const GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glExecuteProgramNV"); if (extproc == NULL) { _ASSERT(0); return; } glExecuteProgramNV = extproc; glExecuteProgramNV(target, id, params); } static void APIENTRY InitGenProgramsNV (GLsizei n, GLuint *programs) { void *extproc; extproc = (void *) wglGetProcAddress("glGenProgramsNV"); if (extproc == NULL) { _ASSERT(0); return; } glGenProgramsNV = extproc; glGenProgramsNV(n, programs); } static void APIENTRY InitGetProgramParameterdvNV (GLenum target, GLuint index, GLenum pname, GLdouble *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetProgramParameterdvNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetProgramParameterdvNV = extproc; glGetProgramParameterdvNV(target, index, pname, params); } static void APIENTRY InitGetProgramParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetProgramParameterfvNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetProgramParameterfvNV = extproc; glGetProgramParameterfvNV(target, index, pname, params); } static void APIENTRY InitGetProgramivNV (GLuint id, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetProgramivNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetProgramivNV = extproc; glGetProgramivNV(id, pname, params); } static void APIENTRY InitGetProgramStringNV (GLuint id, GLenum pname, GLubyte *program) { void *extproc; extproc = (void *) wglGetProcAddress("glGetProgramStringNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetProgramStringNV = extproc; glGetProgramStringNV(id, pname, program); } static void APIENTRY InitGetTrackMatrixivNV (GLenum target, GLuint address, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetTrackMatrixivNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetTrackMatrixivNV = extproc; glGetTrackMatrixivNV(target, address, pname, params); } static void APIENTRY InitGetVertexAttribdvNV (GLuint index, GLenum pname, GLdouble *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetVertexAttribdvNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetVertexAttribdvNV = extproc; glGetVertexAttribdvNV(index, pname, params); } static void APIENTRY InitGetVertexAttribfvNV (GLuint index, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetVertexAttribfvNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetVertexAttribfvNV = extproc; glGetVertexAttribfvNV(index, pname, params); } static void APIENTRY InitGetVertexAttribivNV (GLuint index, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetVertexAttribivNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetVertexAttribivNV = extproc; glGetVertexAttribivNV(index, pname, params); } static void APIENTRY InitGetVertexAttribPointervNV (GLuint index, GLenum pname, GLvoid* *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glGetVertexAttribPointervNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetVertexAttribPointervNV = extproc; glGetVertexAttribPointervNV(index, pname, pointer); } static GLboolean APIENTRY InitIsProgramNV (GLuint id) { void *extproc; extproc = (void *) wglGetProcAddress("glIsProgramNV"); if (extproc == NULL) { _ASSERT(0); return 0; } glIsProgramNV = extproc; return glIsProgramNV(id); } static void APIENTRY InitLoadProgramNV (GLenum target, GLuint id, GLsizei len, const GLubyte *program) { void *extproc; extproc = (void *) wglGetProcAddress("glLoadProgramNV"); if (extproc == NULL) { _ASSERT(0); return; } glLoadProgramNV = extproc; glLoadProgramNV(target, id, len, program); } static void APIENTRY InitProgramParameter4dNV (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramParameter4dNV"); if (extproc == NULL) { _ASSERT(0); return; } glProgramParameter4dNV = extproc; glProgramParameter4dNV(target, index, x, y, z, w); } static void APIENTRY InitProgramParameter4dvNV (GLenum target, GLuint index, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramParameter4dvNV"); if (extproc == NULL) { _ASSERT(0); return; } glProgramParameter4dvNV = extproc; glProgramParameter4dvNV(target, index, v); } static void APIENTRY InitProgramParameter4fNV (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramParameter4fNV"); if (extproc == NULL) { _ASSERT(0); return; } glProgramParameter4fNV = extproc; glProgramParameter4fNV(target, index, x, y, z, w); } static void APIENTRY InitProgramParameter4fvNV (GLenum target, GLuint index, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramParameter4fvNV"); if (extproc == NULL) { _ASSERT(0); return; } glProgramParameter4fvNV = extproc; glProgramParameter4fvNV(target, index, v); } static void APIENTRY InitProgramParameters4dvNV (GLenum target, GLuint index, GLuint count, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramParameters4dvNV"); if (extproc == NULL) { _ASSERT(0); return; } glProgramParameters4dvNV = extproc; glProgramParameters4dvNV(target, index, count, v); } static void APIENTRY InitProgramParameters4fvNV (GLenum target, GLuint index, GLuint count, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramParameters4fvNV"); if (extproc == NULL) { _ASSERT(0); return; } glProgramParameters4fvNV = extproc; glProgramParameters4fvNV(target, index, count, v); } static void APIENTRY InitRequestResidentProgramsNV (GLsizei n, const GLuint *programs) { void *extproc; extproc = (void *) wglGetProcAddress("glRequestResidentProgramsNV"); if (extproc == NULL) { _ASSERT(0); return; } glRequestResidentProgramsNV = extproc; glRequestResidentProgramsNV(n, programs); } static void APIENTRY InitTrackMatrixNV (GLenum target, GLuint address, GLenum matrix, GLenum transform) { void *extproc; extproc = (void *) wglGetProcAddress("glTrackMatrixNV"); if (extproc == NULL) { _ASSERT(0); return; } glTrackMatrixNV = extproc; glTrackMatrixNV(target, address, matrix, transform); } static void APIENTRY InitVertexAttribPointerNV (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribPointerNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribPointerNV = extproc; glVertexAttribPointerNV(index, fsize, type, stride, pointer); } static void APIENTRY InitVertexAttrib1dNV (GLuint index, GLdouble x) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib1dNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib1dNV = extproc; glVertexAttrib1dNV(index, x); } static void APIENTRY InitVertexAttrib1dvNV (GLuint index, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib1dvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib1dvNV = extproc; glVertexAttrib1dvNV(index, v); } static void APIENTRY InitVertexAttrib1fNV (GLuint index, GLfloat x) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib1fNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib1fNV = extproc; glVertexAttrib1fNV(index, x); } static void APIENTRY InitVertexAttrib1fvNV (GLuint index, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib1fvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib1fvNV = extproc; glVertexAttrib1fvNV(index, v); } static void APIENTRY InitVertexAttrib1sNV (GLuint index, GLshort x) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib1sNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib1sNV = extproc; glVertexAttrib1sNV(index, x); } static void APIENTRY InitVertexAttrib1svNV (GLuint index, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib1svNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib1svNV = extproc; glVertexAttrib1svNV(index, v); } static void APIENTRY InitVertexAttrib2dNV (GLuint index, GLdouble x, GLdouble y) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib2dNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib2dNV = extproc; glVertexAttrib2dNV(index, x, y); } static void APIENTRY InitVertexAttrib2dvNV (GLuint index, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib2dvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib2dvNV = extproc; glVertexAttrib2dvNV(index, v); } static void APIENTRY InitVertexAttrib2fNV (GLuint index, GLfloat x, GLfloat y) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib2fNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib2fNV = extproc; glVertexAttrib2fNV(index, x, y); } static void APIENTRY InitVertexAttrib2fvNV (GLuint index, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib2fvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib2fvNV = extproc; glVertexAttrib2fvNV(index, v); } static void APIENTRY InitVertexAttrib2sNV (GLuint index, GLshort x, GLshort y) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib2sNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib2sNV = extproc; glVertexAttrib2sNV(index, x, y); } static void APIENTRY InitVertexAttrib2svNV (GLuint index, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib2svNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib2svNV = extproc; glVertexAttrib2svNV(index, v); } static void APIENTRY InitVertexAttrib3dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib3dNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib3dNV = extproc; glVertexAttrib3dNV(index, x, y, z); } static void APIENTRY InitVertexAttrib3dvNV (GLuint index, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib3dvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib3dvNV = extproc; glVertexAttrib3dvNV(index, v); } static void APIENTRY InitVertexAttrib3fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib3fNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib3fNV = extproc; glVertexAttrib3fNV(index, x, y, z); } static void APIENTRY InitVertexAttrib3fvNV (GLuint index, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib3fvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib3fvNV = extproc; glVertexAttrib3fvNV(index, v); } static void APIENTRY InitVertexAttrib3sNV (GLuint index, GLshort x, GLshort y, GLshort z) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib3sNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib3sNV = extproc; glVertexAttrib3sNV(index, x, y, z); } static void APIENTRY InitVertexAttrib3svNV (GLuint index, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib3svNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib3svNV = extproc; glVertexAttrib3svNV(index, v); } static void APIENTRY InitVertexAttrib4dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4dNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4dNV = extproc; glVertexAttrib4dNV(index, x, y, z, w); } static void APIENTRY InitVertexAttrib4dvNV (GLuint index, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4dvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4dvNV = extproc; glVertexAttrib4dvNV(index, v); } static void APIENTRY InitVertexAttrib4fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4fNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4fNV = extproc; glVertexAttrib4fNV(index, x, y, z, w); } static void APIENTRY InitVertexAttrib4fvNV (GLuint index, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4fvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4fvNV = extproc; glVertexAttrib4fvNV(index, v); } static void APIENTRY InitVertexAttrib4sNV (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4sNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4sNV = extproc; glVertexAttrib4sNV(index, x, y, z, w); } static void APIENTRY InitVertexAttrib4svNV (GLuint index, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4svNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4svNV = extproc; glVertexAttrib4svNV(index, v); } static void APIENTRY InitVertexAttrib4ubNV (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4ubNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4ubNV = extproc; glVertexAttrib4ubNV(index, x, y, z, w); } static void APIENTRY InitVertexAttrib4ubvNV (GLuint index, const GLubyte *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4ubvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4ubvNV = extproc; glVertexAttrib4ubvNV(index, v); } static void APIENTRY InitVertexAttribs1dvNV (GLuint index, GLsizei count, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribs1dvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribs1dvNV = extproc; glVertexAttribs1dvNV(index, count, v); } static void APIENTRY InitVertexAttribs1fvNV (GLuint index, GLsizei count, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribs1fvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribs1fvNV = extproc; glVertexAttribs1fvNV(index, count, v); } static void APIENTRY InitVertexAttribs1svNV (GLuint index, GLsizei count, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribs1svNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribs1svNV = extproc; glVertexAttribs1svNV(index, count, v); } static void APIENTRY InitVertexAttribs2dvNV (GLuint index, GLsizei count, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribs2dvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribs2dvNV = extproc; glVertexAttribs2dvNV(index, count, v); } static void APIENTRY InitVertexAttribs2fvNV (GLuint index, GLsizei count, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribs2fvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribs2fvNV = extproc; glVertexAttribs2fvNV(index, count, v); } static void APIENTRY InitVertexAttribs2svNV (GLuint index, GLsizei count, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribs2svNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribs2svNV = extproc; glVertexAttribs2svNV(index, count, v); } static void APIENTRY InitVertexAttribs3dvNV (GLuint index, GLsizei count, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribs3dvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribs3dvNV = extproc; glVertexAttribs3dvNV(index, count, v); } static void APIENTRY InitVertexAttribs3fvNV (GLuint index, GLsizei count, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribs3fvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribs3fvNV = extproc; glVertexAttribs3fvNV(index, count, v); } static void APIENTRY InitVertexAttribs3svNV (GLuint index, GLsizei count, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribs3svNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribs3svNV = extproc; glVertexAttribs3svNV(index, count, v); } static void APIENTRY InitVertexAttribs4dvNV (GLuint index, GLsizei count, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribs4dvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribs4dvNV = extproc; glVertexAttribs4dvNV(index, count, v); } static void APIENTRY InitVertexAttribs4fvNV (GLuint index, GLsizei count, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribs4fvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribs4fvNV = extproc; glVertexAttribs4fvNV(index, count, v); } static void APIENTRY InitVertexAttribs4svNV (GLuint index, GLsizei count, const GLshort *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribs4svNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribs4svNV = extproc; glVertexAttribs4svNV(index, count, v); } static void APIENTRY InitVertexAttribs4ubvNV (GLuint index, GLsizei count, const GLubyte *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribs4ubvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribs4ubvNV = extproc; glVertexAttribs4ubvNV(index, count, v); } static void APIENTRY InitTexBumpParameterivATI (GLenum pname, const GLint *param) { void *extproc; extproc = (void *) wglGetProcAddress("glTexBumpParameterivATI"); if (extproc == NULL) { _ASSERT(0); return; } glTexBumpParameterivATI = extproc; glTexBumpParameterivATI(pname, param); } static void APIENTRY InitTexBumpParameterfvATI (GLenum pname, const GLfloat *param) { void *extproc; extproc = (void *) wglGetProcAddress("glTexBumpParameterfvATI"); if (extproc == NULL) { _ASSERT(0); return; } glTexBumpParameterfvATI = extproc; glTexBumpParameterfvATI(pname, param); } static void APIENTRY InitGetTexBumpParameterivATI (GLenum pname, GLint *param) { void *extproc; extproc = (void *) wglGetProcAddress("glGetTexBumpParameterivATI"); if (extproc == NULL) { _ASSERT(0); return; } glGetTexBumpParameterivATI = extproc; glGetTexBumpParameterivATI(pname, param); } static void APIENTRY InitGetTexBumpParameterfvATI (GLenum pname, GLfloat *param) { void *extproc; extproc = (void *) wglGetProcAddress("glGetTexBumpParameterfvATI"); if (extproc == NULL) { _ASSERT(0); return; } glGetTexBumpParameterfvATI = extproc; glGetTexBumpParameterfvATI(pname, param); } static GLuint APIENTRY InitGenFragmentShadersATI (GLuint range) { void *extproc; extproc = (void *) wglGetProcAddress("glGenFragmentShadersATI"); if (extproc == NULL) { _ASSERT(0); return 0; } glGenFragmentShadersATI = extproc; return glGenFragmentShadersATI(range); } static void APIENTRY InitBindFragmentShaderATI (GLuint id) { void *extproc; extproc = (void *) wglGetProcAddress("glBindFragmentShaderATI"); if (extproc == NULL) { _ASSERT(0); return; } glBindFragmentShaderATI = extproc; glBindFragmentShaderATI(id); } static void APIENTRY InitDeleteFragmentShaderATI (GLuint id) { void *extproc; extproc = (void *) wglGetProcAddress("glDeleteFragmentShaderATI"); if (extproc == NULL) { _ASSERT(0); return; } glDeleteFragmentShaderATI = extproc; glDeleteFragmentShaderATI(id); } static void APIENTRY InitBeginFragmentShaderATI (void) { void *extproc; extproc = (void *) wglGetProcAddress("glBeginFragmentShaderATI"); if (extproc == NULL) { _ASSERT(0); return; } glBeginFragmentShaderATI = extproc; glBeginFragmentShaderATI(); } static void APIENTRY InitEndFragmentShaderATI (void) { void *extproc; extproc = (void *) wglGetProcAddress("glEndFragmentShaderATI"); if (extproc == NULL) { _ASSERT(0); return; } glEndFragmentShaderATI = extproc; glEndFragmentShaderATI(); } static void APIENTRY InitPassTexCoordATI (GLuint dst, GLuint coord, GLenum swizzle) { void *extproc; extproc = (void *) wglGetProcAddress("glPassTexCoordATI"); if (extproc == NULL) { _ASSERT(0); return; } glPassTexCoordATI = extproc; glPassTexCoordATI(dst, coord, swizzle); } static void APIENTRY InitSampleMapATI (GLuint dst, GLuint interp, GLenum swizzle) { void *extproc; extproc = (void *) wglGetProcAddress("glSampleMapATI"); if (extproc == NULL) { _ASSERT(0); return; } glSampleMapATI = extproc; glSampleMapATI(dst, interp, swizzle); } static void APIENTRY InitColorFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod) { void *extproc; extproc = (void *) wglGetProcAddress("glColorFragmentOp1ATI"); if (extproc == NULL) { _ASSERT(0); return; } glColorFragmentOp1ATI = extproc; glColorFragmentOp1ATI(op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod); } static void APIENTRY InitColorFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod) { void *extproc; extproc = (void *) wglGetProcAddress("glColorFragmentOp2ATI"); if (extproc == NULL) { _ASSERT(0); return; } glColorFragmentOp2ATI = extproc; glColorFragmentOp2ATI(op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod); } static void APIENTRY InitColorFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod) { void *extproc; extproc = (void *) wglGetProcAddress("glColorFragmentOp3ATI"); if (extproc == NULL) { _ASSERT(0); return; } glColorFragmentOp3ATI = extproc; glColorFragmentOp3ATI(op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3, arg3Rep, arg3Mod); } static void APIENTRY InitAlphaFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod) { void *extproc; extproc = (void *) wglGetProcAddress("glAlphaFragmentOp1ATI"); if (extproc == NULL) { _ASSERT(0); return; } glAlphaFragmentOp1ATI = extproc; glAlphaFragmentOp1ATI(op, dst, dstMod, arg1, arg1Rep, arg1Mod); } static void APIENTRY InitAlphaFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod) { void *extproc; extproc = (void *) wglGetProcAddress("glAlphaFragmentOp2ATI"); if (extproc == NULL) { _ASSERT(0); return; } glAlphaFragmentOp2ATI = extproc; glAlphaFragmentOp2ATI(op, dst, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod); } static void APIENTRY InitAlphaFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod) { void *extproc; extproc = (void *) wglGetProcAddress("glAlphaFragmentOp3ATI"); if (extproc == NULL) { _ASSERT(0); return; } glAlphaFragmentOp3ATI = extproc; glAlphaFragmentOp3ATI(op, dst, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3, arg3Rep, arg3Mod); } static void APIENTRY InitSetFragmentShaderConstantATI (GLuint dst, const GLfloat *value) { void *extproc; extproc = (void *) wglGetProcAddress("glSetFragmentShaderConstantATI"); if (extproc == NULL) { _ASSERT(0); return; } glSetFragmentShaderConstantATI = extproc; glSetFragmentShaderConstantATI(dst, value); } static void APIENTRY InitPNTrianglesiATI (GLenum pname, GLint param) { void *extproc; extproc = (void *) wglGetProcAddress("glPNTrianglesiATI"); if (extproc == NULL) { _ASSERT(0); return; } glPNTrianglesiATI = extproc; glPNTrianglesiATI(pname, param); } static void APIENTRY InitPNTrianglesfATI (GLenum pname, GLfloat param) { void *extproc; extproc = (void *) wglGetProcAddress("glPNTrianglesfATI"); if (extproc == NULL) { _ASSERT(0); return; } glPNTrianglesfATI = extproc; glPNTrianglesfATI(pname, param); } static GLuint APIENTRY InitNewObjectBufferATI (GLsizei size, const GLvoid *pointer, GLenum usage) { void *extproc; extproc = (void *) wglGetProcAddress("glNewObjectBufferATI"); if (extproc == NULL) { _ASSERT(0); return 0; } glNewObjectBufferATI = extproc; return glNewObjectBufferATI(size, pointer, usage); } static GLboolean APIENTRY InitIsObjectBufferATI (GLuint buffer) { void *extproc; extproc = (void *) wglGetProcAddress("glIsObjectBufferATI"); if (extproc == NULL) { _ASSERT(0); return 0; } glIsObjectBufferATI = extproc; return glIsObjectBufferATI(buffer); } static void APIENTRY InitUpdateObjectBufferATI (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve) { void *extproc; extproc = (void *) wglGetProcAddress("glUpdateObjectBufferATI"); if (extproc == NULL) { _ASSERT(0); return; } glUpdateObjectBufferATI = extproc; glUpdateObjectBufferATI(buffer, offset, size, pointer, preserve); } static void APIENTRY InitGetObjectBufferfvATI (GLuint buffer, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetObjectBufferfvATI"); if (extproc == NULL) { _ASSERT(0); return; } glGetObjectBufferfvATI = extproc; glGetObjectBufferfvATI(buffer, pname, params); } static void APIENTRY InitGetObjectBufferivATI (GLuint buffer, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetObjectBufferivATI"); if (extproc == NULL) { _ASSERT(0); return; } glGetObjectBufferivATI = extproc; glGetObjectBufferivATI(buffer, pname, params); } static void APIENTRY InitFreeObjectBufferATI (GLuint buffer) { void *extproc; extproc = (void *) wglGetProcAddress("glFreeObjectBufferATI"); if (extproc == NULL) { _ASSERT(0); return; } glFreeObjectBufferATI = extproc; glFreeObjectBufferATI(buffer); } static void APIENTRY InitArrayObjectATI (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset) { void *extproc; extproc = (void *) wglGetProcAddress("glArrayObjectATI"); if (extproc == NULL) { _ASSERT(0); return; } glArrayObjectATI = extproc; glArrayObjectATI(array, size, type, stride, buffer, offset); } static void APIENTRY InitGetArrayObjectfvATI (GLenum array, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetArrayObjectfvATI"); if (extproc == NULL) { _ASSERT(0); return; } glGetArrayObjectfvATI = extproc; glGetArrayObjectfvATI(array, pname, params); } static void APIENTRY InitGetArrayObjectivATI (GLenum array, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetArrayObjectivATI"); if (extproc == NULL) { _ASSERT(0); return; } glGetArrayObjectivATI = extproc; glGetArrayObjectivATI(array, pname, params); } static void APIENTRY InitVariantArrayObjectATI (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset) { void *extproc; extproc = (void *) wglGetProcAddress("glVariantArrayObjectATI"); if (extproc == NULL) { _ASSERT(0); return; } glVariantArrayObjectATI = extproc; glVariantArrayObjectATI(id, type, stride, buffer, offset); } static void APIENTRY InitGetVariantArrayObjectfvATI (GLuint id, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetVariantArrayObjectfvATI"); if (extproc == NULL) { _ASSERT(0); return; } glGetVariantArrayObjectfvATI = extproc; glGetVariantArrayObjectfvATI(id, pname, params); } static void APIENTRY InitGetVariantArrayObjectivATI (GLuint id, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetVariantArrayObjectivATI"); if (extproc == NULL) { _ASSERT(0); return; } glGetVariantArrayObjectivATI = extproc; glGetVariantArrayObjectivATI(id, pname, params); } static void APIENTRY InitBeginVertexShaderEXT (void) { void *extproc; extproc = (void *) wglGetProcAddress("glBeginVertexShaderEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBeginVertexShaderEXT = extproc; glBeginVertexShaderEXT(); } static void APIENTRY InitEndVertexShaderEXT (void) { void *extproc; extproc = (void *) wglGetProcAddress("glEndVertexShaderEXT"); if (extproc == NULL) { _ASSERT(0); return; } glEndVertexShaderEXT = extproc; glEndVertexShaderEXT(); } static void APIENTRY InitBindVertexShaderEXT (GLuint id) { void *extproc; extproc = (void *) wglGetProcAddress("glBindVertexShaderEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBindVertexShaderEXT = extproc; glBindVertexShaderEXT(id); } static GLuint APIENTRY InitGenVertexShadersEXT (GLuint range) { void *extproc; extproc = (void *) wglGetProcAddress("glGenVertexShadersEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } glGenVertexShadersEXT = extproc; return glGenVertexShadersEXT(range); } static void APIENTRY InitDeleteVertexShaderEXT (GLuint id) { void *extproc; extproc = (void *) wglGetProcAddress("glDeleteVertexShaderEXT"); if (extproc == NULL) { _ASSERT(0); return; } glDeleteVertexShaderEXT = extproc; glDeleteVertexShaderEXT(id); } static void APIENTRY InitShaderOp1EXT (GLenum op, GLuint res, GLuint arg1) { void *extproc; extproc = (void *) wglGetProcAddress("glShaderOp1EXT"); if (extproc == NULL) { _ASSERT(0); return; } glShaderOp1EXT = extproc; glShaderOp1EXT(op, res, arg1); } static void APIENTRY InitShaderOp2EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2) { void *extproc; extproc = (void *) wglGetProcAddress("glShaderOp2EXT"); if (extproc == NULL) { _ASSERT(0); return; } glShaderOp2EXT = extproc; glShaderOp2EXT(op, res, arg1, arg2); } static void APIENTRY InitShaderOp3EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3) { void *extproc; extproc = (void *) wglGetProcAddress("glShaderOp3EXT"); if (extproc == NULL) { _ASSERT(0); return; } glShaderOp3EXT = extproc; glShaderOp3EXT(op, res, arg1, arg2, arg3); } static void APIENTRY InitSwizzleEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW) { void *extproc; extproc = (void *) wglGetProcAddress("glSwizzleEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSwizzleEXT = extproc; glSwizzleEXT(res, in, outX, outY, outZ, outW); } static void APIENTRY InitWriteMaskEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW) { void *extproc; extproc = (void *) wglGetProcAddress("glWriteMaskEXT"); if (extproc == NULL) { _ASSERT(0); return; } glWriteMaskEXT = extproc; glWriteMaskEXT(res, in, outX, outY, outZ, outW); } static void APIENTRY InitInsertComponentEXT (GLuint res, GLuint src, GLuint num) { void *extproc; extproc = (void *) wglGetProcAddress("glInsertComponentEXT"); if (extproc == NULL) { _ASSERT(0); return; } glInsertComponentEXT = extproc; glInsertComponentEXT(res, src, num); } static void APIENTRY InitExtractComponentEXT (GLuint res, GLuint src, GLuint num) { void *extproc; extproc = (void *) wglGetProcAddress("glExtractComponentEXT"); if (extproc == NULL) { _ASSERT(0); return; } glExtractComponentEXT = extproc; glExtractComponentEXT(res, src, num); } static GLuint APIENTRY InitGenSymbolsEXT (GLenum datatype, GLenum storagetype, GLenum range, GLuint components) { void *extproc; extproc = (void *) wglGetProcAddress("glGenSymbolsEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } glGenSymbolsEXT = extproc; return glGenSymbolsEXT(datatype, storagetype, range, components); } static void APIENTRY InitSetInvariantEXT (GLuint id, GLenum type, const GLvoid *addr) { void *extproc; extproc = (void *) wglGetProcAddress("glSetInvariantEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSetInvariantEXT = extproc; glSetInvariantEXT(id, type, addr); } static void APIENTRY InitSetLocalConstantEXT (GLuint id, GLenum type, const GLvoid *addr) { void *extproc; extproc = (void *) wglGetProcAddress("glSetLocalConstantEXT"); if (extproc == NULL) { _ASSERT(0); return; } glSetLocalConstantEXT = extproc; glSetLocalConstantEXT(id, type, addr); } static void APIENTRY InitVariantbvEXT (GLuint id, const GLbyte *addr) { void *extproc; extproc = (void *) wglGetProcAddress("glVariantbvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glVariantbvEXT = extproc; glVariantbvEXT(id, addr); } static void APIENTRY InitVariantsvEXT (GLuint id, const GLshort *addr) { void *extproc; extproc = (void *) wglGetProcAddress("glVariantsvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glVariantsvEXT = extproc; glVariantsvEXT(id, addr); } static void APIENTRY InitVariantivEXT (GLuint id, const GLint *addr) { void *extproc; extproc = (void *) wglGetProcAddress("glVariantivEXT"); if (extproc == NULL) { _ASSERT(0); return; } glVariantivEXT = extproc; glVariantivEXT(id, addr); } static void APIENTRY InitVariantfvEXT (GLuint id, const GLfloat *addr) { void *extproc; extproc = (void *) wglGetProcAddress("glVariantfvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glVariantfvEXT = extproc; glVariantfvEXT(id, addr); } static void APIENTRY InitVariantdvEXT (GLuint id, const GLdouble *addr) { void *extproc; extproc = (void *) wglGetProcAddress("glVariantdvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glVariantdvEXT = extproc; glVariantdvEXT(id, addr); } static void APIENTRY InitVariantubvEXT (GLuint id, const GLubyte *addr) { void *extproc; extproc = (void *) wglGetProcAddress("glVariantubvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glVariantubvEXT = extproc; glVariantubvEXT(id, addr); } static void APIENTRY InitVariantusvEXT (GLuint id, const GLushort *addr) { void *extproc; extproc = (void *) wglGetProcAddress("glVariantusvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glVariantusvEXT = extproc; glVariantusvEXT(id, addr); } static void APIENTRY InitVariantuivEXT (GLuint id, const GLuint *addr) { void *extproc; extproc = (void *) wglGetProcAddress("glVariantuivEXT"); if (extproc == NULL) { _ASSERT(0); return; } glVariantuivEXT = extproc; glVariantuivEXT(id, addr); } static void APIENTRY InitVariantPointerEXT (GLuint id, GLenum type, GLuint stride, const GLvoid *addr) { void *extproc; extproc = (void *) wglGetProcAddress("glVariantPointerEXT"); if (extproc == NULL) { _ASSERT(0); return; } glVariantPointerEXT = extproc; glVariantPointerEXT(id, type, stride, addr); } static void APIENTRY InitEnableVariantClientStateEXT (GLuint id) { void *extproc; extproc = (void *) wglGetProcAddress("glEnableVariantClientStateEXT"); if (extproc == NULL) { _ASSERT(0); return; } glEnableVariantClientStateEXT = extproc; glEnableVariantClientStateEXT(id); } static void APIENTRY InitDisableVariantClientStateEXT (GLuint id) { void *extproc; extproc = (void *) wglGetProcAddress("glDisableVariantClientStateEXT"); if (extproc == NULL) { _ASSERT(0); return; } glDisableVariantClientStateEXT = extproc; glDisableVariantClientStateEXT(id); } static GLuint APIENTRY InitBindLightParameterEXT (GLenum light, GLenum value) { void *extproc; extproc = (void *) wglGetProcAddress("glBindLightParameterEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } glBindLightParameterEXT = extproc; return glBindLightParameterEXT(light, value); } static GLuint APIENTRY InitBindMaterialParameterEXT (GLenum face, GLenum value) { void *extproc; extproc = (void *) wglGetProcAddress("glBindMaterialParameterEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } glBindMaterialParameterEXT = extproc; return glBindMaterialParameterEXT(face, value); } static GLuint APIENTRY InitBindTexGenParameterEXT (GLenum unit, GLenum coord, GLenum value) { void *extproc; extproc = (void *) wglGetProcAddress("glBindTexGenParameterEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } glBindTexGenParameterEXT = extproc; return glBindTexGenParameterEXT(unit, coord, value); } static GLuint APIENTRY InitBindTextureUnitParameterEXT (GLenum unit, GLenum value) { void *extproc; extproc = (void *) wglGetProcAddress("glBindTextureUnitParameterEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } glBindTextureUnitParameterEXT = extproc; return glBindTextureUnitParameterEXT(unit, value); } static GLuint APIENTRY InitBindParameterEXT (GLenum value) { void *extproc; extproc = (void *) wglGetProcAddress("glBindParameterEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } glBindParameterEXT = extproc; return glBindParameterEXT(value); } static GLboolean APIENTRY InitIsVariantEnabledEXT (GLuint id, GLenum cap) { void *extproc; extproc = (void *) wglGetProcAddress("glIsVariantEnabledEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } glIsVariantEnabledEXT = extproc; return glIsVariantEnabledEXT(id, cap); } static void APIENTRY InitGetVariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data) { void *extproc; extproc = (void *) wglGetProcAddress("glGetVariantBooleanvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetVariantBooleanvEXT = extproc; glGetVariantBooleanvEXT(id, value, data); } static void APIENTRY InitGetVariantIntegervEXT (GLuint id, GLenum value, GLint *data) { void *extproc; extproc = (void *) wglGetProcAddress("glGetVariantIntegervEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetVariantIntegervEXT = extproc; glGetVariantIntegervEXT(id, value, data); } static void APIENTRY InitGetVariantFloatvEXT (GLuint id, GLenum value, GLfloat *data) { void *extproc; extproc = (void *) wglGetProcAddress("glGetVariantFloatvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetVariantFloatvEXT = extproc; glGetVariantFloatvEXT(id, value, data); } static void APIENTRY InitGetVariantPointervEXT (GLuint id, GLenum value, GLvoid* *data) { void *extproc; extproc = (void *) wglGetProcAddress("glGetVariantPointervEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetVariantPointervEXT = extproc; glGetVariantPointervEXT(id, value, data); } static void APIENTRY InitGetInvariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data) { void *extproc; extproc = (void *) wglGetProcAddress("glGetInvariantBooleanvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetInvariantBooleanvEXT = extproc; glGetInvariantBooleanvEXT(id, value, data); } static void APIENTRY InitGetInvariantIntegervEXT (GLuint id, GLenum value, GLint *data) { void *extproc; extproc = (void *) wglGetProcAddress("glGetInvariantIntegervEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetInvariantIntegervEXT = extproc; glGetInvariantIntegervEXT(id, value, data); } static void APIENTRY InitGetInvariantFloatvEXT (GLuint id, GLenum value, GLfloat *data) { void *extproc; extproc = (void *) wglGetProcAddress("glGetInvariantFloatvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetInvariantFloatvEXT = extproc; glGetInvariantFloatvEXT(id, value, data); } static void APIENTRY InitGetLocalConstantBooleanvEXT (GLuint id, GLenum value, GLboolean *data) { void *extproc; extproc = (void *) wglGetProcAddress("glGetLocalConstantBooleanvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetLocalConstantBooleanvEXT = extproc; glGetLocalConstantBooleanvEXT(id, value, data); } static void APIENTRY InitGetLocalConstantIntegervEXT (GLuint id, GLenum value, GLint *data) { void *extproc; extproc = (void *) wglGetProcAddress("glGetLocalConstantIntegervEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetLocalConstantIntegervEXT = extproc; glGetLocalConstantIntegervEXT(id, value, data); } static void APIENTRY InitGetLocalConstantFloatvEXT (GLuint id, GLenum value, GLfloat *data) { void *extproc; extproc = (void *) wglGetProcAddress("glGetLocalConstantFloatvEXT"); if (extproc == NULL) { _ASSERT(0); return; } glGetLocalConstantFloatvEXT = extproc; glGetLocalConstantFloatvEXT(id, value, data); } static void APIENTRY InitVertexStream1sATI (GLenum stream, GLshort x) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream1sATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream1sATI = extproc; glVertexStream1sATI(stream, x); } static void APIENTRY InitVertexStream1svATI (GLenum stream, const GLshort *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream1svATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream1svATI = extproc; glVertexStream1svATI(stream, coords); } static void APIENTRY InitVertexStream1iATI (GLenum stream, GLint x) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream1iATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream1iATI = extproc; glVertexStream1iATI(stream, x); } static void APIENTRY InitVertexStream1ivATI (GLenum stream, const GLint *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream1ivATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream1ivATI = extproc; glVertexStream1ivATI(stream, coords); } static void APIENTRY InitVertexStream1fATI (GLenum stream, GLfloat x) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream1fATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream1fATI = extproc; glVertexStream1fATI(stream, x); } static void APIENTRY InitVertexStream1fvATI (GLenum stream, const GLfloat *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream1fvATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream1fvATI = extproc; glVertexStream1fvATI(stream, coords); } static void APIENTRY InitVertexStream1dATI (GLenum stream, GLdouble x) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream1dATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream1dATI = extproc; glVertexStream1dATI(stream, x); } static void APIENTRY InitVertexStream1dvATI (GLenum stream, const GLdouble *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream1dvATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream1dvATI = extproc; glVertexStream1dvATI(stream, coords); } static void APIENTRY InitVertexStream2sATI (GLenum stream, GLshort x, GLshort y) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream2sATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream2sATI = extproc; glVertexStream2sATI(stream, x, y); } static void APIENTRY InitVertexStream2svATI (GLenum stream, const GLshort *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream2svATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream2svATI = extproc; glVertexStream2svATI(stream, coords); } static void APIENTRY InitVertexStream2iATI (GLenum stream, GLint x, GLint y) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream2iATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream2iATI = extproc; glVertexStream2iATI(stream, x, y); } static void APIENTRY InitVertexStream2ivATI (GLenum stream, const GLint *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream2ivATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream2ivATI = extproc; glVertexStream2ivATI(stream, coords); } static void APIENTRY InitVertexStream2fATI (GLenum stream, GLfloat x, GLfloat y) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream2fATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream2fATI = extproc; glVertexStream2fATI(stream, x, y); } static void APIENTRY InitVertexStream2fvATI (GLenum stream, const GLfloat *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream2fvATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream2fvATI = extproc; glVertexStream2fvATI(stream, coords); } static void APIENTRY InitVertexStream2dATI (GLenum stream, GLdouble x, GLdouble y) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream2dATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream2dATI = extproc; glVertexStream2dATI(stream, x, y); } static void APIENTRY InitVertexStream2dvATI (GLenum stream, const GLdouble *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream2dvATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream2dvATI = extproc; glVertexStream2dvATI(stream, coords); } static void APIENTRY InitVertexStream3sATI (GLenum stream, GLshort x, GLshort y, GLshort z) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream3sATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream3sATI = extproc; glVertexStream3sATI(stream, x, y, z); } static void APIENTRY InitVertexStream3svATI (GLenum stream, const GLshort *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream3svATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream3svATI = extproc; glVertexStream3svATI(stream, coords); } static void APIENTRY InitVertexStream3iATI (GLenum stream, GLint x, GLint y, GLint z) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream3iATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream3iATI = extproc; glVertexStream3iATI(stream, x, y, z); } static void APIENTRY InitVertexStream3ivATI (GLenum stream, const GLint *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream3ivATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream3ivATI = extproc; glVertexStream3ivATI(stream, coords); } static void APIENTRY InitVertexStream3fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream3fATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream3fATI = extproc; glVertexStream3fATI(stream, x, y, z); } static void APIENTRY InitVertexStream3fvATI (GLenum stream, const GLfloat *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream3fvATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream3fvATI = extproc; glVertexStream3fvATI(stream, coords); } static void APIENTRY InitVertexStream3dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream3dATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream3dATI = extproc; glVertexStream3dATI(stream, x, y, z); } static void APIENTRY InitVertexStream3dvATI (GLenum stream, const GLdouble *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream3dvATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream3dvATI = extproc; glVertexStream3dvATI(stream, coords); } static void APIENTRY InitVertexStream4sATI (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream4sATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream4sATI = extproc; glVertexStream4sATI(stream, x, y, z, w); } static void APIENTRY InitVertexStream4svATI (GLenum stream, const GLshort *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream4svATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream4svATI = extproc; glVertexStream4svATI(stream, coords); } static void APIENTRY InitVertexStream4iATI (GLenum stream, GLint x, GLint y, GLint z, GLint w) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream4iATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream4iATI = extproc; glVertexStream4iATI(stream, x, y, z, w); } static void APIENTRY InitVertexStream4ivATI (GLenum stream, const GLint *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream4ivATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream4ivATI = extproc; glVertexStream4ivATI(stream, coords); } static void APIENTRY InitVertexStream4fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream4fATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream4fATI = extproc; glVertexStream4fATI(stream, x, y, z, w); } static void APIENTRY InitVertexStream4fvATI (GLenum stream, const GLfloat *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream4fvATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream4fvATI = extproc; glVertexStream4fvATI(stream, coords); } static void APIENTRY InitVertexStream4dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream4dATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream4dATI = extproc; glVertexStream4dATI(stream, x, y, z, w); } static void APIENTRY InitVertexStream4dvATI (GLenum stream, const GLdouble *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexStream4dvATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexStream4dvATI = extproc; glVertexStream4dvATI(stream, coords); } static void APIENTRY InitNormalStream3bATI (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz) { void *extproc; extproc = (void *) wglGetProcAddress("glNormalStream3bATI"); if (extproc == NULL) { _ASSERT(0); return; } glNormalStream3bATI = extproc; glNormalStream3bATI(stream, nx, ny, nz); } static void APIENTRY InitNormalStream3bvATI (GLenum stream, const GLbyte *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glNormalStream3bvATI"); if (extproc == NULL) { _ASSERT(0); return; } glNormalStream3bvATI = extproc; glNormalStream3bvATI(stream, coords); } static void APIENTRY InitNormalStream3sATI (GLenum stream, GLshort nx, GLshort ny, GLshort nz) { void *extproc; extproc = (void *) wglGetProcAddress("glNormalStream3sATI"); if (extproc == NULL) { _ASSERT(0); return; } glNormalStream3sATI = extproc; glNormalStream3sATI(stream, nx, ny, nz); } static void APIENTRY InitNormalStream3svATI (GLenum stream, const GLshort *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glNormalStream3svATI"); if (extproc == NULL) { _ASSERT(0); return; } glNormalStream3svATI = extproc; glNormalStream3svATI(stream, coords); } static void APIENTRY InitNormalStream3iATI (GLenum stream, GLint nx, GLint ny, GLint nz) { void *extproc; extproc = (void *) wglGetProcAddress("glNormalStream3iATI"); if (extproc == NULL) { _ASSERT(0); return; } glNormalStream3iATI = extproc; glNormalStream3iATI(stream, nx, ny, nz); } static void APIENTRY InitNormalStream3ivATI (GLenum stream, const GLint *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glNormalStream3ivATI"); if (extproc == NULL) { _ASSERT(0); return; } glNormalStream3ivATI = extproc; glNormalStream3ivATI(stream, coords); } static void APIENTRY InitNormalStream3fATI (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz) { void *extproc; extproc = (void *) wglGetProcAddress("glNormalStream3fATI"); if (extproc == NULL) { _ASSERT(0); return; } glNormalStream3fATI = extproc; glNormalStream3fATI(stream, nx, ny, nz); } static void APIENTRY InitNormalStream3fvATI (GLenum stream, const GLfloat *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glNormalStream3fvATI"); if (extproc == NULL) { _ASSERT(0); return; } glNormalStream3fvATI = extproc; glNormalStream3fvATI(stream, coords); } static void APIENTRY InitNormalStream3dATI (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz) { void *extproc; extproc = (void *) wglGetProcAddress("glNormalStream3dATI"); if (extproc == NULL) { _ASSERT(0); return; } glNormalStream3dATI = extproc; glNormalStream3dATI(stream, nx, ny, nz); } static void APIENTRY InitNormalStream3dvATI (GLenum stream, const GLdouble *coords) { void *extproc; extproc = (void *) wglGetProcAddress("glNormalStream3dvATI"); if (extproc == NULL) { _ASSERT(0); return; } glNormalStream3dvATI = extproc; glNormalStream3dvATI(stream, coords); } static void APIENTRY InitClientActiveVertexStreamATI (GLenum stream) { void *extproc; extproc = (void *) wglGetProcAddress("glClientActiveVertexStreamATI"); if (extproc == NULL) { _ASSERT(0); return; } glClientActiveVertexStreamATI = extproc; glClientActiveVertexStreamATI(stream); } static void APIENTRY InitVertexBlendEnviATI (GLenum pname, GLint param) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexBlendEnviATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexBlendEnviATI = extproc; glVertexBlendEnviATI(pname, param); } static void APIENTRY InitVertexBlendEnvfATI (GLenum pname, GLfloat param) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexBlendEnvfATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexBlendEnvfATI = extproc; glVertexBlendEnvfATI(pname, param); } static void APIENTRY InitElementPointerATI (GLenum type, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glElementPointerATI"); if (extproc == NULL) { _ASSERT(0); return; } glElementPointerATI = extproc; glElementPointerATI(type, pointer); } static void APIENTRY InitDrawElementArrayATI (GLenum mode, GLsizei count) { void *extproc; extproc = (void *) wglGetProcAddress("glDrawElementArrayATI"); if (extproc == NULL) { _ASSERT(0); return; } glDrawElementArrayATI = extproc; glDrawElementArrayATI(mode, count); } static void APIENTRY InitDrawRangeElementArrayATI (GLenum mode, GLuint start, GLuint end, GLsizei count) { void *extproc; extproc = (void *) wglGetProcAddress("glDrawRangeElementArrayATI"); if (extproc == NULL) { _ASSERT(0); return; } glDrawRangeElementArrayATI = extproc; glDrawRangeElementArrayATI(mode, start, end, count); } static void APIENTRY InitDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width) { void *extproc; extproc = (void *) wglGetProcAddress("glDrawMeshArraysSUN"); if (extproc == NULL) { _ASSERT(0); return; } glDrawMeshArraysSUN = extproc; glDrawMeshArraysSUN(mode, first, count, width); } static void APIENTRY InitGenOcclusionQueriesNV (GLsizei n, GLuint *ids) { void *extproc; extproc = (void *) wglGetProcAddress("glGenOcclusionQueriesNV"); if (extproc == NULL) { _ASSERT(0); return; } glGenOcclusionQueriesNV = extproc; glGenOcclusionQueriesNV(n, ids); } static void APIENTRY InitDeleteOcclusionQueriesNV (GLsizei n, const GLuint *ids) { void *extproc; extproc = (void *) wglGetProcAddress("glDeleteOcclusionQueriesNV"); if (extproc == NULL) { _ASSERT(0); return; } glDeleteOcclusionQueriesNV = extproc; glDeleteOcclusionQueriesNV(n, ids); } static GLboolean APIENTRY InitIsOcclusionQueryNV (GLuint id) { void *extproc; extproc = (void *) wglGetProcAddress("glIsOcclusionQueryNV"); if (extproc == NULL) { _ASSERT(0); return 0; } glIsOcclusionQueryNV = extproc; return glIsOcclusionQueryNV(id); } static void APIENTRY InitBeginOcclusionQueryNV (GLuint id) { void *extproc; extproc = (void *) wglGetProcAddress("glBeginOcclusionQueryNV"); if (extproc == NULL) { _ASSERT(0); return; } glBeginOcclusionQueryNV = extproc; glBeginOcclusionQueryNV(id); } static void APIENTRY InitEndOcclusionQueryNV (void) { void *extproc; extproc = (void *) wglGetProcAddress("glEndOcclusionQueryNV"); if (extproc == NULL) { _ASSERT(0); return; } glEndOcclusionQueryNV = extproc; glEndOcclusionQueryNV(); } static void APIENTRY InitGetOcclusionQueryivNV (GLuint id, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetOcclusionQueryivNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetOcclusionQueryivNV = extproc; glGetOcclusionQueryivNV(id, pname, params); } static void APIENTRY InitGetOcclusionQueryuivNV (GLuint id, GLenum pname, GLuint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetOcclusionQueryuivNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetOcclusionQueryuivNV = extproc; glGetOcclusionQueryuivNV(id, pname, params); } static void APIENTRY InitPointParameteriNV (GLenum pname, GLint param) { void *extproc; extproc = (void *) wglGetProcAddress("glPointParameteriNV"); if (extproc == NULL) { _ASSERT(0); return; } glPointParameteriNV = extproc; glPointParameteriNV(pname, param); } static void APIENTRY InitPointParameterivNV (GLenum pname, const GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glPointParameterivNV"); if (extproc == NULL) { _ASSERT(0); return; } glPointParameterivNV = extproc; glPointParameterivNV(pname, params); } static void APIENTRY InitActiveStencilFaceEXT (GLenum face) { void *extproc; extproc = (void *) wglGetProcAddress("glActiveStencilFaceEXT"); if (extproc == NULL) { _ASSERT(0); return; } glActiveStencilFaceEXT = extproc; glActiveStencilFaceEXT(face); } static void APIENTRY InitElementPointerAPPLE (GLenum type, const GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glElementPointerAPPLE"); if (extproc == NULL) { _ASSERT(0); return; } glElementPointerAPPLE = extproc; glElementPointerAPPLE(type, pointer); } static void APIENTRY InitDrawElementArrayAPPLE (GLenum mode, GLint first, GLsizei count) { void *extproc; extproc = (void *) wglGetProcAddress("glDrawElementArrayAPPLE"); if (extproc == NULL) { _ASSERT(0); return; } glDrawElementArrayAPPLE = extproc; glDrawElementArrayAPPLE(mode, first, count); } static void APIENTRY InitDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count) { void *extproc; extproc = (void *) wglGetProcAddress("glDrawRangeElementArrayAPPLE"); if (extproc == NULL) { _ASSERT(0); return; } glDrawRangeElementArrayAPPLE = extproc; glDrawRangeElementArrayAPPLE(mode, start, end, first, count); } static void APIENTRY InitMultiDrawElementArrayAPPLE (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiDrawElementArrayAPPLE"); if (extproc == NULL) { _ASSERT(0); return; } glMultiDrawElementArrayAPPLE = extproc; glMultiDrawElementArrayAPPLE(mode, first, count, primcount); } static void APIENTRY InitMultiDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiDrawRangeElementArrayAPPLE"); if (extproc == NULL) { _ASSERT(0); return; } glMultiDrawRangeElementArrayAPPLE = extproc; glMultiDrawRangeElementArrayAPPLE(mode, start, end, first, count, primcount); } static void APIENTRY InitGenFencesAPPLE (GLsizei n, GLuint *fences) { void *extproc; extproc = (void *) wglGetProcAddress("glGenFencesAPPLE"); if (extproc == NULL) { _ASSERT(0); return; } glGenFencesAPPLE = extproc; glGenFencesAPPLE(n, fences); } static void APIENTRY InitDeleteFencesAPPLE (GLsizei n, const GLuint *fences) { void *extproc; extproc = (void *) wglGetProcAddress("glDeleteFencesAPPLE"); if (extproc == NULL) { _ASSERT(0); return; } glDeleteFencesAPPLE = extproc; glDeleteFencesAPPLE(n, fences); } static void APIENTRY InitSetFenceAPPLE (GLuint fence) { void *extproc; extproc = (void *) wglGetProcAddress("glSetFenceAPPLE"); if (extproc == NULL) { _ASSERT(0); return; } glSetFenceAPPLE = extproc; glSetFenceAPPLE(fence); } static GLboolean APIENTRY InitIsFenceAPPLE (GLuint fence) { void *extproc; extproc = (void *) wglGetProcAddress("glIsFenceAPPLE"); if (extproc == NULL) { _ASSERT(0); return 0; } glIsFenceAPPLE = extproc; return glIsFenceAPPLE(fence); } static GLboolean APIENTRY InitTestFenceAPPLE (GLuint fence) { void *extproc; extproc = (void *) wglGetProcAddress("glTestFenceAPPLE"); if (extproc == NULL) { _ASSERT(0); return 0; } glTestFenceAPPLE = extproc; return glTestFenceAPPLE(fence); } static void APIENTRY InitFinishFenceAPPLE (GLuint fence) { void *extproc; extproc = (void *) wglGetProcAddress("glFinishFenceAPPLE"); if (extproc == NULL) { _ASSERT(0); return; } glFinishFenceAPPLE = extproc; glFinishFenceAPPLE(fence); } static GLboolean APIENTRY InitTestObjectAPPLE (GLenum object, GLuint name) { void *extproc; extproc = (void *) wglGetProcAddress("glTestObjectAPPLE"); if (extproc == NULL) { _ASSERT(0); return 0; } glTestObjectAPPLE = extproc; return glTestObjectAPPLE(object, name); } static void APIENTRY InitFinishObjectAPPLE (GLenum object, GLint name) { void *extproc; extproc = (void *) wglGetProcAddress("glFinishObjectAPPLE"); if (extproc == NULL) { _ASSERT(0); return; } glFinishObjectAPPLE = extproc; glFinishObjectAPPLE(object, name); } static void APIENTRY InitBindVertexArrayAPPLE (GLuint array) { void *extproc; extproc = (void *) wglGetProcAddress("glBindVertexArrayAPPLE"); if (extproc == NULL) { _ASSERT(0); return; } glBindVertexArrayAPPLE = extproc; glBindVertexArrayAPPLE(array); } static void APIENTRY InitDeleteVertexArraysAPPLE (GLsizei n, const GLuint *arrays) { void *extproc; extproc = (void *) wglGetProcAddress("glDeleteVertexArraysAPPLE"); if (extproc == NULL) { _ASSERT(0); return; } glDeleteVertexArraysAPPLE = extproc; glDeleteVertexArraysAPPLE(n, arrays); } static void APIENTRY InitGenVertexArraysAPPLE (GLsizei n, const GLuint *arrays) { void *extproc; extproc = (void *) wglGetProcAddress("glGenVertexArraysAPPLE"); if (extproc == NULL) { _ASSERT(0); return; } glGenVertexArraysAPPLE = extproc; glGenVertexArraysAPPLE(n, arrays); } static GLboolean APIENTRY InitIsVertexArrayAPPLE (GLuint array) { void *extproc; extproc = (void *) wglGetProcAddress("glIsVertexArrayAPPLE"); if (extproc == NULL) { _ASSERT(0); return 0; } glIsVertexArrayAPPLE = extproc; return glIsVertexArrayAPPLE(array); } static void APIENTRY InitVertexArrayRangeAPPLE (GLsizei length, GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexArrayRangeAPPLE"); if (extproc == NULL) { _ASSERT(0); return; } glVertexArrayRangeAPPLE = extproc; glVertexArrayRangeAPPLE(length, pointer); } static void APIENTRY InitFlushVertexArrayRangeAPPLE (GLsizei length, GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glFlushVertexArrayRangeAPPLE"); if (extproc == NULL) { _ASSERT(0); return; } glFlushVertexArrayRangeAPPLE = extproc; glFlushVertexArrayRangeAPPLE(length, pointer); } static void APIENTRY InitVertexArrayParameteriAPPLE (GLenum pname, GLint param) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexArrayParameteriAPPLE"); if (extproc == NULL) { _ASSERT(0); return; } glVertexArrayParameteriAPPLE = extproc; glVertexArrayParameteriAPPLE(pname, param); } static void APIENTRY InitDrawBuffersATI (GLsizei n, const GLenum *bufs) { void *extproc; extproc = (void *) wglGetProcAddress("glDrawBuffersATI"); if (extproc == NULL) { _ASSERT(0); return; } glDrawBuffersATI = extproc; glDrawBuffersATI(n, bufs); } static void APIENTRY InitProgramNamedParameter4fNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramNamedParameter4fNV"); if (extproc == NULL) { _ASSERT(0); return; } glProgramNamedParameter4fNV = extproc; glProgramNamedParameter4fNV(id, len, name, x, y, z, w); } static void APIENTRY InitProgramNamedParameter4dNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramNamedParameter4dNV"); if (extproc == NULL) { _ASSERT(0); return; } glProgramNamedParameter4dNV = extproc; glProgramNamedParameter4dNV(id, len, name, x, y, z, w); } static void APIENTRY InitProgramNamedParameter4fvNV (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramNamedParameter4fvNV"); if (extproc == NULL) { _ASSERT(0); return; } glProgramNamedParameter4fvNV = extproc; glProgramNamedParameter4fvNV(id, len, name, v); } static void APIENTRY InitProgramNamedParameter4dvNV (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v) { void *extproc; extproc = (void *) wglGetProcAddress("glProgramNamedParameter4dvNV"); if (extproc == NULL) { _ASSERT(0); return; } glProgramNamedParameter4dvNV = extproc; glProgramNamedParameter4dvNV(id, len, name, v); } static void APIENTRY InitGetProgramNamedParameterfvNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetProgramNamedParameterfvNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetProgramNamedParameterfvNV = extproc; glGetProgramNamedParameterfvNV(id, len, name, params); } static void APIENTRY InitGetProgramNamedParameterdvNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetProgramNamedParameterdvNV"); if (extproc == NULL) { _ASSERT(0); return; } glGetProgramNamedParameterdvNV = extproc; glGetProgramNamedParameterdvNV(id, len, name, params); } static void APIENTRY InitVertex2hNV (GLhalfNV x, GLhalfNV y) { void *extproc; extproc = (void *) wglGetProcAddress("glVertex2hNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertex2hNV = extproc; glVertex2hNV(x, y); } static void APIENTRY InitVertex2hvNV (const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertex2hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertex2hvNV = extproc; glVertex2hvNV(v); } static void APIENTRY InitVertex3hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z) { void *extproc; extproc = (void *) wglGetProcAddress("glVertex3hNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertex3hNV = extproc; glVertex3hNV(x, y, z); } static void APIENTRY InitVertex3hvNV (const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertex3hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertex3hvNV = extproc; glVertex3hvNV(v); } static void APIENTRY InitVertex4hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w) { void *extproc; extproc = (void *) wglGetProcAddress("glVertex4hNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertex4hNV = extproc; glVertex4hNV(x, y, z, w); } static void APIENTRY InitVertex4hvNV (const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertex4hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertex4hvNV = extproc; glVertex4hvNV(v); } static void APIENTRY InitNormal3hNV (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz) { void *extproc; extproc = (void *) wglGetProcAddress("glNormal3hNV"); if (extproc == NULL) { _ASSERT(0); return; } glNormal3hNV = extproc; glNormal3hNV(nx, ny, nz); } static void APIENTRY InitNormal3hvNV (const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glNormal3hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glNormal3hvNV = extproc; glNormal3hvNV(v); } static void APIENTRY InitColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue) { void *extproc; extproc = (void *) wglGetProcAddress("glColor3hNV"); if (extproc == NULL) { _ASSERT(0); return; } glColor3hNV = extproc; glColor3hNV(red, green, blue); } static void APIENTRY InitColor3hvNV (const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glColor3hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glColor3hvNV = extproc; glColor3hvNV(v); } static void APIENTRY InitColor4hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha) { void *extproc; extproc = (void *) wglGetProcAddress("glColor4hNV"); if (extproc == NULL) { _ASSERT(0); return; } glColor4hNV = extproc; glColor4hNV(red, green, blue, alpha); } static void APIENTRY InitColor4hvNV (const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glColor4hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glColor4hvNV = extproc; glColor4hvNV(v); } static void APIENTRY InitTexCoord1hNV (GLhalfNV s) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord1hNV"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord1hNV = extproc; glTexCoord1hNV(s); } static void APIENTRY InitTexCoord1hvNV (const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord1hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord1hvNV = extproc; glTexCoord1hvNV(v); } static void APIENTRY InitTexCoord2hNV (GLhalfNV s, GLhalfNV t) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord2hNV"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord2hNV = extproc; glTexCoord2hNV(s, t); } static void APIENTRY InitTexCoord2hvNV (const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord2hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord2hvNV = extproc; glTexCoord2hvNV(v); } static void APIENTRY InitTexCoord3hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord3hNV"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord3hNV = extproc; glTexCoord3hNV(s, t, r); } static void APIENTRY InitTexCoord3hvNV (const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord3hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord3hvNV = extproc; glTexCoord3hvNV(v); } static void APIENTRY InitTexCoord4hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord4hNV"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord4hNV = extproc; glTexCoord4hNV(s, t, r, q); } static void APIENTRY InitTexCoord4hvNV (const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glTexCoord4hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glTexCoord4hvNV = extproc; glTexCoord4hvNV(v); } static void APIENTRY InitMultiTexCoord1hNV (GLenum target, GLhalfNV s) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1hNV"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1hNV = extproc; glMultiTexCoord1hNV(target, s); } static void APIENTRY InitMultiTexCoord1hvNV (GLenum target, const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord1hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord1hvNV = extproc; glMultiTexCoord1hvNV(target, v); } static void APIENTRY InitMultiTexCoord2hNV (GLenum target, GLhalfNV s, GLhalfNV t) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2hNV"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2hNV = extproc; glMultiTexCoord2hNV(target, s, t); } static void APIENTRY InitMultiTexCoord2hvNV (GLenum target, const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord2hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord2hvNV = extproc; glMultiTexCoord2hvNV(target, v); } static void APIENTRY InitMultiTexCoord3hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3hNV"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3hNV = extproc; glMultiTexCoord3hNV(target, s, t, r); } static void APIENTRY InitMultiTexCoord3hvNV (GLenum target, const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord3hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord3hvNV = extproc; glMultiTexCoord3hvNV(target, v); } static void APIENTRY InitMultiTexCoord4hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4hNV"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4hNV = extproc; glMultiTexCoord4hNV(target, s, t, r, q); } static void APIENTRY InitMultiTexCoord4hvNV (GLenum target, const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glMultiTexCoord4hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glMultiTexCoord4hvNV = extproc; glMultiTexCoord4hvNV(target, v); } static void APIENTRY InitFogCoordhNV (GLhalfNV fog) { void *extproc; extproc = (void *) wglGetProcAddress("glFogCoordhNV"); if (extproc == NULL) { _ASSERT(0); return; } glFogCoordhNV = extproc; glFogCoordhNV(fog); } static void APIENTRY InitFogCoordhvNV (const GLhalfNV *fog) { void *extproc; extproc = (void *) wglGetProcAddress("glFogCoordhvNV"); if (extproc == NULL) { _ASSERT(0); return; } glFogCoordhvNV = extproc; glFogCoordhvNV(fog); } static void APIENTRY InitSecondaryColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3hNV"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3hNV = extproc; glSecondaryColor3hNV(red, green, blue); } static void APIENTRY InitSecondaryColor3hvNV (const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glSecondaryColor3hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glSecondaryColor3hvNV = extproc; glSecondaryColor3hvNV(v); } static void APIENTRY InitVertexWeighthNV (GLhalfNV weight) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexWeighthNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexWeighthNV = extproc; glVertexWeighthNV(weight); } static void APIENTRY InitVertexWeighthvNV (const GLhalfNV *weight) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexWeighthvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexWeighthvNV = extproc; glVertexWeighthvNV(weight); } static void APIENTRY InitVertexAttrib1hNV (GLuint index, GLhalfNV x) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib1hNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib1hNV = extproc; glVertexAttrib1hNV(index, x); } static void APIENTRY InitVertexAttrib1hvNV (GLuint index, const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib1hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib1hvNV = extproc; glVertexAttrib1hvNV(index, v); } static void APIENTRY InitVertexAttrib2hNV (GLuint index, GLhalfNV x, GLhalfNV y) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib2hNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib2hNV = extproc; glVertexAttrib2hNV(index, x, y); } static void APIENTRY InitVertexAttrib2hvNV (GLuint index, const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib2hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib2hvNV = extproc; glVertexAttrib2hvNV(index, v); } static void APIENTRY InitVertexAttrib3hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib3hNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib3hNV = extproc; glVertexAttrib3hNV(index, x, y, z); } static void APIENTRY InitVertexAttrib3hvNV (GLuint index, const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib3hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib3hvNV = extproc; glVertexAttrib3hvNV(index, v); } static void APIENTRY InitVertexAttrib4hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4hNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4hNV = extproc; glVertexAttrib4hNV(index, x, y, z, w); } static void APIENTRY InitVertexAttrib4hvNV (GLuint index, const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttrib4hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttrib4hvNV = extproc; glVertexAttrib4hvNV(index, v); } static void APIENTRY InitVertexAttribs1hvNV (GLuint index, GLsizei n, const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribs1hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribs1hvNV = extproc; glVertexAttribs1hvNV(index, n, v); } static void APIENTRY InitVertexAttribs2hvNV (GLuint index, GLsizei n, const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribs2hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribs2hvNV = extproc; glVertexAttribs2hvNV(index, n, v); } static void APIENTRY InitVertexAttribs3hvNV (GLuint index, GLsizei n, const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribs3hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribs3hvNV = extproc; glVertexAttribs3hvNV(index, n, v); } static void APIENTRY InitVertexAttribs4hvNV (GLuint index, GLsizei n, const GLhalfNV *v) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribs4hvNV"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribs4hvNV = extproc; glVertexAttribs4hvNV(index, n, v); } static void APIENTRY InitPixelDataRangeNV (GLenum target, GLsizei length, GLvoid *pointer) { void *extproc; extproc = (void *) wglGetProcAddress("glPixelDataRangeNV"); if (extproc == NULL) { _ASSERT(0); return; } glPixelDataRangeNV = extproc; glPixelDataRangeNV(target, length, pointer); } static void APIENTRY InitFlushPixelDataRangeNV (GLenum target) { void *extproc; extproc = (void *) wglGetProcAddress("glFlushPixelDataRangeNV"); if (extproc == NULL) { _ASSERT(0); return; } glFlushPixelDataRangeNV = extproc; glFlushPixelDataRangeNV(target); } static void APIENTRY InitPrimitiveRestartNV (void) { void *extproc; extproc = (void *) wglGetProcAddress("glPrimitiveRestartNV"); if (extproc == NULL) { _ASSERT(0); return; } glPrimitiveRestartNV = extproc; glPrimitiveRestartNV(); } static void APIENTRY InitPrimitiveRestartIndexNV (GLuint index) { void *extproc; extproc = (void *) wglGetProcAddress("glPrimitiveRestartIndexNV"); if (extproc == NULL) { _ASSERT(0); return; } glPrimitiveRestartIndexNV = extproc; glPrimitiveRestartIndexNV(index); } static GLvoid* APIENTRY InitMapObjectBufferATI (GLuint buffer) { void *extproc; extproc = (void *) wglGetProcAddress("glMapObjectBufferATI"); if (extproc == NULL) { _ASSERT(0); return 0; } glMapObjectBufferATI = extproc; return glMapObjectBufferATI(buffer); } static void APIENTRY InitUnmapObjectBufferATI (GLuint buffer) { void *extproc; extproc = (void *) wglGetProcAddress("glUnmapObjectBufferATI"); if (extproc == NULL) { _ASSERT(0); return; } glUnmapObjectBufferATI = extproc; glUnmapObjectBufferATI(buffer); } static void APIENTRY InitStencilOpSeparateATI (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) { void *extproc; extproc = (void *) wglGetProcAddress("glStencilOpSeparateATI"); if (extproc == NULL) { _ASSERT(0); return; } glStencilOpSeparateATI = extproc; glStencilOpSeparateATI(face, sfail, dpfail, dppass); } static void APIENTRY InitStencilFuncSeparateATI (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask) { void *extproc; extproc = (void *) wglGetProcAddress("glStencilFuncSeparateATI"); if (extproc == NULL) { _ASSERT(0); return; } glStencilFuncSeparateATI = extproc; glStencilFuncSeparateATI(frontfunc, backfunc, ref, mask); } static void APIENTRY InitVertexAttribArrayObjectATI (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset) { void *extproc; extproc = (void *) wglGetProcAddress("glVertexAttribArrayObjectATI"); if (extproc == NULL) { _ASSERT(0); return; } glVertexAttribArrayObjectATI = extproc; glVertexAttribArrayObjectATI(index, size, type, normalized, stride, buffer, offset); } static void APIENTRY InitGetVertexAttribArrayObjectfvATI (GLuint index, GLenum pname, GLfloat *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetVertexAttribArrayObjectfvATI"); if (extproc == NULL) { _ASSERT(0); return; } glGetVertexAttribArrayObjectfvATI = extproc; glGetVertexAttribArrayObjectfvATI(index, pname, params); } static void APIENTRY InitGetVertexAttribArrayObjectivATI (GLuint index, GLenum pname, GLint *params) { void *extproc; extproc = (void *) wglGetProcAddress("glGetVertexAttribArrayObjectivATI"); if (extproc == NULL) { _ASSERT(0); return; } glGetVertexAttribArrayObjectivATI = extproc; glGetVertexAttribArrayObjectivATI(index, pname, params); } static void APIENTRY InitDepthBoundsEXT (GLclampd zmin, GLclampd zmax) { void *extproc; extproc = (void *) wglGetProcAddress("glDepthBoundsEXT"); if (extproc == NULL) { _ASSERT(0); return; } glDepthBoundsEXT = extproc; glDepthBoundsEXT(zmin, zmax); } static void APIENTRY InitBlendEquationSeparateEXT (GLenum modeRGB, GLenum modeAlpha) { void *extproc; extproc = (void *) wglGetProcAddress("glBlendEquationSeparateEXT"); if (extproc == NULL) { _ASSERT(0); return; } glBlendEquationSeparateEXT = extproc; glBlendEquationSeparateEXT(modeRGB, modeAlpha); } static void APIENTRY InitAddSwapHintRectWIN (GLint x, GLint y, GLsizei width, GLsizei height) { void *extproc; extproc = (void *) wglGetProcAddress("glAddSwapHintRectWIN"); if (extproc == NULL) { _ASSERT(0); return; } glAddSwapHintRectWIN = extproc; glAddSwapHintRectWIN(x, y, width, height); } #ifdef _WIN32 static HANDLE WINAPI InitCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType) { void *extproc; extproc = (void *) wglGetProcAddress("wglCreateBufferRegionARB"); if (extproc == NULL) { _ASSERT(0); return 0; } wglCreateBufferRegionARB = extproc; return wglCreateBufferRegionARB(hDC, iLayerPlane, uType); } static VOID WINAPI InitDeleteBufferRegionARB (HANDLE hRegion) { void *extproc; extproc = (void *) wglGetProcAddress("wglDeleteBufferRegionARB"); if (extproc == NULL) { _ASSERT(0); return; } wglDeleteBufferRegionARB = extproc; wglDeleteBufferRegionARB(hRegion); } static BOOL WINAPI InitSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height) { void *extproc; extproc = (void *) wglGetProcAddress("wglSaveBufferRegionARB"); if (extproc == NULL) { _ASSERT(0); return 0; } wglSaveBufferRegionARB = extproc; return wglSaveBufferRegionARB(hRegion, x, y, width, height); } static BOOL WINAPI InitRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc) { void *extproc; extproc = (void *) wglGetProcAddress("wglRestoreBufferRegionARB"); if (extproc == NULL) { _ASSERT(0); return 0; } wglRestoreBufferRegionARB = extproc; return wglRestoreBufferRegionARB(hRegion, x, y, width, height, xSrc, ySrc); } static const WINAPI InitGetExtensionsStringARB (HDC hdc) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetExtensionsStringARB"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetExtensionsStringARB = extproc; return wglGetExtensionsStringARB(hdc); } static BOOL WINAPI InitGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetPixelFormatAttribivARB"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetPixelFormatAttribivARB = extproc; return wglGetPixelFormatAttribivARB(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues); } static BOOL WINAPI InitGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetPixelFormatAttribfvARB"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetPixelFormatAttribfvARB = extproc; return wglGetPixelFormatAttribfvARB(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues); } static BOOL WINAPI InitChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats) { void *extproc; extproc = (void *) wglGetProcAddress("wglChoosePixelFormatARB"); if (extproc == NULL) { _ASSERT(0); return 0; } wglChoosePixelFormatARB = extproc; return wglChoosePixelFormatARB(hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats); } static BOOL WINAPI InitMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc) { void *extproc; extproc = (void *) wglGetProcAddress("wglMakeContextCurrentARB"); if (extproc == NULL) { _ASSERT(0); return 0; } wglMakeContextCurrentARB = extproc; return wglMakeContextCurrentARB(hDrawDC, hReadDC, hglrc); } static HDC WINAPI InitGetCurrentReadDCARB (void) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetCurrentReadDCARB"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetCurrentReadDCARB = extproc; return wglGetCurrentReadDCARB(); } static HPBUFFERARB WINAPI InitCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList) { void *extproc; extproc = (void *) wglGetProcAddress("wglCreatePbufferARB"); if (extproc == NULL) { _ASSERT(0); return 0; } wglCreatePbufferARB = extproc; return wglCreatePbufferARB(hDC, iPixelFormat, iWidth, iHeight, piAttribList); } static HDC WINAPI InitGetPbufferDCARB (HPBUFFERARB hPbuffer) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetPbufferDCARB"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetPbufferDCARB = extproc; return wglGetPbufferDCARB(hPbuffer); } static int WINAPI InitReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC) { void *extproc; extproc = (void *) wglGetProcAddress("wglReleasePbufferDCARB"); if (extproc == NULL) { _ASSERT(0); return 0; } wglReleasePbufferDCARB = extproc; return wglReleasePbufferDCARB(hPbuffer, hDC); } static BOOL WINAPI InitDestroyPbufferARB (HPBUFFERARB hPbuffer) { void *extproc; extproc = (void *) wglGetProcAddress("wglDestroyPbufferARB"); if (extproc == NULL) { _ASSERT(0); return 0; } wglDestroyPbufferARB = extproc; return wglDestroyPbufferARB(hPbuffer); } static BOOL WINAPI InitQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue) { void *extproc; extproc = (void *) wglGetProcAddress("wglQueryPbufferARB"); if (extproc == NULL) { _ASSERT(0); return 0; } wglQueryPbufferARB = extproc; return wglQueryPbufferARB(hPbuffer, iAttribute, piValue); } static BOOL WINAPI InitBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer) { void *extproc; extproc = (void *) wglGetProcAddress("wglBindTexImageARB"); if (extproc == NULL) { _ASSERT(0); return 0; } wglBindTexImageARB = extproc; return wglBindTexImageARB(hPbuffer, iBuffer); } static BOOL WINAPI InitReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer) { void *extproc; extproc = (void *) wglGetProcAddress("wglReleaseTexImageARB"); if (extproc == NULL) { _ASSERT(0); return 0; } wglReleaseTexImageARB = extproc; return wglReleaseTexImageARB(hPbuffer, iBuffer); } static BOOL WINAPI InitSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList) { void *extproc; extproc = (void *) wglGetProcAddress("wglSetPbufferAttribARB"); if (extproc == NULL) { _ASSERT(0); return 0; } wglSetPbufferAttribARB = extproc; return wglSetPbufferAttribARB(hPbuffer, piAttribList); } static GLboolean WINAPI InitCreateDisplayColorTableEXT (GLushort id) { void *extproc; extproc = (void *) wglGetProcAddress("wglCreateDisplayColorTableEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } wglCreateDisplayColorTableEXT = extproc; return wglCreateDisplayColorTableEXT(id); } static GLboolean WINAPI InitLoadDisplayColorTableEXT (const GLushort *table, GLuint length) { void *extproc; extproc = (void *) wglGetProcAddress("wglLoadDisplayColorTableEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } wglLoadDisplayColorTableEXT = extproc; return wglLoadDisplayColorTableEXT(table, length); } static GLboolean WINAPI InitBindDisplayColorTableEXT (GLushort id) { void *extproc; extproc = (void *) wglGetProcAddress("wglBindDisplayColorTableEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } wglBindDisplayColorTableEXT = extproc; return wglBindDisplayColorTableEXT(id); } static VOID WINAPI InitDestroyDisplayColorTableEXT (GLushort id) { void *extproc; extproc = (void *) wglGetProcAddress("wglDestroyDisplayColorTableEXT"); if (extproc == NULL) { _ASSERT(0); return; } wglDestroyDisplayColorTableEXT = extproc; wglDestroyDisplayColorTableEXT(id); } static const WINAPI InitGetExtensionsStringEXT (void) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetExtensionsStringEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetExtensionsStringEXT = extproc; return wglGetExtensionsStringEXT(); } static BOOL WINAPI InitMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc) { void *extproc; extproc = (void *) wglGetProcAddress("wglMakeContextCurrentEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } wglMakeContextCurrentEXT = extproc; return wglMakeContextCurrentEXT(hDrawDC, hReadDC, hglrc); } static HDC WINAPI InitGetCurrentReadDCEXT (void) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetCurrentReadDCEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetCurrentReadDCEXT = extproc; return wglGetCurrentReadDCEXT(); } static HPBUFFEREXT WINAPI InitCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList) { void *extproc; extproc = (void *) wglGetProcAddress("wglCreatePbufferEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } wglCreatePbufferEXT = extproc; return wglCreatePbufferEXT(hDC, iPixelFormat, iWidth, iHeight, piAttribList); } static HDC WINAPI InitGetPbufferDCEXT (HPBUFFEREXT hPbuffer) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetPbufferDCEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetPbufferDCEXT = extproc; return wglGetPbufferDCEXT(hPbuffer); } static int WINAPI InitReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC) { void *extproc; extproc = (void *) wglGetProcAddress("wglReleasePbufferDCEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } wglReleasePbufferDCEXT = extproc; return wglReleasePbufferDCEXT(hPbuffer, hDC); } static BOOL WINAPI InitDestroyPbufferEXT (HPBUFFEREXT hPbuffer) { void *extproc; extproc = (void *) wglGetProcAddress("wglDestroyPbufferEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } wglDestroyPbufferEXT = extproc; return wglDestroyPbufferEXT(hPbuffer); } static BOOL WINAPI InitQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue) { void *extproc; extproc = (void *) wglGetProcAddress("wglQueryPbufferEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } wglQueryPbufferEXT = extproc; return wglQueryPbufferEXT(hPbuffer, iAttribute, piValue); } static BOOL WINAPI InitGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetPixelFormatAttribivEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetPixelFormatAttribivEXT = extproc; return wglGetPixelFormatAttribivEXT(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues); } static BOOL WINAPI InitGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetPixelFormatAttribfvEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetPixelFormatAttribfvEXT = extproc; return wglGetPixelFormatAttribfvEXT(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues); } static BOOL WINAPI InitChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats) { void *extproc; extproc = (void *) wglGetProcAddress("wglChoosePixelFormatEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } wglChoosePixelFormatEXT = extproc; return wglChoosePixelFormatEXT(hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats); } static BOOL WINAPI InitSwapIntervalEXT (int interval) { void *extproc; extproc = (void *) wglGetProcAddress("wglSwapIntervalEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } wglSwapIntervalEXT = extproc; return wglSwapIntervalEXT(interval); } static int WINAPI InitGetSwapIntervalEXT (void) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetSwapIntervalEXT"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetSwapIntervalEXT = extproc; return wglGetSwapIntervalEXT(); } static void* WINAPI InitAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority) { void *extproc; extproc = (void *) wglGetProcAddress("wglAllocateMemoryNV"); if (extproc == NULL) { _ASSERT(0); return 0; } wglAllocateMemoryNV = extproc; return wglAllocateMemoryNV(size, readfreq, writefreq, priority); } static void WINAPI InitFreeMemoryNV (void) { void *extproc; extproc = (void *) wglGetProcAddress("wglFreeMemoryNV"); if (extproc == NULL) { _ASSERT(0); return; } wglFreeMemoryNV = extproc; wglFreeMemoryNV(); } static BOOL WINAPI InitGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetSyncValuesOML"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetSyncValuesOML = extproc; return wglGetSyncValuesOML(hdc, ust, msc, sbc); } static BOOL WINAPI InitGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetMscRateOML"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetMscRateOML = extproc; return wglGetMscRateOML(hdc, numerator, denominator); } static INT64 WINAPI InitSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder) { void *extproc; extproc = (void *) wglGetProcAddress("wglSwapBuffersMscOML"); if (extproc == NULL) { _ASSERT(0); return 0; } wglSwapBuffersMscOML = extproc; return wglSwapBuffersMscOML(hdc, target_msc, divisor, remainder); } static INT64 WINAPI InitSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder) { void *extproc; extproc = (void *) wglGetProcAddress("wglSwapLayerBuffersMscOML"); if (extproc == NULL) { _ASSERT(0); return 0; } wglSwapLayerBuffersMscOML = extproc; return wglSwapLayerBuffersMscOML(hdc, fuPlanes, target_msc, divisor, remainder); } static BOOL WINAPI InitWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc) { void *extproc; extproc = (void *) wglGetProcAddress("wglWaitForMscOML"); if (extproc == NULL) { _ASSERT(0); return 0; } wglWaitForMscOML = extproc; return wglWaitForMscOML(hdc, target_msc, divisor, remainder, ust, msc, sbc); } static BOOL WINAPI InitWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc) { void *extproc; extproc = (void *) wglGetProcAddress("wglWaitForSbcOML"); if (extproc == NULL) { _ASSERT(0); return 0; } wglWaitForSbcOML = extproc; return wglWaitForSbcOML(hdc, target_sbc, ust, msc, sbc); } static BOOL WINAPI InitGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetDigitalVideoParametersI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetDigitalVideoParametersI3D = extproc; return wglGetDigitalVideoParametersI3D(hDC, iAttribute, piValue); } static BOOL WINAPI InitSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue) { void *extproc; extproc = (void *) wglGetProcAddress("wglSetDigitalVideoParametersI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglSetDigitalVideoParametersI3D = extproc; return wglSetDigitalVideoParametersI3D(hDC, iAttribute, piValue); } static BOOL WINAPI InitGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetGammaTableParametersI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetGammaTableParametersI3D = extproc; return wglGetGammaTableParametersI3D(hDC, iAttribute, piValue); } static BOOL WINAPI InitSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue) { void *extproc; extproc = (void *) wglGetProcAddress("wglSetGammaTableParametersI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglSetGammaTableParametersI3D = extproc; return wglSetGammaTableParametersI3D(hDC, iAttribute, piValue); } static BOOL WINAPI InitGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetGammaTableI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetGammaTableI3D = extproc; return wglGetGammaTableI3D(hDC, iEntries, puRed, puGreen, puBlue); } static BOOL WINAPI InitSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue) { void *extproc; extproc = (void *) wglGetProcAddress("wglSetGammaTableI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglSetGammaTableI3D = extproc; return wglSetGammaTableI3D(hDC, iEntries, puRed, puGreen, puBlue); } static BOOL WINAPI InitEnableGenlockI3D (HDC hDC) { void *extproc; extproc = (void *) wglGetProcAddress("wglEnableGenlockI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglEnableGenlockI3D = extproc; return wglEnableGenlockI3D(hDC); } static BOOL WINAPI InitDisableGenlockI3D (HDC hDC) { void *extproc; extproc = (void *) wglGetProcAddress("wglDisableGenlockI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglDisableGenlockI3D = extproc; return wglDisableGenlockI3D(hDC); } static BOOL WINAPI InitIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag) { void *extproc; extproc = (void *) wglGetProcAddress("wglIsEnabledGenlockI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglIsEnabledGenlockI3D = extproc; return wglIsEnabledGenlockI3D(hDC, pFlag); } static BOOL WINAPI InitGenlockSourceI3D (HDC hDC, UINT uSource) { void *extproc; extproc = (void *) wglGetProcAddress("wglGenlockSourceI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGenlockSourceI3D = extproc; return wglGenlockSourceI3D(hDC, uSource); } static BOOL WINAPI InitGetGenlockSourceI3D (HDC hDC, UINT *uSource) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetGenlockSourceI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetGenlockSourceI3D = extproc; return wglGetGenlockSourceI3D(hDC, uSource); } static BOOL WINAPI InitGenlockSourceEdgeI3D (HDC hDC, UINT uEdge) { void *extproc; extproc = (void *) wglGetProcAddress("wglGenlockSourceEdgeI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGenlockSourceEdgeI3D = extproc; return wglGenlockSourceEdgeI3D(hDC, uEdge); } static BOOL WINAPI InitGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetGenlockSourceEdgeI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetGenlockSourceEdgeI3D = extproc; return wglGetGenlockSourceEdgeI3D(hDC, uEdge); } static BOOL WINAPI InitGenlockSampleRateI3D (HDC hDC, UINT uRate) { void *extproc; extproc = (void *) wglGetProcAddress("wglGenlockSampleRateI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGenlockSampleRateI3D = extproc; return wglGenlockSampleRateI3D(hDC, uRate); } static BOOL WINAPI InitGetGenlockSampleRateI3D (HDC hDC, UINT *uRate) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetGenlockSampleRateI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetGenlockSampleRateI3D = extproc; return wglGetGenlockSampleRateI3D(hDC, uRate); } static BOOL WINAPI InitGenlockSourceDelayI3D (HDC hDC, UINT uDelay) { void *extproc; extproc = (void *) wglGetProcAddress("wglGenlockSourceDelayI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGenlockSourceDelayI3D = extproc; return wglGenlockSourceDelayI3D(hDC, uDelay); } static BOOL WINAPI InitGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetGenlockSourceDelayI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetGenlockSourceDelayI3D = extproc; return wglGetGenlockSourceDelayI3D(hDC, uDelay); } static BOOL WINAPI InitQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay) { void *extproc; extproc = (void *) wglGetProcAddress("wglQueryGenlockMaxSourceDelayI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglQueryGenlockMaxSourceDelayI3D = extproc; return wglQueryGenlockMaxSourceDelayI3D(hDC, uMaxLineDelay, uMaxPixelDelay); } static LPVOID WINAPI InitCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags) { void *extproc; extproc = (void *) wglGetProcAddress("wglCreateImageBufferI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglCreateImageBufferI3D = extproc; return wglCreateImageBufferI3D(hDC, dwSize, uFlags); } static BOOL WINAPI InitDestroyImageBufferI3D (HDC hDC, LPVOID pAddress) { void *extproc; extproc = (void *) wglGetProcAddress("wglDestroyImageBufferI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglDestroyImageBufferI3D = extproc; return wglDestroyImageBufferI3D(hDC, pAddress); } static BOOL WINAPI InitAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count) { void *extproc; extproc = (void *) wglGetProcAddress("wglAssociateImageBufferEventsI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglAssociateImageBufferEventsI3D = extproc; return wglAssociateImageBufferEventsI3D(hDC, pEvent, pAddress, pSize, count); } static BOOL WINAPI InitReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count) { void *extproc; extproc = (void *) wglGetProcAddress("wglReleaseImageBufferEventsI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglReleaseImageBufferEventsI3D = extproc; return wglReleaseImageBufferEventsI3D(hDC, pAddress, count); } static BOOL WINAPI InitEnableFrameLockI3D (void) { void *extproc; extproc = (void *) wglGetProcAddress("wglEnableFrameLockI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglEnableFrameLockI3D = extproc; return wglEnableFrameLockI3D(); } static BOOL WINAPI InitDisableFrameLockI3D (void) { void *extproc; extproc = (void *) wglGetProcAddress("wglDisableFrameLockI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglDisableFrameLockI3D = extproc; return wglDisableFrameLockI3D(); } static BOOL WINAPI InitIsEnabledFrameLockI3D (BOOL *pFlag) { void *extproc; extproc = (void *) wglGetProcAddress("wglIsEnabledFrameLockI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglIsEnabledFrameLockI3D = extproc; return wglIsEnabledFrameLockI3D(pFlag); } static BOOL WINAPI InitQueryFrameLockMasterI3D (BOOL *pFlag) { void *extproc; extproc = (void *) wglGetProcAddress("wglQueryFrameLockMasterI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglQueryFrameLockMasterI3D = extproc; return wglQueryFrameLockMasterI3D(pFlag); } static BOOL WINAPI InitGetFrameUsageI3D (float *pUsage) { void *extproc; extproc = (void *) wglGetProcAddress("wglGetFrameUsageI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglGetFrameUsageI3D = extproc; return wglGetFrameUsageI3D(pUsage); } static BOOL WINAPI InitBeginFrameTrackingI3D (void) { void *extproc; extproc = (void *) wglGetProcAddress("wglBeginFrameTrackingI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglBeginFrameTrackingI3D = extproc; return wglBeginFrameTrackingI3D(); } static BOOL WINAPI InitEndFrameTrackingI3D (void) { void *extproc; extproc = (void *) wglGetProcAddress("wglEndFrameTrackingI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglEndFrameTrackingI3D = extproc; return wglEndFrameTrackingI3D(); } static BOOL WINAPI InitQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage) { void *extproc; extproc = (void *) wglGetProcAddress("wglQueryFrameTrackingI3D"); if (extproc == NULL) { _ASSERT(0); return 0; } wglQueryFrameTrackingI3D = extproc; return wglQueryFrameTrackingI3D(pFrameCount, pMissedFrames, pLastMissedUsage); } #endif /* _WIN32 */ _GLextensionProcs _extensionProcs = { InitBlendColor, InitBlendEquation, InitDrawRangeElements, InitColorTable, InitColorTableParameterfv, InitColorTableParameteriv, InitCopyColorTable, InitGetColorTable, InitGetColorTableParameterfv, InitGetColorTableParameteriv, InitColorSubTable, InitCopyColorSubTable, InitConvolutionFilter1D, InitConvolutionFilter2D, InitConvolutionParameterf, InitConvolutionParameterfv, InitConvolutionParameteri, InitConvolutionParameteriv, InitCopyConvolutionFilter1D, InitCopyConvolutionFilter2D, InitGetConvolutionFilter, InitGetConvolutionParameterfv, InitGetConvolutionParameteriv, InitGetSeparableFilter, InitSeparableFilter2D, InitGetHistogram, InitGetHistogramParameterfv, InitGetHistogramParameteriv, InitGetMinmax, InitGetMinmaxParameterfv, InitGetMinmaxParameteriv, InitHistogram, InitMinmax, InitResetHistogram, InitResetMinmax, InitTexImage3D, InitTexSubImage3D, InitCopyTexSubImage3D, InitActiveTexture, InitClientActiveTexture, InitMultiTexCoord1d, InitMultiTexCoord1dv, InitMultiTexCoord1f, InitMultiTexCoord1fv, InitMultiTexCoord1i, InitMultiTexCoord1iv, InitMultiTexCoord1s, InitMultiTexCoord1sv, InitMultiTexCoord2d, InitMultiTexCoord2dv, InitMultiTexCoord2f, InitMultiTexCoord2fv, InitMultiTexCoord2i, InitMultiTexCoord2iv, InitMultiTexCoord2s, InitMultiTexCoord2sv, InitMultiTexCoord3d, InitMultiTexCoord3dv, InitMultiTexCoord3f, InitMultiTexCoord3fv, InitMultiTexCoord3i, InitMultiTexCoord3iv, InitMultiTexCoord3s, InitMultiTexCoord3sv, InitMultiTexCoord4d, InitMultiTexCoord4dv, InitMultiTexCoord4f, InitMultiTexCoord4fv, InitMultiTexCoord4i, InitMultiTexCoord4iv, InitMultiTexCoord4s, InitMultiTexCoord4sv, InitLoadTransposeMatrixf, InitLoadTransposeMatrixd, InitMultTransposeMatrixf, InitMultTransposeMatrixd, InitSampleCoverage, InitCompressedTexImage3D, InitCompressedTexImage2D, InitCompressedTexImage1D, InitCompressedTexSubImage3D, InitCompressedTexSubImage2D, InitCompressedTexSubImage1D, InitGetCompressedTexImage, InitBlendFuncSeparate, InitFogCoordf, InitFogCoordfv, InitFogCoordd, InitFogCoorddv, InitFogCoordPointer, InitMultiDrawArrays, InitMultiDrawElements, InitPointParameterf, InitPointParameterfv, InitPointParameteri, InitPointParameteriv, InitSecondaryColor3b, InitSecondaryColor3bv, InitSecondaryColor3d, InitSecondaryColor3dv, InitSecondaryColor3f, InitSecondaryColor3fv, InitSecondaryColor3i, InitSecondaryColor3iv, InitSecondaryColor3s, InitSecondaryColor3sv, InitSecondaryColor3ub, InitSecondaryColor3ubv, InitSecondaryColor3ui, InitSecondaryColor3uiv, InitSecondaryColor3us, InitSecondaryColor3usv, InitSecondaryColorPointer, InitWindowPos2d, InitWindowPos2dv, InitWindowPos2f, InitWindowPos2fv, InitWindowPos2i, InitWindowPos2iv, InitWindowPos2s, InitWindowPos2sv, InitWindowPos3d, InitWindowPos3dv, InitWindowPos3f, InitWindowPos3fv, InitWindowPos3i, InitWindowPos3iv, InitWindowPos3s, InitWindowPos3sv, InitGenQueries, InitDeleteQueries, InitIsQuery, InitBeginQuery, InitEndQuery, InitGetQueryiv, InitGetQueryObjectiv, InitGetQueryObjectuiv, InitBindBuffer, InitDeleteBuffers, InitGenBuffers, InitIsBuffer, InitBufferData, InitBufferSubData, InitGetBufferSubData, InitMapBuffer, InitUnmapBuffer, InitGetBufferParameteriv, InitGetBufferPointerv, InitActiveTextureARB, InitClientActiveTextureARB, InitMultiTexCoord1dARB, InitMultiTexCoord1dvARB, InitMultiTexCoord1fARB, InitMultiTexCoord1fvARB, InitMultiTexCoord1iARB, InitMultiTexCoord1ivARB, InitMultiTexCoord1sARB, InitMultiTexCoord1svARB, InitMultiTexCoord2dARB, InitMultiTexCoord2dvARB, InitMultiTexCoord2fARB, InitMultiTexCoord2fvARB, InitMultiTexCoord2iARB, InitMultiTexCoord2ivARB, InitMultiTexCoord2sARB, InitMultiTexCoord2svARB, InitMultiTexCoord3dARB, InitMultiTexCoord3dvARB, InitMultiTexCoord3fARB, InitMultiTexCoord3fvARB, InitMultiTexCoord3iARB, InitMultiTexCoord3ivARB, InitMultiTexCoord3sARB, InitMultiTexCoord3svARB, InitMultiTexCoord4dARB, InitMultiTexCoord4dvARB, InitMultiTexCoord4fARB, InitMultiTexCoord4fvARB, InitMultiTexCoord4iARB, InitMultiTexCoord4ivARB, InitMultiTexCoord4sARB, InitMultiTexCoord4svARB, InitLoadTransposeMatrixfARB, InitLoadTransposeMatrixdARB, InitMultTransposeMatrixfARB, InitMultTransposeMatrixdARB, InitSampleCoverageARB, InitCompressedTexImage3DARB, InitCompressedTexImage2DARB, InitCompressedTexImage1DARB, InitCompressedTexSubImage3DARB, InitCompressedTexSubImage2DARB, InitCompressedTexSubImage1DARB, InitGetCompressedTexImageARB, InitPointParameterfARB, InitPointParameterfvARB, InitWeightbvARB, InitWeightsvARB, InitWeightivARB, InitWeightfvARB, InitWeightdvARB, InitWeightubvARB, InitWeightusvARB, InitWeightuivARB, InitWeightPointerARB, InitVertexBlendARB, InitCurrentPaletteMatrixARB, InitMatrixIndexubvARB, InitMatrixIndexusvARB, InitMatrixIndexuivARB, InitMatrixIndexPointerARB, InitWindowPos2dARB, InitWindowPos2dvARB, InitWindowPos2fARB, InitWindowPos2fvARB, InitWindowPos2iARB, InitWindowPos2ivARB, InitWindowPos2sARB, InitWindowPos2svARB, InitWindowPos3dARB, InitWindowPos3dvARB, InitWindowPos3fARB, InitWindowPos3fvARB, InitWindowPos3iARB, InitWindowPos3ivARB, InitWindowPos3sARB, InitWindowPos3svARB, InitVertexAttrib1dARB, InitVertexAttrib1dvARB, InitVertexAttrib1fARB, InitVertexAttrib1fvARB, InitVertexAttrib1sARB, InitVertexAttrib1svARB, InitVertexAttrib2dARB, InitVertexAttrib2dvARB, InitVertexAttrib2fARB, InitVertexAttrib2fvARB, InitVertexAttrib2sARB, InitVertexAttrib2svARB, InitVertexAttrib3dARB, InitVertexAttrib3dvARB, InitVertexAttrib3fARB, InitVertexAttrib3fvARB, InitVertexAttrib3sARB, InitVertexAttrib3svARB, InitVertexAttrib4NbvARB, InitVertexAttrib4NivARB, InitVertexAttrib4NsvARB, InitVertexAttrib4NubARB, InitVertexAttrib4NubvARB, InitVertexAttrib4NuivARB, InitVertexAttrib4NusvARB, InitVertexAttrib4bvARB, InitVertexAttrib4dARB, InitVertexAttrib4dvARB, InitVertexAttrib4fARB, InitVertexAttrib4fvARB, InitVertexAttrib4ivARB, InitVertexAttrib4sARB, InitVertexAttrib4svARB, InitVertexAttrib4ubvARB, InitVertexAttrib4uivARB, InitVertexAttrib4usvARB, InitVertexAttribPointerARB, InitEnableVertexAttribArrayARB, InitDisableVertexAttribArrayARB, InitProgramStringARB, InitBindProgramARB, InitDeleteProgramsARB, InitGenProgramsARB, InitProgramEnvParameter4dARB, InitProgramEnvParameter4dvARB, InitProgramEnvParameter4fARB, InitProgramEnvParameter4fvARB, InitProgramLocalParameter4dARB, InitProgramLocalParameter4dvARB, InitProgramLocalParameter4fARB, InitProgramLocalParameter4fvARB, InitGetProgramEnvParameterdvARB, InitGetProgramEnvParameterfvARB, InitGetProgramLocalParameterdvARB, InitGetProgramLocalParameterfvARB, InitGetProgramivARB, InitGetProgramStringARB, InitGetVertexAttribdvARB, InitGetVertexAttribfvARB, InitGetVertexAttribivARB, InitGetVertexAttribPointervARB, InitIsProgramARB, InitBindBufferARB, InitDeleteBuffersARB, InitGenBuffersARB, InitIsBufferARB, InitBufferDataARB, InitBufferSubDataARB, InitGetBufferSubDataARB, InitMapBufferARB, InitUnmapBufferARB, InitGetBufferParameterivARB, InitGetBufferPointervARB, InitGenQueriesARB, InitDeleteQueriesARB, InitIsQueryARB, InitBeginQueryARB, InitEndQueryARB, InitGetQueryivARB, InitGetQueryObjectivARB, InitGetQueryObjectuivARB, InitDeleteObjectARB, InitGetHandleARB, InitDetachObjectARB, InitCreateShaderObjectARB, InitShaderSourceARB, InitCompileShaderARB, InitCreateProgramObjectARB, InitAttachObjectARB, InitLinkProgramARB, InitUseProgramObjectARB, InitValidateProgramARB, InitUniform1fARB, InitUniform2fARB, InitUniform3fARB, InitUniform4fARB, InitUniform1iARB, InitUniform2iARB, InitUniform3iARB, InitUniform4iARB, InitUniform1fvARB, InitUniform2fvARB, InitUniform3fvARB, InitUniform4fvARB, InitUniform1ivARB, InitUniform2ivARB, InitUniform3ivARB, InitUniform4ivARB, InitUniformMatrix2fvARB, InitUniformMatrix3fvARB, InitUniformMatrix4fvARB, InitGetObjectParameterfvARB, InitGetObjectParameterivARB, InitGetInfoLogARB, InitGetAttachedObjectsARB, InitGetUniformLocationARB, InitGetActiveUniformARB, InitGetUniformfvARB, InitGetUniformivARB, InitGetShaderSourceARB, InitBindAttribLocationARB, InitGetActiveAttribARB, InitGetAttribLocationARB, InitBlendColorEXT, InitPolygonOffsetEXT, InitTexImage3DEXT, InitTexSubImage3DEXT, InitGetTexFilterFuncSGIS, InitTexFilterFuncSGIS, InitTexSubImage1DEXT, InitTexSubImage2DEXT, InitCopyTexImage1DEXT, InitCopyTexImage2DEXT, InitCopyTexSubImage1DEXT, InitCopyTexSubImage2DEXT, InitCopyTexSubImage3DEXT, InitGetHistogramEXT, InitGetHistogramParameterfvEXT, InitGetHistogramParameterivEXT, InitGetMinmaxEXT, InitGetMinmaxParameterfvEXT, InitGetMinmaxParameterivEXT, InitHistogramEXT, InitMinmaxEXT, InitResetHistogramEXT, InitResetMinmaxEXT, InitConvolutionFilter1DEXT, InitConvolutionFilter2DEXT, InitConvolutionParameterfEXT, InitConvolutionParameterfvEXT, InitConvolutionParameteriEXT, InitConvolutionParameterivEXT, InitCopyConvolutionFilter1DEXT, InitCopyConvolutionFilter2DEXT, InitGetConvolutionFilterEXT, InitGetConvolutionParameterfvEXT, InitGetConvolutionParameterivEXT, InitGetSeparableFilterEXT, InitSeparableFilter2DEXT, InitColorTableSGI, InitColorTableParameterfvSGI, InitColorTableParameterivSGI, InitCopyColorTableSGI, InitGetColorTableSGI, InitGetColorTableParameterfvSGI, InitGetColorTableParameterivSGI, InitPixelTexGenSGIX, InitPixelTexGenParameteriSGIS, InitPixelTexGenParameterivSGIS, InitPixelTexGenParameterfSGIS, InitPixelTexGenParameterfvSGIS, InitGetPixelTexGenParameterivSGIS, InitGetPixelTexGenParameterfvSGIS, InitTexImage4DSGIS, InitTexSubImage4DSGIS, InitAreTexturesResidentEXT, InitBindTextureEXT, InitDeleteTexturesEXT, InitGenTexturesEXT, InitIsTextureEXT, InitPrioritizeTexturesEXT, InitDetailTexFuncSGIS, InitGetDetailTexFuncSGIS, InitSharpenTexFuncSGIS, InitGetSharpenTexFuncSGIS, InitSampleMaskSGIS, InitSamplePatternSGIS, InitArrayElementEXT, InitColorPointerEXT, InitDrawArraysEXT, InitEdgeFlagPointerEXT, InitGetPointervEXT, InitIndexPointerEXT, InitNormalPointerEXT, InitTexCoordPointerEXT, InitVertexPointerEXT, InitBlendEquationEXT, InitSpriteParameterfSGIX, InitSpriteParameterfvSGIX, InitSpriteParameteriSGIX, InitSpriteParameterivSGIX, InitPointParameterfEXT, InitPointParameterfvEXT, InitPointParameterfSGIS, InitPointParameterfvSGIS, InitGetInstrumentsSGIX, InitInstrumentsBufferSGIX, InitPollInstrumentsSGIX, InitReadInstrumentsSGIX, InitStartInstrumentsSGIX, InitStopInstrumentsSGIX, InitFrameZoomSGIX, InitTagSampleBufferSGIX, InitDeformationMap3dSGIX, InitDeformationMap3fSGIX, InitDeformSGIX, InitLoadIdentityDeformationMapSGIX, InitReferencePlaneSGIX, InitFlushRasterSGIX, InitFogFuncSGIS, InitGetFogFuncSGIS, InitImageTransformParameteriHP, InitImageTransformParameterfHP, InitImageTransformParameterivHP, InitImageTransformParameterfvHP, InitGetImageTransformParameterivHP, InitGetImageTransformParameterfvHP, InitColorSubTableEXT, InitCopyColorSubTableEXT, InitHintPGI, InitColorTableEXT, InitGetColorTableEXT, InitGetColorTableParameterivEXT, InitGetColorTableParameterfvEXT, InitGetListParameterfvSGIX, InitGetListParameterivSGIX, InitListParameterfSGIX, InitListParameterfvSGIX, InitListParameteriSGIX, InitListParameterivSGIX, InitIndexMaterialEXT, InitIndexFuncEXT, InitLockArraysEXT, InitUnlockArraysEXT, InitCullParameterdvEXT, InitCullParameterfvEXT, InitFragmentColorMaterialSGIX, InitFragmentLightfSGIX, InitFragmentLightfvSGIX, InitFragmentLightiSGIX, InitFragmentLightivSGIX, InitFragmentLightModelfSGIX, InitFragmentLightModelfvSGIX, InitFragmentLightModeliSGIX, InitFragmentLightModelivSGIX, InitFragmentMaterialfSGIX, InitFragmentMaterialfvSGIX, InitFragmentMaterialiSGIX, InitFragmentMaterialivSGIX, InitGetFragmentLightfvSGIX, InitGetFragmentLightivSGIX, InitGetFragmentMaterialfvSGIX, InitGetFragmentMaterialivSGIX, InitLightEnviSGIX, InitDrawRangeElementsEXT, InitApplyTextureEXT, InitTextureLightEXT, InitTextureMaterialEXT, InitAsyncMarkerSGIX, InitFinishAsyncSGIX, InitPollAsyncSGIX, InitGenAsyncMarkersSGIX, InitDeleteAsyncMarkersSGIX, InitIsAsyncMarkerSGIX, InitVertexPointervINTEL, InitNormalPointervINTEL, InitColorPointervINTEL, InitTexCoordPointervINTEL, InitPixelTransformParameteriEXT, InitPixelTransformParameterfEXT, InitPixelTransformParameterivEXT, InitPixelTransformParameterfvEXT, InitSecondaryColor3bEXT, InitSecondaryColor3bvEXT, InitSecondaryColor3dEXT, InitSecondaryColor3dvEXT, InitSecondaryColor3fEXT, InitSecondaryColor3fvEXT, InitSecondaryColor3iEXT, InitSecondaryColor3ivEXT, InitSecondaryColor3sEXT, InitSecondaryColor3svEXT, InitSecondaryColor3ubEXT, InitSecondaryColor3ubvEXT, InitSecondaryColor3uiEXT, InitSecondaryColor3uivEXT, InitSecondaryColor3usEXT, InitSecondaryColor3usvEXT, InitSecondaryColorPointerEXT, InitTextureNormalEXT, InitMultiDrawArraysEXT, InitMultiDrawElementsEXT, InitFogCoordfEXT, InitFogCoordfvEXT, InitFogCoorddEXT, InitFogCoorddvEXT, InitFogCoordPointerEXT, InitTangent3bEXT, InitTangent3bvEXT, InitTangent3dEXT, InitTangent3dvEXT, InitTangent3fEXT, InitTangent3fvEXT, InitTangent3iEXT, InitTangent3ivEXT, InitTangent3sEXT, InitTangent3svEXT, InitBinormal3bEXT, InitBinormal3bvEXT, InitBinormal3dEXT, InitBinormal3dvEXT, InitBinormal3fEXT, InitBinormal3fvEXT, InitBinormal3iEXT, InitBinormal3ivEXT, InitBinormal3sEXT, InitBinormal3svEXT, InitTangentPointerEXT, InitBinormalPointerEXT, InitFinishTextureSUNX, InitGlobalAlphaFactorbSUN, InitGlobalAlphaFactorsSUN, InitGlobalAlphaFactoriSUN, InitGlobalAlphaFactorfSUN, InitGlobalAlphaFactordSUN, InitGlobalAlphaFactorubSUN, InitGlobalAlphaFactorusSUN, InitGlobalAlphaFactoruiSUN, InitReplacementCodeuiSUN, InitReplacementCodeusSUN, InitReplacementCodeubSUN, InitReplacementCodeuivSUN, InitReplacementCodeusvSUN, InitReplacementCodeubvSUN, InitReplacementCodePointerSUN, InitColor4ubVertex2fSUN, InitColor4ubVertex2fvSUN, InitColor4ubVertex3fSUN, InitColor4ubVertex3fvSUN, InitColor3fVertex3fSUN, InitColor3fVertex3fvSUN, InitNormal3fVertex3fSUN, InitNormal3fVertex3fvSUN, InitColor4fNormal3fVertex3fSUN, InitColor4fNormal3fVertex3fvSUN, InitTexCoord2fVertex3fSUN, InitTexCoord2fVertex3fvSUN, InitTexCoord4fVertex4fSUN, InitTexCoord4fVertex4fvSUN, InitTexCoord2fColor4ubVertex3fSUN, InitTexCoord2fColor4ubVertex3fvSUN, InitTexCoord2fColor3fVertex3fSUN, InitTexCoord2fColor3fVertex3fvSUN, InitTexCoord2fNormal3fVertex3fSUN, InitTexCoord2fNormal3fVertex3fvSUN, InitTexCoord2fColor4fNormal3fVertex3fSUN, InitTexCoord2fColor4fNormal3fVertex3fvSUN, InitTexCoord4fColor4fNormal3fVertex4fSUN, InitTexCoord4fColor4fNormal3fVertex4fvSUN, InitReplacementCodeuiVertex3fSUN, InitReplacementCodeuiVertex3fvSUN, InitReplacementCodeuiColor4ubVertex3fSUN, InitReplacementCodeuiColor4ubVertex3fvSUN, InitReplacementCodeuiColor3fVertex3fSUN, InitReplacementCodeuiColor3fVertex3fvSUN, InitReplacementCodeuiNormal3fVertex3fSUN, InitReplacementCodeuiNormal3fVertex3fvSUN, InitReplacementCodeuiColor4fNormal3fVertex3fSUN, InitReplacementCodeuiColor4fNormal3fVertex3fvSUN, InitReplacementCodeuiTexCoord2fVertex3fSUN, InitReplacementCodeuiTexCoord2fVertex3fvSUN, InitReplacementCodeuiTexCoord2fNormal3fVertex3fSUN, InitReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN, InitReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN, InitReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN, InitBlendFuncSeparateEXT, InitBlendFuncSeparateINGR, InitVertexWeightfEXT, InitVertexWeightfvEXT, InitVertexWeightPointerEXT, InitFlushVertexArrayRangeNV, InitVertexArrayRangeNV, InitCombinerParameterfvNV, InitCombinerParameterfNV, InitCombinerParameterivNV, InitCombinerParameteriNV, InitCombinerInputNV, InitCombinerOutputNV, InitFinalCombinerInputNV, InitGetCombinerInputParameterfvNV, InitGetCombinerInputParameterivNV, InitGetCombinerOutputParameterfvNV, InitGetCombinerOutputParameterivNV, InitGetFinalCombinerInputParameterfvNV, InitGetFinalCombinerInputParameterivNV, InitResizeBuffersMESA, InitWindowPos2dMESA, InitWindowPos2dvMESA, InitWindowPos2fMESA, InitWindowPos2fvMESA, InitWindowPos2iMESA, InitWindowPos2ivMESA, InitWindowPos2sMESA, InitWindowPos2svMESA, InitWindowPos3dMESA, InitWindowPos3dvMESA, InitWindowPos3fMESA, InitWindowPos3fvMESA, InitWindowPos3iMESA, InitWindowPos3ivMESA, InitWindowPos3sMESA, InitWindowPos3svMESA, InitWindowPos4dMESA, InitWindowPos4dvMESA, InitWindowPos4fMESA, InitWindowPos4fvMESA, InitWindowPos4iMESA, InitWindowPos4ivMESA, InitWindowPos4sMESA, InitWindowPos4svMESA, InitMultiModeDrawArraysIBM, InitMultiModeDrawElementsIBM, InitColorPointerListIBM, InitSecondaryColorPointerListIBM, InitEdgeFlagPointerListIBM, InitFogCoordPointerListIBM, InitIndexPointerListIBM, InitNormalPointerListIBM, InitTexCoordPointerListIBM, InitVertexPointerListIBM, InitTbufferMask3DFX, InitSampleMaskEXT, InitSamplePatternEXT, InitTextureColorMaskSGIS, InitIglooInterfaceSGIX, InitDeleteFencesNV, InitGenFencesNV, InitIsFenceNV, InitTestFenceNV, InitGetFenceivNV, InitFinishFenceNV, InitSetFenceNV, InitMapControlPointsNV, InitMapParameterivNV, InitMapParameterfvNV, InitGetMapControlPointsNV, InitGetMapParameterivNV, InitGetMapParameterfvNV, InitGetMapAttribParameterivNV, InitGetMapAttribParameterfvNV, InitEvalMapsNV, InitCombinerStageParameterfvNV, InitGetCombinerStageParameterfvNV, InitAreProgramsResidentNV, InitBindProgramNV, InitDeleteProgramsNV, InitExecuteProgramNV, InitGenProgramsNV, InitGetProgramParameterdvNV, InitGetProgramParameterfvNV, InitGetProgramivNV, InitGetProgramStringNV, InitGetTrackMatrixivNV, InitGetVertexAttribdvNV, InitGetVertexAttribfvNV, InitGetVertexAttribivNV, InitGetVertexAttribPointervNV, InitIsProgramNV, InitLoadProgramNV, InitProgramParameter4dNV, InitProgramParameter4dvNV, InitProgramParameter4fNV, InitProgramParameter4fvNV, InitProgramParameters4dvNV, InitProgramParameters4fvNV, InitRequestResidentProgramsNV, InitTrackMatrixNV, InitVertexAttribPointerNV, InitVertexAttrib1dNV, InitVertexAttrib1dvNV, InitVertexAttrib1fNV, InitVertexAttrib1fvNV, InitVertexAttrib1sNV, InitVertexAttrib1svNV, InitVertexAttrib2dNV, InitVertexAttrib2dvNV, InitVertexAttrib2fNV, InitVertexAttrib2fvNV, InitVertexAttrib2sNV, InitVertexAttrib2svNV, InitVertexAttrib3dNV, InitVertexAttrib3dvNV, InitVertexAttrib3fNV, InitVertexAttrib3fvNV, InitVertexAttrib3sNV, InitVertexAttrib3svNV, InitVertexAttrib4dNV, InitVertexAttrib4dvNV, InitVertexAttrib4fNV, InitVertexAttrib4fvNV, InitVertexAttrib4sNV, InitVertexAttrib4svNV, InitVertexAttrib4ubNV, InitVertexAttrib4ubvNV, InitVertexAttribs1dvNV, InitVertexAttribs1fvNV, InitVertexAttribs1svNV, InitVertexAttribs2dvNV, InitVertexAttribs2fvNV, InitVertexAttribs2svNV, InitVertexAttribs3dvNV, InitVertexAttribs3fvNV, InitVertexAttribs3svNV, InitVertexAttribs4dvNV, InitVertexAttribs4fvNV, InitVertexAttribs4svNV, InitVertexAttribs4ubvNV, InitTexBumpParameterivATI, InitTexBumpParameterfvATI, InitGetTexBumpParameterivATI, InitGetTexBumpParameterfvATI, InitGenFragmentShadersATI, InitBindFragmentShaderATI, InitDeleteFragmentShaderATI, InitBeginFragmentShaderATI, InitEndFragmentShaderATI, InitPassTexCoordATI, InitSampleMapATI, InitColorFragmentOp1ATI, InitColorFragmentOp2ATI, InitColorFragmentOp3ATI, InitAlphaFragmentOp1ATI, InitAlphaFragmentOp2ATI, InitAlphaFragmentOp3ATI, InitSetFragmentShaderConstantATI, InitPNTrianglesiATI, InitPNTrianglesfATI, InitNewObjectBufferATI, InitIsObjectBufferATI, InitUpdateObjectBufferATI, InitGetObjectBufferfvATI, InitGetObjectBufferivATI, InitFreeObjectBufferATI, InitArrayObjectATI, InitGetArrayObjectfvATI, InitGetArrayObjectivATI, InitVariantArrayObjectATI, InitGetVariantArrayObjectfvATI, InitGetVariantArrayObjectivATI, InitBeginVertexShaderEXT, InitEndVertexShaderEXT, InitBindVertexShaderEXT, InitGenVertexShadersEXT, InitDeleteVertexShaderEXT, InitShaderOp1EXT, InitShaderOp2EXT, InitShaderOp3EXT, InitSwizzleEXT, InitWriteMaskEXT, InitInsertComponentEXT, InitExtractComponentEXT, InitGenSymbolsEXT, InitSetInvariantEXT, InitSetLocalConstantEXT, InitVariantbvEXT, InitVariantsvEXT, InitVariantivEXT, InitVariantfvEXT, InitVariantdvEXT, InitVariantubvEXT, InitVariantusvEXT, InitVariantuivEXT, InitVariantPointerEXT, InitEnableVariantClientStateEXT, InitDisableVariantClientStateEXT, InitBindLightParameterEXT, InitBindMaterialParameterEXT, InitBindTexGenParameterEXT, InitBindTextureUnitParameterEXT, InitBindParameterEXT, InitIsVariantEnabledEXT, InitGetVariantBooleanvEXT, InitGetVariantIntegervEXT, InitGetVariantFloatvEXT, InitGetVariantPointervEXT, InitGetInvariantBooleanvEXT, InitGetInvariantIntegervEXT, InitGetInvariantFloatvEXT, InitGetLocalConstantBooleanvEXT, InitGetLocalConstantIntegervEXT, InitGetLocalConstantFloatvEXT, InitVertexStream1sATI, InitVertexStream1svATI, InitVertexStream1iATI, InitVertexStream1ivATI, InitVertexStream1fATI, InitVertexStream1fvATI, InitVertexStream1dATI, InitVertexStream1dvATI, InitVertexStream2sATI, InitVertexStream2svATI, InitVertexStream2iATI, InitVertexStream2ivATI, InitVertexStream2fATI, InitVertexStream2fvATI, InitVertexStream2dATI, InitVertexStream2dvATI, InitVertexStream3sATI, InitVertexStream3svATI, InitVertexStream3iATI, InitVertexStream3ivATI, InitVertexStream3fATI, InitVertexStream3fvATI, InitVertexStream3dATI, InitVertexStream3dvATI, InitVertexStream4sATI, InitVertexStream4svATI, InitVertexStream4iATI, InitVertexStream4ivATI, InitVertexStream4fATI, InitVertexStream4fvATI, InitVertexStream4dATI, InitVertexStream4dvATI, InitNormalStream3bATI, InitNormalStream3bvATI, InitNormalStream3sATI, InitNormalStream3svATI, InitNormalStream3iATI, InitNormalStream3ivATI, InitNormalStream3fATI, InitNormalStream3fvATI, InitNormalStream3dATI, InitNormalStream3dvATI, InitClientActiveVertexStreamATI, InitVertexBlendEnviATI, InitVertexBlendEnvfATI, InitElementPointerATI, InitDrawElementArrayATI, InitDrawRangeElementArrayATI, InitDrawMeshArraysSUN, InitGenOcclusionQueriesNV, InitDeleteOcclusionQueriesNV, InitIsOcclusionQueryNV, InitBeginOcclusionQueryNV, InitEndOcclusionQueryNV, InitGetOcclusionQueryivNV, InitGetOcclusionQueryuivNV, InitPointParameteriNV, InitPointParameterivNV, InitActiveStencilFaceEXT, InitElementPointerAPPLE, InitDrawElementArrayAPPLE, InitDrawRangeElementArrayAPPLE, InitMultiDrawElementArrayAPPLE, InitMultiDrawRangeElementArrayAPPLE, InitGenFencesAPPLE, InitDeleteFencesAPPLE, InitSetFenceAPPLE, InitIsFenceAPPLE, InitTestFenceAPPLE, InitFinishFenceAPPLE, InitTestObjectAPPLE, InitFinishObjectAPPLE, InitBindVertexArrayAPPLE, InitDeleteVertexArraysAPPLE, InitGenVertexArraysAPPLE, InitIsVertexArrayAPPLE, InitVertexArrayRangeAPPLE, InitFlushVertexArrayRangeAPPLE, InitVertexArrayParameteriAPPLE, InitDrawBuffersATI, InitProgramNamedParameter4fNV, InitProgramNamedParameter4dNV, InitProgramNamedParameter4fvNV, InitProgramNamedParameter4dvNV, InitGetProgramNamedParameterfvNV, InitGetProgramNamedParameterdvNV, InitVertex2hNV, InitVertex2hvNV, InitVertex3hNV, InitVertex3hvNV, InitVertex4hNV, InitVertex4hvNV, InitNormal3hNV, InitNormal3hvNV, InitColor3hNV, InitColor3hvNV, InitColor4hNV, InitColor4hvNV, InitTexCoord1hNV, InitTexCoord1hvNV, InitTexCoord2hNV, InitTexCoord2hvNV, InitTexCoord3hNV, InitTexCoord3hvNV, InitTexCoord4hNV, InitTexCoord4hvNV, InitMultiTexCoord1hNV, InitMultiTexCoord1hvNV, InitMultiTexCoord2hNV, InitMultiTexCoord2hvNV, InitMultiTexCoord3hNV, InitMultiTexCoord3hvNV, InitMultiTexCoord4hNV, InitMultiTexCoord4hvNV, InitFogCoordhNV, InitFogCoordhvNV, InitSecondaryColor3hNV, InitSecondaryColor3hvNV, InitVertexWeighthNV, InitVertexWeighthvNV, InitVertexAttrib1hNV, InitVertexAttrib1hvNV, InitVertexAttrib2hNV, InitVertexAttrib2hvNV, InitVertexAttrib3hNV, InitVertexAttrib3hvNV, InitVertexAttrib4hNV, InitVertexAttrib4hvNV, InitVertexAttribs1hvNV, InitVertexAttribs2hvNV, InitVertexAttribs3hvNV, InitVertexAttribs4hvNV, InitPixelDataRangeNV, InitFlushPixelDataRangeNV, InitPrimitiveRestartNV, InitPrimitiveRestartIndexNV, InitMapObjectBufferATI, InitUnmapObjectBufferATI, InitStencilOpSeparateATI, InitStencilFuncSeparateATI, InitVertexAttribArrayObjectATI, InitGetVertexAttribArrayObjectfvATI, InitGetVertexAttribArrayObjectivATI, InitDepthBoundsEXT, InitBlendEquationSeparateEXT, InitAddSwapHintRectWIN, #ifdef _WIN32 InitCreateBufferRegionARB, InitDeleteBufferRegionARB, InitSaveBufferRegionARB, InitRestoreBufferRegionARB, InitGetExtensionsStringARB, InitGetPixelFormatAttribivARB, InitGetPixelFormatAttribfvARB, InitChoosePixelFormatARB, InitMakeContextCurrentARB, InitGetCurrentReadDCARB, InitCreatePbufferARB, InitGetPbufferDCARB, InitReleasePbufferDCARB, InitDestroyPbufferARB, InitQueryPbufferARB, InitBindTexImageARB, InitReleaseTexImageARB, InitSetPbufferAttribARB, InitCreateDisplayColorTableEXT, InitLoadDisplayColorTableEXT, InitBindDisplayColorTableEXT, InitDestroyDisplayColorTableEXT, InitGetExtensionsStringEXT, InitMakeContextCurrentEXT, InitGetCurrentReadDCEXT, InitCreatePbufferEXT, InitGetPbufferDCEXT, InitReleasePbufferDCEXT, InitDestroyPbufferEXT, InitQueryPbufferEXT, InitGetPixelFormatAttribivEXT, InitGetPixelFormatAttribfvEXT, InitChoosePixelFormatEXT, InitSwapIntervalEXT, InitGetSwapIntervalEXT, InitAllocateMemoryNV, InitFreeMemoryNV, InitGetSyncValuesOML, InitGetMscRateOML, InitSwapBuffersMscOML, InitSwapLayerBuffersMscOML, InitWaitForMscOML, InitWaitForSbcOML, InitGetDigitalVideoParametersI3D, InitSetDigitalVideoParametersI3D, InitGetGammaTableParametersI3D, InitSetGammaTableParametersI3D, InitGetGammaTableI3D, InitSetGammaTableI3D, InitEnableGenlockI3D, InitDisableGenlockI3D, InitIsEnabledGenlockI3D, InitGenlockSourceI3D, InitGetGenlockSourceI3D, InitGenlockSourceEdgeI3D, InitGetGenlockSourceEdgeI3D, InitGenlockSampleRateI3D, InitGetGenlockSampleRateI3D, InitGenlockSourceDelayI3D, InitGetGenlockSourceDelayI3D, InitQueryGenlockMaxSourceDelayI3D, InitCreateImageBufferI3D, InitDestroyImageBufferI3D, InitAssociateImageBufferEventsI3D, InitReleaseImageBufferEventsI3D, InitEnableFrameLockI3D, InitDisableFrameLockI3D, InitIsEnabledFrameLockI3D, InitQueryFrameLockMasterI3D, InitGetFrameUsageI3D, InitBeginFrameTrackingI3D, InitEndFrameTrackingI3D, InitQueryFrameTrackingI3D, #endif /* _WIN32 */ }; rgl/src/ext/GLsdk/GL/gl.h0000644000176200001440000023474414100762641014525 0ustar liggesusers#ifndef __gl_h_ #define __gl_h_ #ifdef __cplusplus extern "C" { #endif /* ** The contents of this file are subject to the GLX Public License Version 1.0 ** (the "License"). You may not use this file except in compliance with the ** License. You may obtain a copy of the License at Silicon Graphics, Inc., ** attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043 ** or at http://www.sgi.com/software/opensource/glx/license.html. ** ** Software distributed under the License is distributed on an "AS IS" ** basis. ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY ** IMPLIED WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR ** PURPOSE OR OF NON- INFRINGEMENT. See the License for the specific ** language governing rights and limitations under the License. ** ** The Original Software is GLX version 1.2 source code, released February, ** 1999. The developer of the Original Software is Silicon Graphics, Inc. ** Those portions of the Subject Software created by Silicon Graphics, Inc. ** are Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved. */ #ifndef _WIN32 #define WINGDIAPI #define APIENTRY #endif typedef unsigned int GLenum; typedef unsigned char GLboolean; typedef unsigned int GLbitfield; typedef signed char GLbyte; typedef short GLshort; typedef int GLint; typedef int GLsizei; typedef unsigned char GLubyte; typedef unsigned short GLushort; typedef unsigned int GLuint; typedef float GLfloat; typedef float GLclampf; typedef double GLdouble; typedef double GLclampd; typedef void GLvoid; /*************************************************************/ /* Version */ #define GL_VERSION_1_1 1 #define GL_VERSION_1_2 1 /* Extensions */ #define GL_ARB_imaging 1 #define GL_ARB_multitexture 1 /* AccumOp */ #define GL_ACCUM 0x0100 #define GL_LOAD 0x0101 #define GL_RETURN 0x0102 #define GL_MULT 0x0103 #define GL_ADD 0x0104 /* AlphaFunction */ #define GL_NEVER 0x0200 #define GL_LESS 0x0201 #define GL_EQUAL 0x0202 #define GL_LEQUAL 0x0203 #define GL_GREATER 0x0204 #define GL_NOTEQUAL 0x0205 #define GL_GEQUAL 0x0206 #define GL_ALWAYS 0x0207 /* AttribMask */ #define GL_CURRENT_BIT 0x00000001 #define GL_POINT_BIT 0x00000002 #define GL_LINE_BIT 0x00000004 #define GL_POLYGON_BIT 0x00000008 #define GL_POLYGON_STIPPLE_BIT 0x00000010 #define GL_PIXEL_MODE_BIT 0x00000020 #define GL_LIGHTING_BIT 0x00000040 #define GL_FOG_BIT 0x00000080 #define GL_DEPTH_BUFFER_BIT 0x00000100 #define GL_ACCUM_BUFFER_BIT 0x00000200 #define GL_STENCIL_BUFFER_BIT 0x00000400 #define GL_VIEWPORT_BIT 0x00000800 #define GL_TRANSFORM_BIT 0x00001000 #define GL_ENABLE_BIT 0x00002000 #define GL_COLOR_BUFFER_BIT 0x00004000 #define GL_HINT_BIT 0x00008000 #define GL_EVAL_BIT 0x00010000 #define GL_LIST_BIT 0x00020000 #define GL_TEXTURE_BIT 0x00040000 #define GL_SCISSOR_BIT 0x00080000 #define GL_ALL_ATTRIB_BITS 0x000fffff /* BeginMode */ #define GL_POINTS 0x0000 #define GL_LINES 0x0001 #define GL_LINE_LOOP 0x0002 #define GL_LINE_STRIP 0x0003 #define GL_TRIANGLES 0x0004 #define GL_TRIANGLE_STRIP 0x0005 #define GL_TRIANGLE_FAN 0x0006 #define GL_QUADS 0x0007 #define GL_QUAD_STRIP 0x0008 #define GL_POLYGON 0x0009 /* BlendEquationMode */ /* GL_LOGIC_OP */ /* GL_FUNC_ADD */ /* GL_MIN */ /* GL_MAX */ /* GL_FUNC_SUBTRACT */ /* GL_FUNC_REVERSE_SUBTRACT */ /* BlendingFactorDest */ #define GL_ZERO 0 #define GL_ONE 1 #define GL_SRC_COLOR 0x0300 #define GL_ONE_MINUS_SRC_COLOR 0x0301 #define GL_SRC_ALPHA 0x0302 #define GL_ONE_MINUS_SRC_ALPHA 0x0303 #define GL_DST_ALPHA 0x0304 #define GL_ONE_MINUS_DST_ALPHA 0x0305 /* GL_CONSTANT_COLOR */ /* GL_ONE_MINUS_CONSTANT_COLOR */ /* GL_CONSTANT_ALPHA */ /* GL_ONE_MINUS_CONSTANT_ALPHA */ /* BlendingFactorSrc */ /* GL_ZERO */ /* GL_ONE */ #define GL_DST_COLOR 0x0306 #define GL_ONE_MINUS_DST_COLOR 0x0307 #define GL_SRC_ALPHA_SATURATE 0x0308 /* GL_SRC_ALPHA */ /* GL_ONE_MINUS_SRC_ALPHA */ /* GL_DST_ALPHA */ /* GL_ONE_MINUS_DST_ALPHA */ /* GL_CONSTANT_COLOR */ /* GL_ONE_MINUS_CONSTANT_COLOR */ /* GL_CONSTANT_ALPHA */ /* GL_ONE_MINUS_CONSTANT_ALPHA */ /* Boolean */ #define GL_TRUE 1 #define GL_FALSE 0 /* ClearBufferMask */ /* GL_COLOR_BUFFER_BIT */ /* GL_ACCUM_BUFFER_BIT */ /* GL_STENCIL_BUFFER_BIT */ /* GL_DEPTH_BUFFER_BIT */ /* ClientArrayType */ /* GL_VERTEX_ARRAY */ /* GL_NORMAL_ARRAY */ /* GL_COLOR_ARRAY */ /* GL_INDEX_ARRAY */ /* GL_TEXTURE_COORD_ARRAY */ /* GL_EDGE_FLAG_ARRAY */ /* ClipPlaneName */ #define GL_CLIP_PLANE0 0x3000 #define GL_CLIP_PLANE1 0x3001 #define GL_CLIP_PLANE2 0x3002 #define GL_CLIP_PLANE3 0x3003 #define GL_CLIP_PLANE4 0x3004 #define GL_CLIP_PLANE5 0x3005 /* ColorMaterialFace */ /* GL_FRONT */ /* GL_BACK */ /* GL_FRONT_AND_BACK */ /* ColorMaterialParameter */ /* GL_AMBIENT */ /* GL_DIFFUSE */ /* GL_SPECULAR */ /* GL_EMISSION */ /* GL_AMBIENT_AND_DIFFUSE */ /* ColorPointerType */ /* GL_BYTE */ /* GL_UNSIGNED_BYTE */ /* GL_SHORT */ /* GL_UNSIGNED_SHORT */ /* GL_INT */ /* GL_UNSIGNED_INT */ /* GL_FLOAT */ /* GL_DOUBLE */ /* ColorTableParameterPName */ /* GL_COLOR_TABLE_SCALE */ /* GL_COLOR_TABLE_BIAS */ /* ColorTableTarget */ /* GL_COLOR_TABLE */ /* GL_POST_CONVOLUTION_COLOR_TABLE */ /* GL_POST_COLOR_MATRIX_COLOR_TABLE */ /* GL_PROXY_COLOR_TABLE */ /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */ /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */ /* ConvolutionBorderMode */ /* GL_REDUCE */ /* GL_IGNORE_BORDER */ /* GL_CONSTANT_BORDER */ /* ConvolutionParameter */ /* GL_CONVOLUTION_BORDER_MODE */ /* GL_CONVOLUTION_FILTER_SCALE */ /* GL_CONVOLUTION_FILTER_BIAS */ /* ConvolutionTarget */ /* GL_CONVOLUTION_1D */ /* GL_CONVOLUTION_2D */ /* CullFaceMode */ /* GL_FRONT */ /* GL_BACK */ /* GL_FRONT_AND_BACK */ /* DataType */ #define GL_BYTE 0x1400 #define GL_UNSIGNED_BYTE 0x1401 #define GL_SHORT 0x1402 #define GL_UNSIGNED_SHORT 0x1403 #define GL_INT 0x1404 #define GL_UNSIGNED_INT 0x1405 #define GL_FLOAT 0x1406 #define GL_2_BYTES 0x1407 #define GL_3_BYTES 0x1408 #define GL_4_BYTES 0x1409 #define GL_DOUBLE 0x140A /* DepthFunction */ /* GL_NEVER */ /* GL_LESS */ /* GL_EQUAL */ /* GL_LEQUAL */ /* GL_GREATER */ /* GL_NOTEQUAL */ /* GL_GEQUAL */ /* GL_ALWAYS */ /* DrawBufferMode */ #define GL_NONE 0 #define GL_FRONT_LEFT 0x0400 #define GL_FRONT_RIGHT 0x0401 #define GL_BACK_LEFT 0x0402 #define GL_BACK_RIGHT 0x0403 #define GL_FRONT 0x0404 #define GL_BACK 0x0405 #define GL_LEFT 0x0406 #define GL_RIGHT 0x0407 #define GL_FRONT_AND_BACK 0x0408 #define GL_AUX0 0x0409 #define GL_AUX1 0x040A #define GL_AUX2 0x040B #define GL_AUX3 0x040C /* Enable */ /* GL_FOG */ /* GL_LIGHTING */ /* GL_TEXTURE_1D */ /* GL_TEXTURE_2D */ /* GL_LINE_STIPPLE */ /* GL_POLYGON_STIPPLE */ /* GL_CULL_FACE */ /* GL_ALPHA_TEST */ /* GL_BLEND */ /* GL_INDEX_LOGIC_OP */ /* GL_COLOR_LOGIC_OP */ /* GL_DITHER */ /* GL_STENCIL_TEST */ /* GL_DEPTH_TEST */ /* GL_CLIP_PLANE0 */ /* GL_CLIP_PLANE1 */ /* GL_CLIP_PLANE2 */ /* GL_CLIP_PLANE3 */ /* GL_CLIP_PLANE4 */ /* GL_CLIP_PLANE5 */ /* GL_LIGHT0 */ /* GL_LIGHT1 */ /* GL_LIGHT2 */ /* GL_LIGHT3 */ /* GL_LIGHT4 */ /* GL_LIGHT5 */ /* GL_LIGHT6 */ /* GL_LIGHT7 */ /* GL_TEXTURE_GEN_S */ /* GL_TEXTURE_GEN_T */ /* GL_TEXTURE_GEN_R */ /* GL_TEXTURE_GEN_Q */ /* GL_MAP1_VERTEX_3 */ /* GL_MAP1_VERTEX_4 */ /* GL_MAP1_COLOR_4 */ /* GL_MAP1_INDEX */ /* GL_MAP1_NORMAL */ /* GL_MAP1_TEXTURE_COORD_1 */ /* GL_MAP1_TEXTURE_COORD_2 */ /* GL_MAP1_TEXTURE_COORD_3 */ /* GL_MAP1_TEXTURE_COORD_4 */ /* GL_MAP2_VERTEX_3 */ /* GL_MAP2_VERTEX_4 */ /* GL_MAP2_COLOR_4 */ /* GL_MAP2_INDEX */ /* GL_MAP2_NORMAL */ /* GL_MAP2_TEXTURE_COORD_1 */ /* GL_MAP2_TEXTURE_COORD_2 */ /* GL_MAP2_TEXTURE_COORD_3 */ /* GL_MAP2_TEXTURE_COORD_4 */ /* GL_POINT_SMOOTH */ /* GL_LINE_SMOOTH */ /* GL_POLYGON_SMOOTH */ /* GL_SCISSOR_TEST */ /* GL_COLOR_MATERIAL */ /* GL_NORMALIZE */ /* GL_AUTO_NORMAL */ /* GL_VERTEX_ARRAY */ /* GL_NORMAL_ARRAY */ /* GL_COLOR_ARRAY */ /* GL_INDEX_ARRAY */ /* GL_TEXTURE_COORD_ARRAY */ /* GL_EDGE_FLAG_ARRAY */ /* GL_POLYGON_OFFSET_POINT */ /* GL_POLYGON_OFFSET_LINE */ /* GL_POLYGON_OFFSET_FILL */ /* GL_COLOR_TABLE */ /* GL_POST_CONVOLUTION_COLOR_TABLE */ /* GL_POST_COLOR_MATRIX_COLOR_TABLE */ /* GL_CONVOLUTION_1D */ /* GL_CONVOLUTION_2D */ /* GL_SEPARABLE_2D */ /* GL_HISTOGRAM */ /* GL_MINMAX */ /* GL_RESCALE_NORMAL */ /* GL_TEXTURE_3D */ /* ErrorCode */ #define GL_NO_ERROR 0 #define GL_INVALID_ENUM 0x0500 #define GL_INVALID_VALUE 0x0501 #define GL_INVALID_OPERATION 0x0502 #define GL_STACK_OVERFLOW 0x0503 #define GL_STACK_UNDERFLOW 0x0504 #define GL_OUT_OF_MEMORY 0x0505 /* GL_TABLE_TOO_LARGE */ /* FeedBackMode */ #define GL_2D 0x0600 #define GL_3D 0x0601 #define GL_3D_COLOR 0x0602 #define GL_3D_COLOR_TEXTURE 0x0603 #define GL_4D_COLOR_TEXTURE 0x0604 /* FeedBackToken */ #define GL_PASS_THROUGH_TOKEN 0x0700 #define GL_POINT_TOKEN 0x0701 #define GL_LINE_TOKEN 0x0702 #define GL_POLYGON_TOKEN 0x0703 #define GL_BITMAP_TOKEN 0x0704 #define GL_DRAW_PIXEL_TOKEN 0x0705 #define GL_COPY_PIXEL_TOKEN 0x0706 #define GL_LINE_RESET_TOKEN 0x0707 /* FogMode */ /* GL_LINEAR */ #define GL_EXP 0x0800 #define GL_EXP2 0x0801 /* FogParameter */ /* GL_FOG_COLOR */ /* GL_FOG_DENSITY */ /* GL_FOG_END */ /* GL_FOG_INDEX */ /* GL_FOG_MODE */ /* GL_FOG_START */ /* FrontFaceDirection */ #define GL_CW 0x0900 #define GL_CCW 0x0901 /* GetColorTableParameterPName */ /* GL_COLOR_TABLE_SCALE */ /* GL_COLOR_TABLE_BIAS */ /* GL_COLOR_TABLE_FORMAT */ /* GL_COLOR_TABLE_WIDTH */ /* GL_COLOR_TABLE_RED_SIZE */ /* GL_COLOR_TABLE_GREEN_SIZE */ /* GL_COLOR_TABLE_BLUE_SIZE */ /* GL_COLOR_TABLE_ALPHA_SIZE */ /* GL_COLOR_TABLE_LUMINANCE_SIZE */ /* GL_COLOR_TABLE_INTENSITY_SIZE */ /* GetConvolutionParameterPName */ /* GL_CONVOLUTION_BORDER_COLOR */ /* GL_CONVOLUTION_BORDER_MODE */ /* GL_CONVOLUTION_FILTER_SCALE */ /* GL_CONVOLUTION_FILTER_BIAS */ /* GL_CONVOLUTION_FORMAT */ /* GL_CONVOLUTION_WIDTH */ /* GL_CONVOLUTION_HEIGHT */ /* GL_MAX_CONVOLUTION_WIDTH */ /* GL_MAX_CONVOLUTION_HEIGHT */ /* GetHistogramParameterPName */ /* GL_HISTOGRAM_WIDTH */ /* GL_HISTOGRAM_FORMAT */ /* GL_HISTOGRAM_RED_SIZE */ /* GL_HISTOGRAM_GREEN_SIZE */ /* GL_HISTOGRAM_BLUE_SIZE */ /* GL_HISTOGRAM_ALPHA_SIZE */ /* GL_HISTOGRAM_LUMINANCE_SIZE */ /* GL_HISTOGRAM_SINK */ /* GetMapTarget */ #define GL_COEFF 0x0A00 #define GL_ORDER 0x0A01 #define GL_DOMAIN 0x0A02 /* GetMinmaxParameterPName */ /* GL_MINMAX_FORMAT */ /* GL_MINMAX_SINK */ /* GetPixelMap */ /* GL_PIXEL_MAP_I_TO_I */ /* GL_PIXEL_MAP_S_TO_S */ /* GL_PIXEL_MAP_I_TO_R */ /* GL_PIXEL_MAP_I_TO_G */ /* GL_PIXEL_MAP_I_TO_B */ /* GL_PIXEL_MAP_I_TO_A */ /* GL_PIXEL_MAP_R_TO_R */ /* GL_PIXEL_MAP_G_TO_G */ /* GL_PIXEL_MAP_B_TO_B */ /* GL_PIXEL_MAP_A_TO_A */ /* GetPointerTarget */ /* GL_VERTEX_ARRAY_POINTER */ /* GL_NORMAL_ARRAY_POINTER */ /* GL_COLOR_ARRAY_POINTER */ /* GL_INDEX_ARRAY_POINTER */ /* GL_TEXTURE_COORD_ARRAY_POINTER */ /* GL_EDGE_FLAG_ARRAY_POINTER */ /* GetTarget */ #define GL_CURRENT_COLOR 0x0B00 #define GL_CURRENT_INDEX 0x0B01 #define GL_CURRENT_NORMAL 0x0B02 #define GL_CURRENT_TEXTURE_COORDS 0x0B03 #define GL_CURRENT_RASTER_COLOR 0x0B04 #define GL_CURRENT_RASTER_INDEX 0x0B05 #define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 #define GL_CURRENT_RASTER_POSITION 0x0B07 #define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 #define GL_CURRENT_RASTER_DISTANCE 0x0B09 #define GL_POINT_SMOOTH 0x0B10 #define GL_POINT_SIZE 0x0B11 #define GL_POINT_SIZE_RANGE 0x0B12 #define GL_POINT_SIZE_GRANULARITY 0x0B13 #define GL_LINE_SMOOTH 0x0B20 #define GL_LINE_WIDTH 0x0B21 #define GL_LINE_WIDTH_RANGE 0x0B22 #define GL_LINE_WIDTH_GRANULARITY 0x0B23 #define GL_LINE_STIPPLE 0x0B24 #define GL_LINE_STIPPLE_PATTERN 0x0B25 #define GL_LINE_STIPPLE_REPEAT 0x0B26 /* GL_SMOOTH_POINT_SIZE_RANGE */ /* GL_SMOOTH_POINT_SIZE_GRANULARITY */ /* GL_SMOOTH_LINE_WIDTH_RANGE */ /* GL_SMOOTH_LINE_WIDTH_GRANULARITY */ /* GL_ALIASED_POINT_SIZE_RANGE */ /* GL_ALIASED_LINE_WIDTH_RANGE */ #define GL_LIST_MODE 0x0B30 #define GL_MAX_LIST_NESTING 0x0B31 #define GL_LIST_BASE 0x0B32 #define GL_LIST_INDEX 0x0B33 #define GL_POLYGON_MODE 0x0B40 #define GL_POLYGON_SMOOTH 0x0B41 #define GL_POLYGON_STIPPLE 0x0B42 #define GL_EDGE_FLAG 0x0B43 #define GL_CULL_FACE 0x0B44 #define GL_CULL_FACE_MODE 0x0B45 #define GL_FRONT_FACE 0x0B46 #define GL_LIGHTING 0x0B50 #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 #define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 #define GL_LIGHT_MODEL_AMBIENT 0x0B53 #define GL_SHADE_MODEL 0x0B54 #define GL_COLOR_MATERIAL_FACE 0x0B55 #define GL_COLOR_MATERIAL_PARAMETER 0x0B56 #define GL_COLOR_MATERIAL 0x0B57 #define GL_FOG 0x0B60 #define GL_FOG_INDEX 0x0B61 #define GL_FOG_DENSITY 0x0B62 #define GL_FOG_START 0x0B63 #define GL_FOG_END 0x0B64 #define GL_FOG_MODE 0x0B65 #define GL_FOG_COLOR 0x0B66 #define GL_DEPTH_RANGE 0x0B70 #define GL_DEPTH_TEST 0x0B71 #define GL_DEPTH_WRITEMASK 0x0B72 #define GL_DEPTH_CLEAR_VALUE 0x0B73 #define GL_DEPTH_FUNC 0x0B74 #define GL_ACCUM_CLEAR_VALUE 0x0B80 #define GL_STENCIL_TEST 0x0B90 #define GL_STENCIL_CLEAR_VALUE 0x0B91 #define GL_STENCIL_FUNC 0x0B92 #define GL_STENCIL_VALUE_MASK 0x0B93 #define GL_STENCIL_FAIL 0x0B94 #define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 #define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 #define GL_STENCIL_REF 0x0B97 #define GL_STENCIL_WRITEMASK 0x0B98 #define GL_MATRIX_MODE 0x0BA0 #define GL_NORMALIZE 0x0BA1 #define GL_VIEWPORT 0x0BA2 #define GL_MODELVIEW_STACK_DEPTH 0x0BA3 #define GL_PROJECTION_STACK_DEPTH 0x0BA4 #define GL_TEXTURE_STACK_DEPTH 0x0BA5 #define GL_MODELVIEW_MATRIX 0x0BA6 #define GL_PROJECTION_MATRIX 0x0BA7 #define GL_TEXTURE_MATRIX 0x0BA8 #define GL_ATTRIB_STACK_DEPTH 0x0BB0 #define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 #define GL_ALPHA_TEST 0x0BC0 #define GL_ALPHA_TEST_FUNC 0x0BC1 #define GL_ALPHA_TEST_REF 0x0BC2 #define GL_DITHER 0x0BD0 #define GL_BLEND_DST 0x0BE0 #define GL_BLEND_SRC 0x0BE1 #define GL_BLEND 0x0BE2 #define GL_LOGIC_OP_MODE 0x0BF0 #define GL_INDEX_LOGIC_OP 0x0BF1 #define GL_COLOR_LOGIC_OP 0x0BF2 #define GL_AUX_BUFFERS 0x0C00 #define GL_DRAW_BUFFER 0x0C01 #define GL_READ_BUFFER 0x0C02 #define GL_SCISSOR_BOX 0x0C10 #define GL_SCISSOR_TEST 0x0C11 #define GL_INDEX_CLEAR_VALUE 0x0C20 #define GL_INDEX_WRITEMASK 0x0C21 #define GL_COLOR_CLEAR_VALUE 0x0C22 #define GL_COLOR_WRITEMASK 0x0C23 #define GL_INDEX_MODE 0x0C30 #define GL_RGBA_MODE 0x0C31 #define GL_DOUBLEBUFFER 0x0C32 #define GL_STEREO 0x0C33 #define GL_RENDER_MODE 0x0C40 #define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 #define GL_POINT_SMOOTH_HINT 0x0C51 #define GL_LINE_SMOOTH_HINT 0x0C52 #define GL_POLYGON_SMOOTH_HINT 0x0C53 #define GL_FOG_HINT 0x0C54 #define GL_TEXTURE_GEN_S 0x0C60 #define GL_TEXTURE_GEN_T 0x0C61 #define GL_TEXTURE_GEN_R 0x0C62 #define GL_TEXTURE_GEN_Q 0x0C63 #define GL_PIXEL_MAP_I_TO_I 0x0C70 #define GL_PIXEL_MAP_S_TO_S 0x0C71 #define GL_PIXEL_MAP_I_TO_R 0x0C72 #define GL_PIXEL_MAP_I_TO_G 0x0C73 #define GL_PIXEL_MAP_I_TO_B 0x0C74 #define GL_PIXEL_MAP_I_TO_A 0x0C75 #define GL_PIXEL_MAP_R_TO_R 0x0C76 #define GL_PIXEL_MAP_G_TO_G 0x0C77 #define GL_PIXEL_MAP_B_TO_B 0x0C78 #define GL_PIXEL_MAP_A_TO_A 0x0C79 #define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 #define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 #define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 #define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 #define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 #define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 #define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 #define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 #define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 #define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 #define GL_UNPACK_SWAP_BYTES 0x0CF0 #define GL_UNPACK_LSB_FIRST 0x0CF1 #define GL_UNPACK_ROW_LENGTH 0x0CF2 #define GL_UNPACK_SKIP_ROWS 0x0CF3 #define GL_UNPACK_SKIP_PIXELS 0x0CF4 #define GL_UNPACK_ALIGNMENT 0x0CF5 #define GL_PACK_SWAP_BYTES 0x0D00 #define GL_PACK_LSB_FIRST 0x0D01 #define GL_PACK_ROW_LENGTH 0x0D02 #define GL_PACK_SKIP_ROWS 0x0D03 #define GL_PACK_SKIP_PIXELS 0x0D04 #define GL_PACK_ALIGNMENT 0x0D05 #define GL_MAP_COLOR 0x0D10 #define GL_MAP_STENCIL 0x0D11 #define GL_INDEX_SHIFT 0x0D12 #define GL_INDEX_OFFSET 0x0D13 #define GL_RED_SCALE 0x0D14 #define GL_RED_BIAS 0x0D15 #define GL_ZOOM_X 0x0D16 #define GL_ZOOM_Y 0x0D17 #define GL_GREEN_SCALE 0x0D18 #define GL_GREEN_BIAS 0x0D19 #define GL_BLUE_SCALE 0x0D1A #define GL_BLUE_BIAS 0x0D1B #define GL_ALPHA_SCALE 0x0D1C #define GL_ALPHA_BIAS 0x0D1D #define GL_DEPTH_SCALE 0x0D1E #define GL_DEPTH_BIAS 0x0D1F #define GL_MAX_EVAL_ORDER 0x0D30 #define GL_MAX_LIGHTS 0x0D31 #define GL_MAX_CLIP_PLANES 0x0D32 #define GL_MAX_TEXTURE_SIZE 0x0D33 #define GL_MAX_PIXEL_MAP_TABLE 0x0D34 #define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 #define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 #define GL_MAX_NAME_STACK_DEPTH 0x0D37 #define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 #define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 #define GL_MAX_VIEWPORT_DIMS 0x0D3A #define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B #define GL_SUBPIXEL_BITS 0x0D50 #define GL_INDEX_BITS 0x0D51 #define GL_RED_BITS 0x0D52 #define GL_GREEN_BITS 0x0D53 #define GL_BLUE_BITS 0x0D54 #define GL_ALPHA_BITS 0x0D55 #define GL_DEPTH_BITS 0x0D56 #define GL_STENCIL_BITS 0x0D57 #define GL_ACCUM_RED_BITS 0x0D58 #define GL_ACCUM_GREEN_BITS 0x0D59 #define GL_ACCUM_BLUE_BITS 0x0D5A #define GL_ACCUM_ALPHA_BITS 0x0D5B #define GL_NAME_STACK_DEPTH 0x0D70 #define GL_AUTO_NORMAL 0x0D80 #define GL_MAP1_COLOR_4 0x0D90 #define GL_MAP1_INDEX 0x0D91 #define GL_MAP1_NORMAL 0x0D92 #define GL_MAP1_TEXTURE_COORD_1 0x0D93 #define GL_MAP1_TEXTURE_COORD_2 0x0D94 #define GL_MAP1_TEXTURE_COORD_3 0x0D95 #define GL_MAP1_TEXTURE_COORD_4 0x0D96 #define GL_MAP1_VERTEX_3 0x0D97 #define GL_MAP1_VERTEX_4 0x0D98 #define GL_MAP2_COLOR_4 0x0DB0 #define GL_MAP2_INDEX 0x0DB1 #define GL_MAP2_NORMAL 0x0DB2 #define GL_MAP2_TEXTURE_COORD_1 0x0DB3 #define GL_MAP2_TEXTURE_COORD_2 0x0DB4 #define GL_MAP2_TEXTURE_COORD_3 0x0DB5 #define GL_MAP2_TEXTURE_COORD_4 0x0DB6 #define GL_MAP2_VERTEX_3 0x0DB7 #define GL_MAP2_VERTEX_4 0x0DB8 #define GL_MAP1_GRID_DOMAIN 0x0DD0 #define GL_MAP1_GRID_SEGMENTS 0x0DD1 #define GL_MAP2_GRID_DOMAIN 0x0DD2 #define GL_MAP2_GRID_SEGMENTS 0x0DD3 #define GL_TEXTURE_1D 0x0DE0 #define GL_TEXTURE_2D 0x0DE1 #define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 #define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 #define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 #define GL_SELECTION_BUFFER_POINTER 0x0DF3 #define GL_SELECTION_BUFFER_SIZE 0x0DF4 /* GL_TEXTURE_BINDING_1D */ /* GL_TEXTURE_BINDING_2D */ /* GL_TEXTURE_BINDING_3D */ /* GL_VERTEX_ARRAY */ /* GL_NORMAL_ARRAY */ /* GL_COLOR_ARRAY */ /* GL_INDEX_ARRAY */ /* GL_TEXTURE_COORD_ARRAY */ /* GL_EDGE_FLAG_ARRAY */ /* GL_VERTEX_ARRAY_SIZE */ /* GL_VERTEX_ARRAY_TYPE */ /* GL_VERTEX_ARRAY_STRIDE */ /* GL_NORMAL_ARRAY_TYPE */ /* GL_NORMAL_ARRAY_STRIDE */ /* GL_COLOR_ARRAY_SIZE */ /* GL_COLOR_ARRAY_TYPE */ /* GL_COLOR_ARRAY_STRIDE */ /* GL_INDEX_ARRAY_TYPE */ /* GL_INDEX_ARRAY_STRIDE */ /* GL_TEXTURE_COORD_ARRAY_SIZE */ /* GL_TEXTURE_COORD_ARRAY_TYPE */ /* GL_TEXTURE_COORD_ARRAY_STRIDE */ /* GL_EDGE_FLAG_ARRAY_STRIDE */ /* GL_POLYGON_OFFSET_FACTOR */ /* GL_POLYGON_OFFSET_UNITS */ /* GL_COLOR_TABLE */ /* GL_POST_CONVOLUTION_COLOR_TABLE */ /* GL_POST_COLOR_MATRIX_COLOR_TABLE */ /* GL_CONVOLUTION_1D */ /* GL_CONVOLUTION_2D */ /* GL_SEPARABLE_2D */ /* GL_POST_CONVOLUTION_RED_SCALE */ /* GL_POST_CONVOLUTION_GREEN_SCALE */ /* GL_POST_CONVOLUTION_BLUE_SCALE */ /* GL_POST_CONVOLUTION_ALPHA_SCALE */ /* GL_POST_CONVOLUTION_RED_BIAS */ /* GL_POST_CONVOLUTION_GREEN_BIAS */ /* GL_POST_CONVOLUTION_BLUE_BIAS */ /* GL_POST_CONVOLUTION_ALPHA_BIAS */ /* GL_COLOR_MATRIX */ /* GL_COLOR_MATRIX_STACK_DEPTH */ /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */ /* GL_POST_COLOR_MATRIX_RED_SCALE */ /* GL_POST_COLOR_MATRIX_GREEN_SCALE */ /* GL_POST_COLOR_MATRIX_BLUE_SCALE */ /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */ /* GL_POST_COLOR_MATRIX_RED_BIAS */ /* GL_POST_COLOR_MATRIX_GREEN_BIAS */ /* GL_POST_COLOR_MATRIX_BLUE_BIAS */ /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */ /* GL_HISTOGRAM */ /* GL_MINMAX */ /* GL_MAX_ELEMENTS_VERTICES */ /* GL_MAX_ELEMENTS_INDICES */ /* GL_RESCALE_NORMAL */ /* GL_LIGHT_MODEL_COLOR_CONTROL */ /* GL_PACK_SKIP_IMAGES */ /* GL_PACK_IMAGE_HEIGHT */ /* GL_UNPACK_SKIP_IMAGES */ /* GL_UNPACK_IMAGE_HEIGHT */ /* GL_TEXTURE_3D */ /* GL_MAX_3D_TEXTURE_SIZE */ /* GL_BLEND_COLOR */ /* GL_BLEND_EQUATION */ /* GL_ACTIVE_TEXTURE_ARB */ /* GL_CLIENT_ACTIVE_TEXTURE_ARB */ /* GL_MAX_TEXTURE_UNITS_ARB */ /* GetTextureParameter */ /* GL_TEXTURE_MAG_FILTER */ /* GL_TEXTURE_MIN_FILTER */ /* GL_TEXTURE_WRAP_S */ /* GL_TEXTURE_WRAP_T */ #define GL_TEXTURE_WIDTH 0x1000 #define GL_TEXTURE_HEIGHT 0x1001 #define GL_TEXTURE_INTERNAL_FORMAT 0x1003 #define GL_TEXTURE_BORDER_COLOR 0x1004 #define GL_TEXTURE_BORDER 0x1005 /* GL_TEXTURE_RED_SIZE */ /* GL_TEXTURE_GREEN_SIZE */ /* GL_TEXTURE_BLUE_SIZE */ /* GL_TEXTURE_ALPHA_SIZE */ /* GL_TEXTURE_LUMINANCE_SIZE */ /* GL_TEXTURE_INTENSITY_SIZE */ /* GL_TEXTURE_PRIORITY */ /* GL_TEXTURE_RESIDENT */ /* GL_TEXTURE_DEPTH */ /* GL_TEXTURE_WRAP_R */ /* GL_TEXTURE_MIN_LOD */ /* GL_TEXTURE_MAX_LOD */ /* GL_TEXTURE_BASE_LEVEL */ /* GL_TEXTURE_MAX_LEVEL */ /* HintMode */ #define GL_DONT_CARE 0x1100 #define GL_FASTEST 0x1101 #define GL_NICEST 0x1102 /* HintTarget */ /* GL_PERSPECTIVE_CORRECTION_HINT */ /* GL_POINT_SMOOTH_HINT */ /* GL_LINE_SMOOTH_HINT */ /* GL_POLYGON_SMOOTH_HINT */ /* GL_FOG_HINT */ /* HistogramTarget */ /* GL_HISTOGRAM */ /* GL_PROXY_HISTOGRAM */ /* IndexPointerType */ /* GL_SHORT */ /* GL_INT */ /* GL_FLOAT */ /* GL_DOUBLE */ /* LightModelColorControl */ /* GL_SINGLE_COLOR */ /* GL_SEPARATE_SPECULAR_COLOR */ /* LightModelParameter */ /* GL_LIGHT_MODEL_AMBIENT */ /* GL_LIGHT_MODEL_LOCAL_VIEWER */ /* GL_LIGHT_MODEL_TWO_SIDE */ /* GL_LIGHT_MODEL_COLOR_CONTROL */ /* LightName */ #define GL_LIGHT0 0x4000 #define GL_LIGHT1 0x4001 #define GL_LIGHT2 0x4002 #define GL_LIGHT3 0x4003 #define GL_LIGHT4 0x4004 #define GL_LIGHT5 0x4005 #define GL_LIGHT6 0x4006 #define GL_LIGHT7 0x4007 /* LightParameter */ #define GL_AMBIENT 0x1200 #define GL_DIFFUSE 0x1201 #define GL_SPECULAR 0x1202 #define GL_POSITION 0x1203 #define GL_SPOT_DIRECTION 0x1204 #define GL_SPOT_EXPONENT 0x1205 #define GL_SPOT_CUTOFF 0x1206 #define GL_CONSTANT_ATTENUATION 0x1207 #define GL_LINEAR_ATTENUATION 0x1208 #define GL_QUADRATIC_ATTENUATION 0x1209 /* InterleavedArrays */ /* GL_V2F */ /* GL_V3F */ /* GL_C4UB_V2F */ /* GL_C4UB_V3F */ /* GL_C3F_V3F */ /* GL_N3F_V3F */ /* GL_C4F_N3F_V3F */ /* GL_T2F_V3F */ /* GL_T4F_V4F */ /* GL_T2F_C4UB_V3F */ /* GL_T2F_C3F_V3F */ /* GL_T2F_N3F_V3F */ /* GL_T2F_C4F_N3F_V3F */ /* GL_T4F_C4F_N3F_V4F */ /* ListMode */ #define GL_COMPILE 0x1300 #define GL_COMPILE_AND_EXECUTE 0x1301 /* ListNameType */ /* GL_BYTE */ /* GL_UNSIGNED_BYTE */ /* GL_SHORT */ /* GL_UNSIGNED_SHORT */ /* GL_INT */ /* GL_UNSIGNED_INT */ /* GL_FLOAT */ /* GL_2_BYTES */ /* GL_3_BYTES */ /* GL_4_BYTES */ /* LogicOp */ #define GL_CLEAR 0x1500 #define GL_AND 0x1501 #define GL_AND_REVERSE 0x1502 #define GL_COPY 0x1503 #define GL_AND_INVERTED 0x1504 #define GL_NOOP 0x1505 #define GL_XOR 0x1506 #define GL_OR 0x1507 #define GL_NOR 0x1508 #define GL_EQUIV 0x1509 #define GL_INVERT 0x150A #define GL_OR_REVERSE 0x150B #define GL_COPY_INVERTED 0x150C #define GL_OR_INVERTED 0x150D #define GL_NAND 0x150E #define GL_SET 0x150F /* MapTarget */ /* GL_MAP1_COLOR_4 */ /* GL_MAP1_INDEX */ /* GL_MAP1_NORMAL */ /* GL_MAP1_TEXTURE_COORD_1 */ /* GL_MAP1_TEXTURE_COORD_2 */ /* GL_MAP1_TEXTURE_COORD_3 */ /* GL_MAP1_TEXTURE_COORD_4 */ /* GL_MAP1_VERTEX_3 */ /* GL_MAP1_VERTEX_4 */ /* GL_MAP2_COLOR_4 */ /* GL_MAP2_INDEX */ /* GL_MAP2_NORMAL */ /* GL_MAP2_TEXTURE_COORD_1 */ /* GL_MAP2_TEXTURE_COORD_2 */ /* GL_MAP2_TEXTURE_COORD_3 */ /* GL_MAP2_TEXTURE_COORD_4 */ /* GL_MAP2_VERTEX_3 */ /* GL_MAP2_VERTEX_4 */ /* MaterialFace */ /* GL_FRONT */ /* GL_BACK */ /* GL_FRONT_AND_BACK */ /* MaterialParameter */ #define GL_EMISSION 0x1600 #define GL_SHININESS 0x1601 #define GL_AMBIENT_AND_DIFFUSE 0x1602 #define GL_COLOR_INDEXES 0x1603 /* GL_AMBIENT */ /* GL_DIFFUSE */ /* GL_SPECULAR */ /* MatrixMode */ #define GL_MODELVIEW 0x1700 #define GL_PROJECTION 0x1701 #define GL_TEXTURE 0x1702 /* MeshMode1 */ /* GL_POINT */ /* GL_LINE */ /* MeshMode2 */ /* GL_POINT */ /* GL_LINE */ /* GL_FILL */ /* MinmaxTarget */ /* GL_MINMAX */ /* NormalPointerType */ /* GL_BYTE */ /* GL_SHORT */ /* GL_INT */ /* GL_FLOAT */ /* GL_DOUBLE */ /* PixelCopyType */ #define GL_COLOR 0x1800 #define GL_DEPTH 0x1801 #define GL_STENCIL 0x1802 /* PixelFormat */ #define GL_COLOR_INDEX 0x1900 #define GL_STENCIL_INDEX 0x1901 #define GL_DEPTH_COMPONENT 0x1902 #define GL_RED 0x1903 #define GL_GREEN 0x1904 #define GL_BLUE 0x1905 #define GL_ALPHA 0x1906 #define GL_RGB 0x1907 #define GL_RGBA 0x1908 #define GL_LUMINANCE 0x1909 #define GL_LUMINANCE_ALPHA 0x190A /* GL_ABGR */ /* PixelInternalFormat */ /* GL_ALPHA4 */ /* GL_ALPHA8 */ /* GL_ALPHA12 */ /* GL_ALPHA16 */ /* GL_LUMINANCE4 */ /* GL_LUMINANCE8 */ /* GL_LUMINANCE12 */ /* GL_LUMINANCE16 */ /* GL_LUMINANCE4_ALPHA4 */ /* GL_LUMINANCE6_ALPHA2 */ /* GL_LUMINANCE8_ALPHA8 */ /* GL_LUMINANCE12_ALPHA4 */ /* GL_LUMINANCE12_ALPHA12 */ /* GL_LUMINANCE16_ALPHA16 */ /* GL_INTENSITY */ /* GL_INTENSITY4 */ /* GL_INTENSITY8 */ /* GL_INTENSITY12 */ /* GL_INTENSITY16 */ /* GL_R3_G3_B2 */ /* GL_RGB4 */ /* GL_RGB5 */ /* GL_RGB8 */ /* GL_RGB10 */ /* GL_RGB12 */ /* GL_RGB16 */ /* GL_RGBA2 */ /* GL_RGBA4 */ /* GL_RGB5_A1 */ /* GL_RGBA8 */ /* GL_RGB10_A2 */ /* GL_RGBA12 */ /* GL_RGBA16 */ /* PixelMap */ /* GL_PIXEL_MAP_I_TO_I */ /* GL_PIXEL_MAP_S_TO_S */ /* GL_PIXEL_MAP_I_TO_R */ /* GL_PIXEL_MAP_I_TO_G */ /* GL_PIXEL_MAP_I_TO_B */ /* GL_PIXEL_MAP_I_TO_A */ /* GL_PIXEL_MAP_R_TO_R */ /* GL_PIXEL_MAP_G_TO_G */ /* GL_PIXEL_MAP_B_TO_B */ /* GL_PIXEL_MAP_A_TO_A */ /* PixelStore */ /* GL_UNPACK_SWAP_BYTES */ /* GL_UNPACK_LSB_FIRST */ /* GL_UNPACK_ROW_LENGTH */ /* GL_UNPACK_SKIP_ROWS */ /* GL_UNPACK_SKIP_PIXELS */ /* GL_UNPACK_ALIGNMENT */ /* GL_PACK_SWAP_BYTES */ /* GL_PACK_LSB_FIRST */ /* GL_PACK_ROW_LENGTH */ /* GL_PACK_SKIP_ROWS */ /* GL_PACK_SKIP_PIXELS */ /* GL_PACK_ALIGNMENT */ /* GL_PACK_SKIP_IMAGES */ /* GL_PACK_IMAGE_HEIGHT */ /* GL_UNPACK_SKIP_IMAGES */ /* GL_UNPACK_IMAGE_HEIGHT */ /* PixelTransfer */ /* GL_MAP_COLOR */ /* GL_MAP_STENCIL */ /* GL_INDEX_SHIFT */ /* GL_INDEX_OFFSET */ /* GL_RED_SCALE */ /* GL_RED_BIAS */ /* GL_GREEN_SCALE */ /* GL_GREEN_BIAS */ /* GL_BLUE_SCALE */ /* GL_BLUE_BIAS */ /* GL_ALPHA_SCALE */ /* GL_ALPHA_BIAS */ /* GL_DEPTH_SCALE */ /* GL_DEPTH_BIAS */ /* GL_POST_CONVOLUTION_RED_SCALE */ /* GL_POST_CONVOLUTION_GREEN_SCALE */ /* GL_POST_CONVOLUTION_BLUE_SCALE */ /* GL_POST_CONVOLUTION_ALPHA_SCALE */ /* GL_POST_CONVOLUTION_RED_BIAS */ /* GL_POST_CONVOLUTION_GREEN_BIAS */ /* GL_POST_CONVOLUTION_BLUE_BIAS */ /* GL_POST_CONVOLUTION_ALPHA_BIAS */ /* GL_POST_COLOR_MATRIX_RED_SCALE */ /* GL_POST_COLOR_MATRIX_GREEN_SCALE */ /* GL_POST_COLOR_MATRIX_BLUE_SCALE */ /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */ /* GL_POST_COLOR_MATRIX_RED_BIAS */ /* GL_POST_COLOR_MATRIX_GREEN_BIAS */ /* GL_POST_COLOR_MATRIX_BLUE_BIAS */ /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */ /* PixelType */ #define GL_BITMAP 0x1A00 /* GL_BYTE */ /* GL_UNSIGNED_BYTE */ /* GL_SHORT */ /* GL_UNSIGNED_SHORT */ /* GL_INT */ /* GL_UNSIGNED_INT */ /* GL_FLOAT */ /* GL_BGR */ /* GL_BGRA */ /* GL_UNSIGNED_BYTE_3_3_2 */ /* GL_UNSIGNED_SHORT_4_4_4_4 */ /* GL_UNSIGNED_SHORT_5_5_5_1 */ /* GL_UNSIGNED_INT_8_8_8_8 */ /* GL_UNSIGNED_INT_10_10_10_2 */ /* GL_UNSIGNED_SHORT_5_6_5 */ /* GL_UNSIGNED_BYTE_2_3_3_REV */ /* GL_UNSIGNED_SHORT_5_6_5_REV */ /* GL_UNSIGNED_SHORT_4_4_4_4_REV */ /* GL_UNSIGNED_SHORT_1_5_5_5_REV */ /* GL_UNSIGNED_INT_8_8_8_8_REV */ /* GL_UNSIGNED_INT_2_10_10_10_REV */ /* PolygonMode */ #define GL_POINT 0x1B00 #define GL_LINE 0x1B01 #define GL_FILL 0x1B02 /* ReadBufferMode */ /* GL_FRONT_LEFT */ /* GL_FRONT_RIGHT */ /* GL_BACK_LEFT */ /* GL_BACK_RIGHT */ /* GL_FRONT */ /* GL_BACK */ /* GL_LEFT */ /* GL_RIGHT */ /* GL_AUX0 */ /* GL_AUX1 */ /* GL_AUX2 */ /* GL_AUX3 */ /* RenderingMode */ #define GL_RENDER 0x1C00 #define GL_FEEDBACK 0x1C01 #define GL_SELECT 0x1C02 /* SeparableTarget */ /* GL_SEPARABLE_2D */ /* ShadingModel */ #define GL_FLAT 0x1D00 #define GL_SMOOTH 0x1D01 /* StencilFunction */ /* GL_NEVER */ /* GL_LESS */ /* GL_EQUAL */ /* GL_LEQUAL */ /* GL_GREATER */ /* GL_NOTEQUAL */ /* GL_GEQUAL */ /* GL_ALWAYS */ /* StencilOp */ /* GL_ZERO */ #define GL_KEEP 0x1E00 #define GL_REPLACE 0x1E01 #define GL_INCR 0x1E02 #define GL_DECR 0x1E03 /* GL_INVERT */ /* StringName */ #define GL_VENDOR 0x1F00 #define GL_RENDERER 0x1F01 #define GL_VERSION 0x1F02 #define GL_EXTENSIONS 0x1F03 /* TextureCoordName */ #define GL_S 0x2000 #define GL_T 0x2001 #define GL_R 0x2002 #define GL_Q 0x2003 /* TexCoordPointerType */ /* GL_SHORT */ /* GL_INT */ /* GL_FLOAT */ /* GL_DOUBLE */ /* TextureEnvMode */ #define GL_MODULATE 0x2100 #define GL_DECAL 0x2101 /* GL_BLEND */ /* GL_REPLACE */ /* TextureEnvParameter */ #define GL_TEXTURE_ENV_MODE 0x2200 #define GL_TEXTURE_ENV_COLOR 0x2201 /* TextureEnvTarget */ #define GL_TEXTURE_ENV 0x2300 /* TextureGenMode */ #define GL_EYE_LINEAR 0x2400 #define GL_OBJECT_LINEAR 0x2401 #define GL_SPHERE_MAP 0x2402 /* TextureGenParameter */ #define GL_TEXTURE_GEN_MODE 0x2500 #define GL_OBJECT_PLANE 0x2501 #define GL_EYE_PLANE 0x2502 /* TextureMagFilter */ #define GL_NEAREST 0x2600 #define GL_LINEAR 0x2601 /* TextureMinFilter */ /* GL_NEAREST */ /* GL_LINEAR */ #define GL_NEAREST_MIPMAP_NEAREST 0x2700 #define GL_LINEAR_MIPMAP_NEAREST 0x2701 #define GL_NEAREST_MIPMAP_LINEAR 0x2702 #define GL_LINEAR_MIPMAP_LINEAR 0x2703 /* TextureParameterName */ #define GL_TEXTURE_MAG_FILTER 0x2800 #define GL_TEXTURE_MIN_FILTER 0x2801 #define GL_TEXTURE_WRAP_S 0x2802 #define GL_TEXTURE_WRAP_T 0x2803 /* GL_TEXTURE_BORDER_COLOR */ /* GL_TEXTURE_PRIORITY */ /* GL_TEXTURE_WRAP_R */ /* GL_TEXTURE_MIN_LOD */ /* GL_TEXTURE_MAX_LOD */ /* GL_TEXTURE_BASE_LEVEL */ /* GL_TEXTURE_MAX_LEVEL */ /* TextureTarget */ /* GL_TEXTURE_1D */ /* GL_TEXTURE_2D */ /* GL_PROXY_TEXTURE_1D */ /* GL_PROXY_TEXTURE_2D */ /* GL_TEXTURE_3D */ /* GL_PROXY_TEXTURE_3D */ /* TextureUnit */ /* GL_TEXTURE0_ARB */ /* GL_TEXTURE1_ARB */ /* GL_TEXTURE2_ARB */ /* GL_TEXTURE3_ARB */ /* GL_TEXTURE4_ARB */ /* GL_TEXTURE5_ARB */ /* GL_TEXTURE6_ARB */ /* GL_TEXTURE7_ARB */ /* GL_TEXTURE8_ARB */ /* GL_TEXTURE9_ARB */ /* GL_TEXTURE10_ARB */ /* GL_TEXTURE11_ARB */ /* GL_TEXTURE12_ARB */ /* GL_TEXTURE13_ARB */ /* GL_TEXTURE14_ARB */ /* GL_TEXTURE15_ARB */ /* GL_TEXTURE16_ARB */ /* GL_TEXTURE17_ARB */ /* GL_TEXTURE18_ARB */ /* GL_TEXTURE19_ARB */ /* GL_TEXTURE20_ARB */ /* GL_TEXTURE21_ARB */ /* GL_TEXTURE22_ARB */ /* GL_TEXTURE23_ARB */ /* GL_TEXTURE24_ARB */ /* GL_TEXTURE25_ARB */ /* GL_TEXTURE26_ARB */ /* GL_TEXTURE27_ARB */ /* GL_TEXTURE28_ARB */ /* GL_TEXTURE29_ARB */ /* GL_TEXTURE30_ARB */ /* GL_TEXTURE31_ARB */ /* TextureWrapMode */ #define GL_CLAMP 0x2900 #define GL_REPEAT 0x2901 /* GL_CLAMP_TO_EDGE */ /* VertexPointerType */ /* GL_SHORT */ /* GL_INT */ /* GL_FLOAT */ /* GL_DOUBLE */ /* ClientAttribMask */ #define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 #define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 #define GL_CLIENT_ALL_ATTRIB_BITS 0xffffffff /* polygon_offset */ #define GL_POLYGON_OFFSET_FACTOR 0x8038 #define GL_POLYGON_OFFSET_UNITS 0x2A00 #define GL_POLYGON_OFFSET_POINT 0x2A01 #define GL_POLYGON_OFFSET_LINE 0x2A02 #define GL_POLYGON_OFFSET_FILL 0x8037 /* texture */ #define GL_ALPHA4 0x803B #define GL_ALPHA8 0x803C #define GL_ALPHA12 0x803D #define GL_ALPHA16 0x803E #define GL_LUMINANCE4 0x803F #define GL_LUMINANCE8 0x8040 #define GL_LUMINANCE12 0x8041 #define GL_LUMINANCE16 0x8042 #define GL_LUMINANCE4_ALPHA4 0x8043 #define GL_LUMINANCE6_ALPHA2 0x8044 #define GL_LUMINANCE8_ALPHA8 0x8045 #define GL_LUMINANCE12_ALPHA4 0x8046 #define GL_LUMINANCE12_ALPHA12 0x8047 #define GL_LUMINANCE16_ALPHA16 0x8048 #define GL_INTENSITY 0x8049 #define GL_INTENSITY4 0x804A #define GL_INTENSITY8 0x804B #define GL_INTENSITY12 0x804C #define GL_INTENSITY16 0x804D #define GL_R3_G3_B2 0x2A10 #define GL_RGB4 0x804F #define GL_RGB5 0x8050 #define GL_RGB8 0x8051 #define GL_RGB10 0x8052 #define GL_RGB12 0x8053 #define GL_RGB16 0x8054 #define GL_RGBA2 0x8055 #define GL_RGBA4 0x8056 #define GL_RGB5_A1 0x8057 #define GL_RGBA8 0x8058 #define GL_RGB10_A2 0x8059 #define GL_RGBA12 0x805A #define GL_RGBA16 0x805B #define GL_TEXTURE_RED_SIZE 0x805C #define GL_TEXTURE_GREEN_SIZE 0x805D #define GL_TEXTURE_BLUE_SIZE 0x805E #define GL_TEXTURE_ALPHA_SIZE 0x805F #define GL_TEXTURE_LUMINANCE_SIZE 0x8060 #define GL_TEXTURE_INTENSITY_SIZE 0x8061 #define GL_PROXY_TEXTURE_1D 0x8063 #define GL_PROXY_TEXTURE_2D 0x8064 /* texture_object */ #define GL_TEXTURE_PRIORITY 0x8066 #define GL_TEXTURE_RESIDENT 0x8067 #define GL_TEXTURE_BINDING_1D 0x8068 #define GL_TEXTURE_BINDING_2D 0x8069 #define GL_TEXTURE_BINDING_3D 0x806A /* vertex_array */ #define GL_VERTEX_ARRAY 0x8074 #define GL_NORMAL_ARRAY 0x8075 #define GL_COLOR_ARRAY 0x8076 #define GL_INDEX_ARRAY 0x8077 #define GL_TEXTURE_COORD_ARRAY 0x8078 #define GL_EDGE_FLAG_ARRAY 0x8079 #define GL_VERTEX_ARRAY_SIZE 0x807A #define GL_VERTEX_ARRAY_TYPE 0x807B #define GL_VERTEX_ARRAY_STRIDE 0x807C #define GL_NORMAL_ARRAY_TYPE 0x807E #define GL_NORMAL_ARRAY_STRIDE 0x807F #define GL_COLOR_ARRAY_SIZE 0x8081 #define GL_COLOR_ARRAY_TYPE 0x8082 #define GL_COLOR_ARRAY_STRIDE 0x8083 #define GL_INDEX_ARRAY_TYPE 0x8085 #define GL_INDEX_ARRAY_STRIDE 0x8086 #define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 #define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 #define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A #define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C #define GL_VERTEX_ARRAY_POINTER 0x808E #define GL_NORMAL_ARRAY_POINTER 0x808F #define GL_COLOR_ARRAY_POINTER 0x8090 #define GL_INDEX_ARRAY_POINTER 0x8091 #define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 #define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 #define GL_V2F 0x2A20 #define GL_V3F 0x2A21 #define GL_C4UB_V2F 0x2A22 #define GL_C4UB_V3F 0x2A23 #define GL_C3F_V3F 0x2A24 #define GL_N3F_V3F 0x2A25 #define GL_C4F_N3F_V3F 0x2A26 #define GL_T2F_V3F 0x2A27 #define GL_T4F_V4F 0x2A28 #define GL_T2F_C4UB_V3F 0x2A29 #define GL_T2F_C3F_V3F 0x2A2A #define GL_T2F_N3F_V3F 0x2A2B #define GL_T2F_C4F_N3F_V3F 0x2A2C #define GL_T4F_C4F_N3F_V4F 0x2A2D /* bgra */ #define GL_BGR 0x80E0 #define GL_BGRA 0x80E1 /* blend_color */ #define GL_CONSTANT_COLOR 0x8001 #define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 #define GL_CONSTANT_ALPHA 0x8003 #define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 #define GL_BLEND_COLOR 0x8005 /* blend_minmax */ #define GL_FUNC_ADD 0x8006 #define GL_MIN 0x8007 #define GL_MAX 0x8008 #define GL_BLEND_EQUATION 0x8009 /* blend_subtract */ #define GL_FUNC_SUBTRACT 0x800A #define GL_FUNC_REVERSE_SUBTRACT 0x800B /* color_matrix */ #define GL_COLOR_MATRIX 0x80B1 #define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 #define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 #define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 #define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 #define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 #define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 #define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 #define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 #define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA #define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB /* color_table */ #define GL_COLOR_TABLE 0x80D0 #define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 #define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 #define GL_PROXY_COLOR_TABLE 0x80D3 #define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 #define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 #define GL_COLOR_TABLE_SCALE 0x80D6 #define GL_COLOR_TABLE_BIAS 0x80D7 #define GL_COLOR_TABLE_FORMAT 0x80D8 #define GL_COLOR_TABLE_WIDTH 0x80D9 #define GL_COLOR_TABLE_RED_SIZE 0x80DA #define GL_COLOR_TABLE_GREEN_SIZE 0x80DB #define GL_COLOR_TABLE_BLUE_SIZE 0x80DC #define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD #define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE #define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF /* convolution */ #define GL_CONVOLUTION_1D 0x8010 #define GL_CONVOLUTION_2D 0x8011 #define GL_SEPARABLE_2D 0x8012 #define GL_CONVOLUTION_BORDER_MODE 0x8013 #define GL_CONVOLUTION_FILTER_SCALE 0x8014 #define GL_CONVOLUTION_FILTER_BIAS 0x8015 #define GL_REDUCE 0x8016 #define GL_CONVOLUTION_FORMAT 0x8017 #define GL_CONVOLUTION_WIDTH 0x8018 #define GL_CONVOLUTION_HEIGHT 0x8019 #define GL_MAX_CONVOLUTION_WIDTH 0x801A #define GL_MAX_CONVOLUTION_HEIGHT 0x801B #define GL_POST_CONVOLUTION_RED_SCALE 0x801C #define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D #define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E #define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F #define GL_POST_CONVOLUTION_RED_BIAS 0x8020 #define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 #define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 #define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 #define GL_CONSTANT_BORDER 0x8151 #define GL_REPLICATE_BORDER 0x8153 #define GL_CONVOLUTION_BORDER_COLOR 0x8154 /* draw_range_elements */ #define GL_MAX_ELEMENTS_VERTICES 0x80E8 #define GL_MAX_ELEMENTS_INDICES 0x80E9 /* histogram */ #define GL_HISTOGRAM 0x8024 #define GL_PROXY_HISTOGRAM 0x8025 #define GL_HISTOGRAM_WIDTH 0x8026 #define GL_HISTOGRAM_FORMAT 0x8027 #define GL_HISTOGRAM_RED_SIZE 0x8028 #define GL_HISTOGRAM_GREEN_SIZE 0x8029 #define GL_HISTOGRAM_BLUE_SIZE 0x802A #define GL_HISTOGRAM_ALPHA_SIZE 0x802B #define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C #define GL_HISTOGRAM_SINK 0x802D #define GL_MINMAX 0x802E #define GL_MINMAX_FORMAT 0x802F #define GL_MINMAX_SINK 0x8030 #define GL_TABLE_TOO_LARGE 0x8031 /* packed_pixels */ #define GL_UNSIGNED_BYTE_3_3_2 0x8032 #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 #define GL_UNSIGNED_INT_8_8_8_8 0x8035 #define GL_UNSIGNED_INT_10_10_10_2 0x8036 #define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 #define GL_UNSIGNED_SHORT_5_6_5 0x8363 #define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 #define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 #define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 #define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 #define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 /* rescale_normal */ #define GL_RESCALE_NORMAL 0x803A /* separate_specular_color */ #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 #define GL_SINGLE_COLOR 0x81F9 #define GL_SEPARATE_SPECULAR_COLOR 0x81FA /* texture3D */ #define GL_PACK_SKIP_IMAGES 0x806B #define GL_PACK_IMAGE_HEIGHT 0x806C #define GL_UNPACK_SKIP_IMAGES 0x806D #define GL_UNPACK_IMAGE_HEIGHT 0x806E #define GL_TEXTURE_3D 0x806F #define GL_PROXY_TEXTURE_3D 0x8070 #define GL_TEXTURE_DEPTH 0x8071 #define GL_TEXTURE_WRAP_R 0x8072 #define GL_MAX_3D_TEXTURE_SIZE 0x8073 /* texture_edge_clamp */ #define GL_CLAMP_TO_EDGE 0x812F /* texture_lod */ #define GL_TEXTURE_MIN_LOD 0x813A #define GL_TEXTURE_MAX_LOD 0x813B #define GL_TEXTURE_BASE_LEVEL 0x813C #define GL_TEXTURE_MAX_LEVEL 0x813D /* GetTarget1_2 */ #define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 #define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 #define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 #define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 #define GL_ALIASED_POINT_SIZE_RANGE 0x846D #define GL_ALIASED_LINE_WIDTH_RANGE 0x846E /* multitexture */ #define GL_TEXTURE0_ARB 0x84C0 #define GL_TEXTURE1_ARB 0x84C1 #define GL_TEXTURE2_ARB 0x84C2 #define GL_TEXTURE3_ARB 0x84C3 #define GL_TEXTURE4_ARB 0x84C4 #define GL_TEXTURE5_ARB 0x84C5 #define GL_TEXTURE6_ARB 0x84C6 #define GL_TEXTURE7_ARB 0x84C7 #define GL_TEXTURE8_ARB 0x84C8 #define GL_TEXTURE9_ARB 0x84C9 #define GL_TEXTURE10_ARB 0x84CA #define GL_TEXTURE11_ARB 0x84CB #define GL_TEXTURE12_ARB 0x84CC #define GL_TEXTURE13_ARB 0x84CD #define GL_TEXTURE14_ARB 0x84CE #define GL_TEXTURE15_ARB 0x84CF #define GL_TEXTURE16_ARB 0x84D0 #define GL_TEXTURE17_ARB 0x84D1 #define GL_TEXTURE18_ARB 0x84D2 #define GL_TEXTURE19_ARB 0x84D3 #define GL_TEXTURE20_ARB 0x84D4 #define GL_TEXTURE21_ARB 0x84D5 #define GL_TEXTURE22_ARB 0x84D6 #define GL_TEXTURE23_ARB 0x84D7 #define GL_TEXTURE24_ARB 0x84D8 #define GL_TEXTURE25_ARB 0x84D9 #define GL_TEXTURE26_ARB 0x84DA #define GL_TEXTURE27_ARB 0x84DB #define GL_TEXTURE28_ARB 0x84DC #define GL_TEXTURE29_ARB 0x84DD #define GL_TEXTURE30_ARB 0x84DE #define GL_TEXTURE31_ARB 0x84DF #define GL_ACTIVE_TEXTURE_ARB 0x84E0 #define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 #define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 /* Extensions */ #define GL_EXT_abgr 1 #define GL_EXT_blend_color 1 #define GL_EXT_blend_minmax 1 #define GL_EXT_blend_subtract 1 #define GL_EXT_texture_env_combine 1 #define GL_EXT_texture_env_add 1 /* EXT_abgr */ #define GL_ABGR_EXT 0x8000 /* EXT_blend_color */ #define GL_CONSTANT_COLOR_EXT 0x8001 #define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 #define GL_CONSTANT_ALPHA_EXT 0x8003 #define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 #define GL_BLEND_COLOR_EXT 0x8005 /* EXT_blend_minmax */ #define GL_FUNC_ADD_EXT 0x8006 #define GL_MIN_EXT 0x8007 #define GL_MAX_EXT 0x8008 #define GL_BLEND_EQUATION_EXT 0x8009 /* EXT_blend_subtract */ #define GL_FUNC_SUBTRACT_EXT 0x800A #define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B /* EXT_texture_env_combine */ #define GL_COMBINE_EXT 0x8570 #define GL_COMBINE_RGB_EXT 0x8571 #define GL_COMBINE_ALPHA_EXT 0x8572 #define GL_RGB_SCALE_EXT 0x8573 #define GL_ADD_SIGNED_EXT 0x8574 #define GL_INTERPOLATE_EXT 0x8575 #define GL_CONSTANT_EXT 0x8576 #define GL_PRIMARY_COLOR_EXT 0x8577 #define GL_PREVIOUS_EXT 0x8578 #define GL_SOURCE0_RGB_EXT 0x8580 #define GL_SOURCE1_RGB_EXT 0x8581 #define GL_SOURCE2_RGB_EXT 0x8582 #define GL_SOURCE0_ALPHA_EXT 0x8588 #define GL_SOURCE1_ALPHA_EXT 0x8589 #define GL_SOURCE2_ALPHA_EXT 0x858A #define GL_OPERAND0_RGB_EXT 0x8590 #define GL_OPERAND1_RGB_EXT 0x8591 #define GL_OPERAND2_RGB_EXT 0x8592 #define GL_OPERAND0_ALPHA_EXT 0x8598 #define GL_OPERAND1_ALPHA_EXT 0x8599 #define GL_OPERAND2_ALPHA_EXT 0x859A /* For compatibility with OpenGL v1.0 */ #define GL_LOGIC_OP GL_INDEX_LOGIC_OP #define GL_TEXTURE_COMPONENTS GL_TEXTURE_INTERNAL_FORMAT /*************************************************************/ WINGDIAPI void APIENTRY glAccum (GLenum op, GLfloat value); WINGDIAPI void APIENTRY glAlphaFunc (GLenum func, GLclampf ref); WINGDIAPI GLboolean APIENTRY glAreTexturesResident (GLsizei n, const GLuint *textures, GLboolean *residences); WINGDIAPI void APIENTRY glArrayElement (GLint i); WINGDIAPI void APIENTRY glBegin (GLenum mode); WINGDIAPI void APIENTRY glBindTexture (GLenum target, GLuint texture); WINGDIAPI void APIENTRY glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); WINGDIAPI void APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); WINGDIAPI void APIENTRY glCallList (GLuint list); WINGDIAPI void APIENTRY glCallLists (GLsizei n, GLenum type, const GLvoid *lists); WINGDIAPI void APIENTRY glClear (GLbitfield mask); WINGDIAPI void APIENTRY glClearAccum (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); WINGDIAPI void APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); WINGDIAPI void APIENTRY glClearDepth (GLclampd depth); WINGDIAPI void APIENTRY glClearIndex (GLfloat c); WINGDIAPI void APIENTRY glClearStencil (GLint s); WINGDIAPI void APIENTRY glClipPlane (GLenum plane, const GLdouble *equation); WINGDIAPI void APIENTRY glColor3b (GLbyte red, GLbyte green, GLbyte blue); WINGDIAPI void APIENTRY glColor3bv (const GLbyte *v); WINGDIAPI void APIENTRY glColor3d (GLdouble red, GLdouble green, GLdouble blue); WINGDIAPI void APIENTRY glColor3dv (const GLdouble *v); WINGDIAPI void APIENTRY glColor3f (GLfloat red, GLfloat green, GLfloat blue); WINGDIAPI void APIENTRY glColor3fv (const GLfloat *v); WINGDIAPI void APIENTRY glColor3i (GLint red, GLint green, GLint blue); WINGDIAPI void APIENTRY glColor3iv (const GLint *v); WINGDIAPI void APIENTRY glColor3s (GLshort red, GLshort green, GLshort blue); WINGDIAPI void APIENTRY glColor3sv (const GLshort *v); WINGDIAPI void APIENTRY glColor3ub (GLubyte red, GLubyte green, GLubyte blue); WINGDIAPI void APIENTRY glColor3ubv (const GLubyte *v); WINGDIAPI void APIENTRY glColor3ui (GLuint red, GLuint green, GLuint blue); WINGDIAPI void APIENTRY glColor3uiv (const GLuint *v); WINGDIAPI void APIENTRY glColor3us (GLushort red, GLushort green, GLushort blue); WINGDIAPI void APIENTRY glColor3usv (const GLushort *v); WINGDIAPI void APIENTRY glColor4b (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); WINGDIAPI void APIENTRY glColor4bv (const GLbyte *v); WINGDIAPI void APIENTRY glColor4d (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); WINGDIAPI void APIENTRY glColor4dv (const GLdouble *v); WINGDIAPI void APIENTRY glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); WINGDIAPI void APIENTRY glColor4fv (const GLfloat *v); WINGDIAPI void APIENTRY glColor4i (GLint red, GLint green, GLint blue, GLint alpha); WINGDIAPI void APIENTRY glColor4iv (const GLint *v); WINGDIAPI void APIENTRY glColor4s (GLshort red, GLshort green, GLshort blue, GLshort alpha); WINGDIAPI void APIENTRY glColor4sv (const GLshort *v); WINGDIAPI void APIENTRY glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); WINGDIAPI void APIENTRY glColor4ubv (const GLubyte *v); WINGDIAPI void APIENTRY glColor4ui (GLuint red, GLuint green, GLuint blue, GLuint alpha); WINGDIAPI void APIENTRY glColor4uiv (const GLuint *v); WINGDIAPI void APIENTRY glColor4us (GLushort red, GLushort green, GLushort blue, GLushort alpha); WINGDIAPI void APIENTRY glColor4usv (const GLushort *v); WINGDIAPI void APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); WINGDIAPI void APIENTRY glColorMaterial (GLenum face, GLenum mode); WINGDIAPI void APIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); WINGDIAPI void APIENTRY glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); WINGDIAPI void APIENTRY glCopyTexImage1D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); WINGDIAPI void APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); WINGDIAPI void APIENTRY glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); WINGDIAPI void APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); WINGDIAPI void APIENTRY glCullFace (GLenum mode); WINGDIAPI void APIENTRY glDeleteLists (GLuint list, GLsizei range); WINGDIAPI void APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); WINGDIAPI void APIENTRY glDepthFunc (GLenum func); WINGDIAPI void APIENTRY glDepthMask (GLboolean flag); WINGDIAPI void APIENTRY glDepthRange (GLclampd zNear, GLclampd zFar); WINGDIAPI void APIENTRY glDisable (GLenum cap); WINGDIAPI void APIENTRY glDisableClientState (GLenum array); WINGDIAPI void APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); WINGDIAPI void APIENTRY glDrawBuffer (GLenum mode); WINGDIAPI void APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); WINGDIAPI void APIENTRY glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); WINGDIAPI void APIENTRY glEdgeFlag (GLboolean flag); WINGDIAPI void APIENTRY glEdgeFlagPointer (GLsizei stride, const GLboolean *pointer); WINGDIAPI void APIENTRY glEdgeFlagv (const GLboolean *flag); WINGDIAPI void APIENTRY glEnable (GLenum cap); WINGDIAPI void APIENTRY glEnableClientState (GLenum array); WINGDIAPI void APIENTRY glEnd (void); WINGDIAPI void APIENTRY glEndList (void); WINGDIAPI void APIENTRY glEvalCoord1d (GLdouble u); WINGDIAPI void APIENTRY glEvalCoord1dv (const GLdouble *u); WINGDIAPI void APIENTRY glEvalCoord1f (GLfloat u); WINGDIAPI void APIENTRY glEvalCoord1fv (const GLfloat *u); WINGDIAPI void APIENTRY glEvalCoord2d (GLdouble u, GLdouble v); WINGDIAPI void APIENTRY glEvalCoord2dv (const GLdouble *u); WINGDIAPI void APIENTRY glEvalCoord2f (GLfloat u, GLfloat v); WINGDIAPI void APIENTRY glEvalCoord2fv (const GLfloat *u); WINGDIAPI void APIENTRY glEvalMesh1 (GLenum mode, GLint i1, GLint i2); WINGDIAPI void APIENTRY glEvalMesh2 (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); WINGDIAPI void APIENTRY glEvalPoint1 (GLint i); WINGDIAPI void APIENTRY glEvalPoint2 (GLint i, GLint j); WINGDIAPI void APIENTRY glFeedbackBuffer (GLsizei size, GLenum type, GLfloat *buffer); WINGDIAPI void APIENTRY glFinish (void); WINGDIAPI void APIENTRY glFlush (void); WINGDIAPI void APIENTRY glFogf (GLenum pname, GLfloat param); WINGDIAPI void APIENTRY glFogfv (GLenum pname, const GLfloat *params); WINGDIAPI void APIENTRY glFogi (GLenum pname, GLint param); WINGDIAPI void APIENTRY glFogiv (GLenum pname, const GLint *params); WINGDIAPI void APIENTRY glFrontFace (GLenum mode); WINGDIAPI void APIENTRY glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); WINGDIAPI GLuint APIENTRY glGenLists (GLsizei range); WINGDIAPI void APIENTRY glGenTextures (GLsizei n, GLuint *textures); WINGDIAPI void APIENTRY glGetBooleanv (GLenum pname, GLboolean *params); WINGDIAPI void APIENTRY glGetClipPlane (GLenum plane, GLdouble *equation); WINGDIAPI void APIENTRY glGetDoublev (GLenum pname, GLdouble *params); WINGDIAPI GLenum APIENTRY glGetError (void); WINGDIAPI void APIENTRY glGetFloatv (GLenum pname, GLfloat *params); WINGDIAPI void APIENTRY glGetIntegerv (GLenum pname, GLint *params); WINGDIAPI void APIENTRY glGetLightfv (GLenum light, GLenum pname, GLfloat *params); WINGDIAPI void APIENTRY glGetLightiv (GLenum light, GLenum pname, GLint *params); WINGDIAPI void APIENTRY glGetMapdv (GLenum target, GLenum query, GLdouble *v); WINGDIAPI void APIENTRY glGetMapfv (GLenum target, GLenum query, GLfloat *v); WINGDIAPI void APIENTRY glGetMapiv (GLenum target, GLenum query, GLint *v); WINGDIAPI void APIENTRY glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params); WINGDIAPI void APIENTRY glGetMaterialiv (GLenum face, GLenum pname, GLint *params); WINGDIAPI void APIENTRY glGetPixelMapfv (GLenum map, GLfloat *values); WINGDIAPI void APIENTRY glGetPixelMapuiv (GLenum map, GLuint *values); WINGDIAPI void APIENTRY glGetPixelMapusv (GLenum map, GLushort *values); WINGDIAPI void APIENTRY glGetPointerv (GLenum pname, GLvoid* *params); WINGDIAPI void APIENTRY glGetPolygonStipple (GLubyte *mask); WINGDIAPI const GLubyte * APIENTRY glGetString (GLenum name); WINGDIAPI void APIENTRY glGetTexEnvfv (GLenum target, GLenum pname, GLfloat *params); WINGDIAPI void APIENTRY glGetTexEnviv (GLenum target, GLenum pname, GLint *params); WINGDIAPI void APIENTRY glGetTexGendv (GLenum coord, GLenum pname, GLdouble *params); WINGDIAPI void APIENTRY glGetTexGenfv (GLenum coord, GLenum pname, GLfloat *params); WINGDIAPI void APIENTRY glGetTexGeniv (GLenum coord, GLenum pname, GLint *params); WINGDIAPI void APIENTRY glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); WINGDIAPI void APIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params); WINGDIAPI void APIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params); WINGDIAPI void APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); WINGDIAPI void APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); WINGDIAPI void APIENTRY glHint (GLenum target, GLenum mode); WINGDIAPI void APIENTRY glIndexMask (GLuint mask); WINGDIAPI void APIENTRY glIndexPointer (GLenum type, GLsizei stride, const GLvoid *pointer); WINGDIAPI void APIENTRY glIndexd (GLdouble c); WINGDIAPI void APIENTRY glIndexdv (const GLdouble *c); WINGDIAPI void APIENTRY glIndexf (GLfloat c); WINGDIAPI void APIENTRY glIndexfv (const GLfloat *c); WINGDIAPI void APIENTRY glIndexi (GLint c); WINGDIAPI void APIENTRY glIndexiv (const GLint *c); WINGDIAPI void APIENTRY glIndexs (GLshort c); WINGDIAPI void APIENTRY glIndexsv (const GLshort *c); WINGDIAPI void APIENTRY glIndexub (GLubyte c); WINGDIAPI void APIENTRY glIndexubv (const GLubyte *c); WINGDIAPI void APIENTRY glInitNames (void); WINGDIAPI void APIENTRY glInterleavedArrays (GLenum format, GLsizei stride, const GLvoid *pointer); WINGDIAPI GLboolean APIENTRY glIsEnabled (GLenum cap); WINGDIAPI GLboolean APIENTRY glIsList (GLuint list); WINGDIAPI GLboolean APIENTRY glIsTexture (GLuint texture); WINGDIAPI void APIENTRY glLightModelf (GLenum pname, GLfloat param); WINGDIAPI void APIENTRY glLightModelfv (GLenum pname, const GLfloat *params); WINGDIAPI void APIENTRY glLightModeli (GLenum pname, GLint param); WINGDIAPI void APIENTRY glLightModeliv (GLenum pname, const GLint *params); WINGDIAPI void APIENTRY glLightf (GLenum light, GLenum pname, GLfloat param); WINGDIAPI void APIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params); WINGDIAPI void APIENTRY glLighti (GLenum light, GLenum pname, GLint param); WINGDIAPI void APIENTRY glLightiv (GLenum light, GLenum pname, const GLint *params); WINGDIAPI void APIENTRY glLineStipple (GLint factor, GLushort pattern); WINGDIAPI void APIENTRY glLineWidth (GLfloat width); WINGDIAPI void APIENTRY glListBase (GLuint base); WINGDIAPI void APIENTRY glLoadIdentity (void); WINGDIAPI void APIENTRY glLoadMatrixd (const GLdouble *m); WINGDIAPI void APIENTRY glLoadMatrixf (const GLfloat *m); WINGDIAPI void APIENTRY glLoadName (GLuint name); WINGDIAPI void APIENTRY glLogicOp (GLenum opcode); WINGDIAPI void APIENTRY glMap1d (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); WINGDIAPI void APIENTRY glMap1f (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); WINGDIAPI void APIENTRY glMap2d (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); WINGDIAPI void APIENTRY glMap2f (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); WINGDIAPI void APIENTRY glMapGrid1d (GLint un, GLdouble u1, GLdouble u2); WINGDIAPI void APIENTRY glMapGrid1f (GLint un, GLfloat u1, GLfloat u2); WINGDIAPI void APIENTRY glMapGrid2d (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); WINGDIAPI void APIENTRY glMapGrid2f (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); WINGDIAPI void APIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param); WINGDIAPI void APIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params); WINGDIAPI void APIENTRY glMateriali (GLenum face, GLenum pname, GLint param); WINGDIAPI void APIENTRY glMaterialiv (GLenum face, GLenum pname, const GLint *params); WINGDIAPI void APIENTRY glMatrixMode (GLenum mode); WINGDIAPI void APIENTRY glMultMatrixd (const GLdouble *m); WINGDIAPI void APIENTRY glMultMatrixf (const GLfloat *m); WINGDIAPI void APIENTRY glNewList (GLuint list, GLenum mode); WINGDIAPI void APIENTRY glNormal3b (GLbyte nx, GLbyte ny, GLbyte nz); WINGDIAPI void APIENTRY glNormal3bv (const GLbyte *v); WINGDIAPI void APIENTRY glNormal3d (GLdouble nx, GLdouble ny, GLdouble nz); WINGDIAPI void APIENTRY glNormal3dv (const GLdouble *v); WINGDIAPI void APIENTRY glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz); WINGDIAPI void APIENTRY glNormal3fv (const GLfloat *v); WINGDIAPI void APIENTRY glNormal3i (GLint nx, GLint ny, GLint nz); WINGDIAPI void APIENTRY glNormal3iv (const GLint *v); WINGDIAPI void APIENTRY glNormal3s (GLshort nx, GLshort ny, GLshort nz); WINGDIAPI void APIENTRY glNormal3sv (const GLshort *v); WINGDIAPI void APIENTRY glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer); WINGDIAPI void APIENTRY glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); WINGDIAPI void APIENTRY glPassThrough (GLfloat token); WINGDIAPI void APIENTRY glPixelMapfv (GLenum map, GLint mapsize, const GLfloat *values); WINGDIAPI void APIENTRY glPixelMapuiv (GLenum map, GLint mapsize, const GLuint *values); WINGDIAPI void APIENTRY glPixelMapusv (GLenum map, GLint mapsize, const GLushort *values); WINGDIAPI void APIENTRY glPixelStoref (GLenum pname, GLfloat param); WINGDIAPI void APIENTRY glPixelStorei (GLenum pname, GLint param); WINGDIAPI void APIENTRY glPixelTransferf (GLenum pname, GLfloat param); WINGDIAPI void APIENTRY glPixelTransferi (GLenum pname, GLint param); WINGDIAPI void APIENTRY glPixelZoom (GLfloat xfactor, GLfloat yfactor); WINGDIAPI void APIENTRY glPointSize (GLfloat size); WINGDIAPI void APIENTRY glPolygonMode (GLenum face, GLenum mode); WINGDIAPI void APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); WINGDIAPI void APIENTRY glPolygonStipple (const GLubyte *mask); WINGDIAPI void APIENTRY glPopAttrib (void); WINGDIAPI void APIENTRY glPopClientAttrib (void); WINGDIAPI void APIENTRY glPopMatrix (void); WINGDIAPI void APIENTRY glPopName (void); WINGDIAPI void APIENTRY glPrioritizeTextures (GLsizei n, const GLuint *textures, const GLclampf *priorities); WINGDIAPI void APIENTRY glPushAttrib (GLbitfield mask); WINGDIAPI void APIENTRY glPushClientAttrib (GLbitfield mask); WINGDIAPI void APIENTRY glPushMatrix (void); WINGDIAPI void APIENTRY glPushName (GLuint name); WINGDIAPI void APIENTRY glRasterPos2d (GLdouble x, GLdouble y); WINGDIAPI void APIENTRY glRasterPos2dv (const GLdouble *v); WINGDIAPI void APIENTRY glRasterPos2f (GLfloat x, GLfloat y); WINGDIAPI void APIENTRY glRasterPos2fv (const GLfloat *v); WINGDIAPI void APIENTRY glRasterPos2i (GLint x, GLint y); WINGDIAPI void APIENTRY glRasterPos2iv (const GLint *v); WINGDIAPI void APIENTRY glRasterPos2s (GLshort x, GLshort y); WINGDIAPI void APIENTRY glRasterPos2sv (const GLshort *v); WINGDIAPI void APIENTRY glRasterPos3d (GLdouble x, GLdouble y, GLdouble z); WINGDIAPI void APIENTRY glRasterPos3dv (const GLdouble *v); WINGDIAPI void APIENTRY glRasterPos3f (GLfloat x, GLfloat y, GLfloat z); WINGDIAPI void APIENTRY glRasterPos3fv (const GLfloat *v); WINGDIAPI void APIENTRY glRasterPos3i (GLint x, GLint y, GLint z); WINGDIAPI void APIENTRY glRasterPos3iv (const GLint *v); WINGDIAPI void APIENTRY glRasterPos3s (GLshort x, GLshort y, GLshort z); WINGDIAPI void APIENTRY glRasterPos3sv (const GLshort *v); WINGDIAPI void APIENTRY glRasterPos4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); WINGDIAPI void APIENTRY glRasterPos4dv (const GLdouble *v); WINGDIAPI void APIENTRY glRasterPos4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); WINGDIAPI void APIENTRY glRasterPos4fv (const GLfloat *v); WINGDIAPI void APIENTRY glRasterPos4i (GLint x, GLint y, GLint z, GLint w); WINGDIAPI void APIENTRY glRasterPos4iv (const GLint *v); WINGDIAPI void APIENTRY glRasterPos4s (GLshort x, GLshort y, GLshort z, GLshort w); WINGDIAPI void APIENTRY glRasterPos4sv (const GLshort *v); WINGDIAPI void APIENTRY glReadBuffer (GLenum mode); WINGDIAPI void APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); WINGDIAPI void APIENTRY glRectd (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); WINGDIAPI void APIENTRY glRectdv (const GLdouble *v1, const GLdouble *v2); WINGDIAPI void APIENTRY glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); WINGDIAPI void APIENTRY glRectfv (const GLfloat *v1, const GLfloat *v2); WINGDIAPI void APIENTRY glRecti (GLint x1, GLint y1, GLint x2, GLint y2); WINGDIAPI void APIENTRY glRectiv (const GLint *v1, const GLint *v2); WINGDIAPI void APIENTRY glRects (GLshort x1, GLshort y1, GLshort x2, GLshort y2); WINGDIAPI void APIENTRY glRectsv (const GLshort *v1, const GLshort *v2); WINGDIAPI GLint APIENTRY glRenderMode (GLenum mode); WINGDIAPI void APIENTRY glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z); WINGDIAPI void APIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z); WINGDIAPI void APIENTRY glScaled (GLdouble x, GLdouble y, GLdouble z); WINGDIAPI void APIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z); WINGDIAPI void APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); WINGDIAPI void APIENTRY glSelectBuffer (GLsizei size, GLuint *buffer); WINGDIAPI void APIENTRY glShadeModel (GLenum mode); WINGDIAPI void APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); WINGDIAPI void APIENTRY glStencilMask (GLuint mask); WINGDIAPI void APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); WINGDIAPI void APIENTRY glTexCoord1d (GLdouble s); WINGDIAPI void APIENTRY glTexCoord1dv (const GLdouble *v); WINGDIAPI void APIENTRY glTexCoord1f (GLfloat s); WINGDIAPI void APIENTRY glTexCoord1fv (const GLfloat *v); WINGDIAPI void APIENTRY glTexCoord1i (GLint s); WINGDIAPI void APIENTRY glTexCoord1iv (const GLint *v); WINGDIAPI void APIENTRY glTexCoord1s (GLshort s); WINGDIAPI void APIENTRY glTexCoord1sv (const GLshort *v); WINGDIAPI void APIENTRY glTexCoord2d (GLdouble s, GLdouble t); WINGDIAPI void APIENTRY glTexCoord2dv (const GLdouble *v); WINGDIAPI void APIENTRY glTexCoord2f (GLfloat s, GLfloat t); WINGDIAPI void APIENTRY glTexCoord2fv (const GLfloat *v); WINGDIAPI void APIENTRY glTexCoord2i (GLint s, GLint t); WINGDIAPI void APIENTRY glTexCoord2iv (const GLint *v); WINGDIAPI void APIENTRY glTexCoord2s (GLshort s, GLshort t); WINGDIAPI void APIENTRY glTexCoord2sv (const GLshort *v); WINGDIAPI void APIENTRY glTexCoord3d (GLdouble s, GLdouble t, GLdouble r); WINGDIAPI void APIENTRY glTexCoord3dv (const GLdouble *v); WINGDIAPI void APIENTRY glTexCoord3f (GLfloat s, GLfloat t, GLfloat r); WINGDIAPI void APIENTRY glTexCoord3fv (const GLfloat *v); WINGDIAPI void APIENTRY glTexCoord3i (GLint s, GLint t, GLint r); WINGDIAPI void APIENTRY glTexCoord3iv (const GLint *v); WINGDIAPI void APIENTRY glTexCoord3s (GLshort s, GLshort t, GLshort r); WINGDIAPI void APIENTRY glTexCoord3sv (const GLshort *v); WINGDIAPI void APIENTRY glTexCoord4d (GLdouble s, GLdouble t, GLdouble r, GLdouble q); WINGDIAPI void APIENTRY glTexCoord4dv (const GLdouble *v); WINGDIAPI void APIENTRY glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q); WINGDIAPI void APIENTRY glTexCoord4fv (const GLfloat *v); WINGDIAPI void APIENTRY glTexCoord4i (GLint s, GLint t, GLint r, GLint q); WINGDIAPI void APIENTRY glTexCoord4iv (const GLint *v); WINGDIAPI void APIENTRY glTexCoord4s (GLshort s, GLshort t, GLshort r, GLshort q); WINGDIAPI void APIENTRY glTexCoord4sv (const GLshort *v); WINGDIAPI void APIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); WINGDIAPI void APIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param); WINGDIAPI void APIENTRY glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params); WINGDIAPI void APIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param); WINGDIAPI void APIENTRY glTexEnviv (GLenum target, GLenum pname, const GLint *params); WINGDIAPI void APIENTRY glTexGend (GLenum coord, GLenum pname, GLdouble param); WINGDIAPI void APIENTRY glTexGendv (GLenum coord, GLenum pname, const GLdouble *params); WINGDIAPI void APIENTRY glTexGenf (GLenum coord, GLenum pname, GLfloat param); WINGDIAPI void APIENTRY glTexGenfv (GLenum coord, GLenum pname, const GLfloat *params); WINGDIAPI void APIENTRY glTexGeni (GLenum coord, GLenum pname, GLint param); WINGDIAPI void APIENTRY glTexGeniv (GLenum coord, GLenum pname, const GLint *params); WINGDIAPI void APIENTRY glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); WINGDIAPI void APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); WINGDIAPI void APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); WINGDIAPI void APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); WINGDIAPI void APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); WINGDIAPI void APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); WINGDIAPI void APIENTRY glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); WINGDIAPI void APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); WINGDIAPI void APIENTRY glTranslated (GLdouble x, GLdouble y, GLdouble z); WINGDIAPI void APIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z); WINGDIAPI void APIENTRY glVertex2d (GLdouble x, GLdouble y); WINGDIAPI void APIENTRY glVertex2dv (const GLdouble *v); WINGDIAPI void APIENTRY glVertex2f (GLfloat x, GLfloat y); WINGDIAPI void APIENTRY glVertex2fv (const GLfloat *v); WINGDIAPI void APIENTRY glVertex2i (GLint x, GLint y); WINGDIAPI void APIENTRY glVertex2iv (const GLint *v); WINGDIAPI void APIENTRY glVertex2s (GLshort x, GLshort y); WINGDIAPI void APIENTRY glVertex2sv (const GLshort *v); WINGDIAPI void APIENTRY glVertex3d (GLdouble x, GLdouble y, GLdouble z); WINGDIAPI void APIENTRY glVertex3dv (const GLdouble *v); WINGDIAPI void APIENTRY glVertex3f (GLfloat x, GLfloat y, GLfloat z); WINGDIAPI void APIENTRY glVertex3fv (const GLfloat *v); WINGDIAPI void APIENTRY glVertex3i (GLint x, GLint y, GLint z); WINGDIAPI void APIENTRY glVertex3iv (const GLint *v); WINGDIAPI void APIENTRY glVertex3s (GLshort x, GLshort y, GLshort z); WINGDIAPI void APIENTRY glVertex3sv (const GLshort *v); WINGDIAPI void APIENTRY glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); WINGDIAPI void APIENTRY glVertex4dv (const GLdouble *v); WINGDIAPI void APIENTRY glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); WINGDIAPI void APIENTRY glVertex4fv (const GLfloat *v); WINGDIAPI void APIENTRY glVertex4i (GLint x, GLint y, GLint z, GLint w); WINGDIAPI void APIENTRY glVertex4iv (const GLint *v); WINGDIAPI void APIENTRY glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w); WINGDIAPI void APIENTRY glVertex4sv (const GLshort *v); WINGDIAPI void APIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); WINGDIAPI void APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); #ifdef __cplusplus } #endif #endif /* __gl_h_ */ rgl/src/rglview.h0000644000176200001440000000447014100762641013463 0ustar liggesusers#ifndef RGLVIEW_H #define RGLVIEW_H // C++ header file // This file is part of RGL #include "scene.h" #include "gui.h" #include "fps.h" #include "pixmap.h" namespace rgl { class RGLView : public View { public: RGLView(Scene* scene); ~RGLView(); bool snapshot(PixmapFileFormatID formatID, const char* filename); bool pixels(int* ll, int* size, int component, double* result); bool postscript(int format, const char* filename, bool drawText); // event handler: void show(void); void hide(void); void paint(void); void resize(int width, int height); void buttonPress(int button, int mouseX, int mouseY); void buttonRelease(int button, int mouseX, int mouseY); void mouseMove(int mouseX, int mouseY); void wheelRotate(int dir, int mouseX, int mouseY); void captureLost(); void keyPress(int code); Scene* getScene(); void getUserMatrix(double* dest); void setUserMatrix(double* src); void getScale(double* dest); void setScale(double* src); const char* getFontFamily() const; void setFontFamily(const char *family); int getFontStyle() const; void setFontStyle(int style); double getFontCex() const; void setFontCex(double cex); bool getFontUseFreeType() const; void setFontUseFreeType(bool useFreeType); void setDefaultFont(const char *family, int style, double cex, bool useFreeType); const char* getFontname() const; int getActiveSubscene() {return activeSubscene;} /* NB: these functions do not maintain consistency with userMatrix */ void getPosition(double* dest); void setPosition(double* src); void setMouseListeners(Subscene* sub, unsigned int n, int* ids); protected: void setWindowImpl(WindowImpl* impl); private: // // DRAG USER-INPUT // int activeSubscene; // Translate from OS window-relative coordinates (relative to top left corner) to // OpenGL window relative (relative to bottom left corner) void translateCoords(int* mouseX, int* mouseY) const { *mouseY = height - *mouseY; } // // RENDER SYSTEM // // o LAYERS Scene* scene; FPS fps; // o CONTEXT RenderContext renderContext; bool autoUpdate; enum { FSHOWFPS = 1<<0, FAUTOUPDATE = 1<<1 }; int flags; }; } // namespace rgl #endif /* RGLVIEW_H */ rgl/src/gui.h0000644000176200001440000001347214137472630012600 0ustar liggesusers#ifndef RGL_GUI_H #define RGL_GUI_H // --------------------------------------------------------------------------- // C++ header file // This file is part of RGL // // --------------------------------------------------------------------------- #include "types.h" #include "glgui.h" #include "Disposable.h" namespace rgl { // --------------------------------------------------------------------------- enum { GUI_ButtonLeft = 1, GUI_ButtonRight, GUI_ButtonMiddle }; // --------------------------------------------------------------------------- enum { GUI_WheelForward = 1, GUI_WheelBackward }; // --------------------------------------------------------------------------- enum { GUI_KeyF1 = 128, GUI_KeyF2, GUI_KeyF3, GUI_KeyF4, GUI_KeyF5, GUI_KeyF6, GUI_KeyF7, GUI_KeyF8, GUI_KeyF9, GUI_KeyF10, GUI_KeyF11, GUI_KeyF12, GUI_KeyReturn, GUI_KeyUp, GUI_KeyDown, GUI_KeyLeft, GUI_KeyRight, GUI_KeyInsert, GUI_KeyESC }; // --------------------------------------------------------------------------- // // IMPLEMENTATION INTERFACE // // --------------------------------------------------------------------------- class View; class Window; // --------------------------------------------------------------------------- class WindowImpl { public: inline WindowImpl(Window* in_window) : window(in_window) { fonts.resize(1); } virtual ~WindowImpl() { } inline void unbind() { window = 0; } virtual void setTitle(const char* title) = 0; virtual void setWindowRect(int left, int top, int right, int bottom) = 0; virtual void getWindowRect(int *in_left, int *in_top, int *in_right, int *in_bottom) = 0; virtual int setSkipRedraw(int in_skipRedraw); virtual void show(void) = 0; virtual void hide(void) = 0; virtual void update(void) = 0; virtual void bringToTop(int stay) = 0; /// @doc notifyDestroy will be called on success virtual void destroy(void) = 0; virtual bool beginGL(void) = 0; virtual void endGL(void) = 0; virtual void swap(void) = 0; virtual void captureMouse(View* captureView) = 0; virtual void releaseMouse(void) = 0; virtual void watchMouse(bool withoutButton) = 0; virtual GLFont* getFont(const char* family, int style, double cex, bool useFreeType) = 0; void getFonts(FontArray& outfonts, int nfonts, char** family, int* style, double* cex, bool useFreeType); virtual int getAntialias(); virtual int getMaxClipPlanes(); // OpenGL support (FIXME: remove) FontArray fonts; protected: Window* window; }; // --------------------------------------------------------------------------- // // GUIFactory to be used in ABSTRACT GUI TOOLKIT // // --------------------------------------------------------------------------- class GUIFactory { public: virtual ~GUIFactory() { } virtual WindowImpl* createWindowImpl(Window*) = 0; }; // --------------------------------------------------------------------------- // // implementation specific // rgl::GUIFactory* getGUIFactory(bool useNULLDevice); // --------------------------------------------------------------------------- // // ABSTRACT GUI TOOLKIT // // --------------------------------------------------------------------------- // // view flags // // --------------------------------------------------------------------------- #define WINDOW_IMPL_OWNER (1<<0) // --------------------------------------------------------------------------- class View { public: View(); View(int basex, int basey, int width, int height, int flags); virtual ~View(); // services: virtual void setSize(int width, int height); virtual void setLocation(int basex, int basey); virtual void update(void); // event handlers: virtual void show(void); virtual void hide(void); virtual void paint(void); virtual void relocate(int baseX, int baseY); virtual void resize(int inWidth, int inHeight); virtual void keyPress(int code); virtual void keyRelease(int code); virtual void buttonPress(int button, int mouseX, int mouseY); virtual void buttonRelease(int button, int mouseX, int mouseY); virtual void wheelRotate(int direction, int mouseX, int mouseY); virtual void mouseMove(int mouseX, int mouseY); virtual void captureLost(); // protected services: virtual void setWindowImpl(WindowImpl* impl); // data: int baseX, baseY; int width, height; int flags; WindowImpl* windowImpl; friend class Window; }; // --------------------------------------------------------------------------- class Window : public View, public Disposable { public: Window(View* child=NULL, GUIFactory* factory=rgl::getGUIFactory(0) ); ~Window(); // overloaded view methods: void setWindowImpl(WindowImpl* windowImpl); // services: void setTitle(const char* title); void setVisibility(bool state); void update(void); int getSkipRedraw(void); void setSkipRedraw(int in_skipRedraw, int doUpdate = 1); /** * Close the window. **/ public: void close() { if (windowImpl) windowImpl->destroy(); else dispose(); } // protected: // event handlers: void show(); void hide(); void resize(int width, int height); void paint(); void on_close(); void notifyDestroy(); void buttonPress(int button, int mouseX, int mouseY); void buttonRelease(int button, int mouseX, int mouseY); void mouseMove(int mouseX, int mouseY); void keyPress(int code); void wheelRotate(int dir, int mouseX, int mouseY); void bringToTop(int stay); void setWindowRect(int left, int top, int right, int bottom); void getWindowRect(int *left, int *top, int *right, int *bottom); void getFonts(FontArray& outfonts, int nfonts, char** family, int* style, double* cex, bool useFreeType); // data: View* child; const char* title; bool skipRedraw; }; // --------------------------------------------------------------------------- } // namespace rgl #endif // RGL_GUI_H rgl/src/scene.cpp0000644000176200001440000002061714133075560013440 0ustar liggesusers// C++ source // This file is part of RGL. // #include "gl2ps.h" #include "scene.h" #include "SpriteSet.h" #include "rglmath.h" #include "render.h" #include "geom.h" #include #include #include #include "R.h" using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // Scene // ObjID SceneNode::nextID = 1; Scene::Scene() : rootSubscene(EMBED_REPLACE, EMBED_REPLACE, EMBED_REPLACE, EMBED_REPLACE, false), doIgnoreExtent(false) { nodes.reserve(6); nodes.push_back( currentSubscene = &rootSubscene ); add( new UserViewpoint ); add( new ModelViewpoint ); add( new Background ); add( new Light ); } Scene::~Scene() { clear(SHAPE); clear(LIGHT); clear(BBOXDECO); clear(BACKGROUND); clear(MODELVIEWPOINT); clear(USERVIEWPOINT); } UserViewpoint* Scene::getUserViewpoint() { return currentSubscene->getUserViewpoint(); } ModelViewpoint* Scene::getModelViewpoint() { return currentSubscene->getModelViewpoint(); } bool Scene::clear(TypeID type) { std::vector::iterator iter; for (iter = nodes.begin(); iter != nodes.end();) { if ((*iter)->getTypeID() == type) { SceneNode* node = (*iter); int id = node->getObjID(); if (id == rootSubscene.getObjID()) ++iter; else { hide(node->getObjID()); if (node->owner) { ++iter; } else { delete node; iter = nodes.erase(iter); } } } else ++iter; } SAVEGLERROR; return true; } bool Scene::add(SceneNode* node) { nodes.push_back( node ); return currentSubscene->add(node); } bool Scene::pop(TypeID type, int id) { std::vector::iterator iter; if (id == 0) { for (iter = nodes.end(); iter != nodes.begin();) { --iter; if ((*iter)->getTypeID() == type) { id = (*iter)->getObjID(); break; } } if (!id) return false; } iter = std::find_if(nodes.begin(), nodes.end(), // std::bind(std::ptr_fun(&sameID), placeholders::_1, id)); std::bind(&sameID, placeholders::_1, id)); if (iter != nodes.end()) { SceneNode* node = *iter; if (node == &rootSubscene) return true; hide((*iter)->getObjID()); // Rprintf("removing references to %d\n", id); removeReferences(*iter); /* Might be in mouseListeners */ nodes.erase(iter); delete node; return true; } return false; } void Scene::hide(int id) { std::vector::iterator inode; SceneNode* node = get_scenenode(id); if (node) { TypeID type = node->getTypeID(); for (inode = nodes.begin(); inode != nodes.end(); ++inode) { if ((*inode)->getTypeID() == SUBSCENE) { Subscene* subscene = static_cast((*inode)); switch (type) { case SUBSCENE: currentSubscene = subscene->hideSubscene(id, currentSubscene); break; case SHAPE: subscene->hideShape(id); break; case LIGHT: subscene->hideLight(id); break; case BBOXDECO: subscene->hideBBoxDeco(id); break; case BACKGROUND: subscene->hideBackground(id); break; case USERVIEWPOINT: case MODELVIEWPOINT: subscene->hideViewpoint(id); break; default: error("hiding type %d not implemented", type); } } } } } void Scene::removeReferences(SceneNode* node) { int id = node->getObjID(), type = node->getTypeID(); // Rprintf("node id = %d type = %u\n", id, node); for (std::vector::iterator iter = nodes.begin(); iter != nodes.end(); ++iter) { int itertype = (*iter)->getTypeID(); // Rprintf("itertype = %u\n", itertype); if (itertype == SUBSCENE) { Subscene* subscene = (Subscene*)*iter; switch (type) { case SUBSCENE: subscene->deleteMouseListener((Subscene*)node); setCurrentSubscene(subscene->hideSubscene(id, getCurrentSubscene() ) ); break; case SHAPE: subscene->hideShape(id); break; case LIGHT: subscene->hideLight(id); break; case BACKGROUND: subscene->hideBackground(id); break; case USERVIEWPOINT: case MODELVIEWPOINT: subscene->hideViewpoint(id); break; } } else if (itertype == SHAPE) { char buffer[20]; buffer[19] = 0; (*iter)->getTypeName(buffer, 20); if (!strcmp(buffer, "sprites")) { // Rprintf("removing from sprites\n"); SpriteSet* sprite = (SpriteSet*)*iter; sprite->remove_shape(id); } } } } int Scene::get_id_count(TypeID type) { int count = 0; for (std::vector::iterator iter = nodes.begin(); iter != nodes.end(); ++iter) if (type == (*iter)->getTypeID()) count++; return count; } void Scene::get_ids(TypeID type, int* ids, char** types) { char buffer[20]; for (std::vector::iterator iter = nodes.begin(); iter != nodes.end(); ++ iter) { if (type == (*iter)->getTypeID()) { *ids++ = (*iter)->getObjID(); buffer[19] = 0; (*iter)->getTypeName(buffer, 20); *types = R_alloc(strlen(buffer)+1, 1); strcpy(*types, buffer); types++; } } } SceneNode* Scene::get_scenenode(int id) { for (std::vector::iterator iter = nodes.begin(); iter != nodes.end(); ++iter) if (id == (*iter)->getObjID()) return *iter; return NULL; } SceneNode* Scene::get_scenenode(TypeID type, int id) { SceneNode* node = get_scenenode(id); if (node && node->getTypeID() == type) return node; else return NULL; } Shape* Scene::get_shape(int id) { return (Shape*)get_scenenode(SHAPE, id); } Background* Scene::get_background(int id) { return (Background*)get_scenenode(BACKGROUND, id); } BBoxDeco* Scene::get_bboxdeco(int id) { return (BBoxDeco*)get_scenenode(BBOXDECO, id); } Subscene* Scene::getSubscene(int id) { return (Subscene*)get_scenenode(SUBSCENE, id); } Subscene* Scene::whichSubscene(int id) { Subscene* result = rootSubscene.whichSubscene(id); if (!result) result = &rootSubscene; return result; } Subscene* Scene::whichSubscene(int mouseX, int mouseY) { Subscene* result = rootSubscene.whichSubscene(mouseX, mouseY); if (!result) result = &rootSubscene; return result; } Subscene* Scene::setCurrentSubscene(Subscene* subscene) { Subscene* prev = currentSubscene; currentSubscene = subscene; return prev; } void Scene::setupLightModel() { #ifndef RGL_NO_OPENGL Color global_ambient(0.0f,0.0f,0.0f,1.0f); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient.data ); glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE ); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE ); SAVEGLERROR; #endif } void Scene::update(RenderContext* renderContext) { rootSubscene.update(renderContext); } void Scene::render(RenderContext* renderContext) { #ifndef RGL_NO_OPENGL // // CLEAR BUFFERS // GLbitfield clearFlags = GL_COLOR_BUFFER_BIT; rootSubscene.get_background()->material.colors.getColor(0).useClearColor(); SAVEGLERROR; // Depth Buffer glClearDepth(1.0); glDepthFunc(GL_LESS); glDepthMask(GL_TRUE); // mask and func will be reset by material // if ( unsortedShapes.size() ) clearFlags |= GL_DEPTH_BUFFER_BIT; // The subscenes use the scissor test to limit where they draw, but we want to clear everything here // clear glDisable(GL_SCISSOR_TEST); glClear(clearFlags); glEnable(GL_SCISSOR_TEST); // userMatrix and scale might change the length of normals. If this slows us // down, we should test for that instead of just enabling GL_NORMALIZE glEnable(GL_NORMALIZE); setupLightModel(); SAVEGLERROR; // // RENDER MODEL // rootSubscene.render(renderContext, true); // All opaque stuff rootSubscene.render(renderContext, false); // non-opaque stuff #endif } // --------------------------------------------------------------------------- void Scene::invalidateDisplaylists() { std::vector::iterator iter; for (iter = nodes.begin(); iter != nodes.end(); ++iter) { if ((*iter)->getTypeID() == SHAPE) ((Shape*)(*iter))->invalidateDisplaylist(); } } bool rgl::sameID(SceneNode* node, int id) { return node->getObjID() == id; } rgl/src/Color.h0000644000176200001440000000347114100762641013062 0ustar liggesusers#ifndef COLOR_H #define COLOR_H // // CLASS // Color // // IMPLEMENTATION // uses floats as the general format for single colors, clear colors, // lighting and material color properties // #include "types.h" namespace rgl { class Color { public: Color(); Color(float red, float green, float blue, float alpha=1.0f); Color(u8 red, u8 green, u8 blue, u8 alpha); Color(const char* string); float getRedf() const { return data[0]; } float getGreenf() const { return data[1]; } float getBluef() const { return data[2]; } float getAlphaf() const { return data[3]; } u8 getRedub() const { return (u8) (data[0]*255.0f); } u8 getGreenub()const { return (u8) (data[1]*255.0f); } u8 getBlueub() const { return (u8) (data[2]*255.0f); } u8 getAlphaub()const { return (u8) (data[3]*255.0f); } float* getFloatPtr() const { return (float*) data; } /// set by integer ptr void set3iv(int* color); void useClearColor() const; void useColor() const; float data[4]; }; // // CLASS // ColorArray // IMPLEMENTATION // uses unsigned bytes as internal format for mass color datas // carries alpha values // class ColorArray { public: ColorArray(); ColorArray( ColorArray& src ); ColorArray( Color& bg, Color& fg ); ~ColorArray(); // void set( int ncolor, RColor* rcolors, u8 alpha=255 ); void set( int ncolor, char** colors, int nalpha, double* alphas ); void set( int ncolor, int* colors, int nalpha, double* alphas ); void useColor( int index ) const; void useArray() const; unsigned int getLength() const; Color getColor( int index ) const; void recycle( unsigned int newsize ); bool hasAlpha() const; private: bool hint_alphablend; unsigned int ncolor; unsigned int nalpha; u8* arrayptr; friend class Material; }; } // namespace rgl #endif // COLOR_H rgl/src/NULLgui.cpp0000644000176200001440000000753014100762641013616 0ustar liggesusers #include #include #include "config.h" // C++ source // This file is part of RGL. // #include "NULLgui.h" #include "lib.h" #include "glgui.h" #include "assert.h" #include "R.h" // --------------------------------------------------------------------------- namespace rgl { class NULLWindowImpl : public WindowImpl { public: NULLWindowImpl(Window* in_window); ~NULLWindowImpl(); void setTitle(const char* title) {}; void setWindowRect(int left, int top, int right, int bottom); void getWindowRect(int *left, int *top, int *right, int *bottom); void show() {}; void hide() {}; void bringToTop(int stay) {}; void update() { if (window) window->paint(); }; void destroy() { if (window) window->notifyDestroy(); }; void captureMouse(View* pView) {}; void releaseMouse() {}; void watchMouse(bool withoutButton) {}; GLFont* getFont(const char* family, int style, double cex, bool useFreeType); int getAntialias() { return 8; } int getMaxClipPlanes() { return INT_MAX; } private: int rect[4]; friend class NULLGUIFactory; public: bool beginGL() { return false; }; void endGL() {}; void swap() {}; }; } // namespace rgl using namespace rgl; // ---------------------------------------------------------------------------- // constructor // ---------------------------------------------------------------------------- NULLWindowImpl::NULLWindowImpl(Window* in_window) : WindowImpl(in_window) { setWindowRect(0, 0, 256, 256); fonts[0] = new NULLFont("sans", 1, 1.0, true); } NULLWindowImpl::~NULLWindowImpl() { if (window) window->notifyDestroy(); } void NULLWindowImpl::setWindowRect(int left, int top, int right, int bottom) { rect[0] = left; rect[1] = top; rect[2] = right; rect[3] = bottom; window->resize(right-left, bottom-top); } void NULLWindowImpl::getWindowRect(int *left, int *top, int *right, int *bottom) { *left = rect[0]; *top = rect[1]; *right = rect[2]; *bottom = rect[3]; } GLFont* NULLWindowImpl::getFont(const char* family, int style, double cex, bool useFreeType) { for (unsigned int i=0; i < fonts.size(); i++) { if (fonts[i]->cex == cex && fonts[i]->style == style && !strcmp(fonts[i]->family, family) && fonts[i]->useFreeType == useFreeType) return fonts[i]; } GLFont* font = new NULLFont(family, style, cex, useFreeType); fonts.push_back(font); return font; } // --------------------------------------------------------------------------- // // NULLGUIFactory class // // --------------------------------------------------------------------------- NULLGUIFactory::NULLGUIFactory() { } // --------------------------------------------------------------------------- NULLGUIFactory::~NULLGUIFactory() { } // --------------------------------------------------------------------------- WindowImpl* NULLGUIFactory::createWindowImpl(Window* in_window) { NULLWindowImpl* impl = new NULLWindowImpl(in_window); return impl; } // --------------------------------------------------------------------------- #ifdef RGL_NO_OPENGL #include namespace rgl { NULLGUIFactory* gpNULLGUIFactory = NULL; } void rgl::printMessage( const char* string ) { warning("RGL: %s\n", string); } GUIFactory* rgl::getGUIFactory(bool useNULLDevice) { if (useNULLDevice) return (GUIFactory*) gpNULLGUIFactory; else error("OpenGL is not available in this build"); } const char * rgl::GUIFactoryName(bool useNULLDevice) { return "null"; } bool rgl::init(bool useNULLDevice) { gpNULLGUIFactory = new NULLGUIFactory(); return true; } void rgl::quit() { assert(gpNULLGUIFactory != NULL); delete gpNULLGUIFactory; gpNULLGUIFactory = NULL; } double rgl::getTime() { struct ::timeval t; gettimeofday(&t,NULL); return ( (double) t.tv_sec ) * 1000.0 + ( ( (double) t.tv_usec ) / 1000.0 ); } #endif rgl/src/win32gui.cpp0000644000176200001440000006043114137472630014013 0ustar liggesusers#include "config.h" #ifdef RGL_W32 // C++ source // This file is part of RGL. // #include "win32gui.h" #include "lib.h" #include "glgui.h" #include #include #include "assert.h" #include "R.h" #include #include namespace rgl { extern int gInitValue; extern HANDLE gHandle; extern SEXP rglNamespace; static WNDPROC gDefWindowProc; static HWND gMDIClientHandle = 0; static HWND gMDIFrameHandle = 0; // describe requirements static const PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 1, // version number 0 | PFD_DRAW_TO_WINDOW // support window | PFD_SUPPORT_OPENGL // support OpenGL | PFD_GENERIC_FORMAT // generic format | PFD_DOUBLEBUFFER // double buffered , PFD_TYPE_RGBA, // RGBA type 16, // 16-bit color depth 0, 0, 0, 0, 0, 0, // color bits ignored 1, // alpha buffer 0, // shift bit ignored 0, // no accumulation buffer 0, 0, 0, 0, // accum bits ignored 16, // 16-bit z-buffer 0, // no stencil buffer 0, // no auxiliary buffer PFD_MAIN_PLANE, // main layer 0, // reserved 0, 0, 0 // layer masks ignored }; // --------------------------------------------------------------------------- // // translate keycode // // --------------------------------------------------------------------------- static int translate_key(int wParam) { if ( (wParam >= VK_F1) && (wParam <= VK_F12) ) { return ( GUI_KeyF1 + (wParam - VK_F1) ); } else { switch(wParam) { case VK_UP: return GUI_KeyUp; case VK_DOWN: return GUI_KeyDown; case VK_LEFT: return GUI_KeyLeft; case VK_RIGHT: return GUI_KeyRight; case VK_INSERT: return GUI_KeyInsert; case VK_ESCAPE: return GUI_KeyESC; default: return 0; } } } // --------------------------------------------------------------------------- class Win32WindowImpl : public WindowImpl { public: Win32WindowImpl(Window* in_window); ~Win32WindowImpl(); void setTitle(const char* title); void setWindowRect(int left, int top, int right, int bottom); void getWindowRect(int *left, int *top, int *right, int *bottom); void show(); void hide(); int isTopmost(HWND handle); void bringToTop(int stay); void update(); void destroy(); void captureMouse(View* pView); void releaseMouse(); void watchMouse(bool withoutButton) {}; GLFont* getFont(const char* family, int style, double cex, bool useFreeType); private: LRESULT processMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); static bool registerClass(); static void unregisterClass(); static LRESULT CALLBACK delegateWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); static LRESULT CALLBACK windowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); static ATOM classAtom; HWND windowHandle; View* captureView; bool painting; // window is currently busy painting bool autoUpdate; // update/refresh automatically bool refreshMenu; // need to tell Windows to update the menu #if defined(WGL_ARB_pixel_format) && !defined(WGL_WGLEXT_PROTOTYPES) PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB; #endif friend class Win32GUIFactory; public: bool beginGL(); void endGL(); void swap(); private: bool initGL(); void shutdownGL(); GLBitmapFont* initGLBitmapFont(u8 firstGlyph, u8 lastGlyph); HDC dcHandle; // temporary variable setup by lock HGLRC glrcHandle; }; } // namespace rgl using namespace rgl; // ---------------------------------------------------------------------------- // constructor // ---------------------------------------------------------------------------- Win32WindowImpl::Win32WindowImpl(Window* in_window) : WindowImpl(in_window) { windowHandle = NULL; captureView = NULL; dcHandle = NULL; glrcHandle = NULL; painting = false; autoUpdate = false; refreshMenu = false; } Win32WindowImpl::~Win32WindowImpl() { beginGL(); for (unsigned int i=0; i < fonts.size(); i++) { delete fonts[i]; } endGL(); } void Win32WindowImpl::setTitle(const char* title) { SetWindowText(windowHandle, title); } void Win32WindowImpl::setWindowRect(int left, int top, int right, int bottom) { if (windowHandle) { RECT rect; rect.left = left; rect.top = top; rect.right = right; rect.bottom = bottom; // Specification gives the desired client coordinates; expand to include the frame AdjustWindowRectEx(&rect, GetWindowLong(windowHandle, GWL_STYLE), FALSE, GetWindowLong(windowHandle, GWL_EXSTYLE)); MoveWindow(windowHandle, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE); } } void Win32WindowImpl::getWindowRect(int *left, int *top, int *right, int *bottom) { if (windowHandle) { RECT rect; GetClientRect(windowHandle, &rect); ClientToScreen(windowHandle, (LPPOINT)&rect.left); ClientToScreen(windowHandle, (LPPOINT)&rect.right); // Rect is now in screen coordinates; convert to parent client area coordinates // for MDI HWND parent = GetParent(windowHandle); if (parent) { ScreenToClient(parent, (LPPOINT)&rect.left); ScreenToClient(parent, (LPPOINT)&rect.right); } *left = rect.left; *top = rect.top; *right = rect.right; *bottom = rect.bottom; } } void Win32WindowImpl::show() { if (windowHandle) { // ShowWindow is required in SDI to show the window once // (otherwise to update takes place) ShowWindow(windowHandle, SW_SHOW); SetWindowPos( windowHandle ,HWND_TOP ,0,0,0,0 ,SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOSIZE ); update(); } else printMessage("window not bound"); } void Win32WindowImpl::hide() { if (windowHandle) { ShowWindow(windowHandle, SW_HIDE); } } int Win32WindowImpl::isTopmost(HWND handle) { return GetWindowLong(handle, GWL_EXSTYLE) & WS_EX_TOPMOST; } void Win32WindowImpl::bringToTop(int stay) /* stay=0 for regular, 1 for topmost, 2 for toggle */ { if (windowHandle) { SetForegroundWindow(windowHandle); /* needed in Rterm */ BringWindowToTop(windowHandle); /* needed in Rgui --mdi */ if (stay == 2) stay = !isTopmost(windowHandle); if (stay) SetWindowPos( windowHandle , HWND_TOPMOST , 0, 0, 0, 0 , SWP_NOMOVE | SWP_NOSIZE ); else SetWindowPos(windowHandle , HWND_NOTOPMOST , 0, 0, 0, 0 , SWP_NOMOVE | SWP_NOSIZE ); } else printMessage("window not bound"); } void Win32WindowImpl::update() { InvalidateRect(windowHandle, NULL, false); SAVEGLERROR; UpdateWindow(windowHandle); SAVEGLERROR; } void Win32WindowImpl::destroy() { if (gHandle) SendMessage(gMDIClientHandle, WM_MDIDESTROY, (WPARAM) windowHandle, 0); else DestroyWindow(windowHandle); } bool Win32WindowImpl::beginGL() { dcHandle = GetDC(windowHandle); if (wglMakeCurrent( dcHandle, glrcHandle )) return true; else return false; } void Win32WindowImpl::endGL() { ReleaseDC(windowHandle, dcHandle); } void Win32WindowImpl::swap() { dcHandle = GetDC(windowHandle); SwapBuffers(dcHandle); ReleaseDC(windowHandle, dcHandle); } void Win32WindowImpl::captureMouse(View* inCaptureView) { captureView = inCaptureView; SetCapture(windowHandle); } void Win32WindowImpl::releaseMouse(void) { captureView = NULL; ReleaseCapture(); } bool Win32WindowImpl::initGL () { bool success = false; // obtain a device context for the window dcHandle = GetDC(windowHandle); if (dcHandle) { int iPixelFormat; #ifdef WGL_ARB_pixel_format // Setup antialiasing based on "rgl.antialias" option int aa; SEXP rgl_aa = GetOption(install("rgl.antialias"),R_BaseEnv); if (isNull(rgl_aa)) aa = RGL_ANTIALIAS; else aa = asInteger(rgl_aa); if (aa > 0) { float fAttributes[] = { 0, 0 }; int iAttributes[] = { WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, WGL_SUPPORT_OPENGL_ARB, GL_TRUE, WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, WGL_COLOR_BITS_ARB, 24, WGL_ALPHA_BITS_ARB, 8, WGL_DEPTH_BITS_ARB, 16, WGL_STENCIL_BITS_ARB, 0, WGL_DOUBLE_BUFFER_ARB, GL_TRUE, WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, WGL_SAMPLES_ARB, aa, 0, 0 }; UINT numFormats = 0; if (!wglChoosePixelFormatARB || !wglChoosePixelFormatARB(dcHandle, iAttributes, fAttributes, 1, &iPixelFormat, &numFormats) || numFormats < 1) { iPixelFormat = ChoosePixelFormat(dcHandle, &pfd); } } else #endif // get the device context's best, available pixel format match iPixelFormat = ChoosePixelFormat(dcHandle, &pfd); if (iPixelFormat != 0) { // make that match the device context's current pixel format SetPixelFormat(dcHandle, iPixelFormat, &pfd); // create GL context if ( ( glrcHandle = wglCreateContext( dcHandle ) ) ) success = true; else printMessage("wglCreateContext failed"); } else printMessage("iPixelFormat == 0!"); ReleaseDC(windowHandle,dcHandle); } return success; } void Win32WindowImpl::shutdownGL() { dcHandle = GetDC(windowHandle); wglMakeCurrent(NULL,NULL); ReleaseDC(windowHandle, dcHandle); wglDeleteContext(glrcHandle); } GLFont* Win32WindowImpl::getFont(const char* family, int style, double cex, bool useFreeType) { for (unsigned int i=0; i < fonts.size(); i++) { if (fonts[i]->cex == cex && fonts[i]->style == style && !strcmp(fonts[i]->family, family) && fonts[i]->useFreeType == useFreeType) return fonts[i]; } if (!useFreeType) { // Not found, so create it. This is based on code from graphapp gdraw.c if (strcmp(family, "NA") && beginGL()) { // User passes NA_character_ for default, looks like "NA" here SEXP Rfontname = VECTOR_ELT(PROTECT(eval(lang2(install("windowsFonts"), ScalarString(mkChar(family))), rglNamespace)), 0); if (isString(Rfontname)) { const char* fontname = CHAR(STRING_ELT(Rfontname, 0)); GLBitmapFont* font = new GLBitmapFont(family, style, cex, fontname); HFONT hf; LOGFONT lf; double size = 12*cex + 0.5; lf.lfHeight = -MulDiv(size, GetDeviceCaps(dcHandle, LOGPIXELSY), 72); lf.lfWidth = 0 ; lf.lfEscapement = lf.lfOrientation = 0; lf.lfWeight = FW_NORMAL; lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0; if ((! strcmp(fontname, "Symbol")) || (! strcmp(fontname, "Wingdings"))) lf.lfCharSet = SYMBOL_CHARSET; else lf.lfCharSet = DEFAULT_CHARSET; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; if ((strlen(fontname) > 1) && (fontname[0] == 'T') && (fontname[1] == 'T')) { const char *pf; lf.lfOutPrecision = OUT_TT_ONLY_PRECIS; for (pf = &fontname[2]; isspace(*pf) ; pf++); strncpy(lf.lfFaceName, pf, LF_FACESIZE-1); } else { lf.lfOutPrecision = OUT_DEFAULT_PRECIS; strncpy(lf.lfFaceName, fontname, LF_FACESIZE-1); } if (style == 2 || style == 4) lf.lfWeight = FW_BOLD; if (style == 3 || style == 4) lf.lfItalic = 1; if ((hf = CreateFontIndirect(&lf))) { SelectObject (dcHandle, hf ); font->nglyph = GL_BITMAP_FONT_LAST_GLYPH - GL_BITMAP_FONT_FIRST_GLYPH + 1; font->widths = new unsigned int [font->nglyph]; GLuint listBase = glGenLists(font->nglyph); font->firstGlyph = GL_BITMAP_FONT_FIRST_GLYPH; font->listBase = listBase - font->firstGlyph; GetCharWidth32( dcHandle, font->firstGlyph, GL_BITMAP_FONT_LAST_GLYPH, (LPINT) font->widths ); { TEXTMETRIC tm; GetTextMetrics( dcHandle, &tm); font->ascent = tm.tmAscent; } wglUseFontBitmaps(dcHandle, font->firstGlyph, font->nglyph, listBase); DeleteObject( hf ); endGL(); fonts.push_back(font); UNPROTECT(1); return font; } delete font; endGL(); } UNPROTECT(1); } } else { // useFreeType #ifdef HAVE_FREETYPE char fontname_absolute[MAX_PATH+1] = ""; int len=0; SEXP Rfontname = VECTOR_ELT(PROTECT(eval(lang2(install("rglFonts"), ScalarString(mkChar(family))), rglNamespace)), 0); if (isString(Rfontname) && length(Rfontname) >= style) { const char* fontname = CHAR(STRING_ELT(Rfontname, style-1)); if (!IS_ABSOLUTE_PATH(fontname)) { LPITEMIDLIST pidlFonts; assert(SUCCEEDED(SHGetSpecialFolderLocation(0, CSIDL_FONTS, &pidlFonts)) && SUCCEEDED(SHGetPathFromIDList(pidlFonts, fontname_absolute)) ); len = strlen(fontname_absolute); if (len && fontname_absolute[len-1] != '\\') { strcat(fontname_absolute, "\\"); len++; } } assert(len + strlen(fontname) <= MAX_PATH); strcat(fontname_absolute, fontname); GLFTFont* font=new GLFTFont(family, style, cex, fontname_absolute); if (font->font) { fonts.push_back(font); UNPROTECT(1); return font; } else { warning(font->errmsg); delete font; } } UNPROTECT(1); #endif } if (strcmp(family, fonts[0]->family)) warning("font family \"%s\" not found, using \"%s\"", family, fonts[0]->family); else if (style != fonts[0]->style) warning("\"%s\" family only supports font %d", fonts[0]->family, fonts[0]->style); else if (cex != fonts[0]->cex) warning("\"%s\" family only supports cex = %g", fonts[0]->family, fonts[0]->cex); else if (useFreeType) warning("FreeType font not available"); return fonts[0]; } GLBitmapFont* Win32WindowImpl::initGLBitmapFont(u8 firstGlyph, u8 lastGlyph) { GLBitmapFont* font = NULL; if (beginGL()) { font = new GLBitmapFont("bitmap", 1, 1, "System"); SelectObject (dcHandle, GetStockObject (SYSTEM_FONT) ); font->nglyph = lastGlyph-firstGlyph+1; font->widths = new unsigned int [font->nglyph]; GLuint listBase = glGenLists(font->nglyph); font->firstGlyph = firstGlyph; font->listBase = listBase - firstGlyph; GetCharWidth32( dcHandle, font->firstGlyph, lastGlyph, (LPINT) font->widths ); { TEXTMETRIC tm; GetTextMetrics( dcHandle, &tm); font->ascent = tm.tmAscent; } wglUseFontBitmaps(dcHandle, font->firstGlyph, font->nglyph, listBase); endGL(); } return font; } LRESULT Win32WindowImpl::processMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { LRESULT returnValue = 0; switch(message) { case WM_CREATE: windowHandle = hwnd; initGL(); fonts[0] = initGLBitmapFont(GL_BITMAP_FONT_FIRST_GLYPH, GL_BITMAP_FONT_LAST_GLYPH); if (gHandle) { refreshMenu = true; } break; case WM_SHOWWINDOW: if ( ( (BOOL) wParam ) == TRUE ) { window->show(); autoUpdate = true; } else { window->hide(); autoUpdate = false; } break; case WM_PAINT: // Fixed now? don't put Rprintf calls in paint/render/draw methods, or you get a permanent loop! if (!painting) { painting = true; if (refreshMenu) { SendMessage(gMDIClientHandle, WM_MDIREFRESHMENU, 0, 0); DrawMenuBar(gMDIFrameHandle); refreshMenu = false; } if (!window->skipRedraw) { window->paint(); swap(); } painting = false; } ValidateRect(hwnd, NULL); break; case WM_SIZE: window->resize(LOWORD(lParam), HIWORD(lParam)); if (gHandle) return gDefWindowProc(hwnd,message,wParam,lParam); else break; case WM_CLOSE: window->on_close(); break; case WM_KEYDOWN: if (int keycode = translate_key(wParam) ) { window->keyPress(keycode); } else return -1; case WM_CHAR: window->keyPress( (int) ( (char) wParam ) ); break; case WM_LBUTTONDOWN: ( (captureView) ? captureView : window ) -> buttonPress(GUI_ButtonLeft, (short) LOWORD(lParam), (short) HIWORD(lParam) ); break; case WM_LBUTTONUP: ( (captureView) ? captureView : window ) -> buttonRelease(GUI_ButtonLeft, (short) LOWORD(lParam), (short) HIWORD(lParam)); break; case WM_RBUTTONDOWN: ( (captureView) ? captureView : window ) -> buttonPress(GUI_ButtonRight,(short) LOWORD(lParam), (short) HIWORD(lParam) ); break; case WM_RBUTTONUP: ( (captureView) ? captureView : window ) -> buttonRelease(GUI_ButtonRight,(short) LOWORD(lParam), (short) HIWORD(lParam) ); break; case WM_MBUTTONDOWN: ( (captureView) ? captureView : window ) -> buttonPress(GUI_ButtonMiddle, (short) LOWORD(lParam), (short) HIWORD(lParam) ); break; case WM_MBUTTONUP: ( (captureView) ? captureView : window ) -> buttonRelease(GUI_ButtonMiddle, (short) LOWORD(lParam), (short) HIWORD(lParam) ); break; #if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400) case WM_MOUSEWHEEL: { int dir = ( (short) HIWORD(wParam) > 0 ) ? GUI_WheelForward : GUI_WheelBackward; ( (captureView) ? captureView : window ) -> wheelRotate(dir, (short) LOWORD(lParam), (short) HIWORD(lParam) ); break; } #endif case WM_MOUSEMOVE: ( (captureView) ? captureView : window ) -> mouseMove( ( (short) LOWORD(lParam) ), ( (short) HIWORD(lParam) ) ); break; case WM_CAPTURECHANGED: if (captureView) { captureView->captureLost(); captureView = NULL; } break; case WM_DESTROY: shutdownGL(); #if defined (WIN64) || defined(_MSC_VER) SetWindowLongPtr(hwnd, GWLP_USERDATA, (long)NULL); #else SetWindowLong(hwnd, GWL_USERDATA, (LONG) NULL ); #endif if (window) window->notifyDestroy(); delete this; break; default: return gDefWindowProc(hwnd,message,wParam,lParam); } return returnValue; } // static LRESULT CALLBACK Win32WindowImpl::delegateWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { #if defined (WIN64) || defined(_MSC_VER) Win32WindowImpl* windowImpl = (Win32WindowImpl*) GetWindowLongPtr(hwnd, GWLP_USERDATA); #else Win32WindowImpl* windowImpl = (Win32WindowImpl*) GetWindowLong(hwnd, GWL_USERDATA); #endif return windowImpl->processMessage(hwnd, message, wParam, lParam); } // static LRESULT CALLBACK Win32WindowImpl::windowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { if (message == WM_CREATE) { Win32WindowImpl* windowImpl; LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); if (gHandle) { LPMDICREATESTRUCT pMDICreateStruct = reinterpret_cast(pCreateStruct->lpCreateParams); windowImpl = reinterpret_cast( pMDICreateStruct->lParam ); } else { windowImpl = reinterpret_cast( pCreateStruct->lpCreateParams ); } if (windowImpl) { #if defined (WIN64) || defined(_MSC_VER) SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)windowImpl ); SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) delegateWindowProc ); #else SetWindowLong(hwnd, GWL_USERDATA, (long) windowImpl ); SetWindowLong(hwnd, GWL_WNDPROC, (long) delegateWindowProc ); #endif return windowImpl->processMessage(hwnd, message, wParam, lParam); } } return gDefWindowProc(hwnd, message, wParam, lParam); } // static bool Win32WindowImpl::registerClass() { WNDCLASSEX wcex; ZeroMemory( &wcex, sizeof(WNDCLASSEX) ); wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wcex.lpfnWndProc = (WNDPROC) windowProc; wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.lpszClassName = "RGLDevice"; classAtom = RegisterClassEx(&wcex); return (classAtom) ? true : false; } // static void Win32WindowImpl::unregisterClass(void) { if (classAtom) UnregisterClass(MAKEINTATOM(classAtom), NULL ); } // static ATOM Win32WindowImpl::classAtom = (ATOM) NULL; // --------------------------------------------------------------------------- // // Win32GUIFactory class // // --------------------------------------------------------------------------- Win32GUIFactory::Win32GUIFactory() #if defined(WGL_ARB_pixel_format) && !defined(WGL_WGLEXT_PROTOTYPES) : wglChoosePixelFormatARB(NULL) #endif { if (gInitValue) { // we must be running in pre-2.6.0 R gHandle = reinterpret_cast(gInitValue); } if (gHandle) { // the handle is given for the console window, so that // client and frame windows can be derived HWND consoleHandle = reinterpret_cast(gHandle); gMDIClientHandle = GetParent(consoleHandle); gMDIFrameHandle = GetParent(gMDIClientHandle); gDefWindowProc = &DefMDIChildProc; } else gDefWindowProc = &DefWindowProc; if ( !Win32WindowImpl::registerClass() ) error("window class registration failed"); #if defined(WGL_ARB_pixel_format) && !defined(WGL_WGLEXT_PROTOTYPES) HANDLE saveHandle = gHandle; gHandle = NULL; /* call below fails for MDI windows */ // wglGetProcAddress needs to be called within valid GL context, we need to create dummy window here HWND windowHandle = CreateWindow(MAKEINTATOM(Win32WindowImpl::classAtom), "", WS_POPUP | WS_DISABLED, 0, 0, 10, 10, NULL, NULL, NULL, NULL); if (windowHandle) { HDC dcHandle = GetDC(windowHandle); if (dcHandle) { int iPixelFormat = ChoosePixelFormat(dcHandle, &pfd); if (iPixelFormat != 0) { SetPixelFormat(dcHandle, iPixelFormat, &pfd); HGLRC glrcHandle = wglCreateContext(dcHandle); if (glrcHandle) { wglMakeCurrent(dcHandle, glrcHandle); wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); wglMakeCurrent(NULL, NULL); wglDeleteContext(glrcHandle); } } ReleaseDC(windowHandle, dcHandle); } DestroyWindow(windowHandle); } gHandle = saveHandle; #endif } // --------------------------------------------------------------------------- Win32GUIFactory::~Win32GUIFactory() { Win32WindowImpl::unregisterClass(); } // --------------------------------------------------------------------------- WindowImpl* Win32GUIFactory::createWindowImpl(Window* in_window) { Win32WindowImpl* impl = new Win32WindowImpl(in_window); #if defined(WGL_ARB_pixel_format) && !defined(WGL_WGLEXT_PROTOTYPES) impl->wglChoosePixelFormatARB = wglChoosePixelFormatARB; #endif RECT size; size.left = 0; size.right = in_window->width-1; size.top = 0; size.bottom = in_window->height-1; AdjustWindowRect( &size , WS_OVERLAPPEDWINDOW // WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX , false // no menu ); HWND success = 0; if (gHandle) { success = CreateMDIWindow( MAKEINTATOM(Win32WindowImpl::classAtom) , in_window->title , MDIS_ALLCHILDSTYLES|WS_OVERLAPPEDWINDOW , CW_USEDEFAULT, 0 , size.right- size.left+1, size.bottom - size.top+1 , gMDIClientHandle, NULL // GetModuleHandle(NULL) , reinterpret_cast(impl) ); } else { success = CreateWindow( MAKEINTATOM(Win32WindowImpl::classAtom) , in_window->title , WS_OVERLAPPEDWINDOW , CW_USEDEFAULT, 0 , size.right- size.left+1, size.bottom - size.top+1 , NULL, NULL, NULL , reinterpret_cast(impl) ); } if (!success) error("window creation failed"); return impl; } // --------------------------------------------------------------------------- #endif // RGL_W32 rgl/src/rglmath.cpp0000644000176200001440000001547314142256754014013 0ustar liggesusers// C++ source // This file is part of RGL. // #include "rglmath.h" #include "R.h" using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // Vertex // void Vec3::normalize() { float len = this->getLength(); if (len != 0.0f) { float f = 1.0f/len; x *= f; y *= f; z *= f; } } Vec3 Vec3::cross(Vec3 op2) const { Vec3 v; v.x = y * op2.z - z * op2.y; v.y = z * op2.x - x * op2.z; v.z = x * op2.y - y * op2.x; return v; } float Vec3::angle(const Vec3& that) const { float dot; dot = x*that.x + y*that.y + z*that.z; return math::rad2deg(math::acos( dot/(this->getLength() * that.getLength()))); } Vec3 Vec3::operator * (float s) { Vec3 v; v.x = x*s; v.y = y*s; v.z = z*s; return v; } float Vec3::operator * (Vec3 v) { return (x*v.x + y*v.y + z*v.z); } Vec3 Vec3::operator - (Vec3 op2) const { Vec3 v; v.x = x - op2.x; v.y = y - op2.y; v.z = z - op2.z; return v; } void Vec3::operator += (Vec3 op2) { x += op2.x; y += op2.y; z += op2.z; } float& Vec3::operator [] (int i) { switch (i) { case 0: return x; case 1: return y; case 2: return z; } error("out of bounds"); } Vec3 Vec3::scale(const Vec3& op2) const { Vec3 t(*this); t.x *= op2.x; t.y *= op2.y; t.z *= op2.z; return t; } Vec3 Vertex::operator + (Vec3 op2) const { Vec3 t(*this); t += op2; return t; } void Vec3::rotateX(float degree) { Vec3 t(*this); float rad = math::deg2rad(degree); float s = math::sin(rad); float c = math::cos(rad); y = c*t.y + -s*t.z; z = s*t.y + c*t.z; } void Vec3::rotateY(float degree) { Vec3 t(*this); float rad = math::deg2rad(degree); float s = math::sin(rad); float c = math::cos(rad); x = c*t.x + s*t.z; z = -s*t.x + c*t.z; } bool Vec3::missing() const { return ISNAN(x) || ISNAN(y) || ISNAN(z); } ////////////////////////////////////////////////////////////////////////////// // // CLASS // Vec4 // Vec4::Vec4(const float in_x, const float in_y, const float in_z, const float in_w) { x = in_x; y = in_y; z = in_z; w = in_w; } float Vec4::operator * (const Vec4& v) const { return (x*v.x + y*v.y + z*v.z + w*v.w); } Vec4 Vec4::operator * (const float s) const { Vec4 r; r.x = x*s; r.y = y*s; r.z = z*s; r.w = w*s; return r; } Vec4 Vec4::operator + (const Vec4& v) const { return Vec4(x+v.x, y+v.y, z+v.z, w+v.w); } float& Vec4::operator [] (int i) { switch (i) { case 0: return x; case 1: return y; case 2: return z; case 3: return w; } error("out of bounds"); } ////////////////////////////////////////////////////////////////////////////// // // CLASS // Matrix4x4 // Matrix4x4::Matrix4x4() { } Matrix4x4::Matrix4x4(const Matrix4x4& src) { for(int i=0;i<16;i++) data[i] = src.data[i]; } Matrix4x4::Matrix4x4(const double* from) { loadData(from); } void Matrix4x4::loadData(const double* from) { for(int i=0;i<16;i++) data[i] = (float) from[i]; } void Matrix4x4::loadData(const float* from) { for(int i=0;i<16;i++) data[i] = from[i]; } void Matrix4x4::loadData(const Matrix4x4& from) { loadData(from.data); } Vec3 Matrix4x4::operator * (const Vec3 v) const { Vec3 r; const float v_w = 1.0f; float rw; rw = val(3,0) * v.x + val(3,1) * v.y + val(3,2) * v.z + val(3,3) * v_w; r.x = (val(0,0) * v.x + val(0,1) * v.y + val(0,2) * v.z + val(0,3) * v_w)/rw; r.y = (val(1,0) * v.x + val(1,1) * v.y + val(1,2) * v.z + val(1,3) * v_w)/rw; r.z = (val(2,0) * v.x + val(2,1) * v.y + val(2,2) * v.z + val(2,3) * v_w)/rw; return r; } Vec4 Matrix4x4::operator*(const Vec4& v) const { Vec4 r; r.x = val(0,0) * v.x + val(0,1) * v.y + val(0,2) * v.z + val(0,3) * v.w; r.y = val(1,0) * v.x + val(1,1) * v.y + val(1,2) * v.z + val(1,3) * v.w; r.z = val(2,0) * v.x + val(2,1) * v.y + val(2,2) * v.z + val(2,3) * v.w; r.w = val(3,0) * v.x + val(3,1) * v.y + val(3,2) * v.z + val(3,3) * v.w; return r; } bool Vec4::missing() const { return ISNAN(x) || ISNAN(y) || ISNAN(z) || ISNAN(w); } Matrix4x4 Matrix4x4::operator * (const Matrix4x4& op2) const { Matrix4x4 r; for(int i=0;i<4;i++) for(int j=0;j<4;j++) { float tmp = 0; for(int k=0;k<4;k++) tmp += val(i, k) * op2.val(k, j); r.ref(i,j) = tmp; } return r; } Vec4 Matrix4x4::getRow(int row) { Vec4 r; r.x = val(row, 0); r.y = val(row, 1); r.z = val(row, 2); r.w = val(row, 3); return r; } void Matrix4x4::setIdentity(void) { for(int i=0;i<16;i++) data[i] = 0.0f; ref(0,0) = 1.0f; ref(1,1) = 1.0f; ref(2,2) = 1.0f; ref(3,3) = 1.0f; } void Matrix4x4::setRotate(const int axis, const float degree) { float rad = math::deg2rad(degree); float s = math::sin(rad); float c = math::cos(rad); setIdentity(); switch(axis) { case 0: ref(1,1) = c; ref(1,2) = -s; ref(2,1) = s; ref(2,2) = c; break; case 1: ref(0,0) = c; ref(0,2) = s; ref(2,0) = -s; ref(2,2) = c; break; case 2: ref(0,0) = c; ref(0,1) = -s; ref(1,0) = s; ref(1,1) = c; break; } } void Matrix4x4::transpose() { for (int i = 0; i < 3; i++) for (int j = i+1; j < 4; j++) { float temp = val(i,j); ref(i,j) = val(j,i); ref(j,i) = temp; } } void Matrix4x4::getData(double* dest) { for(int i=0;i<16;i++) dest[i] = data[i]; } Matrix4x4 Matrix4x4::scaleMatrix(double sx, double sy, double sz) { Matrix4x4 result; result.setIdentity(); result.ref(0,0) = static_cast(sx); result.ref(1,1) = static_cast(sy); result.ref(2,2) = static_cast(sz); return result; } Matrix4x4 Matrix4x4::translationMatrix(double x, double y, double z) { Matrix4x4 result; result.setIdentity(); result.ref(0,3) = static_cast(x); result.ref(1,3) = static_cast(y); result.ref(2,3) = static_cast(z); return result; } void Matrix4x4::multRight(const Matrix4x4& M) { Matrix4x4 result; for (int i = 0; i < 4; i++ ) for (int k = 0; k < 4; k++) { result.ref(i, k) = 0.0; for (int j = 0; j < 4; j++) result.ref(i, k) += val(i, j)*M.val(j, k); } loadData(result); } void Matrix4x4::multLeft(const Matrix4x4& M) { Matrix4x4 result; for (int i = 0; i < 4; i++ ) for (int k = 0; k < 4; k++) { result.ref(i, k) = 0.0; for (int j = 0; j < 4; j++) result.ref(i, k) += M.val(i, j)*val(j, k); } loadData(result); } Matrix4x4 Matrix4x4::permutationMatrix(int newx, int newy, int newz) { Matrix4x4 result; result.ref(0, newx) = 1.0; result.ref(1, newy) = 1.0; result.ref(2, newz) = 1.0; result.ref(3, 3) = 1.0; return result; } Vertex PolarCoord::vector() const { float t = math::deg2rad(theta); float p = math::deg2rad(phi); return Vertex ( math::cos(p) * math::sin(t), math::sin(p), math::cos(p) * math::cos(t) ); } rgl/src/build/0000755000176200001440000000000014100762641012725 5ustar liggesusersrgl/src/build/autoconf/0000755000176200001440000000000014100762641014543 5ustar liggesusersrgl/src/build/autoconf/config.sub0000755000176200001440000010264614100762641016537 0ustar liggesusers#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2020 Free Software Foundation, Inc. timestamp='2020-12-02' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # 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, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=$(echo "$0" | sed -e 's,.*/,,') usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. echo "$1" exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Split fields of configuration type # shellcheck disable=SC2162 IFS="-" read field1 field2 field3 field4 <&2 exit 1 ;; *-*-*-*) basic_machine=$field1-$field2 basic_os=$field3-$field4 ;; *-*-*) # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two # parts maybe_os=$field2-$field3 case $maybe_os in nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ | storm-chaos* | os2-emx* | rtmk-nova*) basic_machine=$field1 basic_os=$maybe_os ;; android-linux) basic_machine=$field1-unknown basic_os=linux-android ;; *) basic_machine=$field1-$field2 basic_os=$field3 ;; esac ;; *-*) # A lone config we happen to match not fitting any pattern case $field1-$field2 in decstation-3100) basic_machine=mips-dec basic_os= ;; *-*) # Second component is usually, but not always the OS case $field2 in # Prevent following clause from handling this valid os sun*os*) basic_machine=$field1 basic_os=$field2 ;; # Manufacturers dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ | unicom* | ibm* | next | hp | isi* | apollo | altos* \ | convergent* | ncr* | news | 32* | 3600* | 3100* \ | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ | ultra | tti* | harris | dolphin | highlevel | gould \ | cbm | ns | masscomp | apple | axis | knuth | cray \ | microblaze* | sim | cisco \ | oki | wec | wrs | winbond) basic_machine=$field1-$field2 basic_os= ;; *) basic_machine=$field1 basic_os=$field2 ;; esac ;; esac ;; *) # Convert single-component short-hands not valid as part of # multi-component configurations. case $field1 in 386bsd) basic_machine=i386-pc basic_os=bsd ;; a29khif) basic_machine=a29k-amd basic_os=udi ;; adobe68k) basic_machine=m68010-adobe basic_os=scout ;; alliant) basic_machine=fx80-alliant basic_os= ;; altos | altos3068) basic_machine=m68k-altos basic_os= ;; am29k) basic_machine=a29k-none basic_os=bsd ;; amdahl) basic_machine=580-amdahl basic_os=sysv ;; amiga) basic_machine=m68k-unknown basic_os= ;; amigaos | amigados) basic_machine=m68k-unknown basic_os=amigaos ;; amigaunix | amix) basic_machine=m68k-unknown basic_os=sysv4 ;; apollo68) basic_machine=m68k-apollo basic_os=sysv ;; apollo68bsd) basic_machine=m68k-apollo basic_os=bsd ;; aros) basic_machine=i386-pc basic_os=aros ;; aux) basic_machine=m68k-apple basic_os=aux ;; balance) basic_machine=ns32k-sequent basic_os=dynix ;; blackfin) basic_machine=bfin-unknown basic_os=linux ;; cegcc) basic_machine=arm-unknown basic_os=cegcc ;; convex-c1) basic_machine=c1-convex basic_os=bsd ;; convex-c2) basic_machine=c2-convex basic_os=bsd ;; convex-c32) basic_machine=c32-convex basic_os=bsd ;; convex-c34) basic_machine=c34-convex basic_os=bsd ;; convex-c38) basic_machine=c38-convex basic_os=bsd ;; cray) basic_machine=j90-cray basic_os=unicos ;; crds | unos) basic_machine=m68k-crds basic_os= ;; da30) basic_machine=m68k-da30 basic_os= ;; decstation | pmax | pmin | dec3100 | decstatn) basic_machine=mips-dec basic_os= ;; delta88) basic_machine=m88k-motorola basic_os=sysv3 ;; dicos) basic_machine=i686-pc basic_os=dicos ;; djgpp) basic_machine=i586-pc basic_os=msdosdjgpp ;; ebmon29k) basic_machine=a29k-amd basic_os=ebmon ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson basic_os=ose ;; gmicro) basic_machine=tron-gmicro basic_os=sysv ;; go32) basic_machine=i386-pc basic_os=go32 ;; h8300hms) basic_machine=h8300-hitachi basic_os=hms ;; h8300xray) basic_machine=h8300-hitachi basic_os=xray ;; h8500hms) basic_machine=h8500-hitachi basic_os=hms ;; harris) basic_machine=m88k-harris basic_os=sysv3 ;; hp300 | hp300hpux) basic_machine=m68k-hp basic_os=hpux ;; hp300bsd) basic_machine=m68k-hp basic_os=bsd ;; hppaosf) basic_machine=hppa1.1-hp basic_os=osf ;; hppro) basic_machine=hppa1.1-hp basic_os=proelf ;; i386mach) basic_machine=i386-mach basic_os=mach ;; isi68 | isi) basic_machine=m68k-isi basic_os=sysv ;; m68knommu) basic_machine=m68k-unknown basic_os=linux ;; magnum | m3230) basic_machine=mips-mips basic_os=sysv ;; merlin) basic_machine=ns32k-utek basic_os=sysv ;; mingw64) basic_machine=x86_64-pc basic_os=mingw64 ;; mingw32) basic_machine=i686-pc basic_os=mingw32 ;; mingw32ce) basic_machine=arm-unknown basic_os=mingw32ce ;; monitor) basic_machine=m68k-rom68k basic_os=coff ;; morphos) basic_machine=powerpc-unknown basic_os=morphos ;; moxiebox) basic_machine=moxie-unknown basic_os=moxiebox ;; msdos) basic_machine=i386-pc basic_os=msdos ;; msys) basic_machine=i686-pc basic_os=msys ;; mvs) basic_machine=i370-ibm basic_os=mvs ;; nacl) basic_machine=le32-unknown basic_os=nacl ;; ncr3000) basic_machine=i486-ncr basic_os=sysv4 ;; netbsd386) basic_machine=i386-pc basic_os=netbsd ;; netwinder) basic_machine=armv4l-rebel basic_os=linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony basic_os=newsos ;; news1000) basic_machine=m68030-sony basic_os=newsos ;; necv70) basic_machine=v70-nec basic_os=sysv ;; nh3000) basic_machine=m68k-harris basic_os=cxux ;; nh[45]000) basic_machine=m88k-harris basic_os=cxux ;; nindy960) basic_machine=i960-intel basic_os=nindy ;; mon960) basic_machine=i960-intel basic_os=mon960 ;; nonstopux) basic_machine=mips-compaq basic_os=nonstopux ;; os400) basic_machine=powerpc-ibm basic_os=os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson basic_os=ose ;; os68k) basic_machine=m68k-none basic_os=os68k ;; paragon) basic_machine=i860-intel basic_os=osf ;; parisc) basic_machine=hppa-unknown basic_os=linux ;; psp) basic_machine=mipsallegrexel-sony basic_os=psp ;; pw32) basic_machine=i586-unknown basic_os=pw32 ;; rdos | rdos64) basic_machine=x86_64-pc basic_os=rdos ;; rdos32) basic_machine=i386-pc basic_os=rdos ;; rom68k) basic_machine=m68k-rom68k basic_os=coff ;; sa29200) basic_machine=a29k-amd basic_os=udi ;; sei) basic_machine=mips-sei basic_os=seiux ;; sequent) basic_machine=i386-sequent basic_os= ;; sps7) basic_machine=m68k-bull basic_os=sysv2 ;; st2000) basic_machine=m68k-tandem basic_os= ;; stratus) basic_machine=i860-stratus basic_os=sysv4 ;; sun2) basic_machine=m68000-sun basic_os= ;; sun2os3) basic_machine=m68000-sun basic_os=sunos3 ;; sun2os4) basic_machine=m68000-sun basic_os=sunos4 ;; sun3) basic_machine=m68k-sun basic_os= ;; sun3os3) basic_machine=m68k-sun basic_os=sunos3 ;; sun3os4) basic_machine=m68k-sun basic_os=sunos4 ;; sun4) basic_machine=sparc-sun basic_os= ;; sun4os3) basic_machine=sparc-sun basic_os=sunos3 ;; sun4os4) basic_machine=sparc-sun basic_os=sunos4 ;; sun4sol2) basic_machine=sparc-sun basic_os=solaris2 ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun basic_os= ;; sv1) basic_machine=sv1-cray basic_os=unicos ;; symmetry) basic_machine=i386-sequent basic_os=dynix ;; t3e) basic_machine=alphaev5-cray basic_os=unicos ;; t90) basic_machine=t90-cray basic_os=unicos ;; toad1) basic_machine=pdp10-xkl basic_os=tops20 ;; tpf) basic_machine=s390x-ibm basic_os=tpf ;; udi29k) basic_machine=a29k-amd basic_os=udi ;; ultra3) basic_machine=a29k-nyu basic_os=sym1 ;; v810 | necv810) basic_machine=v810-nec basic_os=none ;; vaxv) basic_machine=vax-dec basic_os=sysv ;; vms) basic_machine=vax-dec basic_os=vms ;; vsta) basic_machine=i386-pc basic_os=vsta ;; vxworks960) basic_machine=i960-wrs basic_os=vxworks ;; vxworks68) basic_machine=m68k-wrs basic_os=vxworks ;; vxworks29k) basic_machine=a29k-wrs basic_os=vxworks ;; xbox) basic_machine=i686-pc basic_os=mingw32 ;; ymp) basic_machine=ymp-cray basic_os=unicos ;; *) basic_machine=$1 basic_os= ;; esac ;; esac # Decode 1-component or ad-hoc basic machines case $basic_machine in # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) cpu=hppa1.1 vendor=winbond ;; op50n) cpu=hppa1.1 vendor=oki ;; op60c) cpu=hppa1.1 vendor=oki ;; ibm*) cpu=i370 vendor=ibm ;; orion105) cpu=clipper vendor=highlevel ;; mac | mpw | mac-mpw) cpu=m68k vendor=apple ;; pmac | pmac-mpw) cpu=powerpc vendor=apple ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) cpu=m68000 vendor=att ;; 3b*) cpu=we32k vendor=att ;; bluegene*) cpu=powerpc vendor=ibm basic_os=cnk ;; decsystem10* | dec10*) cpu=pdp10 vendor=dec basic_os=tops10 ;; decsystem20* | dec20*) cpu=pdp10 vendor=dec basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) cpu=m68k vendor=motorola ;; dpx2*) cpu=m68k vendor=bull basic_os=sysv3 ;; encore | umax | mmax) cpu=ns32k vendor=encore ;; elxsi) cpu=elxsi vendor=elxsi basic_os=${basic_os:-bsd} ;; fx2800) cpu=i860 vendor=alliant ;; genix) cpu=ns32k vendor=ns ;; h3050r* | hiux*) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) cpu=m68000 vendor=hp ;; hp9k3[2-9][0-9]) cpu=m68k vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) cpu=hppa1.1 vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; i*86v32) cpu=$(echo "$1" | sed -e 's/86.*/86/') vendor=pc basic_os=sysv32 ;; i*86v4*) cpu=$(echo "$1" | sed -e 's/86.*/86/') vendor=pc basic_os=sysv4 ;; i*86v) cpu=$(echo "$1" | sed -e 's/86.*/86/') vendor=pc basic_os=sysv ;; i*86sol2) cpu=$(echo "$1" | sed -e 's/86.*/86/') vendor=pc basic_os=solaris2 ;; j90 | j90-cray) cpu=j90 vendor=cray basic_os=${basic_os:-unicos} ;; iris | iris4d) cpu=mips vendor=sgi case $basic_os in irix*) ;; *) basic_os=irix4 ;; esac ;; miniframe) cpu=m68000 vendor=convergent ;; *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) cpu=m68k vendor=atari basic_os=mint ;; news-3600 | risc-news) cpu=mips vendor=sony basic_os=newsos ;; next | m*-next) cpu=m68k vendor=next case $basic_os in openstep*) ;; nextstep*) ;; ns2*) basic_os=nextstep2 ;; *) basic_os=nextstep3 ;; esac ;; np1) cpu=np1 vendor=gould ;; op50n-* | op60c-*) cpu=hppa1.1 vendor=oki basic_os=proelf ;; pa-hitachi) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; pbd) cpu=sparc vendor=tti ;; pbb) cpu=m68k vendor=tti ;; pc532) cpu=ns32k vendor=pc532 ;; pn) cpu=pn vendor=gould ;; power) cpu=power vendor=ibm ;; ps2) cpu=i386 vendor=ibm ;; rm[46]00) cpu=mips vendor=siemens ;; rtpc | rtpc-*) cpu=romp vendor=ibm ;; sde) cpu=mipsisa32 vendor=sde basic_os=${basic_os:-elf} ;; simso-wrs) cpu=sparclite vendor=wrs basic_os=vxworks ;; tower | tower-32) cpu=m68k vendor=ncr ;; vpp*|vx|vx-*) cpu=f301 vendor=fujitsu ;; w65) cpu=w65 vendor=wdc ;; w89k-*) cpu=hppa1.1 vendor=winbond basic_os=proelf ;; none) cpu=none vendor=none ;; leon|leon[3-9]) cpu=sparc vendor=$basic_machine ;; leon-*|leon[3-9]-*) cpu=sparc vendor=$(echo "$basic_machine" | sed 's/-.*//') ;; *-*) # shellcheck disable=SC2162 IFS="-" read cpu vendor <&2 exit 1 ;; esac ;; esac # Here we canonicalize certain aliases for manufacturers. case $vendor in digital*) vendor=dec ;; commodore*) vendor=cbm ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if test x$basic_os != x then # First recognize some ad-hoc caes, or perhaps split kernel-os, or else just # set os. case $basic_os in gnu/linux*) kernel=linux os=$(echo $basic_os | sed -e 's|gnu/linux|gnu|') ;; os2-emx) kernel=os2 os=$(echo $basic_os | sed -e 's|os2-emx|emx|') ;; nto-qnx*) kernel=nto os=$(echo $basic_os | sed -e 's|nto-qnx|qnx|') ;; *-*) # shellcheck disable=SC2162 IFS="-" read kernel os <&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. case $kernel-$os in linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* | linux-musl* | linux-uclibc* ) ;; uclinux-uclibc* ) ;; -dietlibc* | -newlib* | -musl* | -uclibc* ) # These are just libc implementations, not actual OSes, and thus # require a kernel. echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 exit 1 ;; kfreebsd*-gnu* | kopensolaris*-gnu*) ;; nto-qnx*) ;; os2-emx) ;; *-eabi* | *-gnueabi*) ;; -*) # Blank kernel with real OS is always fine. ;; *-*) echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 exit 1 ;; esac # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. case $vendor in unknown) case $cpu-$os in *-riscix*) vendor=acorn ;; *-sunos*) vendor=sun ;; *-cnk* | *-aix*) vendor=ibm ;; *-beos*) vendor=be ;; *-hpux*) vendor=hp ;; *-mpeix*) vendor=hp ;; *-hiux*) vendor=hitachi ;; *-unos*) vendor=crds ;; *-dgux*) vendor=dg ;; *-luna*) vendor=omron ;; *-genix*) vendor=ns ;; *-clix*) vendor=intergraph ;; *-mvs* | *-opened*) vendor=ibm ;; *-os400*) vendor=ibm ;; s390-* | s390x-*) vendor=ibm ;; *-ptx*) vendor=sequent ;; *-tpf*) vendor=ibm ;; *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; *-aux*) vendor=apple ;; *-hms*) vendor=hitachi ;; *-mpw* | *-macos*) vendor=apple ;; *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; *-vos*) vendor=stratus ;; esac ;; esac echo "$cpu-$vendor-${kernel:+$kernel-}$os" exit # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: rgl/src/build/autoconf/config.guess0000755000176200001440000014017214100762641017070 0ustar liggesusers#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2020 Free Software Foundation, Inc. timestamp='2020-11-19' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # 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, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . me=$(echo "$0" | sed -e 's,.*/,,') usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. tmp= # shellcheck disable=SC2172 trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 set_cc_for_build() { # prevent multiple calls if $tmp is already set test "$tmp" && return 0 : "${TMPDIR=/tmp}" # shellcheck disable=SC2039 { tmp=$( (umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null) && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" for driver in cc gcc c89 c99 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD="$driver" break fi done if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac } # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown case "$UNAME_SYSTEM" in Linux|GNU|GNU/*) LIBC=unknown set_cc_for_build cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu #else #include /* First heuristic to detect musl libc. */ #ifdef __DEFINED_va_list LIBC=musl #endif #endif EOF eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g')" # Second heuristic to detect musl libc. if [ "$LIBC" = unknown ] && command -v ldd >/dev/null && ldd --version 2>&1 | grep -q ^musl; then LIBC=musl fi # If the system lacks a compiler, then just pick glibc. # We could probably try harder. if [ "$LIBC" = unknown ]; then LIBC=gnu fi ;; esac # Note: order is significant - the case branches are not exclusive. case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=$( (uname -p 2>/dev/null || \ "/sbin/$sysctl" 2>/dev/null || \ "/usr/sbin/$sysctl" 2>/dev/null || \ echo unknown)) case "$UNAME_MACHINE_ARCH" in aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=$(echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,') endian=$(echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p') machine="${arch}${endian}"-unknown ;; *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case "$UNAME_MACHINE_ARCH" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case "$UNAME_MACHINE_ARCH" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr") ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "$UNAME_VERSION" in Debian*) release='-gnu' ;; *) release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2) ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "$machine-${os}${release}${abi-}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//') echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=$(arch | sed 's/OpenBSD.//') echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=$(arch | sed 's/^.*BSD\.//') echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" exit ;; *:MidnightBSD:*:*) echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" exit ;; *:ekkoBSD:*:*) echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" exit ;; *:SolidBSD:*:*) echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" exit ;; *:OS108:*:*) echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE" exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:MirBSD:*:*) echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:Sortix:*:*) echo "$UNAME_MACHINE"-unknown-sortix exit ;; *:Twizzler:*:*) echo "$UNAME_MACHINE"-unknown-twizzler exit ;; *:Redox:*:*) echo "$UNAME_MACHINE"-unknown-redox exit ;; mips:OSF1:*.*) echo mips-dec-osf1 exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $3}') ;; *5.*) UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $4}') ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=$(/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1) case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo "$UNAME_MACHINE"-dec-osf"$(echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)" # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo "$UNAME_MACHINE"-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo "$UNAME_MACHINE"-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix"$UNAME_RELEASE" exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "$( (/bin/universe) 2>/dev/null)" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case $(/usr/bin/uname -p) in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo "$UNAME_MACHINE"-ibm-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')" exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi echo "$SUN_ARCH"-pc-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:*:*) case "$(/usr/bin/arch -k)" in Series*|S4*) UNAME_RELEASE=$(uname -v) ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')" exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=$( (sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null) test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case "$(/bin/arch)" in sun3) echo m68k-sun-sunos"$UNAME_RELEASE" ;; sun4) echo sparc-sun-sunos"$UNAME_RELEASE" ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos"$UNAME_RELEASE" exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint"$UNAME_RELEASE" exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint"$UNAME_RELEASE" exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint"$UNAME_RELEASE" exit ;; m68k:machten:*:*) echo m68k-apple-machten"$UNAME_RELEASE" exit ;; powerpc:machten:*:*) echo powerpc-apple-machten"$UNAME_RELEASE" exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix"$UNAME_RELEASE" exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && dummyarg=$(echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p') && SYSTEM_NAME=$("$dummy" "$dummyarg") && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos"$UNAME_RELEASE" exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=$(/usr/bin/uname -p) if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ test "$TARGET_BINARY_INTERFACE"x = x then echo m88k-dg-dgux"$UNAME_RELEASE" else echo m88k-dg-dguxbcs"$UNAME_RELEASE" fi else echo i586-dg-dgux"$UNAME_RELEASE" fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/g')" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'$(uname -s)'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if test -x /usr/bin/oslevel ; then IBM_REV=$(/usr/bin/oslevel) else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=$(/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }') if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if test -x /usr/bin/lslpp ; then IBM_REV=$(/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/) else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi echo "$IBM_ARCH"-ibm-aix"$IBM_REV" exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//') case "$UNAME_MACHINE" in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if test -x /usr/bin/getconf; then sc_cpu_version=$(/usr/bin/getconf SC_CPU_VERSION 2>/dev/null) sc_kernel_bits=$(/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null) case "$sc_cpu_version" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "$sc_kernel_bits" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if test "$HP_ARCH" = ""; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=$("$dummy") test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if test "$HP_ARCH" = hppa2.0w then set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//') echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if test -x /usr/sbin/sysversion ; then echo "$UNAME_MACHINE"-unknown-osf1mk else echo "$UNAME_MACHINE"-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=$(uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz) FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///') FUJITSU_REL=$(echo "$UNAME_RELEASE" | sed -e 's/ /_/') echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///') FUJITSU_REL=$(echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/') echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; arm:FreeBSD:*:*) UNAME_PROCESSOR=$(uname -p) set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabi else echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf fi exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=$(/usr/bin/uname -p) case "$UNAME_PROCESSOR" in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac echo "$UNAME_PROCESSOR"-unknown-freebsd"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')" exit ;; i*:CYGWIN*:*) echo "$UNAME_MACHINE"-pc-cygwin exit ;; *:MINGW64*:*) echo "$UNAME_MACHINE"-pc-mingw64 exit ;; *:MINGW*:*) echo "$UNAME_MACHINE"-pc-mingw32 exit ;; *:MSYS*:*) echo "$UNAME_MACHINE"-pc-msys exit ;; i*:PW*:*) echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) case "$UNAME_MACHINE" in x86) echo i586-pc-interix"$UNAME_RELEASE" exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix"$UNAME_RELEASE" exit ;; IA64) echo ia64-unknown-interix"$UNAME_RELEASE" exit ;; esac ;; i*:UWIN*:*) echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-pc-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; *:GNU:*:*) # the GNU system echo "$(echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,')-unknown-$LIBC$(echo "$UNAME_RELEASE"|sed -e 's,/.*$,,')" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo "$UNAME_MACHINE-unknown-$(echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]")$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')-$LIBC" exit ;; *:Minix:*:*) echo "$UNAME_MACHINE"-unknown-minix exit ;; aarch64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) case $(sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null) in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi else echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf fi fi exit ;; avr32*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; cris:Linux:*:*) echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; crisv32:Linux:*:*) echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; e2k:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; frv:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; hexagon:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:Linux:*:*) echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; ia64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; k1om:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m32r*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m68*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) set_cc_for_build IS_GLIBC=0 test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef mips #undef mipsel #undef mips64 #undef mips64el #if ${IS_GLIBC} && defined(_ABI64) LIBCABI=gnuabi64 #else #if ${IS_GLIBC} && defined(_ABIN32) LIBCABI=gnuabin32 #else LIBCABI=${LIBC} #endif #endif #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa64r6 #else #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa32r6 #else #if defined(__mips64) CPU=mips64 #else CPU=mips #endif #endif #endif #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) MIPS_ENDIAN= #else MIPS_ENDIAN= #endif #endif EOF eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI')" test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-"$LIBC" exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; padre:Linux:*:*) echo sparc-unknown-linux-"$LIBC" exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-"$LIBC" exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case $(grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2) in PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; *) echo hppa-unknown-linux-"$LIBC" ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-"$LIBC" exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-"$LIBC" exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-"$LIBC" exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-"$LIBC" exit ;; riscv32:Linux:*:* | riscv64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" exit ;; sh64*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sh*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; tile*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; vax:Linux:*:*) echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) set_cc_for_build LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_X32 >/dev/null then LIBCABI="$LIBC"x32 fi fi echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI" exit ;; xtensa*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo "$UNAME_MACHINE"-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo "$UNAME_MACHINE"-unknown-stop exit ;; i*86:atheos:*:*) echo "$UNAME_MACHINE"-unknown-atheos exit ;; i*86:syllable:*:*) echo "$UNAME_MACHINE"-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos"$UNAME_RELEASE" exit ;; i*86:*DOS:*:*) echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; i*86:*:4.*:*) UNAME_REL=$(echo "$UNAME_RELEASE" | sed 's/\/MP$//') if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case $(/bin/uname -X | grep "^Machine") in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=$(sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=$( (/bin/uname -X|grep Release|sed -e 's/.*= //')) (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" else echo "$UNAME_MACHINE"-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos"$UNAME_RELEASE" exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos"$UNAME_RELEASE" exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos"$UNAME_RELEASE" exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos"$UNAME_RELEASE" exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv"$UNAME_RELEASE" exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=$( (uname -p) 2>/dev/null) echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo "$UNAME_MACHINE"-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux"$UNAME_RELEASE" exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if test -d /usr/nec; then echo mips-nec-sysv"$UNAME_RELEASE" else echo mips-unknown-sysv"$UNAME_RELEASE" fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux"$UNAME_RELEASE" exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux"$UNAME_RELEASE" exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux"$UNAME_RELEASE" exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux"$UNAME_RELEASE" exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux"$UNAME_RELEASE" exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux"$UNAME_RELEASE" exit ;; SX-ACE:SUPER-UX:*:*) echo sxace-nec-superux"$UNAME_RELEASE" exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; arm64:Darwin:*:*) echo aarch64-apple-darwin"$UNAME_RELEASE" exit ;; *:Darwin:*:*) UNAME_PROCESSOR=$(uname -p) case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac if command -v xcode-select > /dev/null 2> /dev/null && \ ! xcode-select --print-path > /dev/null 2> /dev/null ; then # Avoid executing cc if there is no toolchain installed as # cc will be a stub that puts up a graphical alert # prompting the user to install developer tools. CC_FOR_BUILD=no_compiler_found else set_cc_for_build fi if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then # uname -m returns i386 or x86_64 UNAME_PROCESSOR=$UNAME_MACHINE fi echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=$(uname -p) if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-*:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk"$UNAME_RELEASE" exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk"$UNAME_RELEASE" exit ;; NSR-*:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk"$UNAME_RELEASE" exit ;; NSV-*:NONSTOP_KERNEL:*:*) echo nsv-tandem-nsk"$UNAME_RELEASE" exit ;; NSX-*:NONSTOP_KERNEL:*:*) echo nsx-tandem-nsk"$UNAME_RELEASE" exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. # shellcheck disable=SC2154 if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo "$UNAME_MACHINE"-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')" exit ;; *:*VMS:*:*) UNAME_MACHINE=$( (uname -p) 2>/dev/null) case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')" exit ;; i*86:rdos:*:*) echo "$UNAME_MACHINE"-pc-rdos exit ;; i*86:AROS:*:*) echo "$UNAME_MACHINE"-pc-aros exit ;; x86_64:VMkernel:*:*) echo "$UNAME_MACHINE"-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; *:Unleashed:*:*) echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" exit ;; esac # No uname command or uname output not recognized. set_cc_for_build cat > "$dummy.c" < #include #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #include #if defined(_SIZE_T_) || defined(SIGLOST) #include #endif #endif #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=$( (hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null); if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) #include #if defined (BSD) #if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); #else #if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); #else printf ("vax-dec-bsd\n"); exit (0); #endif #endif #else printf ("vax-dec-bsd\n"); exit (0); #endif #else #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname un; uname (&un); printf ("vax-dec-ultrix%s\n", un.release); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname *un; uname (&un); printf ("mips-dec-ultrix%s\n", un.release); exit (0); #else printf ("mips-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=$($dummy) && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } echo "$0: unable to guess system type" >&2 case "$UNAME_MACHINE:$UNAME_SYSTEM" in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 <&2 </dev/null || echo unknown) uname -r = $( (uname -r) 2>/dev/null || echo unknown) uname -s = $( (uname -s) 2>/dev/null || echo unknown) uname -v = $( (uname -v) 2>/dev/null || echo unknown) /usr/bin/uname -p = $( (/usr/bin/uname -p) 2>/dev/null) /bin/uname -X = $( (/bin/uname -X) 2>/dev/null) hostinfo = $( (hostinfo) 2>/dev/null) /bin/universe = $( (/bin/universe) 2>/dev/null) /usr/bin/arch -k = $( (/usr/bin/arch -k) 2>/dev/null) /bin/arch = $( (/bin/arch) 2>/dev/null) /usr/bin/oslevel = $( (/usr/bin/oslevel) 2>/dev/null) /usr/convex/getsysinfo = $( (/usr/convex/getsysinfo) 2>/dev/null) UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF fi exit 1 # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: rgl/src/build/autoconf/install-sh0000755000176200001440000003325514100762641016557 0ustar liggesusers#!/bin/sh # install - install a program, script, or datafile scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: rgl/src/Background.cpp0000644000176200001440000001576714145464133014435 0ustar liggesusers#include "Background.h" #include "Viewpoint.h" #include "scene.h" #include "rglmath.h" #include "R.h" using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // Background // Material Background::defaultMaterial( Color(0.3f,0.3f,0.3f), Color(1.0f,0.0f,0.0f) ); Background::Background(Material& in_material, bool in_sphere, int in_fogtype, float in_fogScale) : Shape(in_material, true, BACKGROUND), sphere(in_sphere), fogtype(in_fogtype), fogScale(in_fogScale), quad(NULL) { clearColorBuffer = true; if (sphere) { material.colors.recycle(2); material.front = Material::CULL_FACE; material.colorPerVertex(false); if (material.back == Material::FILL_FACE) clearColorBuffer = false; if ( (material.lit) || ( (material.texture) && (material.texture->is_envmap() ) ) ) sphereMesh.setGenNormal(true); if ( (material.texture) && (!material.texture->is_envmap() ) ) sphereMesh.setGenTexCoord(true); sphereMesh.setGlobe (16,16); sphereMesh.setCenter( Vertex(0.0f,0.0f,0.0f) ); sphereMesh.setRadius( 1.0f ); sphereMesh.update(); } else if (material.texture) { double vertices[12] = { -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1 }; double texcoords[8] = { 0, 0, 1, 0, 1, 1, 0, 1 }; material.colorPerVertex(false); material.colors.recycle(1); quad = new QuadSet(material, 4, vertices, NULL, texcoords, true, 0, NULL, 0, 1); quad->owner = this; } else material.colors.recycle(1); } Background::~Background() { if (quad) { quad->owner = NULL; quad = NULL; } } GLbitfield Background::getClearFlags(RenderContext* renderContext) { if (clearColorBuffer) { material.colors.getColor(0).useClearColor(); return GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT; } else return GL_DEPTH_BUFFER_BIT; } // FIXME: this doesn't follow the pattern of other render methods. void Background::render(RenderContext* renderContext) { #ifndef RGL_NO_OPENGL Subscene* subscene = renderContext->subscene; UserViewpoint* userviewpoint = subscene->getUserViewpoint(); const AABox& bbox = subscene->getBoundingBox(); // setup fog if ((fogtype != FOG_NONE) && (bbox.isValid() )) { // Sphere bsphere(bbox); glFogfv(GL_FOG_COLOR, material.colors.getColor(0).getFloatPtr() ); switch(fogtype) { case FOG_LINEAR: glFogi(GL_FOG_MODE, GL_LINEAR); glFogf(GL_FOG_START, userviewpoint->frustum.znear /*bsphere.radius*2*/); // glFogf(GL_FOG_END, userviewpoint->frustum.zfar /*bsphere.radius*3*/ ); // Scale fog density up by fogScale glFogf(GL_FOG_END, (userviewpoint->frustum.zfar - userviewpoint->frustum.znear)/fogScale + userviewpoint->frustum.znear); break; case FOG_EXP: glFogi(GL_FOG_MODE, GL_EXP); // glFogf(GL_FOG_DENSITY, 1.0f/userviewpoint->frustum.zfar /*(bsphere.radius*3)*/ ); // Multiply fog density parameter by fogScale glFogf(GL_FOG_DENSITY, fogScale*1.0f/userviewpoint->frustum.zfar /*(bsphere.radius*3)*/ ); break; case FOG_EXP2: glFogi(GL_FOG_MODE, GL_EXP2); // Multiply fog density parameter by fogScale glFogf(GL_FOG_DENSITY, fogScale*1.0f/userviewpoint->frustum.zfar /*(bsphere.radius*3)*/ ); break; } glEnable(GL_FOG); } else { glDisable(GL_FOG); } // render bg sphere if (sphere) { float fov = userviewpoint->getFOV(); float hlen, znear; if (fov > 0.0) { double rad = math::deg2rad(fov/2.0f); hlen = static_cast(math::sin(rad) * math::cos(math::deg2rad(45.0))); znear = hlen / static_cast(math::tan(rad)); } else { hlen = static_cast(math::cos(math::deg2rad(45.0))); znear = hlen; } float zfar = znear + 1.0f; float hwidth, hheight; float winwidth = (float) renderContext->rect.width; float winheight = (float) renderContext->rect.height; // aspect ratio if (winwidth >= winheight) { hwidth = hlen; hheight = hlen * (winheight / winwidth); } else { hwidth = hlen * (winwidth / winheight); hheight = hlen; } glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); if (fov != 0.0) { glFrustum(-hwidth, hwidth, -hheight, hheight, znear, zfar ); } else { glOrtho(-hwidth, hwidth, -hheight, hheight, znear, zfar ); } glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glTranslatef(0.0f,0.0f,-znear); ModelViewpoint* modelviewpoint = subscene->getModelViewpoint(); modelviewpoint->setupOrientation(renderContext); Shape::render(renderContext); glMatrixMode(GL_MODELVIEW); /* just in case... */ glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); } else if (quad) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); quad->draw(renderContext); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); } #endif } void Background::drawPrimitive(RenderContext* renderContext, int index) { #ifndef RGL_NO_OPENGL glPushAttrib(GL_ENABLE_BIT); material.beginUse(renderContext); material.useColor(1); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); sphereMesh.drawPrimitive(renderContext, index); material.endUse(renderContext); glPopAttrib(); #endif } int Background::getAttributeCount(AABox& bbox, AttribID attrib) { switch (attrib) { case FLAGS: return 4; case FOGSCALE: return 1; case TYPES: case IDS: if (quad) return 1; else return 0; } return Shape::getAttributeCount(bbox, attrib); } void Background::getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result) { int n = getAttributeCount(bbox, attrib); if (first + count < n) n = first + count; if (first < n) { switch(attrib) { case FLAGS: if (first <= 0) *result++ = (double) sphere; if (first <= 1) *result++ = (double) fogtype == FOG_LINEAR; if (first <= 2) *result++ = (double) fogtype == FOG_EXP; if (first <= 3) *result++ = (double) fogtype == FOG_EXP2; return; case FOGSCALE: if (first <= 0) *result++ = fogScale; return; case IDS: if (quad) *result++ = quad->getObjID(); return; } Shape::getAttribute(bbox, attrib, first, count, result); } } String Background::getTextAttribute(AABox& bbox, AttribID attrib, int index) { int n = getAttributeCount(bbox, attrib); if (index < n && attrib == TYPES) { char* buffer = R_alloc(20, 1); quad->getTypeName(buffer, 20); return String(static_cast(strlen(buffer)), buffer); } else return Shape::getTextAttribute(bbox, attrib, index); } rgl/src/ClipPlane.cpp0000644000176200001440000000726014100762641014206 0ustar liggesusers#include "ClipPlane.h" #include "Viewpoint.h" #include "R.h" #include using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // ClipPlaneSet // int ClipPlaneSet::num_planes = 0; ClipPlaneSet::ClipPlaneSet(Material& in_material, int in_nnormal, double* in_normal, int in_noffset, double* in_offset) : Shape(in_material,true), nPlanes(max(in_nnormal, in_noffset)), normal(in_nnormal, in_normal), offset(in_noffset, in_offset) { } int ClipPlaneSet::getAttributeCount(AABox& bbox, AttribID attrib) { switch (attrib) { case NORMALS: case OFFSETS: return nPlanes; } return 0; } void ClipPlaneSet::getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result) { int n = getAttributeCount(bbox, attrib); if (first + count < n) n = first + count; if (first < n) { if (attrib == NORMALS) { while (first < n) { *result++ = normal.getRecycled(first).x; *result++ = normal.getRecycled(first).y; *result++ = normal.getRecycled(first).z; first++; } } else if (attrib == OFFSETS) { while (first < n) *result++ = offset.getRecycled(first++); } } } void ClipPlaneSet::renderBegin(RenderContext* renderContext) { firstPlane = GL_CLIP_PLANE0 + num_planes; num_planes += nPlanes; } void ClipPlaneSet::drawPrimitive(RenderContext* renderContext, int index) { #ifndef RGL_NO_OPENGL GLdouble eqn[4]; eqn[0] = normal.getRecycled(index).x; eqn[1] = normal.getRecycled(index).y; eqn[2] = normal.getRecycled(index).z; eqn[3] = offset.getRecycled(index); glClipPlane(firstPlane + index, eqn); glEnable(firstPlane + index); #endif } void ClipPlaneSet::enable(bool show) { #ifndef RGL_NO_OPENGL for (int i=0; i 0) bbox.vmin.x = getMax(bbox.vmin.x, b1*(b1 > 0 ? bbox.vmin.y : bbox.vmax.y) +c1*(c1 > 0 ? bbox.vmin.z : bbox.vmax.z) +d1); else if (a < 0) bbox.vmax.x = getMin(bbox.vmax.x, b1*(b1 > 0 ? bbox.vmax.y : bbox.vmin.y) +c1*(c1 > 0 ? bbox.vmax.z : bbox.vmin.z) +d1); a1 = -a/b; c1 = -c/b; d1 = -d/b; if (b > 0) bbox.vmin.y = getMax(bbox.vmin.y, a1*(a1 > 0 ? bbox.vmin.x : bbox.vmax.x) +c1*(c1 > 0 ? bbox.vmin.z : bbox.vmax.z) +d1); else if (b < 0) bbox.vmax.y = getMin(bbox.vmax.y, a1*(a1 > 0 ? bbox.vmax.x : bbox.vmin.x) +c1*(c1 > 0 ? bbox.vmax.z : bbox.vmin.z) +d1); a1 = -a/c; b1 = -b/c; d1 = -d/c; if (c > 0) bbox.vmin.z = getMax(bbox.vmin.z, a1*(a1 > 0 ? bbox.vmin.x : bbox.vmax.x) +b1*(b1 > 0 ? bbox.vmin.y : bbox.vmax.y) +d1); else if (c < 0) bbox.vmax.z = getMin(bbox.vmax.z, a1*(a1 > 0 ? bbox.vmax.x : bbox.vmin.x) +b1*(b1 > 0 ? bbox.vmax.y : bbox.vmin.y) +d1); } } rgl/src/platform.h0000644000176200001440000000160114100762641013621 0ustar liggesusers#ifndef PLATFORM_H #define PLATFORM_H /* These are some platform-specific definitions, currently to support MacOSX */ #include "opengl.h" /* MacOSX */ #ifdef RGL_OSX #include #ifndef __MAC_10_9 #define __MAC_10_9 1090 #endif #if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_9 // pre-Mavericks code #else // Mavericks and later #define MODERN_OPENGL #define gluUnProject rgl_gluUnProject #define gluErrorString rgl_gluErrorString GLint gluUnProject(GLdouble winX, GLdouble winY, GLdouble winZ, const GLdouble * model, const GLdouble * proj, const GLint * view, GLdouble* objX, GLdouble* objY, GLdouble* objZ); const GLubyte * gluErrorString(GLenum error); #endif /* Mavericks */ #endif /* RGL_OSX */ #endif /* PLATFORM_H */ rgl/src/win32gui.h0000644000176200001440000000130714100762641013447 0ustar liggesusers#ifndef RGL_W32_GUI_H #define RGL_W32_GUI_H // --------------------------------------------------------------------------- #include "gui.h" // --------------------------------------------------------------------------- #include namespace rgl { // --------------------------------------------------------------------------- class Win32GUIFactory : public GUIFactory { public: Win32GUIFactory(); virtual ~Win32GUIFactory(); WindowImpl* createWindowImpl(Window* window); #ifndef WGL_WGLEXT_PROTOTYPES PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB; #endif }; // --------------------------------------------------------------------------- } // namespace rgl #endif // RGL_W32_GUI_H rgl/src/Material.h0000644000176200001440000000307314145464133013544 0ustar liggesusers#ifndef MATERIAL_H #define MATERIAL_H #include "Color.h" #include "Texture.h" #include "RenderContext.h" #include namespace rgl { // // STRUCT // Material // class Material { public: enum PolygonMode { FILL_FACE=1, LINE_FACE, POINT_FACE, CULL_FACE }; Material( Color bg, Color fg ); void setup(); // called when complete void beginUse(RenderContext* renderContext); void endUse(RenderContext* renderContext); void useColor(int index); void colorPerVertex(bool enable, int numVertices=0); bool isTransparent() const { return alphablend; } Color ambient; Color specular; Color emission; float shininess; float size; // point size float lwd; // line width float polygon_offset_factor; float polygon_offset_units; ColorArray colors; // color or if lit, represents diffuse color Ref texture; PolygonMode front; PolygonMode back; bool alphablend; bool smooth; bool lit; bool fog; bool useColorArray; bool point_antialias; bool line_antialias; bool depth_mask; int depth_test; // 0=GL_NEVER, 1=GL_LESS, etc. Texture::Type textype; bool mipmap; unsigned int minfilter; unsigned int magfilter; bool envmap; bool polygon_offset; int marginCoord; int edge[3]; bool floating; string tag; double glVersion; }; } // namespace rgl #endif // MATERIAL_H rgl/src/R.h0000644000176200001440000000204714100762641012203 0ustar liggesusers#ifndef RGL_R_H #define RGL_R_H // This define avoids a warning about ERROR redefinition in Windows #define STRICT_R_HEADERS #include /* Default for antialiasing */ #define RGL_ANTIALIAS 8 /* Set this to 1 to turn on glGetError testing */ #define USE_GLGETERROR 0 #if USE_GLGETERROR #define SAVEGLERROR saveGLerror(__FILE__, __LINE__); #define CHECKGLERROR checkGLerror(__FILE__, __LINE__); /* saveGLerror is safe to call from a message handler. It saves one error. */ /* checkGLerror is not safe within a message handler. It checks for saved errors or */ /* other errors, then reports them through R. */ /* Neither one can be called with glBegin() ... glEnd() pairs. */ /* They are defined in glErrors.cpp */ namespace rgl { extern int SaveErrnum; void saveGLerror(const char *, int); void checkGLerror(const char *, int); } // namespace rgl #else #define SAVEGLERROR #define CHECKGLERROR #endif #endif /* RGL_R_H */ rgl/src/subscene.cpp0000644000176200001440000012213714142256754014160 0ustar liggesusers#include "subscene.h" #include "rglview.h" #include "select.h" #include "gl2ps.h" #include "R.h" #include #include using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // Subscene // Subscene::Subscene(Embedding in_viewport, Embedding in_projection, Embedding in_model, Embedding in_mouseHandlers, bool in_ignoreExtent) : SceneNode(SUBSCENE), parent(NULL), do_viewport(in_viewport), do_projection(in_projection), do_model(in_model), do_mouseHandlers(in_mouseHandlers), viewport(0.,0.,1.,1.),Zrow(), Wrow(), pviewport(0,0,1024,1024), drag(0), ignoreExtent(in_ignoreExtent), selectState(msNONE), dragBase(0.0f,0.0f), dragCurrent(0.0f,0.0f) { userviewpoint = NULL; modelviewpoint = NULL; bboxdeco = NULL; background = NULL; bboxChanges = false; data_bbox.invalidate(); modelMatrix.setIdentity(); projMatrix.setIdentity(); mouseListeners.push_back(this); for (int i=0; i<5; i++) { beginCallback[i] = NULL; updateCallback[i] = NULL; endCallback[i] = NULL; cleanupCallback[i] = NULL; for (int j=0; j<3; j++) userData[3*i + j] = NULL; } setDefaultMouseMode(); } Subscene::~Subscene() { for (std::vector::iterator i = subscenes.begin(); i != subscenes.end(); ++ i ) delete (*i); for (int i=0; i<5; i++) if (cleanupCallback[i]) (*cleanupCallback[i])(userData + 3*i); } bool Subscene::add(SceneNode* node) { bool success = false; switch( node->getTypeID() ) { case SHAPE: { Shape* shape = (Shape*) node; addShape(shape); success = true; } break; case LIGHT: { Light* light = (Light*) node; addLight(light); success = true; } break; case USERVIEWPOINT: { userviewpoint = (UserViewpoint*) node; success = true; } break; case MODELVIEWPOINT: { modelviewpoint = (ModelViewpoint*) node; success = true; } break; case SUBSCENE: { Subscene* subscene = static_cast(node); if (subscene->parent) error("Subscene %d is already a child of subscene %d.", subscene->getObjID(), subscene->parent->getObjID()); addSubscene(subscene); success = true; } break; case BACKGROUND: { Background* new_background = static_cast(node); addBackground(new_background); success = true; } break; case BBOXDECO: { BBoxDeco* new_bboxdeco = static_cast(node); addBBoxDeco(new_bboxdeco); success = true; } break; default: break; } return success; } void Subscene::addBackground(Background* newbackground) { background = newbackground; } void Subscene::addBBoxDeco(BBoxDeco* newbboxdeco) { bboxdeco = newbboxdeco; } void Subscene::addShape(Shape* shape) { if (!shape->getIgnoreExtent()) addBBox(shape->getBoundingBox(), shape->getBBoxChanges()); shapes.push_back(shape); if ( shape->isBlended() ) { zsortShapes.push_back(shape); } else if ( shape->isClipPlane() ) { clipPlanes.push_back(static_cast(shape)); shrinkBBox(); } else unsortedShapes.push_back(shape); } void Subscene::addBBox(const AABox& bbox, bool changes) { data_bbox += bbox; bboxChanges |= changes; intersectClipplanes(); if (parent && !ignoreExtent) parent->addBBox(data_bbox, changes); } void Subscene::addLight(Light* light) { lights.push_back(light); } void Subscene::addSubscene(Subscene* subscene) { subscenes.push_back(subscene); subscene->parent = this; subscene->newEmbedding(); if (!subscene->getIgnoreExtent()) addBBox(subscene->getBoundingBox(), subscene->bboxChanges); } void Subscene::hideShape(int id) { std::vector::iterator ishape = std::find_if(shapes.begin(), shapes.end(), std::bind(&sameID, placeholders::_1, id)); if (ishape == shapes.end()) return; Shape* shape = *ishape; shapes.erase(ishape); if ( shape->isBlended() ) zsortShapes.erase(std::find_if(zsortShapes.begin(), zsortShapes.end(), std::bind(&sameID, placeholders::_1, id))); else if ( shape->isClipPlane() ) clipPlanes.erase(std::find_if(clipPlanes.begin(), clipPlanes.end(), std::bind(&sameID, placeholders::_1, id))); else unsortedShapes.erase(std::find_if(unsortedShapes.begin(), unsortedShapes.end(), std::bind(&sameID, placeholders::_1, id))); shrinkBBox(); } void Subscene::hideLight(int id) { std::vector::iterator ilight = std::find_if(lights.begin(), lights.end(), std::bind(&sameID, placeholders::_1, id)); if (ilight != lights.end()) { lights.erase(ilight); } } void Subscene::hideBBoxDeco(int id) { if (bboxdeco && sameID(bboxdeco, id)) bboxdeco = NULL; } void Subscene::hideBackground(int id) { if (background && sameID(background, id)) { if (parent) background = NULL; else background = new( Background ); /* The root must always have a background */ } } Subscene* Subscene::hideSubscene(int id, Subscene* current) { for (std::vector::iterator i = subscenes.begin(); i != subscenes.end(); ++ i) { if (sameID(*i, id)) { if ((*i)->getSubscene(current->getObjID())) current = (*i)->parent; (*i)->parent = NULL; subscenes.erase(i); shrinkBBox(); return current; } } return current; } void Subscene::hideViewpoint(int id) { if (userviewpoint && sameID(userviewpoint, id)) { if (parent) /* the root needs a viewpoint */ userviewpoint = NULL; } else if (modelviewpoint && sameID(modelviewpoint, id)) { if (parent) /* the root needs a viewpoint */ modelviewpoint = NULL; } } Subscene* Subscene::getSubscene(int id) { if (id == getObjID()) return this; for (std::vector::iterator i = subscenes.begin(); i != subscenes.end() ; ++ i ) { Subscene* subscene = (*i)->getSubscene(id); if (subscene) return subscene; } return NULL; } Subscene* Subscene::whichSubscene(int id) { for (std::vector::iterator i = shapes.begin(); i != shapes.end() ; ++ i ) { if ((*i)->getObjID() == id) return this; } for (std::vector::iterator i = lights.begin(); i != lights.end() ; ++ i ) { if ((*i)->getObjID() == id) return this; } if (bboxdeco && bboxdeco->getObjID() == id) return this; for (std::vector::iterator i = subscenes.begin(); i != subscenes.end(); ++ i ) { if ((*i)->getObjID() == id) return this; } if (userviewpoint && userviewpoint->getObjID() == id) return this; if (modelviewpoint && modelviewpoint->getObjID() == id) return this; if (background && background->getObjID() == id) return this; for (std::vector::iterator i = subscenes.begin(); i != subscenes.end() ; ++ i ) { Subscene* result = (*i)->whichSubscene(id); if (result) return result; } return NULL; } Subscene* Subscene::whichSubscene(int mouseX, int mouseY) { Subscene* result = NULL; Subscene* sub; for (std::vector::iterator i = subscenes.begin(); i != subscenes.end() ; ++ i ) { result = (sub = (*i)->whichSubscene(mouseX, mouseY)) ? sub : result; } if (!result && pviewport.x <= mouseX && mouseX < pviewport.x + pviewport.width && pviewport.y <= mouseY && mouseY < pviewport.y + pviewport.height) result = this; return result; } int Subscene::getAttributeCount(AABox& bbox, AttribID attrib) { switch (attrib) { case IDS: case TYPES: return (int)shapes.size(); } return SceneNode::getAttributeCount(bbox, attrib); } void Subscene::getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result) { int n = getAttributeCount(bbox, attrib); int ind = 0; if (first + count < n) n = first + count; if (first < n) { switch(attrib) { case IDS: for (std::vector::iterator i = shapes.begin(); i != shapes.end() ; ++ i ) { if ( first <= ind && ind < n ) *result++ = (*i)->getObjID(); ind++; } return; } SceneNode::getAttribute(bbox, attrib, first, count, result); } } String Subscene::getTextAttribute(AABox& bbox, AttribID attrib, int index) { int n = getAttributeCount(bbox, attrib); if (index < n && attrib == TYPES) { char* buffer = R_alloc(20, 1); shapes[index]->getTypeName(buffer, 20); return String(static_cast(strlen(buffer)), buffer); } else return SceneNode::getTextAttribute(bbox, attrib, index); } void Subscene::renderClipplanes(RenderContext* renderContext) { std::vector::iterator iter; ClipPlaneSet::num_planes = 0; for (iter = clipPlanes.begin() ; iter != clipPlanes.end() ; ++iter ) { ClipPlaneSet* plane = *iter; plane->render(renderContext); SAVEGLERROR; } } void Subscene::disableClipplanes(RenderContext* renderContext) { std::vector::iterator iter; for (iter = clipPlanes.begin() ; iter != clipPlanes.end() ; ++iter ) { ClipPlaneSet* plane = *iter; plane->enable(false); SAVEGLERROR; } } int Subscene::get_id_count(TypeID type, bool recursive) { int result = 0; if (recursive) for (std::vector::iterator i = subscenes.begin(); i != subscenes.end(); ++ i ) result += (*i)->get_id_count(type, recursive); switch (type) { case SHAPE: { result += shapes.size(); break; } case LIGHT: { result += lights.size(); break; } case BBOXDECO: { result += bboxdeco ? 1 : 0; break; } case SUBSCENE: { result += subscenes.size(); break; } case USERVIEWPOINT: { result += do_projection > EMBED_INHERIT ? 1 : 0; break; } case MODELVIEWPOINT: { result += do_model > EMBED_INHERIT ? 1 : 0; break; } case BACKGROUND: { result += background ? 1 : 0; break; } } return result; } int Subscene::get_ids(TypeID type, int* ids, char** types, bool recursive) { char buffer[20]; int count = 0; switch(type) { case SHAPE: for (std::vector::iterator i = shapes.begin(); i != shapes.end() ; ++ i ) { *ids++ = (*i)->getObjID(); buffer[19] = 0; (*i)->getTypeName(buffer, 20); *types = R_alloc(strlen(buffer)+1, 1); strcpy(*types, buffer); types++; count++; } break; case LIGHT: for (std::vector::iterator i = lights.begin(); i != lights.end() ; ++ i ) { *ids++ = (*i)->getObjID(); *types = R_alloc(strlen("light")+1, 1); strcpy(*types, "light"); types++; count++; } break; case BBOXDECO: if (bboxdeco) { *ids++ = bboxdeco->getObjID(); *types = R_alloc(strlen("bboxdeco")+1, 1); strcpy(*types, "bboxdeco"); types++; count++; } break; case SUBSCENE: for (std::vector::iterator i = subscenes.begin(); i != subscenes.end(); ++ i ) { *ids++ = (*i)->getObjID(); *types = R_alloc(strlen("subscene")+1, 1); strcpy(*types, "subscene"); types++; count++; } break; case USERVIEWPOINT: if (userviewpoint) { *ids++ = userviewpoint->getObjID(); *types = R_alloc(strlen("userviewpoint")+1, 1); strcpy(*types, "userviewpoint"); types++; count++; } break; case MODELVIEWPOINT: if (modelviewpoint) { *ids++ = modelviewpoint->getObjID(); *types = R_alloc(strlen("modelviewpoint")+1, 1); strcpy(*types, "modelviewpoint"); types++; count++; } break; case BACKGROUND: if (background) { *ids++ = background->getObjID(); *types = R_alloc(strlen("background")+1, 1); strcpy(*types, "background"); types++; count++; } break; } if (recursive) for (std::vector::iterator i = subscenes.begin(); i != subscenes.end(); ++ i ) { int newcount = (*i)->get_ids(type, ids, types, true); ids += newcount; types += newcount; count += newcount; } return count; } Background* Subscene::get_background() { if (background) return background; else if (parent) return parent->get_background(); else return NULL; } Background* Subscene::get_background(int id) { Background* this_background = get_background(); if (this_background && this_background->getObjID() == id) return this_background; std::vector::const_iterator iter; for(iter = subscenes.begin(); iter != subscenes.end(); ++iter) { this_background = (*iter)->get_background(id); if (this_background) return this_background; } return NULL; } BBoxDeco* Subscene::get_bboxdeco() { if (bboxdeco) return bboxdeco; else if (parent) return parent->get_bboxdeco(); else return NULL; } BBoxDeco* Subscene::get_bboxdeco(int id) { BBoxDeco* this_bboxdeco = get_bboxdeco(); if (this_bboxdeco && this_bboxdeco->getObjID() == id) return this_bboxdeco; std::vector::const_iterator iter; for(iter = subscenes.begin(); iter != subscenes.end(); ++iter) { this_bboxdeco = (*iter)->get_bboxdeco(id); if (this_bboxdeco) return this_bboxdeco; } return NULL; } UserViewpoint* Subscene::getUserViewpoint() { if (userviewpoint && do_projection > EMBED_INHERIT) return userviewpoint; else if (parent) return parent->getUserViewpoint(); else error("must have a user viewpoint"); } ModelViewpoint* Subscene::getModelViewpoint() { if (modelviewpoint && do_model > EMBED_INHERIT) return modelviewpoint; else if (parent) return parent->getModelViewpoint(); else error("must have a model viewpoint"); } void Subscene::update(RenderContext* renderContext) { GLdouble saveprojection[16]; renderContext->subscene = this; setupViewport(renderContext); if (bboxChanges) calcDataBBox(); Sphere total_bsphere; if (data_bbox.isValid()) { // // GET DATA VOLUME SPHERE // total_bsphere = Sphere( (bboxdeco) ? bboxdeco->getBoundingBox(data_bbox) : data_bbox, getModelViewpoint()->scale ); if (total_bsphere.radius <= 0.0) total_bsphere.radius = 1.0; } else { total_bsphere = Sphere( Vertex(0,0,0), 1 ); } // Now get the matrices. First we compute the projection matrix. If we're inheriting, // just use the parent. if (do_projection > EMBED_INHERIT) { projMatrix.getData(saveprojection); setupProjMatrix(renderContext, total_bsphere); } else projMatrix = parent->projMatrix; // Now the model matrix. Since this depends on both the viewpoint and the model // transformations, we don't bother using the parent one, we reconstruct in // every subscene. if (do_projection > EMBED_INHERIT || do_model > EMBED_INHERIT) setupModelViewMatrix(renderContext, total_bsphere.center); else modelMatrix = parent->modelMatrix; // update subscenes std::vector::const_iterator iter; for(iter = subscenes.begin(); iter != subscenes.end(); ++iter) (*iter)->update(renderContext); } void Subscene::loadMatrices() { #ifndef RGL_NO_OPENGL double mat[16]; projMatrix.getData(mat); glMatrixMode(GL_PROJECTION); glLoadMatrixd(mat); SAVEGLERROR; modelMatrix.getData(mat); glMatrixMode(GL_MODELVIEW); glLoadMatrixd(mat); SAVEGLERROR; #endif } void Subscene::render(RenderContext* renderContext, bool opaquePass) { #ifndef RGL_NO_OPENGL renderContext->subscene = this; glViewport(pviewport.x, pviewport.y, pviewport.width, pviewport.height); glScissor(pviewport.x, pviewport.y, pviewport.width, pviewport.height); SAVEGLERROR; if (background && opaquePass) { GLbitfield clearFlags = background->getClearFlags(renderContext); // clear glDepthMask(GL_TRUE); glClear(clearFlags); } SAVEGLERROR; // Now render the current scene. First we load the projection matrix, then the modelview matrix. loadMatrices(); setupLights(renderContext); if (opaquePass) { if (background) { // // RENDER BACKGROUND // // DISABLE Z-BUFFER TEST glDisable(GL_DEPTH_TEST); // DISABLE Z-BUFFER FOR WRITING glDepthMask(GL_FALSE); background->render(renderContext); SAVEGLERROR; } // // RENDER SOLID SHAPES // // ENABLE Z-BUFFER TEST glEnable(GL_DEPTH_TEST); // ENABLE Z-BUFFER FOR WRITING glDepthMask(GL_TRUE); // DISABLE BLENDING glDisable(GL_BLEND); // // RENDER BBOX DECO // if (bboxdeco) bboxdeco->render(renderContext); // This changes the modelview/projection/viewport SAVEGLERROR; } // CLIP PLANES renderClipplanes(renderContext); if (opaquePass) { renderUnsorted(renderContext); // #define NO_BLEND } else { #ifndef NO_BLEND // // RENDER BLENDED SHAPES // // render shapes in bounding-box sorted order according to z value // // DISABLE Z-BUFFER FOR WRITING glDepthMask(GL_FALSE); SAVEGLERROR; // SETUP BLENDING if (renderContext->gl2psActive == GL2PS_NONE) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); else gl2psBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); SAVEGLERROR; // ENABLE BLENDING glEnable(GL_BLEND); SAVEGLERROR; // // GET THE TRANSFORMATION // Matrix4x4 M(modelMatrix); Matrix4x4 P(projMatrix); P = P*M; Zrow = P.getRow(2); Wrow = P.getRow(3); renderZsort(renderContext); #endif } /* Reset flag(s) now that scene has been rendered */ getModelViewpoint()->scaleChanged = false; /* Reset clipplanes */ disableClipplanes(renderContext); SAVEGLERROR; // Render subscenes std::vector::const_iterator iter; for(iter = subscenes.begin(); iter != subscenes.end(); ++iter) (*iter)->render(renderContext, opaquePass); if (selectState == msCHANGING) { SELECT select; select.render(mousePosition); } #endif } void Subscene::calcDataBBox() { data_bbox.invalidate(); std::vector::const_iterator subiter; bboxChanges = false; for(subiter = subscenes.begin(); subiter != subscenes.end(); ++subiter) { Subscene* subscene = *subiter; if (!subscene->getIgnoreExtent()) { subscene->calcDataBBox(); data_bbox += subscene->getBoundingBox(); bboxChanges |= subscene->bboxChanges; } } std::vector::const_iterator iter; for(iter = shapes.begin(); iter != shapes.end(); ++iter) { Shape* shape = *iter; if (!shape->getIgnoreExtent()) { data_bbox += shape->getBoundingBox(this); bboxChanges |= shape->getBBoxChanges(); } } intersectClipplanes(); } void Subscene::intersectClipplanes(void) { std::vector::iterator iter; for (iter = clipPlanes.begin() ; iter != clipPlanes.end() ; ++iter ) { ClipPlaneSet* plane = *iter; plane->intersectBBox(data_bbox); SAVEGLERROR; } } /* Call this when adding a clipplane that can shrink things */ void Subscene::shrinkBBox(void) { if (parent) parent->shrinkBBox(); else { calcDataBBox(); } } // --------------------------------------------------------------------------- void Subscene::setIgnoreExtent(int in_ignoreExtent) { ignoreExtent = (bool)in_ignoreExtent; } void Subscene::setupViewport(RenderContext* rctx) { Rect2 rect(0,0,0,0); if (do_viewport == EMBED_REPLACE) { rect.x = static_cast(rctx->rect.x + viewport.x*rctx->rect.width); rect.y = static_cast(rctx->rect.y + viewport.y*rctx->rect.height); rect.width = static_cast(rctx->rect.width*viewport.width); rect.height = static_cast(rctx->rect.height*viewport.height); } else { rect.x = static_cast(parent->pviewport.x + viewport.x*parent->pviewport.width); rect.y = static_cast(parent->pviewport.y + viewport.y*parent->pviewport.height); rect.width = static_cast(parent->pviewport.width*viewport.width); rect.height = static_cast(parent->pviewport.height*viewport.height); } pviewport = rect; } void Subscene::setupProjMatrix(RenderContext* rctx, const Sphere& viewSphere) { if (do_projection == EMBED_REPLACE) projMatrix.setIdentity(); getUserViewpoint()->setupProjMatrix(rctx, viewSphere); } // The ModelView matrix has components of the user view (the translation at the start) // and also the model transformations. The former comes from the userViewpoint, // the latter from the modelViewpoint, possibly after applying the same from the parents. // We always reconstruct from scratch rather than trying to use the matrix in place. void Subscene::setupModelViewMatrix(RenderContext* rctx, Vertex center) { modelMatrix.setIdentity(); getUserViewpoint()->setupViewer(rctx); setupModelMatrix(rctx, center); } void Subscene::setupModelMatrix(RenderContext* rctx, Vertex center) { /* The recursive call below will set the active subscene modelMatrix, not the inherited one. */ if (do_model < EMBED_REPLACE && parent) parent->setupModelMatrix(rctx, center); if (do_model > EMBED_INHERIT) getModelViewpoint()->setupTransformation(rctx, center); } void Subscene::disableLights(RenderContext* rctx) { // // disable lights; setup will enable them // #ifndef RGL_NO_OPENGL for (int i=0;i<8;i++) glDisable(GL_LIGHT0 + i); #endif } void Subscene::setupLights(RenderContext* rctx) { #ifndef RGL_NO_OPENGL int nlights = 0; bool anyviewpoint = false; std::vector::const_iterator iter; disableLights(rctx); for(iter = lights.begin(); iter != lights.end() ; ++iter ) { Light* light = *iter; light->id = GL_LIGHT0 + (nlights++); if (!light->viewpoint) light->setup(rctx); else anyviewpoint = true; } SAVEGLERROR; if (anyviewpoint) { // // viewpoint lights // glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); for(iter = lights.begin(); iter != lights.end() ; ++iter ) { Light* light = *iter; if (light->viewpoint) light->setup(rctx); } glPopMatrix(); } SAVEGLERROR; #endif } void Subscene::renderUnsorted(RenderContext* renderContext) { std::vector::iterator iter; for (iter = unsortedShapes.begin() ; iter != unsortedShapes.end() ; ++iter ) { Shape* shape = *iter; shape->render(renderContext); SAVEGLERROR; } } void Subscene::renderZsort(RenderContext* renderContext) { std::vector::iterator iter; std::multimap distanceMap; int index = 0; for (iter = zsortShapes.begin() ; iter != zsortShapes.end() ; ++iter ) { Shape* shape = *iter; shape->renderBegin(renderContext); for (int j = 0; j < shape->getPrimitiveCount(); j++) { ShapeItem* item = new ShapeItem(shape, j); float distance = getDistance( shape->getPrimitiveCenter(j) ); distanceMap.insert( std::pair(-distance, item) ); index++; } } { Shape* prev = NULL; std::multimap::iterator iter; for (iter = distanceMap.begin() ; iter != distanceMap.end() ; ++ iter ) { ShapeItem* item = iter->second; Shape* shape = item->shape; if (shape != prev) { if (prev) prev->drawEnd(renderContext); shape->drawBegin(renderContext); prev = shape; } shape->drawPrimitive(renderContext, item->itemnum); delete item; } if (prev) prev->drawEnd(renderContext); } } const AABox& Subscene::getBoundingBox() { if (bboxChanges) calcDataBBox(); return data_bbox; } void Subscene::newEmbedding() { if (parent) { if (do_projection == EMBED_REPLACE && !userviewpoint) add(new UserViewpoint(*(parent->getUserViewpoint()))); else if (do_projection == EMBED_MODIFY && !userviewpoint) add(new UserViewpoint(0.0, 1.0)); /* should be like an identity */ if (do_model == EMBED_REPLACE && !modelviewpoint) add(new ModelViewpoint(*(parent->getModelViewpoint()))); else if (do_model == EMBED_MODIFY && !modelviewpoint) add(new ModelViewpoint(PolarCoord(0.0, 0.0), Vec3(1.0, 1.0, 1.0), parent->getModelViewpoint()->isInteractive())); } } void Subscene::setEmbedding(int which, Embedding value) { switch(which) { case 0: do_viewport = value; break; case 1: do_projection = value; break; case 2: do_model = value; break; case 3: do_mouseHandlers = value; break; } newEmbedding(); } // #include Embedding Subscene::getEmbedding(Embedded which) { // Rprintf("getEmbedding %d, subscene %d\n", which, getObjID()); // usleep(1000000); switch(which) { case EM_VIEWPORT: return do_viewport; case EM_PROJECTION: return do_projection; case EM_MODEL: return do_model; case EM_MOUSEHANDLERS: return do_mouseHandlers; default: error("Bad embedding requested"); } } Subscene* Subscene::getMaster(Embedded which) { if (getEmbedding(which) == EMBED_INHERIT) return getParent()->getMaster(which); else return this; } void Subscene::getUserMatrix(double* dest) { ModelViewpoint* this_modelviewpoint = getModelViewpoint(); this_modelviewpoint->getUserMatrix(dest); } void Subscene::setUserMatrix(double* src) { ModelViewpoint* this_modelviewpoint = getModelViewpoint(); this_modelviewpoint->setUserMatrix(src); } void Subscene::getUserProjection(double* dest) { UserViewpoint* this_userviewpoint = getUserViewpoint(); this_userviewpoint->getUserProjection(dest); } void Subscene::setUserProjection(double* src) { UserViewpoint* this_userviewpoint = getUserViewpoint(); this_userviewpoint->setUserProjection(src); } void Subscene::getScale(double* dest) { ModelViewpoint* this_modelviewpoint = getModelViewpoint(); this_modelviewpoint->getScale(dest); } void Subscene::setScale(double* src) { ModelViewpoint* this_modelviewpoint = getModelViewpoint(); this_modelviewpoint->setScale(src); } void Subscene::getPosition(double* dest) { ModelViewpoint* this_modelviewpoint = getModelViewpoint(); this_modelviewpoint->getPosition(dest); } void Subscene::setPosition(double* src) { ModelViewpoint* this_modelviewpoint = getModelViewpoint(); this_modelviewpoint->setPosition(src); } void Subscene::setViewport(double x, double y, double width, double height) { viewport.x = x; viewport.y = y; viewport.width = width; viewport.height = height; } void Subscene::clearMouseListeners() { mouseListeners.clear(); } void Subscene::addMouseListener(Subscene* sub) { mouseListeners.push_back(sub); } void Subscene::deleteMouseListener(Subscene* sub) { for (unsigned int i=0; i < mouseListeners.size(); i++) { if (sub == mouseListeners[i]) { mouseListeners.erase(mouseListeners.begin() + i); return; } } } void Subscene::getMouseListeners(size_t max, int* ids) { max = max > mouseListeners.size() ? mouseListeners.size() : max; for (unsigned int i = 0; i < max; i++) ids[i] = mouseListeners[i]->getObjID(); } float Subscene::getDistance(const Vertex& v) const { Vertex4 vec = Vertex4(v, 1.0f); return (Zrow*vec) / (Wrow*vec); } viewControlPtr Subscene::getButtonBeginFunc(int button) { return getMaster(EM_MOUSEHANDLERS)->ButtonBeginFunc[button]; } void Subscene::buttonBegin(int button, int mouseX, int mouseY) { (this->*getButtonBeginFunc(button))(mouseX, mouseY); } viewControlPtr Subscene::getButtonUpdateFunc(int button) { return getMaster(EM_MOUSEHANDLERS)->ButtonUpdateFunc[button]; } void Subscene::buttonUpdate(int button, int mouseX, int mouseY) { if (button == bnNOBUTTON && needsBegin != mmNONE) { buttonBegin(button, mouseX, mouseY); needsBegin = mmNONE; } (this->*getButtonUpdateFunc(button))(mouseX, mouseY); } viewControlEndPtr Subscene::getButtonEndFunc(int button) { return getMaster(EM_MOUSEHANDLERS)->ButtonEndFunc[button]; } void Subscene::buttonEnd(int button) { (this->*getButtonEndFunc(button))(); } void Subscene::setDefaultMouseMode() { setMouseMode(bnNOBUTTON,mmNONE); setMouseMode(bnLEFT, mmPOLAR); setMouseMode(bnRIGHT, mmFOV); setMouseMode(bnMIDDLE, mmZOOM); setMouseMode(bnWHEEL, mmNONE); needsBegin = mmNONE; busy = false; } bool Subscene::mouseNeedsWatching() { if (mouseMode[bnNOBUTTON] != mmNONE) return true; for (std::vector::iterator i = subscenes.begin(); i != subscenes.end(); ++ i ) if ((*i)->mouseNeedsWatching()) return true; return false; } void Subscene::setMouseMode(int button, MouseModeID mode) { if (getEmbedding(EM_MOUSEHANDLERS) == EMBED_INHERIT) getParent()->setMouseMode(button, mode); else { mouseMode[button] = mode; if (button == bnNOBUTTON) needsBegin = mode; switch (mode) { case mmNONE: ButtonBeginFunc[button] = &Subscene::noneBegin; ButtonUpdateFunc[button] = &Subscene::noneUpdate; ButtonEndFunc[button] = &Subscene::noneEnd; break; case mmTRACKBALL: ButtonBeginFunc[button] = &Subscene::trackballBegin; ButtonUpdateFunc[button] = &Subscene::trackballUpdate; ButtonEndFunc[button] = &Subscene::trackballEnd; break; case mmXAXIS: case mmYAXIS: case mmZAXIS: ButtonBeginFunc[button] = &Subscene::oneAxisBegin; ButtonUpdateFunc[button] = &Subscene::oneAxisUpdate; ButtonEndFunc[button] = &Subscene::trackballEnd; // No need for separate function if (mode == mmXAXIS) axis[button] = Vertex(1,0,0); else if (mode == mmYAXIS) axis[button] = Vertex(0,1,0); else axis[button] = Vertex(0,0,1); break; case mmPOLAR: ButtonBeginFunc[button] = &Subscene::polarBegin; ButtonUpdateFunc[button] = &Subscene::polarUpdate; ButtonEndFunc[button] = &Subscene::polarEnd; break; case mmSELECTING: ButtonBeginFunc[button] = &Subscene::mouseSelectionBegin; ButtonUpdateFunc[button] = &Subscene::mouseSelectionUpdate; ButtonEndFunc[button] = &Subscene::mouseSelectionEnd; break; case mmZOOM: ButtonBeginFunc[button] = &Subscene::adjustZoomBegin; ButtonUpdateFunc[button] = &Subscene::adjustZoomUpdate; ButtonEndFunc[button] = &Subscene::adjustZoomEnd; break; case mmFOV: ButtonBeginFunc[button] = &Subscene::adjustFOVBegin; ButtonUpdateFunc[button] = &Subscene::adjustFOVUpdate; ButtonEndFunc[button] = &Subscene::adjustFOVEnd; break; case mmUSER: ButtonBeginFunc[button] = &Subscene::userBegin; ButtonUpdateFunc[button] = &Subscene::userUpdate; ButtonEndFunc[button] = &Subscene::userEnd; break; case wmPULL: if (button == bnWHEEL) WheelRotateFunc = &Subscene::wheelRotatePull; break; case wmPUSH: if (button == bnWHEEL) WheelRotateFunc = &Subscene::wheelRotatePush; break; case wmUSER2: if (button == bnWHEEL) WheelRotateFunc = &Subscene::userWheel; break; } } } void Subscene::setMouseCallbacks(int button, userControlPtr begin, userControlPtr update, userControlEndPtr end, userCleanupPtr cleanup, void** user) { if (getEmbedding(EM_MOUSEHANDLERS) == EMBED_INHERIT) getParent()->setMouseCallbacks(button, begin, update, end, cleanup, user); else { if (cleanupCallback[button]) (*cleanupCallback[button])(userData + 3*button); beginCallback[button] = begin; updateCallback[button] = update; endCallback[button] = end; cleanupCallback[button] = cleanup; userData[3*button + 0] = *(user++); userData[3*button + 1] = *(user++); userData[3*button + 2] = *user; setMouseMode(button, mmUSER); } } void Subscene::getMouseCallbacks(int button, userControlPtr *begin, userControlPtr *update, userControlEndPtr *end, userCleanupPtr *cleanup, void** user) { if (getEmbedding(EM_MOUSEHANDLERS) == EMBED_INHERIT) getParent()->getMouseCallbacks(button, begin, update, end, cleanup, user); else { *begin = beginCallback[button]; *update = updateCallback[button]; *end = endCallback[button]; *cleanup = cleanupCallback[button]; *(user++) = userData[3*button + 0]; *(user++) = userData[3*button + 1]; *(user++) = userData[3*button + 2]; } } MouseModeID Subscene::getMouseMode(int button) { return getMaster(EM_MOUSEHANDLERS)->mouseMode[button]; } void Subscene::setWheelCallback(userWheelPtr wheel, void* user) { if (getEmbedding(EM_MOUSEHANDLERS) == EMBED_INHERIT) getParent()->setWheelCallback(wheel, user); else { wheelCallback = wheel; wheelData = user; setMouseMode(bnWHEEL, wmUSER2); } } void Subscene::getWheelCallback(userWheelPtr *wheel, void** user) { if (getEmbedding(EM_MOUSEHANDLERS) == EMBED_INHERIT) getParent()->getWheelCallback(wheel, user); *wheel = wheelCallback; *user = wheelData; } // // FUNCTION // screenToPolar // // DESCRIPTION // screen space is the same as in OpenGL, starting 0,0 at left/bottom(!) of viewport // static PolarCoord screenToPolar(int width, int height, int mouseX, int mouseY) { float cubelen, cx,cy,dx,dy,r; cubelen = (float) getMin(width,height); r = cubelen * 0.5f; cx = ((float)width) * 0.5f; cy = ((float)height) * 0.5f; dx = ((float)mouseX) - cx; dy = ((float)mouseY) - cy; // // dx,dy = distance to center in pixels // dx = clamp(dx, -r,r); dy = clamp(dy, -r,r); // // sin theta = dx / r // sin phi = dy / r // // phi = arc sin ( sin theta ) // theta = arc sin ( sin phi ) // return PolarCoord( math::rad2deg( math::asin( dx/r ) ), math::rad2deg( math::asin( dy/r ) ) ); } static Vertex screenToVector(int width, int height, int mouseX, int mouseY) { float radius = (float) getMax(width, height) * 0.5f; float cx = ((float)width) * 0.5f; float cy = ((float)height) * 0.5f; float x = (((float)mouseX) - cx)/radius; float y = (((float)mouseY) - cy)/radius; // Make unit vector float len = sqrt(x*x + y*y); if (len > 1.0e-6) { x = x/len; y = y/len; } // Find length to first edge float maxlen = math::sqrt(2.0f); // zero length is vertical, max length is horizontal float angle = (maxlen - len)/maxlen*math::pi()/2.0f; float z = math::sin(angle); // renorm to unit length len = math::sqrt(1.0f - z*z); x = x*len; y = y*len; return Vertex(x, y, z); } void Subscene::trackballBegin(int mouseX, int mouseY) { rotBase = screenToVector(pviewport.width,pviewport.height,mouseX,mouseY); } void Subscene::trackballUpdate(int mouseX, int mouseY) { rotCurrent = screenToVector(pviewport.width,pviewport.height,mouseX,mouseY); for (unsigned int i = 0; i < mouseListeners.size(); i++) { Subscene* sub = mouseListeners[i]; if (sub) { ModelViewpoint* this_modelviewpoint = sub->getModelViewpoint(); this_modelviewpoint->updateMouseMatrix(rotBase,rotCurrent); } } } void Subscene::trackballEnd() { for (unsigned int i = 0; i < mouseListeners.size(); i++) { Subscene* sub = mouseListeners[i]; if (sub) { ModelViewpoint* this_modelviewpoint = sub->getModelViewpoint(); this_modelviewpoint->mergeMouseMatrix(); } } } void Subscene::oneAxisBegin(int mouseX, int mouseY) { rotBase = screenToVector(pviewport.width,pviewport.height,mouseX,pviewport.height/2); } void Subscene::oneAxisUpdate(int mouseX, int mouseY) { rotCurrent = screenToVector(pviewport.width,pviewport.height,mouseX,pviewport.height/2); for (unsigned int i = 0; i < mouseListeners.size(); i++) { Subscene* sub = mouseListeners[i]; if (sub) { ModelViewpoint* this_modelviewpoint = sub->getModelViewpoint(); this_modelviewpoint->mouseOneAxis(rotBase,rotCurrent,axis[drag-1]); } } } void Subscene::polarBegin(int mouseX, int mouseY) { ModelViewpoint* this_modelviewpoint = getModelViewpoint(); camBase = this_modelviewpoint->getPosition(); dragBase = screenToPolar(pviewport.width,pviewport.height,mouseX,mouseY); } void Subscene::polarUpdate(int mouseX, int mouseY) { dragCurrent = screenToPolar(pviewport.width,pviewport.height,mouseX,mouseY); PolarCoord newpos = camBase - ( dragCurrent - dragBase ); newpos.phi = clamp( newpos.phi, -90.0f, 90.0f ); for (unsigned int i = 0; i < mouseListeners.size(); i++) { Subscene* sub = mouseListeners[i]; if (sub) { ModelViewpoint* this_modelviewpoint = sub->getModelViewpoint(); this_modelviewpoint->setPosition( newpos ); } } } void Subscene::polarEnd() { // Viewpoint* viewpoint = scene->getViewpoint(); // viewpoint->mergeMouseMatrix(); } void Subscene::adjustFOVBegin(int mouseX, int mouseY) { fovBaseY = mouseY; } void Subscene::adjustFOVUpdate(int mouseX, int mouseY) { int dy = mouseY - fovBaseY; float py = -((float)dy/(float)pviewport.height) * 180.0f; for (unsigned int i = 0; i < mouseListeners.size(); i++) { Subscene* sub = mouseListeners[i]; if (sub) { UserViewpoint* this_userviewpoint = sub->getUserViewpoint(); this_userviewpoint->setFOV( this_userviewpoint->getFOV() + py ); } } fovBaseY = mouseY; } void Subscene::adjustFOVEnd() { } void Subscene::wheelRotatePull(int dir) { for (unsigned int i = 0; i < mouseListeners.size(); i++) { Subscene* sub = mouseListeners[i]; if (sub) { UserViewpoint* this_userviewpoint = sub->getUserViewpoint(); float zoom = this_userviewpoint->getZoom(); #define ZOOM_STEP 1.05f #define ZOOM_PIXELLOGSTEP 0.02f #define ZOOM_MIN 0.0001f #define ZOOM_MAX 10000.0f switch(dir) { case GUI_WheelForward: zoom *= ZOOM_STEP; break; case GUI_WheelBackward: zoom /= ZOOM_STEP; break; } zoom = clamp( zoom , ZOOM_MIN, ZOOM_MAX); this_userviewpoint->setZoom(zoom); } } } void Subscene::wheelRotatePush(int dir) { switch (dir) { case GUI_WheelForward: wheelRotatePull(GUI_WheelBackward); break; case GUI_WheelBackward: wheelRotatePull(GUI_WheelForward); break; } } void Subscene::wheelRotate(int dir) { int mode = getMouseMode(bnWHEEL); if (mode >= wmPULL) (this->*WheelRotateFunc)(dir); else { // Need to fake a click and release dir = 1 rotates away, dir = 2 rotates towards buttonBegin(bnWHEEL, pviewport.width / 2, pviewport.height / 2); buttonUpdate(bnWHEEL, pviewport.width / 2, pviewport.height / 2 + 10*(dir == 1 ? 1 : -1)); buttonEnd(bnWHEEL); } } void Subscene::userBegin(int mouseX, int mouseY) { Subscene* master = getMaster(EM_MOUSEHANDLERS); beginCallback[drag] = master->beginCallback[drag]; void* this_userData = master->userData[3*drag+0]; activeButton = drag; if (beginCallback[drag]) { busy = true; (*beginCallback[drag])(this_userData, mouseX, pviewport.height-mouseY); busy = false; } } void Subscene::userUpdate(int mouseX, int mouseY) { Subscene* master = getMaster(EM_MOUSEHANDLERS); updateCallback[activeButton] = master->updateCallback[activeButton]; void* this_userData = master->userData[3*activeButton+1]; if (!busy && updateCallback[activeButton]) { busy = true; (*updateCallback[activeButton])(this_userData, mouseX, pviewport.height-mouseY); busy = false; } } void Subscene::userEnd() { Subscene* master = getMaster(EM_MOUSEHANDLERS); endCallback[activeButton] = master->endCallback[activeButton]; void* this_userData = master->userData[3*activeButton+2]; if (endCallback[activeButton]) (*endCallback[activeButton])(this_userData); } void Subscene::userWheel(int dir) { wheelCallback = getMaster(EM_MOUSEHANDLERS)->wheelCallback; if (wheelCallback) (*wheelCallback)(wheelData, dir); } void Subscene::adjustZoomBegin(int mouseX, int mouseY) { zoomBaseY = mouseY; } void Subscene::adjustZoomUpdate(int mouseX, int mouseY) { int dy = mouseY - zoomBaseY; for (unsigned int i = 0; i < mouseListeners.size(); i++) { Subscene* sub = mouseListeners[i]; if (sub) { UserViewpoint* this_userviewpoint = sub->getUserViewpoint(); float zoom = clamp ( this_userviewpoint->getZoom() * exp(dy*ZOOM_PIXELLOGSTEP), ZOOM_MIN, ZOOM_MAX); // Rprintf("zoom = %f for subscene %d\n", zoom, sub->getObjID()); this_userviewpoint->setZoom(zoom); } } zoomBaseY = mouseY; } void Subscene::adjustZoomEnd() { } double* Subscene::getMousePosition() { return mousePosition; } MouseSelectionID Subscene::getSelectState() { return selectState; } void Subscene::setSelectState(MouseSelectionID state) { selectState = state; } void Subscene::mouseSelectionBegin(int mouseX,int mouseY) { if (selectState == msABORT) return; mousePosition[0] = (float)mouseX/(float)pviewport.width; mousePosition[1] = (float)mouseY/(float)pviewport.height; mousePosition[2] = mousePosition[0]; mousePosition[3] = mousePosition[1]; selectState = msCHANGING; } void Subscene::mouseSelectionUpdate(int mouseX,int mouseY) { mousePosition[2] = (float)mouseX/(float)pviewport.width; mousePosition[3] = (float)mouseY/(float)pviewport.height; } void Subscene::mouseSelectionEnd() { if (selectState == msABORT) return; selectState = msDONE; } Subscene* Subscene::getRootSubscene() { return parent ? parent->getRootSubscene() : this; } rgl/src/init.h0000644000176200001440000000056014100762641012743 0ustar liggesusers#ifndef RGL_INIT_H #define RGL_INIT_H #include "R.h" #include #include namespace rgl { #ifdef __cplusplus extern "C" { #endif /* // RGL initialization // */ /* library service */ SEXP rgl_init (SEXP initValue, SEXP onlyNULL, SEXP in_namespace, SEXP debug); #ifdef __cplusplus } #endif } // namespace rgl #endif /* RGL_INIT_H */ rgl/src/x11gui.h0000644000176200001440000000301714100762641013116 0ustar liggesusers#ifndef X11_GUI_H #define X11_GUI_H // --------------------------------------------------------------------------- // C++ header file // This file is part of RGL // // --------------------------------------------------------------------------- #include #include #include #include "gui.h" namespace rgl { // --------------------------------------------------------------------------- class X11WindowImpl; enum { GUI_X11_ATOM_WM_DELETE = 0, GUI_X11_ATOM_LAST }; // --------------------------------------------------------------------------- class X11GUIFactory : public GUIFactory { public: X11GUIFactory (const char* displayname); virtual ~X11GUIFactory (); WindowImpl* createWindowImpl(Window* window); inline bool isConnected() { return (xdisplay) ? true : false; } inline int getFD() { return ConnectionNumber(xdisplay); } void notifyDelete(::Window xwindowid); // implementation services: void processEvents(); void flushX(); // display specific: ::Display* xdisplay; ::Atom atoms[GUI_X11_ATOM_LAST]; // GLX specific int errorBase, eventBase; // Font specific XFontStruct* xfont; void throw_error(const char* string); private: void connect(const char* displayname); void disconnect(); // administrative data: typedef std::map< XID , X11WindowImpl*> WindowMap; WindowMap windowMap; ::Window group_leader; }; // --------------------------------------------------------------------------- } // namespace rgl #endif // X11_GUI_H rgl/src/Disposable.h0000644000176200001440000000237714100762641014075 0ustar liggesusers#ifndef RGL_DISPOSABLE_H #define RGL_DISPOSABLE_H #include namespace rgl { // forward declaration class Disposable; /** * Dispose Listener Interface. **/ struct IDisposeListener { virtual ~IDisposeListener() { } virtual void notifyDisposed(Disposable* disposing) = 0; }; /** * Disposable objects can be disposed autonomous while * they might be managed by a different Subject. * They allow for registering listeners that will be notified when * the object becomes disposed. **/ class Disposable { public: /** * register listener. It is not allowed to add the listener * if it is already registered. * * @arg l listener to be added to list **/ void addDisposeListener(IDisposeListener* l); /** * unregister listener. * @arg l listener to be removed **/ void removeDisposeListener(IDisposeListener* l); /** * dispose object. * Default implementatin will fire NotifyDisposed. **/ void dispose(); protected: /** * fires 'notifyDisposed' on all registered listeners. * It is save to call add/remove during 'notifyDisposed'. **/ void fireNotifyDisposed(); private: typedef std::vector Container; Container disposeListeners; }; } // namespace rgl #endif // RGL_DISPOSABLE_H rgl/src/platform.cpp0000644000176200001440000000612014100762641014155 0ustar liggesusers// C++ source // This file is part of RGL. // #include "platform.h" /* MacOSX */ #ifdef RGL_OSX #if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_9 // pre-Mavericks code #else // Mavericks and later #include #include #include GLint gluUnProject(GLdouble winX, GLdouble winY, GLdouble winZ, const GLdouble * model, const GLdouble * proj, const GLint * view, GLdouble* objX, GLdouble* objY, GLdouble* objZ) { int glkview[] = {view[0], view[1], view[2], view[3]}; bool success; GLKVector3 result = GLKMathUnproject(GLKVector3Make(static_cast(winX), static_cast(winY), static_cast(winZ)), GLKMatrix4Make(static_cast(model[0]), static_cast(model[1]), static_cast(model[2]), static_cast(model[3]), static_cast(model[4]), static_cast(model[5]), static_cast(model[6]), static_cast(model[7]), static_cast(model[8]), static_cast(model[9]), static_cast(model[10]), static_cast(model[11]), static_cast(model[12]), static_cast(model[13]), static_cast(model[14]), static_cast(model[15])), GLKMatrix4Make(static_cast(proj[0]), static_cast(proj[1]), static_cast(proj[2]), static_cast(proj[3]), static_cast(proj[4]), static_cast(proj[5]), static_cast(proj[6]), static_cast(proj[7]), static_cast(proj[8]), static_cast(proj[9]), static_cast(proj[10]), static_cast(proj[11]), static_cast(proj[12]), static_cast(proj[13]), static_cast(proj[14]), static_cast(proj[15])), glkview, &success ); *objX = result.v[0]; *objY = result.v[1]; *objZ = result.v[2]; return success ? GLU_TRUE : GLU_FALSE; } const GLubyte * gluErrorString(GLenum error) { return (GLubyte*)"glu Error"; } #endif /* Mavericks */ #endif /* RGL_OSX */ rgl/src/LineSet.cpp0000644000176200001440000000140514145464133013701 0ustar liggesusers#include "PrimitiveSet.h" using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // LineSet // LineSet::LineSet(Material& in_material, int in_nvertices, double* in_vertices, bool in_ignoreExtent, int in_nindices, int* in_indices, bool in_bboxChange) : PrimitiveSet(in_material, in_nvertices, in_vertices, GL_LINES, 2, in_ignoreExtent, in_nindices, in_indices, in_bboxChange) { material.lit = false; if (material.line_antialias) blended = true; } LineSet::LineSet(Material& in_material, bool in_ignoreExtent, bool in_bboxChange) : PrimitiveSet(in_material, GL_LINES, 2, in_ignoreExtent, in_bboxChange) { material.lit = false; if (material.line_antialias) blended = true; } rgl/src/Device.h0000644000176200001440000000406014100762641013176 0ustar liggesusers#ifndef RGL_DEVICE_H #define RGL_DEVICE_H // C++ header file // This file is part of RGL // #include "Disposable.h" #include "types.h" #include "rglview.h" namespace rgl { // // class Device // // - display device title // - setup the view matrix container (rows and columns of views) // - setup the view/scene relation (scene per view -or- shared scene) // - manages current view // - dispatches scene services to current view's scene // class Device : public Disposable, protected IDisposeListener { public: // -- all methods are blocking until action completed Device(int id, bool useNULL); virtual ~Device(); int getID(); void setName(const char* string); bool open(void); // -- if failed, instance is invalid and should be deleted void close(void); // -- when done, instance is invalid and should be deleted bool snapshot(int format, const char* filename); bool pixels(int* ll, int* size, int component, double* result); bool postscript(int format, const char* filename, bool drawText); bool clear(TypeID stackTypeID); int add(SceneNode* node); // -- return a unique id if successful, or zero if not bool pop(TypeID stackTypeID, int id); bool hasWindow() { return window != NULL; } // accessor method for Scene, modeled after getBoundingBox() // from scene.h Scene* getScene() const { return scene; } void bringToTop(int stay); RGLView* getRGLView(void); int getIgnoreExtent(void); void setIgnoreExtent(int in_ignoreExtent); int getSkipRedraw(void); void setSkipRedraw(int in_skipRedraw); void setWindowRect(int left, int top, int right, int bottom); void getWindowRect(int *left, int *top, int *right, int *bottom); void getFonts(FontArray& outfonts, int nfonts, char** family, int* style, double* cex, bool useFreeType); const char* getDevtype(void); // event handlers protected: void notifyDisposed(Disposable* disposable); private: void update(void); Window* window; RGLView* rglview; Scene* scene; const char* devtype; int id_; }; } // namespace rgl #endif // RGL_DEVICE_H rgl/src/SphereMesh.h0000644000176200001440000000264014100762641014044 0ustar liggesusers#ifndef SPHERE_MESH_H #define SPHERE_MESH_H #include "render.h" namespace rgl { // // CLASS // SphereMesh // class SphereMesh { public: enum Type { GLOBE, TESSELATION }; SphereMesh(); inline void setGenNormal (bool in_genNormal) { genNormal = in_genNormal; } inline void setGenTexCoord (bool in_genTexCoord) { genTexCoord = in_genTexCoord; } void setGlobe (int segments, int sections); void setTesselation (int level); void setCenter (const Vertex& center); void setRadius (float radius); void update(); void update (const Vertex& scale); /* void beginDraw(RenderContext* renderContext); void drawSection(int section); void endDraw(RenderContext* renderContext); */ void draw(RenderContext* renderContext); void drawBegin(RenderContext* renderContext, bool endcap); void drawPrimitive(RenderContext* renderContext, int i); void drawEnd(RenderContext* renderContext); int getPrimitiveCount() { return segments*sections; } int getSegments() { return segments; } Vertex getPrimitiveCenter(int i); private: Vertex center; float radius; float philow; float phihigh; VertexArray vertexArray; NormalArray normalArray; TexCoordArray texCoordArray; int segments; int sections; int nvertex; Type type; bool genNormal; bool genTexCoord; void setupMesh(); }; } // namespace rgl #endif // SPHERE_MESH_H rgl/src/Shape.cpp0000644000176200001440000000566014100762641013401 0ustar liggesusers #include #include #include "Shape.h" #include "SceneNode.h" #include "R.h" using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // Shape // Shape::Shape(Material& in_material, bool in_ignoreExtent, TypeID in_typeID, bool in_bboxChanges) : SceneNode(in_typeID), bboxChanges(in_bboxChanges), ignoreExtent(in_ignoreExtent), material(in_material), #ifndef RGL_NO_OPENGL displayList(0), #endif drawLevel(0), doUpdate(true), transparent(in_material.isTransparent()), blended(in_material.isTransparent()) { } Shape::~Shape() { #ifndef RGL_NO_OPENGL if (displayList) glDeleteLists(displayList, 1); #endif } void Shape::update(RenderContext* renderContext) { doUpdate = false; } void Shape::draw(RenderContext* renderContext) { drawBegin(renderContext); SAVEGLERROR; for(int i=0;i ../R/noOpenGL.R clean: rm -f $(OBJECTS) $(SHLIB) rgl/src/ftgl.cpp0000644000176200001440000000060114100762641013263 0ustar liggesusers #ifdef HAVE_FREETYPE #include "FTBuffer.cpp" #include "FTCharmap.cpp" #include "FTFace.cpp" #include "FTFont/FTFont.cpp" #include "FTFont/FTBufferFont.cpp" #include "FTFont/FTPixmapFont.cpp" #include "FTGlyphContainer.cpp" #include "FTGlyph/FTGlyph.cpp" #include "FTGlyph/FTPixmapGlyph.cpp" #include "FTGlyph/FTBufferGlyph.cpp" #include "FTLibrary.cpp" #include "FTSize.cpp" #endif rgl/src/api.h0000644000176200001440000001132014145464133012551 0ustar liggesusers#ifndef RGL_API_H #define RGL_API_H #include "R.h" #include #include "ABCLineSet.h" #include "PlaneSet.h" #include "SphereSet.h" #include "SpriteSet.h" #include "Surface.h" #include "TextSet.h" namespace rgl { #ifdef __cplusplus extern "C" { #endif /* // RGL API IMPLEMENTATION // // // C API FUNCTION DESIGN // rgl_ ( successptr , ... ) // // PARAMETERS // successptr // [0] function success status */ /* library service */ void rgl_quit (int* successptr); /* device management */ void rgl_dev_open (int* successptr, int* useNULL); void rgl_dev_close (int* successptr); SEXP rgl_dev_getcurrent(void); SEXP rgl_dev_list (void); void rgl_dev_setcurrent(int* successptr, int* idata); void rgl_dev_bringtotop(int* successptr, int* stay); /* device services */ void rgl_snapshot (int* successptr, int* idata, char** cdata); void rgl_pixels(int* successptr, int* ll, int* size, int* component, double* result); void rgl_postscript (int* successptr, int* idata, char** cdata); /* scene management */ void rgl_clear (int* successptr, int* idata); void rgl_pop (int* successptr, int* idata); void rgl_id_count (int* type, int* count, int* subsceneID); void rgl_ids (int* type, int* ids, char** types, int* subsceneID); void rgl_attrib_count (int* id, int* attrib, int* count); void rgl_attrib (int* id, int* attrib, int* first, int* count, double* result); void rgl_text_attrib (int* id, int* attrib, int* first, int* count, char** result); void rgl_material (int* successptr, int* idata, char** cdata, double* ddata); void rgl_getcolorcount(int* count); void rgl_getmaterial (int* successptr, int *id, int* idata, char** cdata, double* ddata); void rgl_light (int* successptr, int* idata, double* ddata ); void rgl_viewpoint(int* successptr, int* idata, double* ddata); void rgl_bg (int* successptr, int* idata, double* fogScale); void rgl_bbox (int* successptr, int* idata, double* ddata, double* xat, char** xtext, double* yat, char** ytext, double* zat, char** ztext); void rgl_primitive(int* successptr, int* idata, double* vertex, double* normals, double* texcoords); void rgl_texts (int* successptr, int* idata, double* adj, char** text, double* vertex, int* nfonts, char** family, int* style, double* cex, int* useFreeType, int* npos, int* pos); void rgl_spheres (int* successptr, int* idata, double* vertex, double* radius, int* fastTransparency); void rgl_planes (int* successptr, int* idata, double* normals, double* offsets); void rgl_clipplanes(int* successptr, int* idata, double* normals, double* offsets); void rgl_abclines (int* successptr, int* idata, double* bases, double* directions); void rgl_surface (int* successptr, int* idata, double* x, double* z, double* y, double* normal_x, double* normal_z, double* normal_y, double* texture_s, double* texture_t, int* coords, int* orientation, int* flags); void rgl_sprites (int* successptr, int* idata, double* vertex, double* radius, int* shapes, double* userMatrix, double* adj, int* pos, double* offset); void rgl_newsubscene (int* successptr, int* parentid, int* embedding, int* ignoreExtent); void rgl_setsubscene (int* id); void rgl_getsubsceneid (int* id, int* dev); /* On input, 0 for root, 1 for current */ void rgl_getsubsceneparent(int* id); void rgl_getsubscenechildcount(int* id, int* n); void rgl_getsubscenechildren(int* id, int* children); void rgl_addtosubscene (int* successptr, int* count, int* ids); void rgl_delfromsubscene(int* successptr, int* count, int* ids); void rgl_gc(int* count, int* protect); void rgl_locator(int* successptr, double* locations); void rgl_selectstate(int* dev, int* sub, int* successptr, int* selectstate, double* locations); void rgl_setselectstate(int* dev, int* sub, int* successptr, int *idata); void rgl_setEmbeddings(int* successptr, int* embeddings); void rgl_getEmbeddings(int* successptr, int* embeddings); SEXP rgl_setMouseCallbacks(SEXP button, SEXP begin, SEXP update, SEXP end, SEXP dev, SEXP sub); SEXP rgl_setWheelCallback(SEXP rotate, SEXP dev, SEXP sub); SEXP rgl_getMouseCallbacks(SEXP button, SEXP dev, SEXP sub); SEXP rgl_getWheelCallback(SEXP dev, SEXP sub); SEXP rgl_getAxisCallback(SEXP dev, SEXP sub, SEXP axis); SEXP rgl_setAxisCallback(SEXP draw, SEXP dev, SEXP sub, SEXP axis); SEXP rgl_par3d(SEXP device, SEXP subscene, SEXP args); /* These may be removed if observer is set completely by par3d */ void rgl_getObserver(int* successptr, double* ddata); void rgl_setObserver(int* successptr, double* ddata); #ifdef __cplusplus } #endif } // namespace rgl #endif /* RGL_API_H */ rgl/src/TextSet.h0000644000176200001440000000252414142256754013413 0ustar liggesusers#ifndef TEXTSET_H #define TEXTSET_H #include "Shape.h" #include "render.h" #include "String.h" #include "glgui.h" #ifdef HAVE_FREETYPE #include "FTGL/ftgl.h" #endif namespace rgl { // // TEXTSET // class TextSet : public Shape { public: TextSet(Material& in_material, int in_ntexts, char** in_texts, double *in_center, double in_adjx, double in_adjy, double in_adjz, int in_ignoreExtent, FontArray& in_fonts, int in_npos, const int* in_pos); ~TextSet(); /* Can't use display lists */ void render(RenderContext* renderContext); virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "text", buflen); }; int getElementCount(void){ return textArray.size(); } int getAttributeCount(AABox& bbox, AttribID attrib); void getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result); String getTextAttribute(AABox& bbox, AttribID attrib, int index); Vertex getPrimitiveCenter(int index) { return vertexArray[index]; } void drawBegin(RenderContext* renderContext); void drawPrimitive(RenderContext* renderContext, int index); void drawEnd(RenderContext* renderContext); private: VertexArray vertexArray; StringArray textArray; FontArray fonts; double adjx; double adjy; double adjz; int npos; int* pos; }; } // namespace rgl #endif // TEXTSET_H rgl/src/DeviceManager.h0000644000176200001440000000213214100762641014467 0ustar liggesusers#ifndef RGL_DEVICE_MANAGER_H #define RGL_DEVICE_MANAGER_H // C++ header file // This file is part of RGL // #include "Device.h" #include namespace rgl { /** * Manager component that is used as a front-end for multiple devices access * using an 'id' to set the current device. **/ class DeviceManager : protected IDisposeListener { public: DeviceManager(bool in_useNULLDevice); virtual ~DeviceManager(); bool openDevice(bool useNULL); Device* getCurrentDevice(void); Device* getAnyDevice(void); Device* getDevice(int id); bool setCurrent(int id, bool silent = false); int getCurrent(); int getDeviceCount(); void getDeviceIds(int *buffer, int bufsize); bool createTestWindow(); protected: /** * Dispose Listener implementation **/ void notifyDisposed(Disposable*); private: void nextDevice(); void previousDevice(); typedef std::list Container; typedef Container::iterator Iterator; int newID; Container devices; Iterator current; bool useNULLDevice; }; } // namespace rgl #endif // DEVICE_MANAGER_H rgl/src/x11gui.cpp0000644000176200001440000005312514137472630013464 0ustar liggesusers#include "config.h" #ifdef RGL_X11 // --------------------------------------------------------------------------- // C++ source // This file is part of RGL. // // Uncomment for verbose output on stderr: // #define RGL_X11_DEBUG // --------------------------------------------------------------------------- #include #include #include #include "x11gui.h" #include "lib.h" #include "R.h" namespace rgl { // --------------------------------------------------------------------------- extern SEXP rglNamespace; // --------------------------------------------------------------------------- class X11WindowImpl : public WindowImpl { public: X11WindowImpl(rgl::Window* in_window , X11GUIFactory* in_factory , ::Window in_xwindow , XVisualInfo* invisualinfo ); virtual ~X11WindowImpl(); void setTitle(const char* title); void setWindowRect(int left, int top, int right, int bottom); void getWindowRect(int *left, int *top, int *right, int *bottom); void show(); void hide(); void bringToTop(int stay); void update(); void destroy(); bool beginGL(); void endGL(); void swap(); void captureMouse(View* captureview); void releaseMouse(); void watchMouse(bool withoutButton); GLFont* getFont(const char* family, int style, double cex, bool useFreeType); private: void initGL(); GLBitmapFont* initGLFont(); void shutdownGL(); static int translate_key(KeySym keysym); void on_init(); void on_shutdown(); void on_paint(); void processEvent(XEvent& ev); X11GUIFactory* factory; ::Window xwindow; ::GLXContext glxctx; friend class X11GUIFactory; XVisualInfo* xvisualinfo; }; } // namespace rgl using namespace rgl; // --------------------------------------------------------------------------- // X11WindowImpl Implementation // --------------------------------------------------------------------------- X11WindowImpl::X11WindowImpl(Window* w, X11GUIFactory* f, ::Window in_xwindow, XVisualInfo* invisualinfo) : WindowImpl(w) , factory(f) , xwindow(in_xwindow) , xvisualinfo(invisualinfo) { on_init(); } // --------------------------------------------------------------------------- X11WindowImpl::~X11WindowImpl() { if (xwindow != 0) destroy(); // free XVisualInfo structure if (xvisualinfo) { XFree(xvisualinfo); xvisualinfo = 0; } } // --------------------------------------------------------------------------- void X11WindowImpl::setTitle(const char* title) { XStoreName(factory->xdisplay,xwindow,title); factory->flushX(); } // --------------------------------------------------------------------------- void X11WindowImpl::setWindowRect(int left, int top, int right, int bottom) { ::Window root, child, parent, *children; int x, y; unsigned int nchildren; XQueryTree(factory->xdisplay, xwindow, &root, &parent, &children, &nchildren); XTranslateCoordinates(factory->xdisplay, xwindow, parent, 0, 0, &x, &y, &child); // The weird calculation below (subtracting twice (x,y)) compensates for the diff // between coordinates of the rgl window within the parent window. // There's probably a smarter way to do this... XMoveWindow(factory->xdisplay, xwindow, left-2*x, top-2*y); XResizeWindow(factory->xdisplay, xwindow, right-left, bottom-top); factory->flushX(); } // --------------------------------------------------------------------------- void X11WindowImpl::getWindowRect(int *left, int *top, int *right, int *bottom) { ::Window root, child; int x, y; unsigned int width, height, border_width, depth; do { factory->flushX(); factory->processEvents(); } while (XEventsQueued(factory->xdisplay, QueuedAfterFlush)); XGetGeometry(factory->xdisplay, xwindow, &root, &x, &y, &width, &height, &border_width, &depth); XTranslateCoordinates(factory->xdisplay, xwindow, root, x, y, left, top, &child); XTranslateCoordinates(factory->xdisplay, xwindow, root, x+width, y+height, right, bottom, &child); } // --------------------------------------------------------------------------- static Bool IsMapNotify(Display* d, XEvent* ev, XPointer arg) { ::Window w = (::Window) arg; return ( (ev->xany.window == w) && (ev->type == MapNotify) ); } void X11WindowImpl::show() { XMapWindow(factory->xdisplay, xwindow); XEvent ev; XIfEvent(factory->xdisplay, &ev, IsMapNotify, (XPointer) xwindow ); factory->processEvents(); factory->flushX(); update(); } // --------------------------------------------------------------------------- void X11WindowImpl::hide() { XUnmapWindow(factory->xdisplay, xwindow); factory->flushX(); } // --------------------------------------------------------------------------- void X11WindowImpl::bringToTop(int stay) { XRaiseWindow(factory->xdisplay, xwindow); factory->processEvents(); factory->flushX(); } // --------------------------------------------------------------------------- void X11WindowImpl::on_paint() { if (window) { if (window->skipRedraw) return; window->paint(); SAVEGLERROR; } swap(); SAVEGLERROR; } // --------------------------------------------------------------------------- void X11WindowImpl::update() { on_paint(); SAVEGLERROR; } // --------------------------------------------------------------------------- void X11WindowImpl::destroy() { if (xwindow != 0) { on_shutdown(); if (factory->xdisplay) XDestroyWindow(factory->xdisplay, xwindow); factory->flushX(); factory->notifyDelete(xwindow); /* Why didn't this happen in the lines above, from the DestroyNotify event? */ xwindow = 0; if (window) window->notifyDestroy(); delete this; } } // --------------------------------------------------------------------------- bool X11WindowImpl::beginGL() { if ( glXMakeCurrent(factory->xdisplay, xwindow, glxctx) == False ) { printMessage("ERROR: can't bind glx context to window"); return false; } else return true; } // --------------------------------------------------------------------------- void X11WindowImpl::endGL() { } // --------------------------------------------------------------------------- void X11WindowImpl::swap() { glXSwapBuffers(factory->xdisplay, xwindow); } // --------------------------------------------------------------------------- void X11WindowImpl::captureMouse(View* captureview) { } // --------------------------------------------------------------------------- void X11WindowImpl::releaseMouse() { } // --------------------------------------------------------------------------- void X11WindowImpl::watchMouse(bool withoutButton) { unsigned long valuemask=CWEventMask; XSetWindowAttributes attrib; attrib.event_mask = (withoutButton ? PointerMotionMask : ButtonMotionMask) | PointerMotionHintMask | VisibilityChangeMask | ExposureMask | StructureNotifyMask | ButtonPressMask | KeyPressMask | KeyReleaseMask | ButtonReleaseMask; XChangeWindowAttributes(factory->xdisplay, xwindow, valuemask, &attrib); factory->flushX(); } // --------------------------------------------------------------------------- void X11WindowImpl::processEvent(XEvent& ev) { char keybuffer[8]; KeySym keysym; XComposeStatus compose; int keycode; ::Window root, child; int rootx, rooty, winx, winy; unsigned int mask; switch(ev.type) { case ButtonPress: switch(ev.xbutton.button) { case 1: if (window) window->buttonPress( GUI_ButtonLeft, ev.xbutton.x, ev.xbutton.y ); break; case 2: if (window) window->buttonPress( GUI_ButtonMiddle, ev.xbutton.x, ev.xbutton.y ); break; case 3: if (window) window->buttonPress( GUI_ButtonRight, ev.xbutton.x, ev.xbutton.y ); break; case 4: if (window) window->wheelRotate( GUI_WheelForward, ev.xbutton.x, ev.xbutton.y ); break; case 5: if (window) window->wheelRotate( GUI_WheelBackward, ev.xbutton.x, ev.xbutton.y ); break; } break; case ButtonRelease: switch(ev.xbutton.button) { case 1: if (window) window->buttonRelease( GUI_ButtonLeft, ev.xbutton.x, ev.xbutton.y ); break; case 2: if (window) window->buttonRelease( GUI_ButtonMiddle, ev.xbutton.x, ev.xbutton.y ); break; case 3: if (window) window->buttonRelease( GUI_ButtonRight, ev.xbutton.x, ev.xbutton.y ); break; } break; case KeyPress: XLookupString(&ev.xkey, keybuffer, sizeof(keybuffer), &keysym, &compose); keycode = translate_key(keysym); if (keycode) if (window) window->keyPress(keycode); break; case KeyRelease: XLookupString(&ev.xkey, keybuffer, sizeof(keybuffer), &keysym, &compose); keycode = translate_key(keysym); if (keycode) if (window) window->keyRelease(keycode); break; case MappingNotify: XRefreshKeyboardMapping(&ev.xmapping); break; case MotionNotify: if( XQueryPointer(factory->xdisplay, xwindow, &root, &child, &rootx, &rooty, &winx, &winy, &mask) == True ) if (window) window->mouseMove( winx, winy ); break; case Expose: if (ev.xexpose.count == 0) { if (window) { if (window->skipRedraw) break; window->paint(); } swap(); } break; case ConfigureNotify: if (window) window->resize( ev.xconfigure.width, ev.xconfigure.height ); break; case MapNotify: if (window) window->show(); break; case UnmapNotify: if (window) window->hide(); break; case ClientMessage: if ( ( (::Atom) ev.xclient.data.l[0] ) == factory->atoms[GUI_X11_ATOM_WM_DELETE]) if (window) window->on_close(); break; case DestroyNotify: factory->notifyDelete(xwindow); xwindow = 0; if (window) window->notifyDestroy(); delete this; break; } } // --------------------------------------------------------------------------- static int error_code; static int X11SaveErr(Display *dsp, XErrorEvent *event) { error_code = event->error_code; return 0; } // --------------------------------------------------------------------------- void X11WindowImpl::initGL() { glxctx = glXCreateContext(factory->xdisplay, xvisualinfo, NULL, True); } // --------------------------------------------------------------------------- void X11WindowImpl::shutdownGL() { // destroy GL context if (glxctx) { glXMakeCurrent(factory->xdisplay, None, NULL); glXDestroyContext(factory->xdisplay, glxctx); glxctx = NULL; } } // --------------------------------------------------------------------------- GLFont* X11WindowImpl::getFont(const char* family, int style, double cex, bool useFreeType) { for (unsigned int i=0; i < fonts.size(); i++) { if (fonts[i] && fonts[i]->cex == cex && fonts[i]->style == style && !strcmp(fonts[i]->family, family) && fonts[i]->useFreeType == useFreeType) return fonts[i]; } if (useFreeType) { #ifdef HAVE_FREETYPE SEXP Rfontname = VECTOR_ELT(PROTECT(eval(PROTECT(lang2(PROTECT(install("rglFonts")), PROTECT(ScalarString(mkChar(family))))), rglNamespace)), 0); if (isString(Rfontname) && length(Rfontname) >= style) { const char* fontname = CHAR(STRING_ELT(Rfontname, style-1)); GLFTFont* font=new GLFTFont(family, style, cex, fontname); if (font->font) { fonts.push_back(font); UNPROTECT(4); return font; } else { warning(font->errmsg); delete font; } } UNPROTECT(4); #else warning("FreeType not available"); #endif } if (strcmp(family, fonts.back()->family)) warning("font family \"%s\" not found, using \"%s\"", family, fonts.back()->family); else if (style != fonts.back()->style) warning("\"%s\" family only supports font %d", fonts.back()->family, fonts.back()->style); else if (cex != fonts.back()->cex) warning("\"%s\" family only supports cex = %g", fonts.back()->family, fonts.back()->cex); else if (useFreeType) warning("FreeType font not available"); if (useFreeType) return fonts.back(); else return fonts[0]; } GLBitmapFont* X11WindowImpl::initGLFont() { GLBitmapFont* font = NULL; if (beginGL()) { font = new GLBitmapFont("bitmap", 1, 1, "fixed"); font->nglyph = GL_BITMAP_FONT_COUNT; font->firstGlyph = GL_BITMAP_FONT_FIRST_GLYPH; GLuint listBase = glGenLists(font->nglyph); font->listBase = listBase - font->firstGlyph; glXUseXFont(factory->xfont->fid, font->firstGlyph, font->nglyph, listBase); font->widths = new unsigned int[font->nglyph]; for(unsigned int i=0;inglyph;i++) font->widths[i] = 9; font->ascent = factory->xfont->ascent; endGL(); // Should this be added? } return font; } // --------------------------------------------------------------------------- void X11WindowImpl::on_init() { initGL(); if (glxctx) fonts[0] = initGLFont(); } void X11WindowImpl::on_shutdown() { if (glxctx) for (unsigned int i=0; i < fonts.size(); i++) { if (fonts[i]) { delete fonts[i]; fonts[i] = NULL; } } shutdownGL(); } // --------------------------------------------------------------------------- // // FUNCTION // translate_key // // translates X11 KeySym keycode to GUI_Key code // // --------------------------------------------------------------------------- int X11WindowImpl::translate_key(KeySym keysym) { if ( (keysym >= XK_space) && (keysym <= XK_asciitilde) ) return (int) keysym; else if ((keysym >= XK_F1) && (keysym <= XK_F12)) return static_cast(GUI_KeyF1 + keysym - XK_F1); else { switch(keysym) { case XK_Return: return GUI_KeyReturn; case XK_Escape: return GUI_KeyESC; default: return 0; } } } // --------------------------------------------------------------------------- // X11GUIFactory Implementation // --------------------------------------------------------------------------- // throw error // --------------------------------------------------------------------------- void X11GUIFactory::throw_error(const char* string) { printMessage(string); disconnect(); } // --------------------------------------------------------------------------- X11GUIFactory::X11GUIFactory(const char* displayname) : xdisplay(0) , xfont(0) { // Open one display connection for all RGL X11 devices xdisplay = XOpenDisplay(displayname); if (xdisplay == 0) { throw_error("unable to open X11 display"); return; } /* XSynchronize(xdisplay, True); */ // Load System font xfont = XLoadQueryFont(xdisplay,"fixed"); // Obtain display atoms static char* atom_names[GUI_X11_ATOM_LAST] = { const_cast("WM_DELETE_WINDOW") }; Status s = XInternAtoms(xdisplay, atom_names, sizeof(atom_names)/sizeof(char*), True, atoms); if (!s) printMessage("some atoms not available"); // Query glx extension if ( glXQueryExtension(xdisplay, &errorBase, &eventBase) == False ) { throw_error("GLX extension missing on server"); return; } ::Window rootwin = DefaultRootWindow(xdisplay); group_leader = XCreateSimpleWindow( /* never mapped or visible */ xdisplay, rootwin, 0, 0, 1, 1, 0, 0, 0); } // --------------------------------------------------------------------------- X11GUIFactory::~X11GUIFactory() { disconnect(); } // --------------------------------------------------------------------------- void X11GUIFactory::disconnect() { if (xdisplay) { // close invisible group leader XDestroyWindow(xdisplay, group_leader); // process pending XDestroyNotify events XSync(xdisplay, False); processEvents(); // free xfont if (xfont) { XUnloadFont(xdisplay, xfont->fid); xfont = 0; } // disconnect from X server XCloseDisplay(xdisplay); xdisplay = 0; } } // --------------------------------------------------------------------------- void X11GUIFactory::flushX() { if (xdisplay) XSync(xdisplay, False); glXWaitX(); } // --------------------------------------------------------------------------- void X11GUIFactory::processEvents() { for(;;) { int nevents = XEventsQueued(xdisplay, QueuedAfterReading); if (nevents == 0) return; while(nevents--) { XEvent ev; XNextEvent(xdisplay,&ev); X11WindowImpl* impl = windowMap[ev.xany.window]; if (impl) impl->processEvent(ev); #ifdef RGL_X11_DEBUG else fprintf(stderr,"unknown window id %lx(code %lx)\n" , static_cast(ev.xany.window) , static_cast(ev.type) ); #endif } } } // --------------------------------------------------------------------------- WindowImpl* X11GUIFactory::createWindowImpl(Window* window) { X11WindowImpl* impl = NULL; XVisualInfo* xvisualinfo; // Choose GLX visual static int attribList[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_ALPHA_SIZE, 0, GLX_DEPTH_SIZE, 1, None, None, // Space for optional AA settings None, None, None }; #ifdef GLX_SAMPLE_BUFFERS // Setup antialiasing based on "rgl.antialias" option int aa; SEXP rgl_aa = GetOption(install("rgl.antialias"),R_BaseEnv); if (isNull(rgl_aa)) aa = RGL_ANTIALIAS; else aa = asInteger(rgl_aa); if(aa > 0) { attribList[12] = GLX_SAMPLE_BUFFERS; attribList[13] = 1; attribList[14] = GLX_SAMPLES; attribList[15] = aa; } #endif /* These codes are only used in debugging, they are never displayed. */ #define RGL_ERROR_CODE (LastExtensionError + 1000) /* clear old errors */ while ((error_code = glGetError())) { Rprintf("cleared error %d\n", error_code); }; /* Work around problems with Xvfb on MacOSX and disabled IGLX: temporarily catch protocol errors and convert to R errors */ error_code = 0; XErrorHandler old_handler = XSetErrorHandler(X11SaveErr); xvisualinfo = glXChooseVisual( xdisplay, DefaultScreen(xdisplay), attribList ); #ifdef GLX_SAMPLE_BUFFERS // Try to set up visual without MSAA if it failed if (xvisualinfo == 0 && aa > 0 && !error_code) { attribList[12] = None; xvisualinfo = glXChooseVisual( xdisplay, DefaultScreen(xdisplay), attribList ); } #endif if (xvisualinfo == 0) { error_code = RGL_ERROR_CODE + 1; } // create X11 window // We don't want a border, but MacOSX Xvfb requires one. unsigned long valuemask=CWEventMask|CWColormap|CWBorderPixel; XSetWindowAttributes attrib; attrib.event_mask = PointerMotionMask | PointerMotionHintMask | VisibilityChangeMask | ExposureMask | StructureNotifyMask | ButtonPressMask | KeyPressMask | KeyReleaseMask | ButtonReleaseMask; ::Window xparent = 0; if (!error_code) { xparent = RootWindow(xdisplay, DefaultScreen(xdisplay)); if (!error_code && !xparent) error_code = RGL_ERROR_CODE + 2; } if (!error_code) { attrib.colormap = XCreateColormap(xdisplay, xparent, xvisualinfo->visual, AllocNone); if (!error_code && !attrib.colormap) error_code = RGL_ERROR_CODE + 3; } attrib.border_pixel = 0; ::Window xwindow = 0; if (!error_code) { if (window) window->resize(256, 256); // This may be changed by window manager xwindow = XCreateWindow( xdisplay, xparent, 0, 0, 256, 256, 0, xvisualinfo->depth, InputOutput, xvisualinfo->visual, valuemask, &attrib ); if (!error_code && !xwindow) error_code = RGL_ERROR_CODE + 4; } if (!error_code) XSync(xdisplay, False); /* set WM_CLASS on window */ if (!error_code) { XClassHint *classHint = XAllocClassHint(); if (!error_code) { if (classHint) { classHint->res_name = const_cast("rgl"); classHint->res_class = const_cast("R_x11"); XSetClassHint(xdisplay, xwindow, classHint); XFree(classHint); } else error_code = RGL_ERROR_CODE + 5; } } // set window manager protocols int n = 0; ::Atom proto_atoms[GUI_X11_ATOM_LAST]; if (atoms[GUI_X11_ATOM_WM_DELETE]) { proto_atoms[n] = atoms[GUI_X11_ATOM_WM_DELETE]; n++; } if (xwindow && n && !error_code) XSetWMProtocols(xdisplay,xwindow,proto_atoms,n); // Set group leader if (xwindow && !error_code) { ::XWMHints *hints; hints = XAllocWMHints(); if (hints) { hints->window_group = group_leader; hints->flags |= WindowGroupHint; XSetWMHints(xdisplay, xwindow, hints); XFree(hints); } } // create window implementation instance if (xwindow && !error_code) { impl = new X11WindowImpl(window, this, xwindow, xvisualinfo); if (!error_code && !impl) error_code = RGL_ERROR_CODE + 6; } else { impl = NULL; } // flush X requests flushX(); XSetErrorHandler(old_handler); if (error_code) impl = NULL; // register instance if (xwindow) windowMap[xwindow] = impl; return (WindowImpl*) impl; } // --------------------------------------------------------------------------- void X11GUIFactory::notifyDelete(::Window xwindowid) { #ifdef RGL_X11_DEBUG fprintf(stderr,"notifyDelete %lx\n", xwindowid); #endif // remove window from map windowMap.erase(xwindowid); } // --------------------------------------------------------------------------- #endif // RGL_X11_H rgl/src/Background.h0000644000176200001440000000234714100762641014064 0ustar liggesusers#ifndef BACKGROUND_H #define BACKGROUND_H #include "Shape.h" #include "opengl.h" #include "PrimitiveSet.h" #include "SphereMesh.h" namespace rgl { // // CLASS // Background // class Background : public Shape { public: enum { FOG_NONE=1, FOG_LINEAR, FOG_EXP, FOG_EXP2 }; Background( Material& in_material = defaultMaterial, bool sphere=false, int fogtype=FOG_NONE, float in_fogScale = 1.0); ~Background(); void render(RenderContext* renderContext); int getElementCount(void) { return 1; } void drawPrimitive(RenderContext* renderContext, int index); GLbitfield getClearFlags(RenderContext* renderContext); int getAttributeCount(AABox& bbox, AttribID attrib); void getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result); String getTextAttribute(AABox& bbox, AttribID attrib, int index); void getTypeName(char* buffer, int buflen) { strncpy(buffer, "background", buflen); }; SceneNode* getQuad() { return quad; }; protected: bool clearColorBuffer; bool sphere; int fogtype; float fogScale; SphereMesh sphereMesh; QuadSet* quad; // GLuint displayList; friend class Scene; private: static Material defaultMaterial; }; } // namespace rgl #endif // BACKGROUND_H rgl/src/device.cpp0000644000176200001440000001115714100762641013576 0ustar liggesusers// C++ source // This file is part of RGL. // // --------------------------------------------------------------------------- #include #include "Device.h" #include "lib.h" using namespace rgl; // --------------------------------------------------------------------------- Device::Device(int id, bool useNULL) : id_(id) { scene = new Scene(); rglview = new RGLView(scene); window = new Window( rglview, getGUIFactory(useNULL) ); if (window && !window->windowImpl) { delete window; window = NULL; } if (!window) { devtype = "none"; return; } devtype = GUIFactoryName(useNULL); window->addDisposeListener(this); } // --------------------------------------------------------------------------- Device::~Device() { delete scene; } // --------------------------------------------------------------------------- int Device::getID() { return id_; } // --------------------------------------------------------------------------- void Device::notifyDisposed(Disposable* disposable) { dispose(); } // --------------------------------------------------------------------------- void Device::setName(const char* string) { window->setTitle(string); } // --------------------------------------------------------------------------- void Device::update() { // window->update(); } // --------------------------------------------------------------------------- bool Device::open(void) { if (window) { window->setVisibility(true); return true; } else return false; } // --------------------------------------------------------------------------- void Device::close(void) { window->on_close(); } // --------------------------------------------------------------------------- void Device::bringToTop(int stay) { window->bringToTop(stay); } void Device::setWindowRect(int left, int top, int right, int bottom) { window->setWindowRect(left, top, right, bottom); } void Device::getWindowRect(int *left, int *top, int *right, int *bottom) { window->getWindowRect(left, top, right, bottom); } // --------------------------------------------------------------------------- int Device::getIgnoreExtent(void) { return scene->getIgnoreExtent(); } // --------------------------------------------------------------------------- void Device::setIgnoreExtent(int in_ignoreExtent) { scene->setIgnoreExtent(in_ignoreExtent); } // --------------------------------------------------------------------------- int Device::getSkipRedraw(void) { return window->getSkipRedraw(); } // --------------------------------------------------------------------------- void Device::setSkipRedraw(int in_skipRedraw) { window->setSkipRedraw(in_skipRedraw); } // --------------------------------------------------------------------------- bool Device::clear(TypeID stackTypeID) { bool success; success = scene->clear(stackTypeID); rglview->update(); return success; } // --------------------------------------------------------------------------- int Device::add(SceneNode* node) { bool success; success = scene->add(node); rglview->update(); if (success) return node->getObjID(); else return 0; } // --------------------------------------------------------------------------- bool Device::pop(TypeID stackTypeID, int id) { bool success; bool inGL = rglview->windowImpl->beginGL(); // May need to set context for display lists. success = scene->pop(stackTypeID, id); if (inGL) { rglview->windowImpl->endGL(); } rglview->update(); return success; } // --------------------------------------------------------------------------- bool Device::snapshot(int format, const char* filename) { return rglview->snapshot( (PixmapFileFormatID) format, filename); } // --------------------------------------------------------------------------- bool Device::pixels(int* ll, int* size, int component, double* result) { return rglview->pixels( ll, size, component, result); } // --------------------------------------------------------------------------- RGLView* Device::getRGLView(void) { return rglview; } // --------------------------------------------------------------------------- bool Device::postscript(int format, const char* filename, bool drawText) { return rglview->postscript( format, filename, drawText); } // --------------------------------------------------------------------------- void Device::getFonts(FontArray& outfonts, int nfonts, char** family, int* style, double* cex, bool useFreeType) { window->getFonts(outfonts, nfonts, family, style, cex, useFreeType); } // --------------------------------------------------------------------------- const char * Device::getDevtype() { return devtype; } rgl/src/SphereMesh.cpp0000644000176200001440000000731114100762641014377 0ustar liggesusers#include "SphereMesh.h" #include "subscene.h" #include "opengl.h" #include using namespace rgl; using namespace std; ////////////////////////////////////////////////////////////////////////////// // // CLASS // SphereMesh // SphereMesh::SphereMesh() : center( Vertex(0.0f,0.0f,0.0f) ), radius( 1.0f ), philow(-90.0f ), phihigh( 90.0f ), segments( 16 ), sections( 16 ), type( GLOBE ), genNormal(false), genTexCoord(false) { } void SphereMesh::setGlobe(int in_segments, int in_sections) { type = GLOBE; segments = in_segments; sections = in_sections; setupMesh(); } void SphereMesh::setTesselation(int level) { type = TESSELATION; } void SphereMesh::setupMesh() { // setup arrays nvertex = (sections+1) * (segments+1); vertexArray.alloc(nvertex); if (genNormal) normalArray.alloc(nvertex); if (genTexCoord) texCoordArray.alloc(nvertex); } void SphereMesh::setCenter(const Vertex& in_center) { center = in_center; } void SphereMesh::setRadius(float in_radius) { radius = in_radius; } void SphereMesh::update() { Vertex scale; scale.x = scale.y = scale.z = 1.0; update(scale); } void SphereMesh::update(const Vertex& scale) { int i = 0; for(int iy=0;iy<=sections;iy++) { Vertex p(0.0f,0.0f,radius); float fy = ((float)iy)/((float)sections); float phi = philow + fy * (phihigh - philow); p.rotateX( -phi ); for (int ix=0;ix<=segments;ix++,i++) { float fx = ((float)ix)/((float)segments); float theta = fx * 360.0f; Vertex q(p); q.rotateY( theta ); q.x /= scale.x; q.y /= scale.y; q.z /= scale.z; vertexArray[i] = center + q; if (genNormal) { q.x *= scale.x*scale.x; q.y *= scale.y*scale.y; q.z *= scale.z*scale.z; normalArray[i] = q; normalArray[i].normalize(); } if (genTexCoord) { texCoordArray[i].s = fx; texCoordArray[i].t = fy; } } } } void SphereMesh::draw(RenderContext* renderContext) { #ifndef RGL_NO_OPENGL vertexArray.beginUse(); if (genNormal) normalArray.beginUse(); if (genTexCoord) texCoordArray.beginUse(); for(int i=0; i #include #include "assert.h" using namespace rgl; void Disposable::addDisposeListener(IDisposeListener* l) { assert( std::find( disposeListeners.begin(), disposeListeners.end(), l ) == disposeListeners.end() ); disposeListeners.push_back(l); } void Disposable::removeDisposeListener(IDisposeListener* l) { Container::iterator pos = std::find( disposeListeners.begin(), disposeListeners.end(), l ); assert( pos != disposeListeners.end() ); disposeListeners.erase(pos); } void Disposable::fireNotifyDisposed() { // copy the listeners to a queue, // so add/remove are stable during 'notifyDispose'. std::vector queue( disposeListeners.begin(), disposeListeners.end() ); for ( std::vector::iterator i = queue.begin() ; i != queue.end() ; ++ i ) (*i)->notifyDisposed(this); } void Disposable::dispose() { fireNotifyDisposed(); } rgl/src/glErrors.cpp0000644000176200001440000000152414100762641014133 0ustar liggesusers// // This file is part of RGL. // #include "opengl.h" #include "R.h" #include "platform.h" namespace rgl { int SaveErrnum = GL_NO_ERROR; } using namespace rgl; #ifndef RGL_NO_OPENGL static const char * SaveFile; static int SaveLine; #endif void saveGLerror(const char * file, int line) { #ifndef RGL_NO_OPENGL GLenum errnum; if (SaveErrnum == GL_NO_ERROR && (errnum = glGetError()) != GL_NO_ERROR) { SaveErrnum = errnum; SaveFile = file; SaveLine = line; } #endif } void checkGLerror(const char * file, int line) { #ifndef RGL_NO_OPENGL saveGLerror(file, line); if (SaveErrnum != GL_NO_ERROR) { int err = SaveErrnum; SaveErrnum = GL_NO_ERROR; while (glGetError() != GL_NO_ERROR) {} /* clear other errors, if any */ error("OpenGL error at %s:%d: %s", SaveFile, SaveLine, gluErrorString(err)); } #endif } rgl/src/geom.h0000644000176200001440000000213614100762641012730 0ustar liggesusers#ifndef GEOM_H #define GEOM_H #include "rglmath.h" namespace rgl { // // CLASS // AABox (axis-aligned box) // class Sphere; class AABox { public: AABox(); AABox(const AABox& that) : vmin(that.vmin), vmax(that.vmax) { } void invalidate(void); bool isValid(void) const; void operator += (const AABox& aabox); void operator += (const Sphere& sphere); void operator += (const Vertex& vertex); bool operator < (const AABox& aabox) const; Vertex getCenter(void) const; Vertex vmin, vmax; }; // // CLASS // Sphere // class Sphere { public: Sphere() : center(0,0,0), radius(1) {}; Sphere(const Vertex& center, const float radius); Sphere(const float radius); Sphere(const AABox& aabox); Sphere(const AABox& aabox, const Vertex& scale); Vertex center; float radius; }; // // CLASS // Frustum // class Frustum { public: Frustum() : ortho(false) {}; void enclose(float sphere_radius, float fovangle, int win_width, int win_height); Matrix4x4 getMatrix(); float left, right, bottom, top, znear, zfar, distance; bool ortho; }; } // namespace rgl #endif // GEOM_H rgl/src/LineStripSet.cpp0000644000176200001440000000140714145464133014725 0ustar liggesusers#include "PrimitiveSet.h" using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // LineStripSet // LineStripSet::LineStripSet(Material& in_material, int in_nvertices, double* in_vertex, bool in_ignoreExtent, int in_nindices, int* in_indices, bool in_bboxChange) : PrimitiveSet(in_material, in_nvertices, in_vertex, GL_LINE_STRIP, 1, in_ignoreExtent, in_nindices, in_indices, in_bboxChange) { material.lit = false; if (material.line_antialias) blended = true; } void LineStripSet::drawPrimitive(RenderContext* renderContext, int index) { #ifndef RGL_NO_OPENGL if (index < nvertices-1) glDrawArrays(type, index*nverticesperelement, 2*nverticesperelement); #endif } rgl/src/SpriteSet.cpp0000644000176200001440000002256614142256754014300 0ustar liggesusers #include "SpriteSet.h" #include "Shape.h" #include "R.h" #include using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // SpriteSet // SpriteSet::SpriteSet(Material& in_material, int in_nvertex, double* in_vertex, int in_nsize, double* in_size, int in_ignoreExtent, int count, Shape** in_shapelist, double* in_userMatrix, bool in_fixedSize, Scene *in_scene, double* in_adj, int in_npos, int *in_pos, double in_offset) : Shape(in_material, in_ignoreExtent, SHAPE, true), vertex(in_nvertex, in_vertex), size(in_nsize, in_size), pos(in_npos, in_pos), offset(in_offset), fixedSize(in_fixedSize), scene(in_scene) { if (!count) material.colorPerVertex(false); else { blended = false; for (int i=0;igetObjID()); blended |= in_shapelist[i]->isBlended(); } for (int i=0;i<16;i++) userMatrix[i] = *(in_userMatrix++); } for(int i=0;i(size.getRecycled(i)/1.414) ); if (!in_adj) adj = Vec3(0.5, 0.5, 0.5); else adj = Vec3(in_adj[0], in_adj[1], in_adj[2]); } SpriteSet::~SpriteSet() { shapes.clear(); } int SpriteSet::getElementCount(void) { return vertex.size(); } Vertex SpriteSet::getPrimitiveCenter(int index) { return vertex.get(index); } /* These routines are for debugging static void printMatrix(const char* msg, double* m) { Rprintf("%s:\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n", msg, m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13], m[2], m[6], m[10], m[14], m[3], m[7], m[11], m[15]); } static void printMatrix(const char* msg, Matrix4x4 m) { double data[16]; m.getData(data); printMatrix(msg, data); } static void printMVMatrix(const char* msg) { double m[16] = {0}; #ifndef RGL_NO_OPENGL glGetDoublev(GL_MODELVIEW_MATRIX, m); #endif printMatrix(msg, m); } static void printPRMatrix(const char* msg) { double m[16] = {0}; #ifndef RGL_NO_OPENGL glGetDoublev(GL_PROJECTION_MATRIX, m); #endif printMatrix(msg, m); } */ void SpriteSet::drawBegin(RenderContext* renderContext) { #ifndef RGL_NO_OPENGL Shape::drawBegin(renderContext); m = Matrix4x4(renderContext->subscene->modelMatrix); if (fixedSize) { p = Matrix4x4(renderContext->subscene->projMatrix); renderContext->subscene->projMatrix.setIdentity(); glMatrixMode(GL_MODELVIEW); } if (!shapes.size()) { doTex = (material.texture) ? true : false; glNormal3f(0.0f,0.0f,1.0f); material.beginUse(renderContext); } #endif } void SpriteSet::drawPrimitive(RenderContext* renderContext, int index) { #ifndef RGL_NO_OPENGL Vertex o; BBoxDeco* bboxdeco = 0; if (material.marginCoord >= 0) { Subscene* subscene = renderContext->subscene; bboxdeco = subscene->get_bboxdeco(); } if (bboxdeco) o = bboxdeco->marginVecToDataVec(vertex.get(index), renderContext, &material); else o = vertex.get(index); float s = size.getRecycled(index); if (o.missing() || ISNAN(s)) return; Vec3 v3; /* We need to modify the variable rather than the GPU's * copy, because some objects refer to it */ Matrix4x4 *modelMatrix = &renderContext->subscene->modelMatrix; if (fixedSize) { float winwidth = (float) renderContext->rect.width; float winheight = (float) renderContext->rect.height; // The magic number 27 is chosen so that plotmath3d matches text3d. float scalex = 27.0f/winwidth, scaley = 27.0f/winheight; v3 = (p * m) * o; *modelMatrix = Matrix4x4::translationMatrix(v3.x, v3.y, v3.z)* Matrix4x4::scaleMatrix(scalex, scaley, (scalex + scaley)/2.0f); } else { s = s * 0.5f; v3 = m * o; *modelMatrix = Matrix4x4::translationMatrix(v3.x, v3.y, v3.z); } if (pos.size()) getAdj(index); if (shapes.size()) { Shape::drawEnd(renderContext); // The shape will call drawBegin/drawEnd *modelMatrix = (*modelMatrix)* Matrix4x4::scaleMatrix(2*s,2*s,2*s)* Matrix4x4::translationMatrix((1.0 - 2.0*adj.x), (1.0 - 2.0*adj.y), (1.0 - 2.0*adj.z))* Matrix4x4(userMatrix); /* Since we modified modelMatrix, we need to reload it */ renderContext->subscene->loadMatrices(); for (std::vector::iterator i = shapes.begin(); i != shapes.end() ; ++ i ) scene->get_shape(*i)->draw(renderContext); Shape::drawBegin(renderContext); } else { material.useColor(index); /* Since we modified modelMatrix, we need to reload it */ renderContext->subscene->loadMatrices(); glBegin(GL_QUADS); if (doTex) glTexCoord2f(0.0f,0.0f); glVertex3f(s*(0.0 - 2.0*adj.x), s*(0.0 - 2.0*adj.y), s*(1.0 - 2.0*adj.z)); if (doTex) glTexCoord2f(1.0f,0.0f); glVertex3f(s*(2.0 - 2.0*adj.x), s*(0.0 - 2.0*adj.y), s*(1.0 - 2.0*adj.z)); if (doTex) glTexCoord2f(1.0f,1.0f); glVertex3f(s*(2.0 - 2.0*adj.x), s*(2.0 - 2.0*adj.y), s*(1.0 - 2.0*adj.z)); if (doTex) glTexCoord2f(0.0f,1.0f); glVertex3f(s*(0.0 - 2.0*adj.x), s*(2.0 - 2.0*adj.y), s*(1.0 - 2.0*adj.z)); glEnd(); } #endif } void SpriteSet::getAdj(int index) { int p = pos.get(index); switch(p) { case 0: case 1: case 3: case 5: case 6: adj.x = 0.5; break; case 2: adj.x = 1.0 + offset; break; case 4: adj.x = -offset; break; } switch(p) { case 0: case 2: case 4: case 5: case 6: adj.y = 0.5; break; case 1: adj.y = 1.0 + offset; break; case 3: adj.y = -offset; break; } switch(p) { case 0: case 1: case 2: case 3: case 4: adj.z = 0.5; break; case 5: adj.z = -offset; break; case 6: adj.z = 1.0 + offset; break; } } void SpriteSet::drawEnd(RenderContext* renderContext) { #ifndef RGL_NO_OPENGL if (fixedSize) { renderContext->subscene->projMatrix = Matrix4x4(p); } renderContext->subscene->modelMatrix = Matrix4x4(m); /* Restore the original GPU matrices */ renderContext->subscene->loadMatrices(); if (!shapes.size()) material.endUse(renderContext); Shape::drawEnd(renderContext); #endif } void SpriteSet::render(RenderContext* renderContext) { draw(renderContext); } int SpriteSet::getAttributeCount(AABox& bbox, AttribID attrib) { switch (attrib) { case VERTICES: return vertex.size(); case RADII: return size.size(); case IDS: case TYPES: return static_cast(shapes.size()); case USERMATRIX: { if (!shapes.size()) return 0; else return 4; } case FLAGS: return 2; case ADJ: return 1; case POS: return pos.size(); } return Shape::getAttributeCount(bbox, attrib); } void SpriteSet::getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result) { int n = getAttributeCount(bbox, attrib); int ind = 0; if (first + count < n) n = first + count; if (first < n) { switch(attrib) { case VERTICES: while (first < n) { Vertex v = vertex.get(first); *result++ = v.x; *result++ = v.y; *result++ = v.z; first++; } return; case RADII: while (first < n) *result++ = size.get(first++); return; case IDS: for (std::vector::iterator i = shapes.begin(); i != shapes.end() ; ++ i ) { if ( first <= ind && ind < n ) *result++ = *i; ind++; } return; case USERMATRIX: while (first < n) { *result++ = userMatrix[4*first]; *result++ = userMatrix[4*first+1]; *result++ = userMatrix[4*first+2]; *result++ = userMatrix[4*first+3]; first++; } return; case FLAGS: if (first == 0) *result++ = (double) ignoreExtent; *result++ = (double) fixedSize; return; case ADJ: if (pos.size() > 0) { *result++ = offset; *result++ = NA_REAL; *result++ = NA_REAL; } else { *result++ = adj.x; *result++ = adj.y; *result++ = adj.z; } return; case POS: while (first < n) *result++ = pos.get(first++); return; } Shape::getAttribute(bbox, attrib, first, count, result); } } String SpriteSet::getTextAttribute(AABox& bbox, AttribID attrib, int index) { int n = getAttributeCount(bbox, attrib); if (index < n && attrib == TYPES) { char* buffer = R_alloc(20, 1); scene->get_shape(shapes[index])->getTypeName(buffer, 20); return String(static_cast(strlen(buffer)), buffer); } else return Shape::getTextAttribute(bbox, attrib, index); } Shape* SpriteSet::get_shape(int id) { return scene->get_shape(id); } void SpriteSet::remove_shape(int id) { shapes.erase(std::remove(shapes.begin(), shapes.end(), id), shapes.end()); } rgl/src/SphereSet.cpp0000644000176200001440000001235314100762641014240 0ustar liggesusers#include "SphereSet.h" #include "Viewpoint.h" #include "R.h" using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // SphereSet // SphereSet::SphereSet(Material& in_material, int in_ncenter, double* in_center, int in_nradius, double* in_radius, int in_ignoreExtent, bool in_fastTransparency) : Shape(in_material, in_ignoreExtent, SHAPE, true), center(in_ncenter, in_center), radius(in_nradius, in_radius), lastdrawn(-1), lastendcap(true), fastTransparency(in_fastTransparency) { material.colorPerVertex(false); if (material.lit) sphereMesh.setGenNormal(true); if ( (material.texture) && (!material.texture->is_envmap() ) ) sphereMesh.setGenTexCoord(true); sphereMesh.setGlobe(16,16); for (int i=0;igetModelViewpoint()->scale; scale.x = 1.0f/scale.x; scale.y = 1.0f/scale.y; scale.z = 1.0f/scale.z; boundingBox.invalidate(); for(int i=0;i= 0) { Subscene* subscene = renderContext->subscene; bboxdeco = subscene->get_bboxdeco(); } if (fastTransparency) { if (bboxdeco) { invalidateDisplaylist(); pt = bboxdeco->marginVecToDataVec(center.get(index), renderContext, &material); } else pt = center.get(index); if ( pt.missing() || ISNAN(radius.getRecycled(index)) ) return; material.useColor(index); sphereMesh.setCenter( pt ); sphereMesh.setRadius( radius.getRecycled(index) ); sphereMesh.update( renderContext->subscene->getModelViewpoint()->scale ); sphereMesh.draw(renderContext); } else { int i1 = index / facets, i2 = index % facets; bool endcap = i2 < sphereMesh.getSegments() || i2 >= facets - sphereMesh.getSegments(); if (i1 != lastdrawn) { if (bboxdeco) { invalidateDisplaylist(); pt = bboxdeco->marginVecToDataVec(center.get(i1), renderContext, &material); } else pt = center.get(index); if ( pt.missing() || ISNAN(radius.getRecycled(i1)) ) return; material.useColor(i1); if (lastdrawn >= 0) sphereMesh.drawEnd( renderContext ); sphereMesh.setCenter( pt ); sphereMesh.setRadius( radius.getRecycled(i1) ); sphereMesh.update( renderContext->subscene->getModelViewpoint()->scale ); sphereMesh.drawBegin( renderContext, endcap); lastdrawn = i1; lastendcap = endcap; } else if (endcap != lastendcap) { sphereMesh.drawEnd( renderContext ); sphereMesh.drawBegin( renderContext, endcap); lastendcap = endcap; } sphereMesh.drawPrimitive(renderContext, i2); } } void SphereSet::drawEnd(RenderContext* renderContext) { if (lastdrawn >= 0) sphereMesh.drawEnd( renderContext ); lastdrawn = -1; material.endUse(renderContext); Shape::drawEnd(renderContext); } void SphereSet::render(RenderContext* renderContext) { if (renderContext->subscene->getModelViewpoint()->scaleChanged) doUpdate = true; Shape::render(renderContext); } int SphereSet::getPrimitiveCount() { return (fastTransparency ? 1 : facets) * getElementCount(); } Vertex SphereSet::getPrimitiveCenter(int index) { if (fastTransparency) { return center.get(index); } else { int i1 = index / facets, i2 = index % facets; if (i1 != lastdrawn) { if ( center.get(i1).missing() || ISNAN(radius.getRecycled(i1)) ) return center.get(i1); sphereMesh.setCenter( center.get(i1) ); sphereMesh.setRadius( radius.getRecycled(i1) ); sphereMesh.update(); lastdrawn = i1; } return sphereMesh.getPrimitiveCenter(i2); } } int SphereSet::getAttributeCount(AABox& bbox, AttribID attrib) { switch (attrib) { case RADII: return radius.size(); case VERTICES: return center.size(); case FLAGS: return 2; } return Shape::getAttributeCount(bbox, attrib); } void SphereSet::getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result) { int n = getAttributeCount(bbox, attrib); if (first + count < n) n = first + count; if (first < n) { switch (attrib) { case VERTICES: while (first < n) { *result++ = center.get(first).x; *result++ = center.get(first).y; *result++ = center.get(first).z; first++; } return; case RADII: while (first < n) *result++ = radius.get(first++); return; case FLAGS: if (first == 0) *result++ = ignoreExtent; *result++ = (double) fastTransparency; return; } Shape::getAttribute(bbox, attrib, first, count, result); } } rgl/src/Makevars.ucrt0000644000176200001440000000057514142256754014316 0ustar liggesusersCXX_STD = CXX11 PKG_CPPFLAGS = \ -DHAVE_PNG_H -DHAVE_FREETYPE -Iext -Iext/ftgl \ -I$(LOCAL_SOFT)/include/freetype2 \ -DRGL_W32 PKG_LIBS = \ -lfreetype -lharfbuzz -lfreetype -lpng -lbz2 -lz -lgdi32 -lopengl32 -lglu32 all: winlibs $(SHLIB) $(SHLIB): winlibs winlibs: sed -e "s^@RGL_NO_OPENGL@^FALSE^" ../R/noOpenGL.R.in > ../R/noOpenGL.R clean: rm -f $(OBJECTS) $(SHLIB) rgl/src/pixmap.h0000644000176200001440000000201414100762641013272 0ustar liggesusers#ifndef PIXMAP_H #define PIXMAP_H // C++ header file // This file is part of RGL #include #include "opengl.h" namespace rgl { class PixmapFormat; enum PixmapTypeID { INVALID=0, RGB24, RGB32, RGBA32, GRAY8 }; enum PixmapFileFormatID { PIXMAP_FILEFORMAT_PNG = 0, PIXMAP_FILEFORMAT_LAST }; class Pixmap { public: Pixmap(); ~Pixmap(); bool init(PixmapTypeID typeID, int width, int height, int bits_per_channel); bool load(const char* filename); bool save(PixmapFormat* format, const char* filename); void clear(); PixmapTypeID typeID; unsigned int width; unsigned int height; unsigned int bits_per_channel; unsigned int bytesperrow; unsigned char *data; }; class PixmapFormat { public: virtual ~PixmapFormat() { } virtual bool checkSignature(std::FILE* file) = 0; virtual bool load(std::FILE* file, Pixmap* pixmap) = 0; virtual bool save(std::FILE* file, Pixmap* pixmap) = 0; }; extern PixmapFormat* pixmapFormat[PIXMAP_FILEFORMAT_LAST]; } // namespace rgl #endif /* PIXMAP_H */ rgl/src/SceneNode.h0000644000176200001440000000363514145464133013655 0ustar liggesusers#ifndef SCENENODE_H #define SCENENODE_H // // ABSTRACT BASE CLASS // SceneNode // #include "types.h" #include "String.h" #include "geom.h" namespace rgl { /* enum TypeID { SHAPE=1, LIGHT, BBOXDECO, USERVIEWPOINT, BACKGROUND, SUBSCENE, MODELVIEWPOINT }; */ #define SHAPE 1 #define LIGHT 2 #define BBOXDECO 3 #define USERVIEWPOINT 4 #define BACKGROUND 6 // 5 was used for the material #define SUBSCENE 7 #define MODELVIEWPOINT 8 #define MAX_TYPE 8 typedef unsigned int TypeID; typedef int ObjID; /* Possible attributes to request */ #define VERTICES 1 #define NORMALS 2 #define COLORS 3 #define TEXCOORDS 4 #define SURFACEDIM 5 #define TEXTS 6 #define CEX 7 #define ADJ 8 #define RADII 9 #define CENTERS 10 #define IDS 11 #define USERMATRIX 12 #define TYPES 13 #define FLAGS 14 #define OFFSETS 15 #define FAMILY 16 #define FONT 17 #define POS 18 #define FOGSCALE 19 #define AXES 20 #define INDICES 21 typedef unsigned int AttribID; class SceneNode { public: inline const TypeID getTypeID() const { return typeID; } inline const ObjID getObjID() const { return objID; } virtual ~SceneNode() { }; static ObjID nextID; SceneNode *owner; /* don't delete this node while the owner is non-NULL */ /* Some nodes depend on the bbox, so we pass it to all */ virtual int getAttributeCount(AABox& bbox, AttribID attrib) { return 0; } virtual void getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result) { return; } virtual String getTextAttribute(AABox& bbox, AttribID attrib, int index) { return String(0, NULL); } virtual void getTypeName(char* buffer, int buflen) = 0; protected: SceneNode(const TypeID in_typeID) : typeID(in_typeID) { objID = nextID++; owner = NULL; }; private: const TypeID typeID; ObjID objID; }; /** * used in find_if searches, so can't be a method */ bool sameID(SceneNode* node, int id); } // namespace rgl #endif // SCENENODE_H rgl/src/String.cpp0000644000176200001440000000446714105226324013611 0ustar liggesusers#include "String.h" #include "types.h" using namespace std; ////////////////////////////////////////////////////////////////////////////// // // SECTION: Strings // // // CLASS // StringArrayImpl // namespace rgl { class StringArrayImpl : public AutoDestroy { public: StringArrayImpl(int in_ntexts, char** in_texts) { int i; ntexts = in_ntexts; lengths = new unsigned int [ntexts]; starts = new unsigned int [ntexts]; int buflen = 0; for(i=0;i(strlen(in_texts[i])) ); } char* tptr = textbuffer = new char [buflen]; for(i=0;i 0) { impl = new StringArrayImpl(in_ntexts, in_texts); impl->ref(); } else impl = NULL; } StringArray::StringArray(StringArray& from) { impl = from.impl; if (impl) impl->ref(); } StringArray::~StringArray() { if (impl) impl->unref(); } String StringArray::operator[](int index) { if (impl && index < impl->ntexts) return String(impl->lengths[index], impl->textbuffer + impl->starts[index]); else return String(0, NULL); } int StringArray::size() { if (impl) return impl->ntexts; else return 0; } // // CLASS // StringArrayIterator // StringArrayIterator::StringArrayIterator(StringArray* in_array) { array = in_array; } void StringArrayIterator::first() { cnt = 0; if (array->impl) textptr = array->impl->textbuffer; else textptr = NULL; } void StringArrayIterator::next() { if ( (textptr) && (cnt < array->impl->ntexts) ) textptr += 1 + array->impl->lengths[cnt++]; } String StringArrayIterator::getCurrent() { return String(array->impl->lengths[cnt], textptr ); } bool StringArrayIterator::isDone() const { if (array->impl) return (cnt == array->impl->ntexts) ? true : false; else return true; } rgl/src/pngpixmap.h0000644000176200001440000002400514100762641014003 0ustar liggesusers#include "lib.h" #include "types.h" #include // C++ header file // This file is part of RGL // namespace rgl { class PNGPixmapFormat : public PixmapFormat { public: PNGPixmapFormat() { } bool checkSignature(std::FILE* fd) { unsigned char buf[8]; if (fread(buf, 1, 8, fd) < 8) return false; fseek(fd, 0, SEEK_SET); return !png_sig_cmp(buf, 0, 8); } bool load(std::FILE* fd, Pixmap* pixmap) { Load load(fd, pixmap); if (load.init()) { bool success; success = load.process(); if (!success) printMessage("pixmap png loader: process failed"); return success; } else { printMessage("pixmap png loader: init failed"); return false; } } bool save(std::FILE* fd, Pixmap* pixmap) { Save save(fd, pixmap); if (save.init()) return save.process(); else return false; } private: // // CLASS // Load // class Load { public: Load(std::FILE* _file, Pixmap* _pixmap) { file = _file; pixmap = _pixmap; png_ptr = NULL; info_ptr = NULL; finish = false; error = false; } bool init(void) { bool success = false; png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp)this, error_callback, warning_callback); if (png_ptr) { info_ptr = png_create_info_struct(png_ptr); if (info_ptr) { png_set_progressive_read_fn(png_ptr, (void *)this, info_callback, row_callback, end_callback); success = true; } } return success; } bool process() { while ((!feof(file)) && (!error)) { size_t size = fread(buffer,1,sizeof(buffer),file); if (ferror(file)) { printError("file read error"); return false; } png_process_data(png_ptr, info_ptr, buffer, size); } return finish; } ~Load() { if (png_ptr) png_destroy_read_struct(&png_ptr, (info_ptr) ? &info_ptr : NULL, (png_infopp)NULL); } private: static void printError(const char* error_msg) { char buf[256]; sprintf(buf, "PNG Pixmap Loader Error: %s", error_msg); printMessage(buf); } static void printWarning(const char* warning_msg) { char buf[256]; sprintf(buf, "PNG Pixmap Loader Warning: %s", warning_msg); printMessage(buf); } static void error_callback(png_structp png_ptr, png_const_charp error_msg) { // Load* load = (Load*) png_get_error_ptr(png_ptr); printError( (const char*) error_msg ); } static void warning_callback(png_structp png_ptr, png_const_charp warning_msg) { // Load* load = (Load*) png_get_error_ptr(png_ptr); printWarning( (const char*) warning_msg ); } static void info_callback(png_structp png_ptr, png_infop info) { char buffer[256]; Load* load = (Load*) png_get_progressive_ptr(png_ptr); png_uint_32 width, height; int bit_depth, color_type, interlace_type, compression_type, filter_type; png_get_IHDR(load->png_ptr, load->info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_type); char* color_type_name; switch(color_type) { case PNG_COLOR_TYPE_RGB: color_type_name = (char*)"RGB"; break; case PNG_COLOR_TYPE_GRAY: color_type_name = (char*)"GRAY"; break; case PNG_COLOR_TYPE_PALETTE: color_type_name = (char*)"INDEX"; break; case PNG_COLOR_TYPE_RGB_ALPHA: color_type_name = (char*)"RGBALPHA"; break; case PNG_COLOR_TYPE_GRAY_ALPHA: color_type_name = (char*)"GRAYALPHA"; break; default: color_type_name = (char*)"unknown"; break; }; const char* interlace_string = (interlace_type == PNG_INTERLACE_ADAM7) ? "adam7 interlace " : ""; if (bit_depth == 16) png_set_strip_16(png_ptr); else if (bit_depth < 8 && color_type == PNG_COLOR_TYPE_GRAY) png_set_expand_gray_1_2_4_to_8(png_ptr); else if (bit_depth != 8) /* this should never happen with current formats... */ goto unsupported; if (interlace_type == PNG_INTERLACE_ADAM7) goto unsupported; PixmapTypeID typeID; switch(color_type) { case PNG_COLOR_TYPE_RGB: typeID = RGB24; goto init; case PNG_COLOR_TYPE_GRAY: typeID = GRAY8; goto init; case PNG_COLOR_TYPE_RGB_ALPHA: typeID = RGBA32; goto init; case PNG_COLOR_TYPE_PALETTE: png_set_palette_to_rgb(png_ptr); typeID = RGB24; goto init; case PNG_COLOR_TYPE_GRAY_ALPHA: png_set_gray_to_rgb(png_ptr); typeID = RGBA32; goto init; default: goto unsupported; break; }; init: if (typeID == RGB24 && png_get_valid(png_ptr, info, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(png_ptr); typeID = RGBA32; } load->pixmap->init(typeID, width,height,bit_depth); png_read_update_info(load->png_ptr,load->info_ptr); return; unsupported: sprintf(buffer,"%s%s format unsupported: %lux%lu (%d bits per channel)", interlace_string, color_type_name, (long unsigned int)width, (long unsigned int)height, bit_depth); printMessage(buffer); load->error = true; png_read_update_info(load->png_ptr,load->info_ptr); return; /* Do any setup here, including setting any of the transformations mentioned in the Reading PNG files section. For now, you _must_ call either png_start_read_image() or png_read_update_info() after all the transformations are set (even if you don't set any). You may start getting rows before png_process_data() returns, so this is your last chance to prepare for that. */ } static void row_callback(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass) { Load* load = (Load*) png_get_progressive_ptr(png_ptr); void* rowptr = load->pixmap->data + load->pixmap->bytesperrow * (load->pixmap->height-1-row_num); memcpy(rowptr, new_row, load->pixmap->bytesperrow); } static void end_callback(png_structp png_ptr, png_infop info) { Load* load = (Load*) png_get_progressive_ptr(png_ptr); load->finish = true; /* This function is called after the whole image has been read, including any chunks after the image (up to and including the IEND). You will usually have the same info chunk as you had in the header, although some data may have been added to the comments and time fields. Most people won't do much here, perhaps setting a flag that marks the image as finished. */ } /* static void end_callback(void) { } */ typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp)); std::FILE* file; Pixmap* pixmap; png_structp png_ptr; png_infop info_ptr; unsigned char buffer[4096]; bool error; bool finish; }; // // CLASS // Save // class Save { public: Save(std::FILE* in_file, Pixmap* in_pixmap) { file = in_file; pixmap = in_pixmap; png_ptr = NULL; info_ptr = NULL; } bool init(void) { bool success = false; png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, (png_voidp)this, error_callback, warning_callback); if (png_ptr) { info_ptr = png_create_info_struct(png_ptr); if (info_ptr) { png_init_io(png_ptr, file); success = true; } } return success; } bool process(void) { if (setjmp(png_jmpbuf(png_ptr))) { printError("an error occured"); png_destroy_write_struct(&png_ptr, &info_ptr); return false; } png_set_filter(png_ptr, 0, PNG_FILTER_NONE); const int color_type = PNG_COLOR_TYPE_RGB; const int interlace_type = PNG_INTERLACE_NONE; const int compression_type = PNG_COMPRESSION_TYPE_DEFAULT; const int filter_type = PNG_FILTER_TYPE_DEFAULT; png_set_IHDR(png_ptr, info_ptr, pixmap->width, pixmap->height, pixmap->bits_per_channel, color_type, interlace_type, compression_type, filter_type); png_text text[1]; text[0].key = (png_charp)"Software"; text[0].text = (png_charp)"R/RGL package/libpng"; text[0].compression = PNG_TEXT_COMPRESSION_NONE; png_set_text(png_ptr, info_ptr, text, sizeof(text)/sizeof(png_text) ); png_write_info(png_ptr, info_ptr); png_bytep rowptr = (png_bytep) ( ((u8*)pixmap->data) + (pixmap->height - 1) * pixmap->bytesperrow ); for(unsigned int i=0;iheight;i++) { png_write_row(png_ptr, rowptr); rowptr -= pixmap->bytesperrow; } png_write_end(png_ptr, info_ptr); return true; } ~Save() { if (png_ptr) png_destroy_write_struct(&png_ptr, (info_ptr) ? &info_ptr : NULL); } private: static void printError(const char* error_msg) { char buf[256]; sprintf(buf, "PNG Pixmap Saver Error: %s", error_msg); printMessage(buf); } static void printWarning(const char* warning_msg) { char buf[256]; sprintf(buf, "PNG Pixmap Saver Warning: %s", warning_msg); printMessage(buf); } static void error_callback(png_structp png_ptr, png_const_charp error_msg) { // Save* save = (Save*) png_get_error_ptr(png_ptr); printError( (const char*) error_msg ); } static void warning_callback(png_structp png_ptr, png_const_charp warning_msg) { // Save* save = (Save*) png_get_error_ptr(png_ptr); printWarning( (const char*) warning_msg ); } std::FILE* file; Pixmap* pixmap; png_structp png_ptr; png_infop info_ptr; }; }; } // namespace rgl rgl/src/useNULL/0000755000176200001440000000000014146473376013133 5ustar liggesusersrgl/src/useNULL/Makevars0000644000176200001440000000056214146473263014625 0ustar liggesusers# # R Makevars file auto-generated using template Makevars.in # AUTO-GENERATED from Makevars.in (using configure or configure.win) # This file is part of the RGL project. # CXX_STD = CXX11 PKG_CFLAGS=$(C_VISIBILITY) PKG_CPPFLAGS= -DHAVE_PNG_H -I/usr/local/Cellar/libpng/1.6.37/include/libpng16 -DRGL_NO_OPENGL PKG_LIBS= -L/usr/local/Cellar/libpng/1.6.37/lib -lpng16 rgl/src/useNULL/Makevars.in0000644000176200001440000000041614100762641015217 0ustar liggesusers# # R Makevars file auto-generated using template Makevars.in # AUTO-GENERATED from Makevars.in (using configure or configure.win) # This file is part of the RGL project. # CXX_STD = CXX11 PKG_CFLAGS=$(C_VISIBILITY) PKG_CPPFLAGS=@NULL_CPPFLAGS@ PKG_LIBS=@NULL_LIBS@ rgl/src/api.cpp0000644000176200001440000010745314145464133013121 0ustar liggesusers// C++ source // This file is part of RGL. // #include "lib.h" #include "DeviceManager.h" #include "rglview.h" #include "lib.h" #include "R.h" #include "api.h" #include "platform.h" using namespace rgl; // // API Success is encoded as integer type: // #define RGL_FAIL 0 #define RGL_SUCCESS 1 inline int as_success(int b) { return (b) ; } // // data type conversion utilities: // inline bool as_bool(int idata) { return (idata) ? true : false; } // // rgl::rgl_init moved to init.cpp // namespace rgl { extern DeviceManager* deviceManager; extern void getObserver(double* ddata, Subscene* subscene); extern void setObserver(bool automatic, double* ddata, RGLView* rglview, Subscene* subscene); } // // FUNCTION // rgl::rgl_quit // // DESCRIPTION // Gets called by .onUnload ( R function ) // void rgl::rgl_quit(int* successptr) { if (deviceManager) { delete deviceManager; deviceManager = 0; } quit(); *successptr = RGL_SUCCESS; } // // FUNCTION // rgl::rgl_dev_open // void rgl::rgl_dev_open(int* successptr, int* useNULL) { *successptr = as_success( deviceManager && deviceManager->openDevice(*useNULL) ); CHECKGLERROR; } // // FUNCTION // rgl::rgl_dev_close // void rgl::rgl_dev_close(int* successptr) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getCurrentDevice())) { device->close(); success = RGL_SUCCESS; CHECKGLERROR; } *successptr = success; } void rgl::rgl_dev_bringtotop(int* successptr, int* stay) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getCurrentDevice())) { device->bringToTop(*stay); success = RGL_SUCCESS; CHECKGLERROR; } *successptr = success; } // // FUNCTION // rgl::rgl_dev_getcurrent // // RETURNS // device id // SEXP rgl::rgl_dev_getcurrent(void) { SEXP result; if (deviceManager) { int id = deviceManager->getCurrent(); PROTECT(result = ScalarInteger(id)); if (id) { PROTECT(result = namesgets(result, ScalarString(mkChar(deviceManager->getDevice(id)->getDevtype())))); CHECKGLERROR; UNPROTECT(1); } UNPROTECT(1); return result; } return ScalarInteger(0); } // // FUNCTION // rgl::rgl_dev_list // // RETURNS // list of active device ids // SEXP rgl::rgl_dev_list(void) { SEXP result, names; if (deviceManager) { int n = deviceManager->getDeviceCount(); PROTECT(result = allocVector(INTSXP, n)); deviceManager->getDeviceIds(INTEGER(result), n); PROTECT(names = allocVector(STRSXP, n)); for (int i = 0; i < n; i++) { Device* device = deviceManager->getDevice(INTEGER(result)[i]); SET_STRING_ELT(names, i, mkChar(device->getDevtype())); } PROTECT(result = namesgets(result, names)); CHECKGLERROR; UNPROTECT(3); return result; } return allocVector(INTSXP, 0); } // // FUNCTION // rgl::rgl_dev_setcurrent // // PARAMETERS // idata // [0] device id // void rgl::rgl_dev_setcurrent(int* successptr, int* idata) { int id = idata[0]; bool silent = (bool) idata[1]; *successptr = as_success ( deviceManager && deviceManager->setCurrent(id, silent) ); CHECKGLERROR; } // // SCENE MANAGEMENT // static Material currentMaterial(Color(1.0f,1.0f,1.0f),Color(1.0f,0.0f,0.0f)); // // FUNCTION // rgl::rgl_clear ( successPtr, idata(type) ) // // PARAMETERS // idata // [0] count of types // [1], [2], ... TypeID 1, 2, ... // // void rgl::rgl_clear(int* successptr, int *idata) { int success = RGL_SUCCESS; Device* device; int num = idata[0]; if (deviceManager && (device = deviceManager->getAnyDevice())) { for (int i=1; success && i<=num; i++) { TypeID stackTypeID = (TypeID) idata[i]; success = as_success( device->clear( stackTypeID ) ); // viewpoint & material handled in R, background ignored } CHECKGLERROR; } *successptr = success; } // // FUNCTION // rgl::rgl_pop ( successPtr, idata ) // // PARAMETERS // idata // [0] stack TypeID // [1] id SceneNode identifier // // void rgl::rgl_pop(int* successptr, int* idata) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getCurrentDevice())) { TypeID stackTypeID = (TypeID) idata[0]; int id = idata[1]; success = as_success( device->pop( stackTypeID, id ) ); CHECKGLERROR; } *successptr = success; } // // FUNCTION // rgl::rgl_id_count // void rgl::rgl_id_count(int* type, int* count, int* subsceneID) { Device* device; *count = 0; if (deviceManager && (device = deviceManager->getCurrentDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); Subscene* subscene; if (!*subsceneID) { while (*type) { *count += scene->get_id_count((TypeID) *type); type++; } } else if ((subscene = scene->getSubscene(*subsceneID))) { while (*type) { *count += subscene->get_id_count((TypeID) *type, false); type++; } } CHECKGLERROR; } } // // FUNCTION // rgl::rgl_ids // void rgl::rgl_ids(int* type, int* ids, char** types, int* subsceneID) { Device* device; if (deviceManager && (device = deviceManager->getCurrentDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); Subscene* subscene; if (!*subsceneID) { while (*type) { int n = scene->get_id_count((TypeID) *type); if (n) { scene->get_ids((TypeID) *type, ids, types); ids += n; types += n; } type++; } } else if ((subscene = scene->getSubscene(*subsceneID))) { while (*type) { int n = subscene->get_id_count((TypeID) *type, false); subscene->get_ids((TypeID) *type, ids, types, false); ids += n; types += n; type++; } } CHECKGLERROR; } } // // FUNCTION // rgl::rgl_attrib_count // void rgl::rgl_attrib_count(int* id, int* attrib, int* count) { Device* device; if (deviceManager && (device = deviceManager->getCurrentDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); Subscene* subscene = scene->whichSubscene(*id); AABox bbox = subscene->getBoundingBox(); SceneNode* scenenode = scene->get_scenenode(*id); if ( scenenode ) *count = scenenode->getAttributeCount(bbox, *attrib); else *count = 0; } } // // FUNCTION // rgl::rgl_attrib // void rgl::rgl_attrib(int* id, int* attrib, int* first, int* count, double* result) { Device* device; if (deviceManager && (device = deviceManager->getCurrentDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); Subscene* subscene = scene->whichSubscene(*id); AABox bbox = subscene->getBoundingBox(); SceneNode* scenenode = scene->get_scenenode(*id); if ( scenenode ) scenenode->getAttribute(bbox, *attrib, *first, *count, result); } } // // FUNCTION // rgl::rgl_text_attrib // void rgl::rgl_text_attrib(int* id, int* attrib, int* first, int* count, char** result) { Device* device; if (deviceManager && (device = deviceManager->getCurrentDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); AABox bbox = scene->getBoundingBox(); SceneNode* scenenode = scene->get_scenenode(*id); if (scenenode) for (int i=0; i < *count; i++) { String s = scenenode->getTextAttribute(bbox, *attrib, i + *first); if (s.length) { *result = R_alloc(s.length + 1, 1); strncpy(*result, s.text, s.length); (*result)[s.length] = '\0'; } result++; } } } // // FUNCTION // rgl::rgl_bg ( successPtr, idata ) // // PARAMETERS // idata // [0] bool environment sphere // [1] int fogtype // void rgl::rgl_bg(int* successptr, int* idata, double* fogScale) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { bool sphere = as_bool( idata[0] ); int fogtype = idata[1]; Background* bg = new Background(currentMaterial, sphere, fogtype, static_cast(fogScale[0])); success = as_success( device->add( bg ) ); SceneNode* quad = bg->getQuad(); if (quad) { int save_ignore = device->getIgnoreExtent(), save_redraw = device->getSkipRedraw(); device->setSkipRedraw(true); device->setIgnoreExtent(true); device->add( quad ); device->getScene()->hide(quad->getObjID()); device->setIgnoreExtent(save_ignore); device->setSkipRedraw(save_redraw); } CHECKGLERROR; } *successptr = success; } // // FUNCTION // rgl::rgl_light ( successPtr, idata, cdata, ddata ) // void rgl::rgl_light ( int* successptr, int* idata, double* ddata ) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { bool viewpoint_rel = as_bool( idata[0] ); bool finite_pos = as_bool( idata[10] ); Color ambient; Color diffuse; Color specular; ambient.set3iv ( &idata[1] ); diffuse.set3iv ( &idata[4] ); specular.set3iv( &idata[7] ); float theta = (float) ddata[0]; float phi = (float) ddata[1]; Vertex finposition = Vertex( static_cast(ddata[2]), static_cast(ddata[3]), static_cast(ddata[4]) ); success = as_success( device->add( new Light( PolarCoord(theta, phi), finposition, (bool) viewpoint_rel, (bool) finite_pos, ambient, diffuse, specular ) ) ); CHECKGLERROR; } *successptr = success; } void rgl::rgl_viewpoint(int* successptr, int* idata, double* ddata) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { float theta = static_cast( ddata[0] ); float phi = static_cast( ddata[1] ); float fov = static_cast( ddata[2] ); float zoom = static_cast( ddata[3] ); Vertex scale = Vertex( static_cast(ddata[4]), static_cast(ddata[5]), static_cast(ddata[6]) ); int interactive = idata[0]; int polar = idata[1]; int user = idata[2]; int model = idata[3]; if (model) { if (polar) success = as_success( device->add( new ModelViewpoint(PolarCoord(theta, phi), scale, interactive) ) ); else success = as_success( device->add( new ModelViewpoint(ddata + 7, scale, interactive) ) ); } else success = RGL_SUCCESS; if (user && success) success = as_success( device->add( new UserViewpoint(fov, zoom) ) ); CHECKGLERROR; } *successptr = success; } void rgl::rgl_getObserver(int* successptr, double* ddata) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); Subscene* subscene = scene->getCurrentSubscene(); getObserver(ddata, subscene); success = RGL_SUCCESS; } *successptr = success; } void rgl::rgl_setObserver(int* successptr, double* ddata) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); bool automatic = (bool)*successptr; Subscene* subscene = scene->getCurrentSubscene(); setObserver(automatic, ddata, rglview, subscene); } *successptr = success; } void rgl::rgl_primitive(int* successptr, int* idata, double* vertex, double* normals, double* texcoords) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { int type = idata[0]; int nvertex = idata[1]; int ignoreExtent = device->getIgnoreExtent() || currentMaterial.marginCoord >= 0; int useNormals = idata[2]; int useTexcoords = idata[3]; int nindices = idata[4]; int* indices = idata + 5; SceneNode* node; switch(type) { case 1: // RGL_POINTS: node = new PointSet( currentMaterial, nvertex, vertex, ignoreExtent, nindices, indices); break; case 2: // RGL_LINES: node = new LineSet( currentMaterial, nvertex, vertex, ignoreExtent, nindices, indices); break; case 3: // RGL_TRIANGLES: node = new TriangleSet( currentMaterial, nvertex, vertex, normals, texcoords, ignoreExtent, nindices, indices, useNormals, useTexcoords); break; case 4: // RGL_QUADS: node = new QuadSet( currentMaterial, nvertex, vertex, normals, texcoords, ignoreExtent, nindices, indices, useNormals, useTexcoords); break; case 5: // RGL_LINE_STRIP: node = new LineStripSet( currentMaterial, nvertex, vertex, ignoreExtent, nindices, indices); break; default: node = NULL; } if (node) { success = as_success( device->add( node ) ); if (!success) delete node; } CHECKGLERROR; } *successptr = success; } void rgl::rgl_surface(int* successptr, int* idata, double* x, double* z, double* y, double* normal_x, double* normal_z, double* normal_y, double* texture_s, double* texture_t, int* coords, int* orientation, int* flags) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { int nx = idata[0]; int nz = idata[1]; success = as_success( device->add( new Surface(currentMaterial, nx, nz, x, z, y, normal_x, normal_z, normal_y, texture_s, texture_t, coords, *orientation, flags, device->getIgnoreExtent() || currentMaterial.marginCoord >= 0) ) ); CHECKGLERROR; } *successptr = success; } void rgl::rgl_spheres(int* successptr, int* idata, double* vertex, double* radius, int* fastTransparency) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { int nvertex = idata[0]; int nradius = idata[1]; success = as_success( device->add( new SphereSet(currentMaterial, nvertex, vertex, nradius, radius, device->getIgnoreExtent() || currentMaterial.marginCoord >= 0, *fastTransparency != 0) ) ); CHECKGLERROR; } *successptr = success; } void rgl::rgl_planes(int* successptr, int* idata, double* normals, double* offsets) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { int nnormal = idata[0]; int noffset = idata[1]; success = as_success( device->add( new PlaneSet(currentMaterial, nnormal, normals, noffset, offsets) ) ); CHECKGLERROR; } *successptr = success; } void rgl::rgl_clipplanes(int* successptr, int* idata, double* normals, double* offsets) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { int nnormal = idata[0]; int noffset = idata[1]; success = as_success( device->add( new ClipPlaneSet(currentMaterial, nnormal, normals, noffset, offsets) ) ); CHECKGLERROR; } *successptr = success; } void rgl::rgl_abclines(int* successptr, int* idata, double* bases, double* directions) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { int nbases = idata[0]; int ndirs = idata[1]; success = as_success( device->add( new ABCLineSet(currentMaterial, nbases, bases, ndirs, directions) ) ); CHECKGLERROR; } *successptr = success; } void rgl::rgl_sprites(int* successptr, int* idata, double* vertex, double* radius, int* shapes, double* userMatrix, double* adj, int* pos, double* offset) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { int nvertex = idata[0]; int nradius = idata[1]; int nshapes = idata[2]; bool fixedSize = (bool)idata[3]; int npos = idata[4]; int count = 0; Shape** shapelist; Scene* scene = NULL; if (nshapes) { shapelist = (Shape**) R_alloc(nshapes, sizeof(Shape*)); RGLView* rglview = device->getRGLView(); scene = rglview->getScene(); while (nshapes) { int id = *(shapes++); nshapes--; Shape* shape = scene->get_shape(id); if (shape) { scene->hide(id); shapelist[count++] = shape; } } if (!count) { *successptr = RGL_FAIL; return; } } else shapelist = NULL; success = as_success( device->add( new SpriteSet(currentMaterial, nvertex, vertex, nradius, radius, device->getIgnoreExtent() || currentMaterial.marginCoord >= 0, count, shapelist, userMatrix, fixedSize, scene, adj, npos, pos, *offset) ) ); CHECKGLERROR; } *successptr = success; } void rgl::rgl_newsubscene(int* successptr, int* parentid, int* embedding, int* ignoreExtent) { int success = RGL_FAIL; Device* device; // Rprintf("rgl_newsubscene with %d %d %d %d\n", // embedding[0], embedding[1], embedding[2], embedding[3]); if (deviceManager && (device = deviceManager->getAnyDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); // Rprintf("getting parent %d\n", parentid[0]); Subscene* parent = scene->getSubscene(parentid[0]); if (parent) { Subscene* current = scene->getCurrentSubscene(); scene->setCurrentSubscene(parent); // Rprintf("Creating subscene\n"); Subscene* subscene = new Subscene( (Embedding)embedding[0], (Embedding)embedding[1], (Embedding)embedding[2], EMBED_REPLACE, *ignoreExtent != 0); if (subscene && scene->add(subscene)) { for (int i=0; i<5; i++) subscene->setMouseMode(i, parent->getMouseMode(i)); if (embedding[3] != EMBED_REPLACE) subscene->setEmbedding(3, (Embedding)embedding[3]); success = as_success( subscene->getObjID() ); } scene->setCurrentSubscene(current); } } *successptr = success; } void rgl::rgl_setsubscene(int* id) { Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); Subscene* subscene = scene->getSubscene(*id); if (subscene) { *id = scene->setCurrentSubscene(subscene)->getObjID(); } else *id = 0; } else *id = 0; } void rgl::rgl_getsubsceneid(int* id, int* dev) { Device* device; if (deviceManager && (device = deviceManager->getDevice(*dev))) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); const Subscene* subscene = (*id) == 1 ? scene->getCurrentSubscene() : scene->getRootSubscene(); *id = subscene->getObjID(); } else *id = 0; } void rgl::rgl_getsubsceneparent(int* id) { Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); Subscene* subscene = scene->getSubscene(*id); if (!subscene) { *id = NA_INTEGER; } else { subscene = subscene->getParent(); *id = subscene ? subscene->getObjID() : 0; } } else *id = NA_INTEGER; } void rgl::rgl_getsubscenechildcount(int* id, int* n) { Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); Subscene* subscene = scene->getSubscene(*id); *n = subscene ? static_cast(subscene->getChildCount()) : 0; } else *n = 0; } void rgl::rgl_getsubscenechildren(int* id, int* children) { Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); const Subscene* subscene = scene->getSubscene(*id); if (subscene) { for (size_t i = 0; i < subscene->getChildCount(); i++) { Subscene* child = subscene->getChild(i); children[i] = child ? child->getObjID() : 0; } } } } void rgl::rgl_addtosubscene(int* successptr, int* count, int* ids) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); Subscene* subscene = scene->getSubscene(*successptr); if (subscene) { for (int i=0; i < count[0]; i++) { SceneNode* node = scene->get_scenenode(ids[i]); if (node) { subscene->add(node); success = RGL_SUCCESS; } else warning("id %d not found in scene", ids[i]); } rglview->update(); } } *successptr = success; } void rgl::rgl_delfromsubscene(int* successptr, int* count, int* ids) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); Subscene* subscene = scene->getSubscene(*successptr); if (subscene) { for (int i=0; i < count[0]; i++) { SceneNode* node = scene->get_scenenode(ids[i]); if (node) switch (node->getTypeID()) { case SHAPE: subscene->hideShape( ids[i] ); success++; break; case LIGHT: subscene->hideLight( ids[i] ); success++; break; case BBOXDECO: subscene->hideBBoxDeco( ids[i] ); success++; break; case SUBSCENE: scene->setCurrentSubscene( subscene->hideSubscene( ids[i], scene->getCurrentSubscene() ) ); success++; break; case BACKGROUND: subscene->hideBackground( ids[i] ); success++; break; case USERVIEWPOINT: case MODELVIEWPOINT: subscene->hideViewpoint( ids[i] ); success++; break; default: char buffer[20]; buffer[19] = 0; node->getTypeName(buffer, 20); warning("id %d is type %s; cannot hide", ids[i], buffer); } else warning("id %d not found in scene", ids[i]); } rglview->update(); } } *successptr = success; } void rgl::rgl_gc(int* count, int* protect) { Device* device; int nprotect = *count; *count = 0; if (deviceManager && (device = deviceManager->getAnyDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); if (scene) { Subscene* root = (Subscene *)scene->getRootSubscene(); // need to discard const int rootid = root->getObjID(); for (TypeID i = 1; i < MAX_TYPE; i++) { int n = scene->get_id_count(i); if (n) { std::vector ids(n); std::vector types(n); scene->get_ids(i, &ids[0], &types[0]); // First, remove the protected ones by setting them to zero. bool anyunprot = false; for (int j = 0; j < n; j++) { bool prot = (rootid == ids[j]); for (int k = 0; k < nprotect && !prot; k++) prot = (ids[j] == protect[k]); if (prot) ids[j] = 0; else anyunprot = true; } if (!anyunprot) continue; // Now look for the others in subscenes int m = root->get_id_count(i, true); if (m) { std::vector ids2(m); std::vector types2(m); root->get_ids(i, &ids2[0], &types2[0], true); for (int j = 0; j < n; j++) { for (int k = 0; k < m && ids[j] != 0; k++) { if (ids[j] == ids2[k]) ids[j] = 0; } } } for (int j = 0; j < n; j++) { if (ids[j] != 0) { scene->pop(i, ids[j]); (*count)++; } } } } } } } void rgl::rgl_material(int *successptr, int* idata, char** cdata, double* ddata) { Material& mat = currentMaterial; int ncolor = idata[0]; mat.lit = (idata[1]) ? true : false; mat.smooth = (idata[2]) ? true : false; mat.front = (Material::PolygonMode) idata[3]; mat.back = (Material::PolygonMode) idata[4]; mat.fog = (idata[5]) ? true : false; mat.textype = (Texture::Type) idata[6]; mat.mipmap = (idata[7]) ? true : false; mat.minfilter = idata[8]; mat.magfilter = idata[9]; int nalpha = idata[10]; mat.ambient.set3iv( &idata[11] ); mat.specular.set3iv( &idata[14] ); mat.emission.set3iv( &idata[17] ); mat.envmap = (idata[20]) ? true : false; mat.point_antialias = (idata[21]) ? true : false; mat.line_antialias = (idata[22]) ? true : false; mat.depth_mask = (idata[23]) ? true : false; mat.depth_test = idata[24]; mat.marginCoord = idata[25]; mat.edge[0] = idata[26]; mat.edge[1] = idata[27]; mat.edge[2] = idata[28]; mat.floating = idata[29]; int* colors = &idata[30]; char* pixmapfn = cdata[1]; mat.shininess = (float) ddata[0]; mat.size = (float) ddata[1]; mat.lwd = (float) ddata[2]; mat.polygon_offset_factor = (float) ddata[3]; mat.polygon_offset_units = (float) ddata[4]; mat.polygon_offset = ddata[3] != 0.0 || ddata[4] != 0.0; double* alpha = &ddata[5]; mat.alphablend = false; size_t len_tag = strlen(cdata[0]); if (len_tag) { char* in_tag = new char [len_tag + 1]; strncpy(in_tag, cdata[0], len_tag); in_tag[len_tag] = '\0'; mat.tag = string(in_tag); } else mat.tag = string(); if ( strlen(pixmapfn) > 0 ) { mat.texture = new Texture(pixmapfn, mat.textype, mat.mipmap, mat.minfilter, mat.magfilter, mat.envmap); if ( !mat.texture->isValid() ) { mat.texture->unref(); // delete mat.texture; mat.texture = NULL; } else mat.alphablend = mat.alphablend || mat.texture->hasAlpha(); } else mat.texture = NULL; mat.colors.set( ncolor, colors, nalpha, alpha); mat.alphablend = mat.alphablend || mat.colors.hasAlpha(); CHECKGLERROR; *successptr = RGL_SUCCESS; } void rgl::rgl_getcolorcount(int* count) { *count = currentMaterial.colors.getLength(); CHECKGLERROR; } void rgl::rgl_getmaterial(int *successptr, int *id, int* idata, char** cdata, double* ddata) { Material* mat = ¤tMaterial; unsigned int i,j; if (*id > 0) { Device* device; *successptr = RGL_FAIL; if (deviceManager && (device = deviceManager->getCurrentDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); Shape* shape = scene->get_shape(*id); if (shape) mat = shape->getMaterial(); /* success! successptr will be set below */ else { BBoxDeco* bboxdeco = scene->get_bboxdeco(*id); if (bboxdeco) mat = bboxdeco->getMaterial(); else { Background* background = scene->get_background(*id); if (background) mat = background->getMaterial(); else return; } } } else return; } idata[1] = mat->lit ? 1 : 0; idata[2] = mat->smooth ? 1 : 0; idata[3] = (int) mat->front; idata[4] = (int) mat->back; idata[5] = mat->fog ? 1 : 0; if (mat->texture) { mat->texture->getParameters( (Texture::Type*) (idata + 6), (bool*) (idata + 7), (unsigned int*) (idata + 8), (unsigned int*) (idata + 9), (bool*) (idata + 20), static_cast(strlen(cdata[1])), cdata[1] ); } else { idata[6] = (int)mat->textype; idata[7] = mat->mipmap ? 1 : 0; idata[8] = mat->minfilter; idata[9] = mat->magfilter; idata[20] = mat->envmap ? 1 : 0; cdata[0][0] = '\0'; cdata[1][0] = '\0'; } idata[11] = (int) mat->ambient.getRedub(); idata[12] = (int) mat->ambient.getGreenub(); idata[13] = (int) mat->ambient.getBlueub(); idata[14] = (int) mat->specular.getRedub(); idata[15] = (int) mat->specular.getGreenub(); idata[16] = (int) mat->specular.getBlueub(); idata[17] = (int) mat->emission.getRedub(); idata[18] = (int) mat->emission.getGreenub(); idata[19] = (int) mat->emission.getBlueub(); idata[21] = mat->point_antialias ? 1 : 0; idata[22] = mat->line_antialias ? 1 : 0; idata[23] = mat->depth_mask ? 1 : 0; idata[24] = mat->depth_test; idata[25] = mat->isTransparent(); idata[26] = mat->marginCoord; idata[27] = mat->edge[0]; idata[28] = mat->edge[1]; idata[29] = mat->edge[2]; idata[30] = mat->floating; for (i=0, j=31; (i < mat->colors.getLength()) && (i < (unsigned int)idata[0]); i++) { idata[j++] = (int) mat->colors.getColor(i).getRedub(); idata[j++] = (int) mat->colors.getColor(i).getGreenub(); idata[j++] = (int) mat->colors.getColor(i).getBlueub(); } idata[0] = i; ddata[0] = (double) mat->shininess; ddata[1] = (double) mat->size; ddata[2] = (double) mat->lwd; ddata[3] = (double) mat->polygon_offset_factor; ddata[4] = (double) mat->polygon_offset_units; if (mat->colors.hasAlpha()) { for (i=0, j=5; (i < mat->colors.getLength()) && (i < (unsigned int)idata[10]); i++) ddata[j++] = (double) mat->colors.getColor(i).getAlphaf(); idata[10] = i; } else idata[10] = 0; /* Can't use tag.length() here, because R has highjacked length() */ size_t len_tag = strlen(mat->tag.c_str()); cdata[0] = R_alloc(len_tag + 1, 1); strncpy(cdata[0], mat->tag.c_str(), len_tag); (cdata[0])[len_tag] = '\0'; CHECKGLERROR; *successptr = RGL_SUCCESS; } void rgl::rgl_texts(int* successptr, int* idata, double* adj, char** text, double* vertex, int* nfonts, char** family, int* style, double* cex, int* useFreeType, int* npos, int* pos) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { int ntext = idata[0]; FontArray fonts; device->getFonts(fonts, *nfonts, family, style, cex, (bool) *useFreeType); success = as_success( device->add( new TextSet(currentMaterial, ntext, text, vertex, adj[0], adj[1], adj[2], device->getIgnoreExtent() || currentMaterial.marginCoord >= 0, fonts, *npos, pos) ) ); CHECKGLERROR; } *successptr = success; } void rgl::rgl_bbox(int* successptr, int* idata, double* ddata, double* xat, char** xtext, double* yat, char** ytext, double* zat, char** ztext) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { int xticks = idata[0]; /* these are length of xat etc. */ int yticks = idata[1]; int zticks = idata[2]; int xlen = idata[3]; /* these are suggested tick counts */ int ylen = idata[4]; int zlen = idata[5]; int marklen_rel = idata[6]; int front = idata[7]; float xunit = (float) ddata[0]; float yunit = (float) ddata[1]; float zunit = (float) ddata[2]; float marklen = (float) ddata[3]; float expand = (float) ddata[4]; AxisInfo xaxis(xticks, xat, xtext, xlen, xunit); AxisInfo yaxis(yticks, yat, ytext, ylen, yunit); AxisInfo zaxis(zticks, zat, ztext, zlen, zunit); success = as_success( device->add( new BBoxDeco(currentMaterial, xaxis, yaxis, zaxis, marklen, (bool) marklen_rel, expand, (bool)front ) ) ); CHECKGLERROR; } *successptr = success; } void rgl::rgl_snapshot(int* successptr, int* idata, char** cdata) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getCurrentDevice())) { int format = idata[0]; char* filename = cdata[0]; success = as_success( device->snapshot( format, filename ) ); CHECKGLERROR; } *successptr = success; } void rgl::rgl_pixels(int* successptr, int* ll, int* size, int* component, double* result) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getCurrentDevice())) { success = as_success( device->pixels( ll, size, *component, result) ); CHECKGLERROR; } *successptr = success; } void rgl::rgl_selectstate(int* dev, int* sub, int* successptr, int* selectstate, double* locations) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getDevice(*dev))) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); Subscene* subscene = scene->getSubscene(*sub); selectstate[0] = (int)subscene->getSelectState(); double* mousePosition = subscene->getMousePosition(); locations[0] = *mousePosition; locations[1] = *(mousePosition+1); locations[2] = *(mousePosition+2); locations[3] = *(mousePosition+3); success = RGL_SUCCESS; CHECKGLERROR; } *successptr = success; } void rgl::rgl_setselectstate(int* dev, int* sub, int* successptr, int *idata) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getDevice(*dev))) { MouseSelectionID selectState = (MouseSelectionID) idata[0]; RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); Subscene* subscene = scene->getSubscene(*sub); subscene->setSelectState(selectState); success = RGL_SUCCESS; CHECKGLERROR; } *successptr = success; } void rgl::rgl_getEmbeddings(int* id, int* embeddings) { Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); Subscene* subscene = scene->getSubscene(*id); if (subscene) { embeddings[0] = subscene->getEmbedding(EM_VIEWPORT); embeddings[1] = subscene->getEmbedding(EM_PROJECTION); embeddings[2] = subscene->getEmbedding(EM_MODEL); embeddings[3] = subscene->getEmbedding(EM_MOUSEHANDLERS); } } } void rgl::rgl_setEmbeddings(int* id, int* embeddings) { Device* device; if (deviceManager && (device = deviceManager->getAnyDevice())) { RGLView* rglview = device->getRGLView(); Scene* scene = rglview->getScene(); Subscene* subscene = scene->getSubscene(*id); *id = RGL_FAIL; if (subscene) { if (!subscene->getParent() && // can't change the root (embeddings[0] != EMBED_REPLACE || embeddings[1] != EMBED_REPLACE || embeddings[2] != EMBED_REPLACE || embeddings[3] != EMBED_REPLACE)) return; subscene->setEmbedding(0, (Embedding)embeddings[0]); subscene->setEmbedding(1, (Embedding)embeddings[1]); subscene->setEmbedding(2, (Embedding)embeddings[2]); subscene->setEmbedding(3, (Embedding)embeddings[3]); rglview->update(); *id = RGL_SUCCESS; } } } void rgl::rgl_postscript(int* successptr, int* idata, char** cdata) { int success = RGL_FAIL; Device* device; if (deviceManager && (device = deviceManager->getCurrentDevice())) { int format = idata[0]; bool drawText = (bool)idata[1]; char* filename = cdata[0]; success = as_success( device->postscript( format, filename, drawText ) ); CHECKGLERROR; } *successptr = success; } rgl/src/x11lib.cpp0000644000176200001440000000504314100762641013434 0ustar liggesusers#include "config.h" #ifdef RGL_X11 // C++ source // This file is part of RGL. // #include "R.h" #include "lib.h" #include "NULLgui.h" // // ===[ GUI IMPLEMENTATION ]================================================= // #include "x11gui.h" using namespace rgl; namespace rgl { X11GUIFactory* gpX11GUIFactory = NULL; NULLGUIFactory* gpNULLGUIFactory = NULL; } GUIFactory* rgl::getGUIFactory(bool useNULLDevice) { if (useNULLDevice) return (GUIFactory*) gpNULLGUIFactory; else if (gpX11GUIFactory) return (GUIFactory*) gpX11GUIFactory; else error("glX device not initialized"); } // --------------------------------------------------------------------------- const char * rgl::GUIFactoryName(bool useNULLDevice) { return useNULLDevice ? "null" : "glX"; } // // ===[ R INTEGRATION ]======================================================= // #include "R.h" #include static InputHandler* R_handler = NULL; static void R_rgl_eventHandler(void * userData) { gpX11GUIFactory->processEvents(); } static void set_R_handler() { // add R input handler (R_ext/eventloop.h) // approach taken from GtkDevice ... good work guys! R_handler = ::addInputHandler(R_InputHandlers, gpX11GUIFactory->getFD(), R_rgl_eventHandler, XActivity); // seek end of node while(R_handler->next) R_handler = R_handler->next; } static void unset_R_handler() { if (R_handler) { ::removeInputHandler(&R_InputHandlers, R_handler); R_handler = NULL; } } // // ===[ LIB INIT / QUIT ]===================================================== // bool rgl::init(bool useNULLDevice) { bool success = false; // construct GUI Factory gpNULLGUIFactory = new NULLGUIFactory(); if (useNULLDevice) { success = true; } else { gpX11GUIFactory = new X11GUIFactory(NULL); if ( gpX11GUIFactory->isConnected() ) { set_R_handler(); success = true; } } return success; } void rgl::quit() { unset_R_handler(); delete gpX11GUIFactory; delete gpNULLGUIFactory; gpX11GUIFactory = 0; gpNULLGUIFactory = 0; } // // ===[ LIB SERVICES ]======================================================= // // // printMessage // void rgl::printMessage( const char* string ) { warning("RGL: %s\n", string); } // // getTime // #include #include double rgl::getTime() { struct ::timeval t; gettimeofday(&t,NULL); return ( (double) t.tv_sec ) * 1000.0 + ( ( (double) t.tv_usec ) / 1000.0 ); } // --------------------------------------------------------------------------- #endif // RGL_X11 rgl/src/rgl-win.def0000644000176200001440000000004414100762641013663 0ustar liggesusersLIBRARY rgl.dll EXPORTS R_init_rglrgl/src/Material.cpp0000644000176200001440000001102114145464133014067 0ustar liggesusers#include "gl2ps.h" #include "Material.h" #include "opengl.h" #include "Texture.h" #include "R.h" using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // Material // Material::Material(Color bg, Color fg) : ambient(0.0f,0.0f,0.0f,1.0f), specular(1.0f,1.0f,1.0f,1.0f), emission(0.0f,0.0f,0.0f,0.0f), shininess(50.0f), size(3.0f), lwd(1.0f), polygon_offset_factor(0.0f), polygon_offset_units(0.0f), colors(bg,fg), texture(), front(FILL_FACE), back(FILL_FACE), smooth(true), lit(true), fog(true), useColorArray(false), point_antialias(false), line_antialias(false), depth_mask(true), depth_test(1), // "less" textype(Texture::RGB), mipmap(false), minfilter(1), magfilter(1), envmap(false), marginCoord(-1), floating(false), tag(), glVersion(-1.0) { alphablend = ( ( bg.getAlphaf() < 1.0f ) || ( fg.getAlphaf() < 1.0f ) ) ? true : false; edge[0] = -2; edge[1] = -2; edge[2] = -2; } void Material::setup() { #ifndef RGL_NO_OPENGL const char* version = (const char*)glGetString(GL_VERSION); if (version) glVersion = atof(version); else #endif glVersion = 1.0; } void Material::beginUse(RenderContext* renderContext) { #ifndef RGL_NO_OPENGL int ncolor = colors.getLength(); GLenum depthfunc[] = { GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, GL_ALWAYS }; SAVEGLERROR; glDepthFunc(depthfunc[depth_test]); glDepthMask(depth_mask ? GL_TRUE : GL_FALSE); SAVEGLERROR; glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT ); SAVEGLERROR; if (!alphablend) glDepthMask(GL_TRUE); SAVEGLERROR; if (point_antialias) glEnable(GL_POINT_SMOOTH); if (line_antialias) glEnable(GL_LINE_SMOOTH); SAVEGLERROR; glDisable(GL_CULL_FACE); for (int i=0;i<2;i++) { PolygonMode mode = (i==0) ? front : back; GLenum face = (i==0) ? GL_FRONT : GL_BACK; SAVEGLERROR; switch (mode) { case FILL_FACE: glPolygonMode( face, GL_FILL); break; case LINE_FACE: glPolygonMode( face, GL_LINE); break; case POINT_FACE: glPolygonMode( face, GL_POINT); break; case CULL_FACE: glEnable(GL_CULL_FACE); glCullFace(face); break; } } SAVEGLERROR; glShadeModel( (smooth) ? GL_SMOOTH : GL_FLAT ); SAVEGLERROR; if (lit) { glEnable(GL_LIGHTING); SAVEGLERROR; #ifdef GL_VERSION_1_2 if (glVersion < 0.0) setup(); if (glVersion >= 1.2) glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, (texture) ? GL_SEPARATE_SPECULAR_COLOR : GL_SINGLE_COLOR ); #endif SAVEGLERROR; glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT, ambient.data); glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR, specular.data); glMaterialf (GL_FRONT_AND_BACK,GL_SHININESS, shininess); glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION, emission.data); } SAVEGLERROR; if ( (useColorArray) && ( ncolor > 1 ) ) { glEnableClientState(GL_COLOR_ARRAY); colors.useArray(); } else colors.useColor(0); SAVEGLERROR; if (renderContext->gl2psActive == GL2PS_NONE) { glPointSize( size ); glLineWidth( lwd ); } else { gl2psPointSize( size ); gl2psLineWidth( lwd ); } if (polygon_offset) { glPolygonOffset(polygon_offset_factor, polygon_offset_units); glEnable(GL_POLYGON_OFFSET_FILL); } if (texture) texture->beginUse(renderContext); SAVEGLERROR; if (!fog) glDisable(GL_FOG); SAVEGLERROR; #endif } void Material::useColor(int index) { if (colors.getLength() > 0) colors.useColor( index % colors.getLength() ); } void Material::endUse(RenderContext* renderContext) { #ifndef RGL_NO_OPENGL int ncolor = colors.getLength(); if ( (useColorArray) && ( ncolor > 1 ) ) { glDisableClientState(GL_COLOR_ARRAY); SAVEGLERROR; } if (texture) { texture->endUse(renderContext); SAVEGLERROR; } #if USE_GLGETERROR saveGLerror(__FILE__, __LINE__); #endif glPopAttrib(); #if USE_GLGETERROR if (SaveErrnum == GL_NO_ERROR) glGetError(); /* work around bug in some glX implementations */ #endif SAVEGLERROR; glDepthFunc(GL_LESS); glDepthMask(GL_TRUE); if (polygon_offset) glDisable(GL_POLYGON_OFFSET_FILL); #endif } void Material::colorPerVertex(bool enable, int numVertices) { useColorArray = enable; if (enable) colors.recycle(numVertices); } rgl/src/Makevars.in0000644000176200001440000000221314100762641013725 0ustar liggesusers# # R Makevars file auto-generated using template Makevars.in # AUTO-GENERATED from Makevars.in (using configure or configure.win) # This file is part of the RGL project. # # Makevars will be called in two different circumstances: # # When HIDE_IF_NO_OPENGL="": # # Trying to make $(SHLIB)=rgl.so with full OpenGL support, then # making it again by building it in useNULL, # using the Makevars file there. # # When HIDE_IF_NO_OPENGL="#": # # Trying to make $(SHLIB)=rgl.so with no OpenGL. CXX_STD = CXX11 PKG_CFLAGS=$(C_VISIBILITY) PKG_CPPFLAGS=@NULL_CPPFLAGS@ PKG_LIBS=@NULL_LIBS@ # These lines are only used if configure found OpenGL support @HIDE_IF_NO_OPENGL@ PKG_CPPFLAGS=@CPPFLAGS@ -Iext @HIDE_IF_NO_OPENGL@ PKG_LIBS=@LIBS@ all: $(SHLIB) @HIDE_IF_NO_OPENGL@ ../inst/useNULL$(R_ARCH)/$(SHLIB) ../inst/useNULL$(R_ARCH)/$(SHLIB): $(SHLIB) cp -Rp OpenGL useNULL && \ cp -p *.c *.h *.cpp useNULL/ && \ cd useNULL && \ $(R_HOME)/bin/R CMD SHLIB -o useNULL.so *.cpp *.c && \ cd .. && \ mkdir -p ../inst/useNULL$(R_ARCH) && \ mv useNULL/useNULL.so ../inst/useNULL$(R_ARCH)/$(SHLIB) && \ rm useNULL/*.cpp useNULL/*.c useNULL/*.h useNULL/OpenGL/* rgl/src/Surface.h0000644000176200001440000000307114100762641013370 0ustar liggesusers#ifndef SURFACE_H #define SURFACE_H #include "Shape.h" #include "render.h" #include namespace rgl { // // CLASS // Surface // class Surface : public Shape { public: Surface(Material& material, int nx, int nz, double* x, double* z, double* y, double* normal_x, double* normal_z, double* normal_y, double* texture_s, double* texture_t, int* coords, int orientation, int* flags, int ignoreExtent); /** * overload **/ virtual void draw(RenderContext* renderContext); /* Center of square with upper left at (ix, iz) */ Vertex getCenter(int ix, int iz); virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "surface", buflen); }; int getAttributeCount(AABox& bbox, AttribID attrib); void getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result); virtual int getElementCount(void) { return (nx-1)*(nz-1); } /** * location of individual items **/ virtual Vertex getPrimitiveCenter(int item) ; /** * begin sending items **/ virtual void drawBegin(RenderContext* renderContext) ; /** * send one item **/ virtual void drawPrimitive(RenderContext* renderContext, int index) ; /** * end sending items **/ virtual void drawEnd(RenderContext* renderContext) ; private: Vertex getNormal(int ix, int iz); VertexArray vertexArray; NormalArray normalArray; TexCoordArray texCoordArray; int nx, nz, coords[3], orientation, user_normals, user_textures; bool use_normal, use_texcoord; }; } // namespace rgl #endif // SURFACE_H rgl/src/SphereSet.h0000644000176200001440000000276014100762641013706 0ustar liggesusers#ifndef SPHERESET_H #define SPHERESET_H #include "scene.h" #include "Shape.h" #include "SphereMesh.h" namespace rgl { class SphereSet : public Shape { private: ARRAY center; ARRAY radius; SphereMesh sphereMesh; int facets, lastdrawn; bool lastendcap; bool fastTransparency; public: SphereSet(Material& in_material, int nsphere, double* center, int nradius, double* radius, int in_ignoreExtent, bool in_fastTransparency); ~SphereSet(); /** * overload **/ /* Check whether scale has changed before rendering */ void render(RenderContext* renderContext); int getElementCount(void){ return center.size(); } int getPrimitiveCount(void); int getAttributeCount(AABox& bbox, AttribID attrib); void getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result); /** * location of individual items **/ Vertex getPrimitiveCenter(int index); /** * Spheres appear as spheres, so their bbox depends on scaling **/ virtual AABox& getBoundingBox(Subscene* subscene); /** * begin sending items **/ void drawBegin(RenderContext* renderContext); /** * send one item **/ void drawPrimitive(RenderContext* renderContext, int index); /** * end sending items **/ void drawEnd(RenderContext* renderContext); virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "spheres", buflen); }; }; } // namespace rgl #endif // SPHERESET_H rgl/src/BBoxDeco.cpp0000644000176200001440000006371714142256754014006 0ustar liggesusers#include "BBoxDeco.h" #ifndef RGL_NO_OPENGL #include "gl2ps.h" #endif #include "glgui.h" #include "scene.h" #include #include #include "R.h" #include "pretty.h" #if 0 // This is debugging code to track down font problems. #include "R.h" static GLenum flags[] = { GL_ALPHA_TEST , GL_AUTO_NORMAL , GL_MAP2_VERTEX_4, GL_BLEND, GL_CLIP_PLANE0, GL_CLIP_PLANE1, GL_CLIP_PLANE2, GL_COLOR_LOGIC_OP, GL_COLOR_MATERIAL, GL_COLOR_TABLE, GL_CONVOLUTION_1D, GL_CONVOLUTION_2D, GL_CULL_FACE, GL_DEPTH_TEST, GL_DITHER, GL_FOG, GL_HISTOGRAM, GL_INDEX_LOGIC_OP, GL_LIGHT0, GL_LIGHT1, GL_LIGHT2, GL_LIGHTING, GL_LINE_SMOOTH, GL_LINE_STIPPLE, GL_MAP1_COLOR_4, GL_MAP1_INDEX, GL_MAP1_NORMAL, GL_MAP1_TEXTURE_COORD_1, GL_MAP1_TEXTURE_COORD_2, GL_MAP1_TEXTURE_COORD_3, GL_MAP1_TEXTURE_COORD_4, GL_MAP1_VERTEX_3, GL_MAP1_VERTEX_4, GL_MAP2_COLOR_4, GL_MAP2_INDEX, GL_MAP2_NORMAL, GL_MAP2_TEXTURE_COORD_1, GL_MAP2_TEXTURE_COORD_2, GL_MAP2_TEXTURE_COORD_3, GL_MAP2_TEXTURE_COORD_4, GL_MAP2_VERTEX_3, GL_MAP2_VERTEX_4, GL_MINMAX, GL_NORMALIZE, GL_POINT_SMOOTH, GL_POLYGON_OFFSET_FILL, GL_POLYGON_OFFSET_LINE, GL_POLYGON_OFFSET_POINT, GL_POINT, GL_POLYGON_SMOOTH, GL_POLYGON_STIPPLE, GL_POST_COLOR_MATRIX_COLOR_TABLE, GL_POST_CONVOLUTION_COLOR_TABLE, GL_RESCALE_NORMAL, GL_SEPARABLE_2D, GL_SCISSOR_TEST, GL_STENCIL_TEST, GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_GEN_Q, GL_TEXTURE_GEN_R, GL_TEXTURE_GEN_S, GL_TEXTURE_GEN_T}; void Rpf(const char * msg) { int flag1=0, flag2 = 0; for (int i=0; i< 32; i++) { GLboolean f; glGetBooleanv( flags[i], &f); if (f) flag1 += (1 << i); glGetBooleanv( flags[i+32], &f); if (f) flag2 += (1 << i); } Rprintf("%s: Flags 0 to 31: %x 32 to 63: %x\n", msg, flag1, flag2); GLint modes[2]; glGetIntegerv( GL_POLYGON_MODE, modes); Rprintf(" Polygon modes: %X %X\n", modes[0], modes[1]); } #endif using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // BBoxDeco // AxisInfo::AxisInfo() : textArray() { mode = AXIS_LENGTH; nticks = 0; ticks = NULL; len = 2; unit = 0; } AxisInfo::AxisInfo(int in_nticks, double* in_ticks, char** in_texts, int in_len, float in_unit) : textArray(in_nticks, in_texts) { int i; nticks = in_nticks; len = in_len; unit = in_unit; ticks = NULL; if (nticks > 0) { mode = AXIS_CUSTOM; ticks = new float [nticks]; for(i=0;i 0) mode = AXIS_UNIT; else if (unit < 0 && len > 0) mode = AXIS_PRETTY; else if (len > 0) mode = AXIS_LENGTH; else mode = AXIS_NONE; } } AxisInfo::AxisInfo(AxisInfo& from) : textArray(from.textArray) { mode = from.mode; nticks = from.nticks; len = from.len; unit = from.unit; if (nticks > 0) { ticks = new float [nticks]; memcpy (ticks, from.ticks, sizeof(float)*nticks); } else ticks = NULL; } AxisInfo::~AxisInfo() { if (ticks) { delete [] ticks; } } void AxisInfo::draw(RenderContext* renderContext, Vertex4& v, Vertex4& dir, Matrix4x4& modelview, Vertex& marklen, String& string) { #ifndef RGL_NO_OPENGL Vertex4 p; GLboolean valid; // draw mark ( 1 time ml away ) p.x = v.x + dir.x * marklen.x; p.y = v.y + dir.y * marklen.y; p.z = v.z + dir.z * marklen.z; glBegin(GL_LINES); glVertex3f(v.x,v.y,v.z); glVertex3f(p.x,p.y,p.z); glEnd(); // draw text ( 2 times ml away ) p.x = v.x + 2 * dir.x * marklen.x; p.y = v.y + 2 * dir.y * marklen.y; p.z = v.z + 2 * dir.z * marklen.z; glRasterPos3f( p.x, p.y, p.z ); glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid); if (valid) { // Work out the text adjustment float adj = 0.5; Vertex4 eyedir = modelview * dir; bool xlarge = fabs(eyedir.x) > fabs(eyedir.y); if (xlarge) { adj = fabs(eyedir.y)/fabs(eyedir.x)/2.0f; if (eyedir.x < 0) adj = 1.0f - adj; } if (renderContext->font) renderContext->font->draw(string.text, string.length, adj, 0.5, 0.5, 0, *renderContext); } #endif } int AxisInfo::getNticks(float low, float high) { switch (mode) { case AXIS_CUSTOM: return nticks; case AXIS_LENGTH: return len; case AXIS_UNIT: return static_cast((high - low)/unit); case AXIS_PRETTY: { double lo=low, up=high, shrink_sml=0.75, high_u_fact[2]; int ndiv=len, min_n=3, eps_correction=0; int count=0; high_u_fact[0] = 1.5; high_u_fact[1] = 2.75; unit = static_cast(R_pretty0(&lo, &up, &ndiv, min_n, shrink_sml, high_u_fact, eps_correction, 0)); for (int i=(int)lo; i<=up; i++) { float value = i*unit; if (value >= low && value <= high) count++; } return count; } } return 0; } double AxisInfo::getTick(float low, float high, int index) { switch (mode) { case AXIS_CUSTOM: return ticks[index]; case AXIS_LENGTH: { float delta = (len>1) ? (high-low)/(len-1) : 0; return low + delta*(float)index; } case AXIS_UNIT: { float value = ( (float) ( (int) ( ( low+(unit-1) ) / (unit) ) ) ) * (unit); return value + index*unit; } case AXIS_PRETTY: { double lo=low, up=high, shrink_sml=0.75, high_u_fact[2]; int ndiv=len, min_n=3, eps_correction=0; int count=0; high_u_fact[0] = 1.5; high_u_fact[1] = 2.75; unit = static_cast(R_pretty0(&lo, &up, &ndiv, min_n, shrink_sml, high_u_fact, eps_correction, 0)); for (int i=(int)lo; i<=up; i++) { float value = i*unit; if (value >= low && value <= high) { if (count == index) return value; count++; } } } } return NA_REAL; } struct Side { int vidx[4]; Vertex4 normal; Side( int i0, int i1, int i2, int i3, Vertex4 v ) : normal(v) { vidx[0] = i0; vidx[1] = i1; vidx[2] = i2; vidx[3] = i3; } }; static Side side[6] = { // BACK Side(0, 2, 3, 1, Vertex4( 0.0f, 0.0f,-1.0f, 0.0f) ), // FRONT Side(4, 5, 7, 6, Vertex4( 0.0f, 0.0f, 1.0f, 0.0f) ), // LEFT Side(4, 6, 2, 0, Vertex4(-1.0f, 0.0f, 0.0f, 0.0f) ), // RIGHT Side(5, 1, 3, 7, Vertex4( 1.0f, 0.0f, 0.0f, 0.0f) ), // BOTTOM Side(0, 1, 5, 4, Vertex4( 0.0f,-1.0f, 0.0f, 0.0f) ), // TOP Side(6, 7, 3, 2, Vertex4( 0.0f, 1.0f, 0.0f, 0.0f) ) }; struct Edge{ Edge(int in_from, int in_to, Vertex4 in_dir, Vertex3 in_code) : from(in_from), to(in_to), dir(in_dir), code(in_code) { } int from, to; Vertex4 dir; Vertex3 code; }; static Edge xaxisedge[4] = { Edge( 5,4, Vertex4( 0.0f, 0.0f, 1.0f, 0.0f), Vertex3( 0.0f, -1.0f, 1.0f) ), Edge( 0,1, Vertex4( 0.0f, 0.0f,-1.0f, 0.0f), Vertex3( 0.0f, -1.0f, -1.0f) ), Edge( 6,7, Vertex4( 0.0f, 0.0f, 1.0f, 0.0f), Vertex3( 0.0f, 1.0f, 1.0f) ), Edge( 3,2, Vertex4( 0.0f, 0.0f,-1.0f, 0.0f), Vertex3( 0.0f, 1.0f, -1.0f) ) }; static Edge yaxisedge[8] = { Edge( 5,7, Vertex4( 1.0f, 0.0f, 0.0f, 0.0f), Vertex3( 1.0f, 0.0f, 1.0f) ), Edge( 7,5, Vertex4( 0.0f, 0.0f, 1.0f, 0.0f), Vertex3( 1.0f, 0.0f, 1.0f) ), Edge( 6,4, Vertex4(-1.0f, 0.0f, 0.0f, 0.0f), Vertex3(-1.0f, 0.0f, 1.0f) ), Edge( 4,6, Vertex4( 0.0f, 0.0f, 1.0f, 0.0f), Vertex3(-1.0f, 0.0f, 1.0f) ), Edge( 2,0, Vertex4( 0.0f, 0.0f,-1.0f, 0.0f), Vertex3(-1.0f, 0.0f, -1.0f) ), Edge( 0,2, Vertex4(-1.0f, 0.0f, 0.0f, 0.0f), Vertex3(-1.0f, 0.0f, -1.0f) ), Edge( 3,1, Vertex4( 1.0f, 0.0f, 0.0f, 0.0f), Vertex3( 1.0f, 0.0f, -1.0f) ), Edge( 1,3, Vertex4( 0.0f, 0.0f,-1.0f, 0.0f), Vertex3( 1.0f, 0.0f, -1.0f) ) }; static Edge zaxisedge[4] = { Edge( 1,5, Vertex4( 1.0f, 0.0f, 0.0f, 0.0f), Vertex3( 1.0f,-1.0f, 0.0f) ), Edge( 4,0, Vertex4(-1.0f, 0.0f, 0.0f, 0.0f), Vertex3(-1.0f,-1.0f, 0.0f) ), Edge( 7,3, Vertex4( 1.0f, 0.0f, 0.0f, 0.0f), Vertex3( 1.0f, 1.0f, 0.0f) ), Edge( 2,6, Vertex4(-1.0f, 0.0f, 0.0f, 0.0f), Vertex3(-1.0f, 1.0f, 0.0f) ) }; AxisInfo BBoxDeco::defaultAxis(0,NULL,NULL,0,5); Material BBoxDeco::defaultMaterial( Color(0.6f,0.6f,0.6f,0.5f), Color(1.0f,1.0f,1.0f) ); BBoxDeco::BBoxDeco(Material& in_material, AxisInfo& in_xaxis, AxisInfo& in_yaxis, AxisInfo& in_zaxis, float in_marklen_value, bool in_marklen_fract, float in_expand, bool in_front) : SceneNode(BBOXDECO), material(in_material), xaxis(in_xaxis), yaxis(in_yaxis), zaxis(in_zaxis), marklen_value(in_marklen_value), marklen_fract(in_marklen_fract), expand(in_expand), draw_front(in_front) #ifndef RGL_NO_OPENGL , axisBusy(false) #endif { material.colors.recycle(2); } Vertex BBoxDeco::getMarkLength(const AABox& boundingBox) const { return (marklen_fract) ? (boundingBox.vmax - boundingBox.vmin) * (1 / marklen_value) : Vertex(1,1,1) * marklen_value; } AABox BBoxDeco::getBoundingBox(const AABox& in_bbox) const { AABox bbox2(in_bbox); Vertex marklen = getMarkLength(bbox2); Vertex v = marklen * 2; bbox2 += bbox2.vmin - v; bbox2 += bbox2.vmax + v; return bbox2; } struct BBoxDeco::BBoxDecoImpl { static Edge* chooseEdge(RenderContext* renderContext, BBoxDeco& bboxdeco, int coord) { AABox bbox = renderContext->subscene->getBoundingBox(); Vertex center = bbox.getCenter(); bbox += center + (bbox.vmin - center)*bboxdeco.expand; bbox += center + (bbox.vmax - center)*bboxdeco.expand; // edge adjacent matrix int adjacent[8][8] = { { 0 } }; int i,j; // vertex array: Vertex4 boxv[8] = { Vertex4( bbox.vmin.x, bbox.vmin.y, bbox.vmin.z ), Vertex4( bbox.vmax.x, bbox.vmin.y, bbox.vmin.z ), Vertex4( bbox.vmin.x, bbox.vmax.y, bbox.vmin.z ), Vertex4( bbox.vmax.x, bbox.vmax.y, bbox.vmin.z ), Vertex4( bbox.vmin.x, bbox.vmin.y, bbox.vmax.z ), Vertex4( bbox.vmax.x, bbox.vmin.y, bbox.vmax.z ), Vertex4( bbox.vmin.x, bbox.vmax.y, bbox.vmax.z ), Vertex4( bbox.vmax.x, bbox.vmax.y, bbox.vmax.z ) }; Vertex4 eyev[8]; // transform vertices: used for edge distance criterion and text justification Matrix4x4 modelview(renderContext->subscene->modelMatrix); for(i=0;i<8;i++) eyev[i] = modelview * boxv[i]; for(i=0;i<6;i++) { const Vertex4 q = modelview * side[i].normal; const Vertex4 view(0.0f,0.0f,1.0f,0.0f); float cos_a = view * q; const bool front = (cos_a >= 0.0f) ? true : false; if (bboxdeco.draw_front || !front) { for(j=0;j<4;j++) { if (!front) { // modify adjacent matrix int from = side[i].vidx[j]; int to = side[i].vidx[(j+1)%4]; adjacent[from][to] = 1; } } } } AxisInfo* axis; Edge* axisedge; int nedges; switch(coord) { case 0: axis = &(bboxdeco.xaxis); axisedge = xaxisedge; nedges = 4; break; case 1: axis = &(bboxdeco.yaxis); axisedge = yaxisedge; nedges = 8; break; case 2: default: axis = &(bboxdeco.zaxis); axisedge = zaxisedge; nedges = 4; break; } // search z-nearest contours float d = FLT_MAX; Edge* edge = NULL; for(j=0;jmarginCoord; bool match; switch(coord) { case 0: axisedge = xaxisedge; lim = 4; break; case 1: axisedge = yaxisedge; lim = 8; break; case 2: axisedge = zaxisedge; lim = 4; break; } for (j = 0; j < lim; j++) { match = true; for (i = 0; i < 3; i++) if (coord != i && axisedge[j].code[i] != material->edge[i]) { match = false; break; } if (match) return &axisedge[j]; } error("fixedEdge: material->floating=%d marginCoord=%d edge=%d %d %d\n", material->floating, material->marginCoord, material->edge[0], material->edge[1], material->edge[2]); return axisedge; } static void setMarginParameters(RenderContext* renderContext, BBoxDeco& bboxdeco, Material* material, int *at, int* line, int* level, Vec3* trans, Vec3* scale) { Edge* edge; int j; *at = material->marginCoord; if (material->floating) edge = BBoxDecoImpl::chooseEdge(renderContext, bboxdeco, *at); else edge = BBoxDecoImpl::fixedEdge(material); if (!edge) { *at = NA_INTEGER; return; } for (j = 0; j < 3; j++) { if (edge->dir[j] != 0) { *line = j; break; } } *level = 2; for (j = 0; j < 2; j++) { if (*at != j && *line != j) { *level = j; break; } } /* Set up translation and scaling */ AABox bbox = renderContext->subscene->getBoundingBox(); Vertex marklen = bboxdeco.getMarkLength(bbox); for (j = 0; j < 3; j++) { if (j != *at) { int e = 1; if (material->floating && edge->code[j] < 0) e = -1; e = e*material->edge[j]; (*trans)[j] = e == 1 ? bbox.vmax[j] : bbox.vmin[j]; (*scale)[j] = marklen[j]*e; } else { (*trans)[j] = 0.0; (*scale)[j] = 1.0; } } }; }; void BBoxDeco::render(RenderContext* renderContext) { #ifndef RGL_NO_OPENGL AABox bbox = renderContext->subscene->getBoundingBox(); if (bbox.isValid()) { glPushAttrib(GL_ENABLE_BIT); int i,j; // vertex array: Vertex4 boxv[8] = { Vertex4( bbox.vmin.x, bbox.vmin.y, bbox.vmin.z ), Vertex4( bbox.vmax.x, bbox.vmin.y, bbox.vmin.z ), Vertex4( bbox.vmin.x, bbox.vmax.y, bbox.vmin.z ), Vertex4( bbox.vmax.x, bbox.vmax.y, bbox.vmin.z ), Vertex4( bbox.vmin.x, bbox.vmin.y, bbox.vmax.z ), Vertex4( bbox.vmax.x, bbox.vmin.y, bbox.vmax.z ), Vertex4( bbox.vmin.x, bbox.vmax.y, bbox.vmax.z ), Vertex4( bbox.vmax.x, bbox.vmax.y, bbox.vmax.z ) }; // // // transform vertices: used for edge distance criterion and text justification // Matrix4x4 modelview(renderContext->subscene->modelMatrix); // setup material material.beginUse(renderContext); if (material.line_antialias || material.isTransparent()) { // SETUP BLENDING if (renderContext->gl2psActive == GL2PS_NONE) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); else gl2psBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); // ENABLE BLENDING glEnable(GL_BLEND); } // draw back faces glBegin(GL_QUADS); for(i=0;i<6;i++) { const Vertex4 q = modelview * side[i].normal; const Vertex4 view(0.0f,0.0f,1.0f,0.0f); float cos_a = view * q; const bool front = (cos_a >= 0.0f) ? true : false; if (draw_front || !front) { // draw face glNormal3f(side[i].normal.x, side[i].normal.y, side[i].normal.z); for(j=0;j<4;j++) { // feed vertex Vertex4& v = boxv[ side[i].vidx[j] ]; glVertex3f(v.x, v.y, v.z); } } } glEnd(); // setup mark length Vertex marklen = getMarkLength(bbox); // draw axis and tickmarks // find contours glDisable(GL_LIGHTING); material.useColor(1); for(i=0;i<3;i++) { Vertex4 v; AxisInfo* axis; float* valueptr; float low, high; switch(i) { case 0: axis = &xaxis; valueptr = &v.x; low = bbox.vmin.x; high = bbox.vmax.x; break; case 1: axis = &yaxis; valueptr = &v.y; low = bbox.vmin.y; high = bbox.vmax.y; break; case 2: default: axis = &zaxis; valueptr = &v.z; low = bbox.vmin.z; high = bbox.vmax.z; break; } if (axis->mode == AXIS_NONE) continue; Edge* edge = BBoxDecoImpl::chooseEdge(renderContext, *this, i); if (axis->mode == AXIS_USER) { if (!axisBusy) { axisBusy = true; if (axisCallback[i]) { int e[3]; if (edge) { e[0] = edge->code[0]; e[1] = edge->code[1]; e[2] = edge->code[2]; } else{ e[0] = 0; e[1] = 0; e[2] = 0; } axisCallback[i](axisData[i], i, e); axisBusy = false; } } } else if (edge) { v = boxv[edge->from]; switch (axis->mode) { case AXIS_CUSTOM: { // draw axis and tickmarks StringArrayIterator iter(&axis->textArray); for (iter.first(), j=0; (jnticks) && (!iter.isDone());j++, iter.next()) { float value = axis->ticks[j]; // clip marks if ((value >= low) && (value <= high)) { String string = iter.getCurrent(); *valueptr = value; axis->draw(renderContext, v, edge->dir, modelview, marklen, string); } } } break; case AXIS_LENGTH: { float delta = (axis->len>1) ? (high-low)/((axis->len)-1) : 0; for(int k=0;klen;k++) { float value = low + delta * (float)k; *valueptr = value; char text[32]; sprintf(text, "%.4g", value); String string(static_cast(strlen(text)),text); axis->draw(renderContext, v, edge->dir, modelview, marklen, string); } } break; case AXIS_UNIT: { float value = ( (float) ( (int) ( ( low+(axis->unit-1) ) / (axis->unit) ) ) ) * (axis->unit); while(value < high) { *valueptr = value; char text[32]; sprintf(text, "%.4g", value); String s (static_cast(strlen(text)),text); axis->draw(renderContext, v, edge->dir, modelview, marklen, s ); value += axis->unit; } } break; case AXIS_PRETTY: { /* These are the defaults from the R pretty() function, except min_n is 3 */ double lo=low, up=high, shrink_sml=0.75, high_u_fact[2]; int ndiv=axis->len, min_n=3, eps_correction=0; high_u_fact[0] = 1.5; high_u_fact[1] = 2.75; axis->unit = static_cast(R_pretty0(&lo, &up, &ndiv, min_n, shrink_sml, high_u_fact, eps_correction, 0)); for (int i=(int)lo; i<=up; i++) { float value = i*axis->unit; if (value >= low && value <= high) { *valueptr = value; char text[32]; sprintf(text, "%.4g", value); String s (static_cast(strlen(text)),text); axis->draw(renderContext, v, edge->dir, modelview, marklen, s ); } } } break; } } } material.endUse(renderContext); glPopAttrib(); } #endif } Vec3 BBoxDeco::marginVecToDataVec(Vec3 marginvec, RenderContext* renderContext, Material* material) { /* Create permutation to map at, line, pos to x, y, z */ int at = 0, line = 0, level = 0; /* initialize to suppress warning */ Vec3 trans, scale; BBoxDecoImpl::setMarginParameters(renderContext, *this, material, &at, &line, &level, &trans, &scale); if (at == NA_INTEGER) return Vertex(NA_REAL, NA_REAL, NA_REAL); /* It might make more sense to do this by * modifying the MODELVIEW matrix, but * I couldn't get that right for some reason... */ Vertex result; AABox bbox = renderContext->subscene->getBoundingBox(); if (marginvec.missing()) result[at] = (bbox.vmin[at] + bbox.vmax[at])/2.0; else if (marginvec.x == -INFINITY) result[at] = bbox.vmin[at]; else if (marginvec.x == INFINITY) result[at] = bbox.vmax[at]; else result[at] = marginvec.x*scale[at] + trans[at]; result[line] = marginvec.y*scale[line] + trans[line]; result[level] = marginvec.z*scale[level] + trans[level]; return result; } Vec3 BBoxDeco::marginNormalToDataNormal(Vec3 marginvec, RenderContext* renderContext, Material* material) { int at=0, line=0, level=0; /* initialize to suppress warning */ Vec3 trans, scale; BBoxDecoImpl::setMarginParameters(renderContext, *this, material, &at, &line, &level, &trans, &scale); if (at == NA_INTEGER) return Vertex(NA_REAL, NA_REAL, NA_REAL); Vertex result; result[at] = marginvec.x/scale[at]; result[line] = marginvec.y/scale[line]; result[level] = marginvec.z/scale[level]; return result; } void BBoxDeco::setAxisCallback(userAxisPtr fn, void* user, int axis) { axisCallback[axis] = fn; axisData[axis] = user; switch(axis) { case 0: xaxis.mode = AXIS_USER; break; case 1: yaxis.mode = AXIS_USER; break; case 2: zaxis.mode = AXIS_USER; break; } } void BBoxDeco::getAxisCallback(userAxisPtr *fn, void** user, int axis) { *fn = axisCallback[axis]; *user = axisData[axis]; } int BBoxDeco::getAttributeCount(AABox& bbox, AttribID attrib) { switch (attrib) { case TEXTS: { int count = ((xaxis.mode == AXIS_CUSTOM) ? xaxis.nticks : 0) + ((yaxis.mode == AXIS_CUSTOM) ? yaxis.nticks : 0) + ((zaxis.mode == AXIS_CUSTOM) ? zaxis.nticks : 0); if (count == 0) return 0; } /* if non-zero, we want labels for every vertex, so fall through. */ case VERTICES: return xaxis.getNticks(bbox.vmin.x, bbox.vmax.x) + yaxis.getNticks(bbox.vmin.y, bbox.vmax.y) + zaxis.getNticks(bbox.vmin.z, bbox.vmax.z); case COLORS: return material.colors.getLength(); case FLAGS: return 2; case AXES: return 5; } return SceneNode::getAttributeCount(bbox, attrib); } void BBoxDeco::getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result) { int n = getAttributeCount(bbox, attrib); if (first + count < n) n = first + count; if (first < n) { switch(attrib) { case VERTICES: float low, high; int i, thisn; i = 0; low = bbox.vmin.x; high = bbox.vmax.x; thisn = xaxis.getNticks(low, high); for (int j=0; j #include using namespace std; #include "types.h" #ifndef M_PI #define M_PI 3.1415926535897932384626433832795 #endif namespace rgl { namespace math { // template-based math functions with default 'double' implementation using math.h template inline T acos(T x) { return static_cast( ::acos( static_cast(x) ) ); } template inline T asin(T x) { return static_cast( ::asin( static_cast(x) ) ); } template inline T atan(T x) { return static_cast( ::atan( static_cast(x) ) ); } template inline T atan2(T x, T y) { return static_cast( ::atan2( static_cast(x), static_cast(y) ) ); } template inline T cos(T x) { return static_cast( ::cos( static_cast(x) ) ); } template inline T sin(T x) { return static_cast( ::sin( static_cast(x) ) ); } #ifdef HAVE_SINF template<> inline float sin(float rad) { return ::sinf(rad); } #endif template inline T tan(T x) { return static_cast( ::tan( static_cast(x) ) ); } // template inline T acosh(T x) { return static_cast( ::acosh( static_cast(x) ) ); } // template inline T asinh(T x) { return static_cast( ::asinh( static_cast(x) ) ); } // template inline T atanh(T x) { return static_cast( ::atanh( static_cast(x) ) ); } // template inline T cosh(T x) { return static_cast( ::cosh( static_cast(x) ) ); } // template inline T sinh(T x) { return static_cast( ::sinh( static_cast(x) ) ); } // template inline T tanh(T x) { return static_cast( ::tanh( static_cast(x) ) ); } template inline T exp(T x) { return static_cast( ::exp( static_cast(x) ) ); } // template inline T exp2(T x) { return static_cast( ::exp2( static_cast(x) ) ); } // template inline T expm1(T x) { return static_cast( ::expm1( static_cast(x) ) ); } template inline T log(T x) { return static_cast( ::log( static_cast(x) ) ); } template inline T log10(T x) { return static_cast( ::log10( static_cast(x) ) ); } // template inline T log2(T x) { return static_cast( ::log2( static_cast(x) ) ); } template inline T log1p(T x) { return static_cast( ::log1p( static_cast(x) ) ); } template inline T logb(T x) { return static_cast( ::logb( static_cast(x) ) ); } template inline T modf(T x, T* y) { double i; double r = ::modf( static_cast(x), &i ); *y = static_cast(i); return static_cast(r); } template<> inline double modf(double x, double* y) { return ::modf(x,y); } //template<> inline float modf(float x, float* y) { return ::modff(x,y); } template inline T ldexp(T x, int y) { return static_cast( ::ldexp(static_cast(x),y) ); } // template inline T frexp(T x, int* y) { return static_cast( ::frexp( static_cast(x),n) ); } template inline int ilogb(T x) { return ::ilogb( static_cast(x) ); } template inline T scalbn(T x, int n) { return static_cast( ::scalbn( static_cast(x),n ) ); } template inline T fabs(T x) { return static_cast( ::fabs( static_cast(x) ) ); } template inline T cbrt(T x) { return static_cast( ::cbrt( static_cast(x) ) ); } // template inline T hypot(T x) { return static_cast( ::hypot( static_cast(x) ) ); } template inline T pow(T x, T y) { return static_cast( ::pow( static_cast(x), static_cast(y) ) ); } template inline T sqrt(T x) { return static_cast( ::sqrt( static_cast(x) ) ); } template inline T erf(T x) { return static_cast( ::erf( static_cast(x) ) ); } template inline T erfc(T x) { return static_cast( ::erfc( static_cast(x) ) ); } template inline T lgamma(T x) { return static_cast( ::lgamma( static_cast(x) ) ); } // template inline T tgamma(T x) { return static_cast( ::tgamma( static_cast(x) ) ); } template inline T ceil(T x) { return static_cast( ::ceil( static_cast(x) ) ); } template inline T floor(T x) { return static_cast( ::floor( static_cast(x) ) ); } // template inline T nearbyint(T x) { return static_cast( ::nearbyint( static_cast(x) ) ); } template inline T rint(T x) { return static_cast( ::rint( static_cast(x) ) ); } // template inline long int lrint(T x) { return ( ::lrint( static_cast(x) ) ); } // template inline long long int llrint(T x) { return ::llrint( static_cast(x) ); } // template inline T round(T x) { return static_cast( ::round( static_cast(x) ) ); } template inline T pi() { return static_cast( M_PI ); } template inline T deg2rad(T deg) { return ( pi() / T(180.0) ) * deg; } template inline T rad2deg(T rad) { return rad / ( pi() / T(180.0) ); } } // inline float deg2radf(float deg) { return ((float)(PI/180.0)) * deg; } // inline float rad2degf(float rad) { return rad / ((float)(PI/180.0)); } // inline float deg2radf(float deg) { return deg2rad(deg); } // inline float rad2degf(float rad) { return rad2deg(rad); } struct Vec3 { float x,y,z; Vec3() : x(0),y(0),z(0) { } Vec3(float in_x,float in_y, float in_z) : x(in_x), y(in_y), z(in_z) { } Vec3(const Vec3& that) : x(that.x), y(that.y), z(that.z) { } inline float getLength() const { return math::sqrt( x*x + y*y + z*z ); } void normalize(); Vec3 cross(Vec3 op2) const; float angle(const Vec3& op2) const; float operator * (Vec3 op2); Vec3 operator * (float value); Vec3 operator+(Vec3 op2) const; Vec3 operator-(Vec3 op2) const; Vec3 scale(const Vec3& op2) const; void operator+=(Vec3 op2); void rotateX(float degree); void rotateY(float degree); bool missing() const; /* Any components missing */ float& operator[](int i); static inline Vec3& asVec3(float* ptr) { return *( reinterpret_cast( ptr ) ); } }; template<> inline void copy(double* from, Vec3* to, int size) { copy(from, (float*) to, size*3); } typedef Vec3 Vertex; typedef Vertex Vertex3; typedef Vertex3 Normal; struct Vec4 { float x,y,z,w; Vec4(const Normal& n, float in_w=0.0f) : x(n.x), y(n.y), z(n.z), w(in_w) {}; Vec4() {}; Vec4(const float x, const float y, const float z, const float w=1.0f); float operator * (const Vec4& op2) const; Vec4 operator * (const float value) const; Vec4 operator + (const Vec4& op2) const; bool missing() const; /* Any components missing */ float& operator[](int i); static inline Vec4& asVec4(float* ptr) { return *( reinterpret_cast( ptr ) ); } }; class Matrix4x4 { public: Matrix4x4(); Matrix4x4(const Matrix4x4& src); Matrix4x4(const double*); Vec3 operator*(const Vec3 op2) const; Vec4 operator*(const Vec4& op2) const; Matrix4x4 operator*(const Matrix4x4& op2) const; Vec4 getRow(int row); void setIdentity(void); void setRotate(const int axis, const float degree); void getData(double* dest); void loadData(const double* from); void loadData(const float* from); void loadData(const Matrix4x4& from); void transpose(); void multRight(const Matrix4x4& M); void multLeft(const Matrix4x4& M); static Matrix4x4 scaleMatrix(double sx, double sy, double sz); static Matrix4x4 translationMatrix(double x, double y, double z); static Matrix4x4 permutationMatrix(int newx, int newy, int newz); private: inline float val(int row, int column) const { return data[4*column+row]; } inline float& ref(int row, int column) { return data[4*column+row]; } float data[16]; }; // // CLASS // RectSize // struct RectSize { RectSize() : width(0), height(0) {}; RectSize(int in_width, int in_height) : width(in_width), height(in_height) {}; int width; int height; }; struct Rect2 { Rect2(int in_x, int in_y, int in_w, int in_h) : x(in_x) , y(in_y) , width(in_w) , height(in_h) { } int x, y; int width, height; }; struct Rect2d { Rect2d(double in_x, double in_y, double in_w, double in_h) : x(in_x) , y(in_y) , width(in_w) , height(in_h) { } double x, y; double width, height; }; // // CLASS // PolarCoord // struct PolarCoord { PolarCoord(float in_theta=0.0f, float in_phi=0.0f) : theta(in_theta), phi(in_phi) {}; PolarCoord(const PolarCoord& src) : theta(src.theta), phi(src.phi) {}; PolarCoord operator + (const PolarCoord& op2) const { return PolarCoord(theta+op2.theta, phi+op2.phi); } PolarCoord operator - (const PolarCoord& op2) const { return PolarCoord(theta-op2.theta, phi-op2.phi); } Vec3 vector() const; float theta; float phi; }; typedef Vec4 Vertex4; } // namespace rgl #endif /* MATH_H */ rgl/src/fps.h0000644000176200001440000000055614100762641012575 0ustar liggesusers#ifndef RGL_FPS_H #define RGL_FPS_H // C++ header file // This file is part of RGL // #include "scene.h" namespace rgl { // // FPS COUNTER // class FPS { private: double lastTime; int framecnt; char buffer[12]; public: inline FPS() { }; void init(double t); void render(double t, RenderContext* ctx); }; } // namespace rgl #endif // RGL_FPS_H rgl/src/String.h0000644000176200001440000000140414105226312013237 0ustar liggesusers#ifndef STRING_H #define STRING_H namespace rgl { // // CLASS // StringArray // struct String { String(int in_length, char* in_text) { length = in_length; text = in_text; } int length; char* text; }; class StringArrayImpl; class StringArray { public: StringArray(); StringArray(int ntexts, char** in_texts); StringArray(StringArray& from); ~StringArray(); String operator[](int index); int size(); private: StringArrayImpl* impl; friend class StringArrayIterator; }; class StringArrayIterator { public: StringArrayIterator(StringArray* array); void first(); void next(); String getCurrent(); bool isDone() const; private: StringArray* array; int cnt; char* textptr; }; } // namespace rgl #endif // STRING_H rgl/src/fps.cpp0000644000176200001440000000135714142256754013141 0ustar liggesusers// C++ source // This file is part of RGL. // #include "fps.h" #include "glgui.h" #include using namespace rgl; void FPS::init(double time) { lastTime = time; framecnt = 0; buffer[0] = '0'; buffer[1] = '\0'; } void FPS::render(double t, RenderContext* ctx) { #ifndef RGL_NO_OPENGL if (lastTime + 1.0f < t ) { lastTime = t; sprintf(buffer, "FPS %d", framecnt); framecnt = 0; } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.0f,1.0f,-1.0f,1.0f,-1.0f,1.0f); glColor3f(1.0f,1.0f,1.0f); glRasterPos2f( 1.0f, -0.9f); if (ctx->font) ctx->font->draw(buffer, static_cast(strlen(buffer)), -1, 0.0, 0.5, 0, *ctx); framecnt++; #endif } rgl/src/Viewpoint.cpp0000644000176200001440000001465414100762641014330 0ustar liggesusers#include "Viewpoint.h" #include "subscene.h" #include "opengl.h" #include "R.h" using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // UserViewpoint -- the viewer's portion of the viewpoint // ModelViewpoint -- the model's portion // // These were previously just one Viewpoint class, but subscenes mean they need to be split // UserViewpoint::UserViewpoint(float in_fov, float in_zoom) : SceneNode(USERVIEWPOINT), fov(in_fov), zoom(in_zoom), viewerInScene(false) { clearUserProjection(); } ModelViewpoint::ModelViewpoint(PolarCoord in_position, Vec3 in_scale, bool in_interactive) : SceneNode(MODELVIEWPOINT), interactive(in_interactive) { scale = in_scale; scaleChanged = true; setPosition(in_position); clearMouseMatrix(); } PolarCoord& ModelViewpoint::getPosition() { return position; } ModelViewpoint::ModelViewpoint(double* in_userMatrix, Vec3 in_scale, bool in_interactive) : SceneNode(MODELVIEWPOINT), position( PolarCoord(0.0f, 0.0f) ), interactive(in_interactive) { for (int i=0; i<16; i++) { userMatrix[i] = in_userMatrix[i]; } scale = in_scale; scaleChanged = true; clearMouseMatrix(); } void ModelViewpoint::setPosition(const PolarCoord& in_position) { Matrix4x4 M,N; M.setRotate(0, in_position.phi); N.setRotate(1, -in_position.theta); M = M * N; M.getData((double*)userMatrix); position = in_position; } void ModelViewpoint::clearMouseMatrix() { Matrix4x4 M; M.setIdentity(); M.getData((double*)mouseMatrix); } void UserViewpoint::clearUserProjection() { userProjection.setIdentity(); } void UserViewpoint::getUserProjection(double* dest) { userProjection.transpose(); userProjection.getData(dest); userProjection.transpose(); } void UserViewpoint::setUserProjection(double* src) { userProjection.loadData(src); userProjection.transpose(); } float UserViewpoint::getZoom() const { return zoom; } void UserViewpoint::setZoom(const float in_zoom) { zoom = in_zoom; } bool ModelViewpoint::isInteractive() const { return interactive; } void UserViewpoint::setFOV(const float in_fov) { fov = clamp(in_fov, 0.0, 179.0 ); } float UserViewpoint::getFOV() const { return fov; } void UserViewpoint::setupFrustum(RenderContext* rctx, const Sphere& viewSphere) { frustum.enclose(viewSphere.radius, fov, rctx->subscene->pviewport.width, rctx->subscene->pviewport.height); if (!viewerInScene) { eye.x = 0.; eye.y = 0.; eye.z = frustum.distance; } else { float oldnear = frustum.znear; frustum.znear -= -eye.z + frustum.distance; frustum.zfar -= -eye.z + frustum.distance; if (frustum.zfar < 0) frustum.zfar = 1; if (frustum.znear < frustum.zfar/100.f) // we lose log2(100) bits of depth resolution frustum.znear = frustum.zfar/100.f; float ratio = frustum.znear/oldnear; frustum.left = frustum.left*ratio + eye.x; frustum.right = frustum.right*ratio + eye.x; frustum.top = frustum.top*ratio + eye.y; frustum.bottom = frustum.bottom*ratio + eye.y; } // zoom frustum.left *= zoom; frustum.right *= zoom; frustum.bottom *= zoom; frustum.top *= zoom; } void UserViewpoint::setupProjMatrix(RenderContext* rctx, const Sphere& viewSphere) { setupFrustum(rctx, viewSphere); rctx->subscene->projMatrix.loadData(rctx->subscene->projMatrix*userProjection*frustum.getMatrix()); } Vertex UserViewpoint::getObserver() { return this->eye; } void UserViewpoint::setObserver(bool automatic, Vertex in_eye) { viewerInScene = !automatic; if (viewerInScene && !ISNAN(in_eye.x) &&!ISNAN(in_eye.y) && !ISNAN(in_eye.z)) this->eye = in_eye; } void UserViewpoint::setupViewer(RenderContext* rctx) { rctx->subscene->modelMatrix = rctx->subscene->modelMatrix * Matrix4x4::translationMatrix(-eye.x, -eye.y, -eye.z); } void ModelViewpoint::setupOrientation(RenderContext* rctx) const { rctx->subscene->modelMatrix = rctx->subscene->modelMatrix * mouseMatrix * userMatrix; } void ModelViewpoint::setupTransformation(RenderContext* rctx, Vertex center) { // modelview setupOrientation(rctx); rctx->subscene->modelMatrix = rctx->subscene->modelMatrix * Matrix4x4::scaleMatrix(scale.x, scale.y, scale.z) * Matrix4x4::translationMatrix(-center.x, -center.y, -center.z); } void ModelViewpoint::updateMouseMatrix(Vec3 dragStart, Vec3 dragCurrent) { #ifndef RGL_NO_OPENGL Vec3 axis = dragStart.cross(dragCurrent); float angle = dragStart.angle(dragCurrent); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); if (axis.getLength() > 0) glRotatef((GLfloat)angle, (GLfloat)axis.x, (GLfloat)axis.y, (GLfloat)axis.z); glGetDoublev(GL_MODELVIEW_MATRIX,mouseMatrix); glPopMatrix(); #endif } void ModelViewpoint::updateMouseMatrix(PolarCoord newpos) { Matrix4x4 M,N; M.setRotate(0, newpos.phi); N.setRotate(1, -newpos.theta); M = M * N; M.getData((double*)mouseMatrix); } void ModelViewpoint::mouseOneAxis(Vertex dragStart,Vertex dragCurrent,Vertex axis) { #ifndef RGL_NO_OPENGL float angle = math::rad2deg(dragCurrent.x-dragStart.x); Matrix4x4 M((double *)userMatrix); Vec4 v = M * Vec4(axis.x, axis.y, axis.z); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glRotatef((GLfloat)angle, (GLfloat)v.x/v.w, (GLfloat)v.y/v.w, (GLfloat)v.z/v.w); glGetDoublev(GL_MODELVIEW_MATRIX,mouseMatrix); glPopMatrix(); #endif } void ModelViewpoint::mergeMouseMatrix() { Matrix4x4 M((double *)userMatrix), N((double *)mouseMatrix); M = N * M; M.getData((double *)userMatrix); N.setIdentity(); N.getData((double *)mouseMatrix); } void ModelViewpoint::getUserMatrix(double* dest) { for(int i=0; i<16;i++) dest[i] = userMatrix[i]; } void ModelViewpoint::setUserMatrix(double* src) { for(int i=0; i<16;i++) userMatrix[i] = src[i]; } void ModelViewpoint::getScale(double* dest) { dest[0] = scale.x; dest[1] = scale.y; dest[2] = scale.z; } void ModelViewpoint::setScale(double* src) { scale.x = static_cast(src[0]); scale.y = static_cast(src[1]); scale.z = static_cast(src[2]); scaleChanged = true; } void ModelViewpoint::getPosition(double* dest) { dest[0] = position.theta; dest[1] = position.phi; } void ModelViewpoint::setPosition(double* src) { position.theta = static_cast(src[0]); position.phi = static_cast(src[1]); } rgl/src/Shape.h0000644000176200001440000000764214100762641013050 0ustar liggesusers#ifndef SHAPE_H #define SHAPE_H #include #include "SceneNode.h" #include "Material.h" #include "RenderContext.h" #include "opengl.h" #include "geom.h" namespace rgl { // // CLASS // Shape // class Shape : public SceneNode { public: Shape(Material& in_material,bool in_ignoreExtent, TypeID in_typeID=SHAPE, bool in_bboxChanges=false); ~Shape(); /** * render shape. * Default Implementation: uses z-buffer and a display list * that stores everything from a call to draw(). **/ virtual void render(RenderContext* renderContext); /** * request update of node due to content change. * This will result in a new 'recording' of the display list. **/ virtual void update(RenderContext* renderContext); /** * draw. **/ virtual void draw(RenderContext* renderContext); /** * obtain bounding box **/ const AABox& getBoundingBox() const { return boundingBox; } /** * does this shape change dimensions according to the way it is rendered? * if so, the above is just a guess... **/ const bool getBBoxChanges() const { return bboxChanges; } /** * this shows how the shape would be sized in the given context **/ virtual AABox& getBoundingBox(Subscene* subscene) { return boundingBox; } /** * obtain material **/ Material* getMaterial() { return &material; } const bool getIgnoreExtent() const { return ignoreExtent; } virtual void getTypeName(char* buffer, int buflen) { strncpy(buffer, "shape", buflen); }; /** * invalidate display list **/ void invalidateDisplaylist(); /** * access to individual items **/ virtual int getElementCount(void) = 0; /** * access to primitives (e.g. facets of sphere) **/ virtual int getPrimitiveCount(void) { return getElementCount(); } /* overrides */ int getAttributeCount(AABox& bbox, AttribID attrib); void getAttribute(AABox& bbox, AttribID attrib, int first, int count, double* result); /** * location of individual parts **/ virtual Vertex getPrimitiveCenter(int index) { return boundingBox.getCenter(); } /** * Starting to render the shape. After this, the renderContext won't change until * the next call. This will only be called once per rendering. **/ virtual void renderBegin(RenderContext* renderContext) { }; /** * begin sending items. This may be called multiple times, e.g. if the * items are being intermixed with items from other shapes **/ virtual void drawBegin(RenderContext* renderContext); /** * send one item **/ virtual void drawPrimitive(RenderContext* renderContext, int index) = 0; /** * end sending items **/ virtual void drawEnd(RenderContext* renderContext); /** * Some shapes (currently just sprites) contain others. Do a recursive search */ virtual Shape* get_shape(int id) { return NULL; } const bool isTransparent() const { return transparent; } const bool isBlended() const { return blended; } /** * Does this shape need to go at the head of the shape list, rather than the tail? * (e.g. clip planes need to come first **/ virtual bool isClipPlane() { return false; } protected: /** * bounding volume of overall geometry **/ AABox boundingBox; /** * bounding volume changes depending on the scene? **/ bool bboxChanges; /* * whether this object should be ignored in scene bounding box calculations */ bool ignoreExtent; /** * material **/ Material material; private: #ifndef RGL_NO_OPENGL /** * display list **/ GLuint displayList; #endif int drawLevel; /* for debugging */ protected: /** * update indicator **/ bool doUpdate; bool transparent, blended; }; class ShapeItem { public: ShapeItem(Shape* in_shape, int in_itemnum) : shape(in_shape), itemnum(in_itemnum) {}; Shape* shape; int itemnum; }; } // namespace rgl #endif // SHAPE_H rgl/src/RenderContext.cpp0000644000176200001440000000026414100762641015120 0ustar liggesusers#include "RenderContext.h" #include using namespace rgl; ////////////////////////////////////////////////////////////////////////////// // // CLASS // RenderContext // rgl/src/NULLgui.h0000644000176200001440000000100414100762641013251 0ustar liggesusers#ifndef RGL_NULL_GUI_H #define RGL_NULL_GUI_H // --------------------------------------------------------------------------- #include "gui.h" namespace rgl { // --------------------------------------------------------------------------- class NULLGUIFactory : public GUIFactory { public: NULLGUIFactory(); virtual ~NULLGUIFactory(); WindowImpl* createWindowImpl(Window* window); }; // --------------------------------------------------------------------------- } // namespace rgl #endif // RGL_NULL_GUI_H rgl/vignettes/0000755000176200001440000000000014146473374013063 5ustar liggesusersrgl/vignettes/setup.R0000644000176200001440000000550414100762641014336 0ustar liggesusersoptions(rgl.useNULL=FALSE) suppressPackageStartupMessages(library(rgl)) options(rgl.useNULL=TRUE) options(rgl.printRglwidget=FALSE) if (!requireNamespace("rmarkdown", quietly = TRUE) || !rmarkdown::pandoc_available("1.14")) { warning(call. = FALSE, "These vignettes assume rmarkdown and pandoc version 1.14. These were not found. Older versions will not work.") knitr::knit_exit() } # knitr::opts_chunk$set(snapshot = TRUE) # for snapshots instead of dynamic documentedfns <- c() backticked <- function(s) paste0("`", s, "`") indexfns <- function(fns, text = backticked(fns), show = TRUE, pkg = "rgl") { documentedfns <<- c(documentedfns, fns) anchors <- paste0('', if (show) linkfn(fns, text, pkg = pkg), '') paste(anchors, collapse=if (show) ", " else "") } indexclass <- indexproperties <- function(fns, text = backticked(fns), show = TRUE) { documentedfns <<- c(documentedfns, fns) anchors <- paste0('', if (show) text, '') paste(anchors, collapse=if (show) ", " else "") } indexmethods <- function(fns, text = backticked(paste0(fns, "()")), show = TRUE) { documentedfns <<- c(documentedfns, fns) anchors <- paste0('', if (show) text, '') paste(anchors, collapse=if (show) ", " else "") } linkfn <- function(fn, text = backticked(fn), pkg = NA) { if (is.na(pkg)) paste0('', text, '') else { if (requireNamespace("downlit", quietly = TRUE)) url <- downlit::autolink_url(paste0(pkg, "::", fn)) else url <- NA if (is.na(url)) url <- paste0('../../', pkg, '/help/', fn) paste0('', text, '') } } # Write this once at the start of the document. cat(' ') writeIndex <- function(cols = 4) { if (!is.null(documentedfns)) { documentedfns <- sort(documentedfns) entries <- paste0('', documentedfns, '  ') len <- length(entries) padding <- ((len + cols - 1) %/% cols) * cols - len if (padding) entries <- c(entries, rep("", length.out=padding)) cat('\n
\n') print(knitr::kable(matrix(entries, ncol=cols), format="pandoc")) cat("
\n") } } # This displays the string code as `r code` when entered # as `r rinline(code)`. Due to Stephane Laurent rinline <- function(code, script = FALSE){ if (script) html <- "`r CODE`" else html <- '``` `r CODE` ```' sub("CODE", code, html) } rgl/vignettes/rgl.Rmd0000644000176200001440000013130314146471171014305 0ustar liggesusers--- title: "rgl Overview" author: "Duncan Murdoch" date: "`r format(Sys.time(), '%B %d, %Y')`" output: rmarkdown::html_vignette: fig_height: 5 fig_width: 5 toc: yes html_document: df_print: paged toc: yes pdf_document: fig_height: 5 fig_width: 5 toc: yes vignette: > %\VignetteIndexEntry{rgl Overview} %\VignetteEngine{knitr::rmarkdown} --- ```{r setup, echo=FALSE, results="asis"} source("setup.R") setupKnitr(autoprint = TRUE) set.seed(123) ``` ## Introduction The `rgl` package is used to produce interactive 3-D plots. It contains high-level graphics commands modelled loosely after classic R graphics, but working in three dimensions. It also contains low level structure inspired by (but incompatible with) the `grid` package. This document gives an overview. See the help pages for details. For installation instructions, see the `README` file in the top level directory of the source tarball `r paste0("rgl_", packageVersion("rgl"), ".tar.gz")` (or a later version). ### About this document This document was written in R Markdown, using the `knitr` package for production. It corresponds to `rgl` version `r packageVersion("rgl")`. Most of the highlighted function names are HTML links. The internal links should work in any browser; the links to help topics should work if you view the vignette from within the R help system. The document includes WebGL figures. To view these, you must have Javascript and WebGL enabled in your browser. Some older browsers may not support this -- see https://get.webgl.org for tests and links to a discussion. ## Basics and High Level Functions The `r indexfns("plot3d")` function plots points within an RGL window. It is similar to the classic `r linkfn("plot", pkg="graphics")` function, but works in 3 dimensions. For example ```{r} with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length, type="s", col=as.numeric(Species))) ``` \noindent can be used to plot three columns of the `iris` data. Allowed plot types include `"p", "l", "h", "s"`, meaning points, lines, segments from z=0, and spheres. There's a lot of flexibility in specifying the coordinates; the `r linkfn("xyz.coords", pkg = "grDevices")` function from the `grDevices` package is used for this. You can use your mouse to manipulate the plot. The default is that if you click and hold with the left mouse button, you can rotate the plot by dragging it. The right mouse button is used to resize it, and the middle button changes the perspective in the point of view. If you call `r linkfn("plot3d")` again, it will overwrite the current plot. To open a new graphics window, use `r linkfn("open3d")`. The other high level function is `r indexfns("persp3d")` to draw surfaces. It is similar to the classic `r linkfn("persp", pkg = "graphics")` function, but with greater flexibility. First, any of `x`, `y` or `z` can be specified using matrices, not just `z`. This allows parametric surfaces to be plotted. An even simpler specification is possible: `x` may be a function, in which case `persp3d` will work out the grid itself. See `r linkfn("persp3d.function", text="?persp3d.function", pkg="rgl")` for details. For example, the `MASS` package estimates Gamma parameters using maximum likelihood in a `r linkfn("fitdistr", text="?MASS::fitdistr", pkg="MASS")` example. Here we show the log likelihood surface. ```{r persp3d, fig.height=3, fig.width=6, fig.keep="last"} library(MASS) # from the fitdistr example set.seed(123) x <- rgamma(100, shape = 5, rate = 0.1) fit <- fitdistr(x, dgamma, list(shape = 1, rate = 0.1), lower = 0.001) loglik <- function(shape, rate) sum(dgamma(x, shape=shape, rate=rate, log=TRUE)) loglik <- Vectorize(loglik) xlim <- fit$estimate[1]+4*fit$sd[1]*c(-1,1) ylim <- fit$estimate[2]+4*fit$sd[2]*c(-1,1) mfrow3d(1, 2, sharedMouse = TRUE) persp3d(loglik, xlim = xlim, ylim = ylim, n = 30) zlim <- fit$loglik + c(-qchisq(0.99, 2)/2, 0) next3d() persp3d(loglik, xlim = xlim, ylim = ylim, zlim = zlim, n = 30) ``` On the left, the whole surface over a range of the parameters; on the right, only the parts of the surface with log likelihood values near the maximum. Note: this example used the `knitr` hook functions (see `r linkfn("setupKnitr")`) to insert the scene into this vignette; the previous example used the `rglwidget` function. We generally recommend the newer `r linkfn("rglwidget")` approach. Note that both `plot3d` and `persp3d` are generic functions, with the following methods defined: ```{r} methods(plot3d) methods(persp3d) ``` ## Adding Graphical Elements ### Primitive shapes Just as we have `r linkfn("points", pkg="graphics")` and `r linkfn("lines", pkg="graphics")` in classic graphics, there are a number of low level functions in `rgl` to add graphical elements to the currently active plot. The "primitive" shapes are those that are native to OpenGL: Function | Description ----------------------------- | ----------- `r indexfns("points3d")`: | adds points `r indexfns("lines3d")`: | adds lines `r indexfns("segments3d")`: | adds line segments `r indexfns("triangles3d")`: | adds triangles `r indexfns("quads3d")`: | adds quadrilaterals Each of the above functions takes arguments `x`, `y` and `z`, again using `r linkfn("xyz.coords", pkg="grDevices")` for flexibility. They group successive entries as necessary. For example, the `r linkfn("triangles3d")` function takes each successive triple of points as the vertices of a triangle. You can use these functions to annotate the current graph, or to construct a figure from scratch. ### Constructed shapes `rgl` also has a number of objects which it constructs from the primitives. Function | Description ----------------------------- | ----------- `r indexfns(c("text3d", "texts3d"))`: | adds text `r indexfns("abclines3d")`: | adds straight lines to plot (like `abline`) `r indexfns("arc3d")`: | adds spherical arcs or spirals to plot `r indexfns("planes3d")`: | adds planes to plot `r indexfns("clipplanes3d")`: | add clipping planes to plot `r indexfns(c("sprites3d", "particles3d"))`: | add sprites (fixed shapes or images) to plot `r indexfns("spheres3d")`: | adds spheres `r indexfns(c("surface3d", "terrain3d"))`: | a surface (as used in `r linkfn("persp3d")`) `r indexfns("drape3d")`: | drapes lines on a surface or object(s) `r indexfns("shadow3d")`: | projects mesh onto a surface `r indexfns("arrow3d")`: | add an arrow to a scene `r indexfns("pch3d")`: | draw base-style plotting symbols `r indexfns("plotmath3d")`: | used by `r linkfn("text3d")` for math text ### Axes and other "decorations" The following low-level functions control the look of the graph: Function | Description ------------------------------------ | ----------- `r indexfns(c("axes3d", "axis3d"))`: | add axes to plot `r indexfns(c("box3d", "bbox3d"))`: | add box around plot `r indexfns("title3d")`: | add title to plot `r indexfns("mtext3d")`: | add marginal text to plot `r indexfns("decorate3d")`: | add multiple "decorations" (scales, etc.) to plot `r indexfns("aspect3d")`: | set the aspect ratios for the plot `r indexfns(c("bg3d", "bgplot3d"))`: | set the background of the scene `r indexfns("show2d")`: | show a 2D plot or image in a 3D scene `r indexfns("legend3d")`: | set a legend for the scene `r indexfns("grid3d")`: | add a reference grid to a graph `r indexfns("thigmophobe3d")`: | choose label positions to avoid overlap `r indexfns("setAxisCallbacks")`: | set user-defined axis annotations For example, to plot three random triangles, one could use ```{r fig.width=3, fig.height=3} triangles3d(cbind(x=rnorm(9), y=rnorm(9), z=rnorm(9)), col = "green") decorate3d() bg3d("lightgray") aspect3d(1,1,1) ``` Besides the `*3d` functions mentioned above, there are even lower-level functions `r indexfns(c("rgl.primitive", "rgl.points", "rgl.linestrips", "rgl.lines", "rgl.triangles", "rgl.quads", "rgl.texts", "rgl.abclines", "rgl.planes", "rgl.bg", "rgl.clipplanes", "rgl.bbox", "rgl.spheres", "rgl.sprites", "rgl.surface"))`. You should avoid using these functions, which do not work well with the higher level `*3d` functions. See the `r linkfn("r3d", text="?r3d", pkg="rgl")` help topic for details. The functions `r indexfns(c("rgl.setAxisCallback", "rgl.getAxisCallback"))` provide low-level support for `r linkfn("setAxisCallbacks")`. ## Controlling the Look of the Scene ### Lighting In most scenes, objects are "lit", meaning that their appearance depends on their position and orientation relative to lights in the scene. The lights themselves don't normally show up, but their effect on the objects does. Use the `r indexfns("light3d")` function to specify the position and characteristics of a light. Lights may be infinitely distant, or may be embedded within the scene. Their characteristics include `ambient`, `diffuse`, and `specular` components, all defaulting to white. The `ambient` component appears the same from any direction. The `diffuse` component depends on the angle between the surface and the light, while the `specular` component also takes the viewer's position into account. The `r indexfns("rgl.light")` function is a lower-level function with different defaults; users should normally use `r linkfn("light3d")`. ### Materials The mental model used in `rgl` is that the objects being shown in scenes are physical objects in space, with material properties that affect how light reflects from them (or is emitted by them). These are mainly controlled by the `r indexfns("material3d")` function, or by arguments to other functions that are passed to it. The material properties that can be set by calls to `material3d` are described in detail in the `r linkfn("material3d", text="?material3d", pkg="rgl")` help page. Here we give an overview. Property | Default | Meaning --------- | ------- | ------------------ color | white | vector of surface colors to apply to successive vertices for diffuse light alpha | 1 | transparency: 0 is invisible, 1 is opaque lit | TRUE | whether lighting calculations should be done ambient | black | color in ambient light specular | white | color in specular light emission | black | color emitted by the surface shininess | 50 | controls the specular lighting: high values look shiny smooth | TRUE | whether shading should be interpolated between vertices texture | NULL | optional path to a "texture" bitmap to be displayed on the surface front, back | fill | should polygons be filled, or outlined? size | 3 | size of points in pixels lwd | 1 | width of lines in pixels Other properties include "texmipmap", "texmagfilter", "texminfilter", "texenvmap", "fog", "point\_antialias", "line\_antialias", "depth\_mask", "depth\_test", "polygon_offset", "margin", "floating" and "tag"; see `r linkfn("material3d", "the help page", pkg = "rgl")` for details. There is also an `r indexfns("rgl.material")` function that works at a lower level; users should normally avoid it. ### Textures As described in the previous section, one of the material properties is `texture`, the name of a bitmap file (in `.png` format) containing an image to be displayed on the surface. This section gives more details about textures. In `OpenGL`, each vertex in a polygon may be associated with a particular location in the bitmap. The interior of the polygon interpolates within the bitmap. There are two conventions in `rgl` functions for specifying these coordinates. Functions which specify primitives (`r linkfn("triangles3d")`, etc.) accept an optional matrix argument `texcoords` which gives `s` (horizontal) and `t` (vertical) locations within the bitmap in columns with one row per vertex. The coordinates are `(0,0)` for the lower left, and `(1,1)` for the upper right. If values outside this range are given, the image repeats, i.e. `(1.1, 1.1)` would specify the same point in the image as `(0.1, 0.1)`. Other functions such as `r linkfn("surface3d")` that take matrices for each vertex coordinate accept texture coordinates as matrices as well, in arguments `texture_s` and `texture_t`. For example, the following code displays four copies of a 2D plot on a quad, because the texture coordinates run from 0 to 2 in both `s` and `t`: ```{r} filename <- tempfile(fileext = ".png") png(filename = filename) plot(rnorm(1000), rnorm(1000)) dev.off() open3d() xyz <- cbind(c(0,1,1,0), 0, c(0,0,1,1)) quads3d(xyz, texture = filename, texcoords = xyz[,c(1, 3)]*2, col = "white", specular = "black") ``` Some other notes: - The color in the figure above was specified to be white. By default, the colors in the bitmap will modify the colour of the quad. If `col` is black (a common default), you won't see anything. - On the other hand, you usually don't want specular reflections (which show up as glare). Setting `specular` to black prevents those. - How the bitmap is handled is controlled by the material property `"textype"`. The default is `"rgb"`, which takes the red-green-blue colours from the bitmap and uses them to modify the corresponding colours in the polygon. Other possibilities for `"textype"` are described in `r linkfn("material3d", "the material3d help page", pkg = "rgl")`. - The other `"tex*"` material properties control how the interpolation within the image is done. - Modern `OpenGL` supports 1- and 3-dimensional textures; these are not supported in `rgl`. ### Fonts `rgl` uses the same ideas as base graphics for drawing text: there are font families named `"sans"`, `"serif"`, and `"mono"` for drawing text of those types. In `rgl`, the `"symbol"` family is not supported. New font families can be defined using the low-level function `r indexfns("rglFonts")`, or more simply using the higher level function `r indexfns("rglExtrafonts")`. The latter function requires the `extrafont` package to be installed. ### par3d: Miscellaneous graphical parameters The `r indexfns("par3d")` function, modelled after the classic graphics `r linkfn("par", pkg="graphics")` function, sets or reads a variety of different `rgl` internal parameters. Some parameters are completely read-only; others are fixed at the time the window is opened, and others may be changed at any time. Name | Changeable? | Description ----------- | ----- | ----------- antialias | fixed | Amount of hardware antialiasing cex | | Default size for text family | | Device-independent font family name; see `r linkfn("text3d", text="?text3d", pkg="rgl")` font | | Integer font number useFreeType | | Should FreeType fonts be used if available? fontname | read-only | System-dependent font name set by `r linkfn("rglFonts")` FOV | | Field of view, in degrees. Zero means isometric perspective ignoreExtent | | Should `rgl` ignore the size of new objects when computing the bounding box? skipRedraw | | Should `rgl` suppress updates to the display? maxClipPlanes | read-only | How many clip planes can be defined? modelMatrix | read-only | The OpenGL ModelView matrix; partly set by `r indexfns("view3d")` or the obsolete `r indexfns("rgl.viewpoint")` projMatrix | read-only | The OpenGL Projection matrix bbox | read-only | Current bounding-box of the scene viewport | | Dimensions in pixels of the scene within the window windowRect | | Dimensions in pixels of the window on the whole screen listeners | | Which subscenes respond to mouse actions in the current one mouseMode | | What the mouse buttons do. See `r linkfn("mouseMode", '"mouseMode"')` observer | read-only | The position of the observer; set by `r indexfns("observer3d")` scale | | Rescaling for each coordinate; see `r linkfn("aspect3d")` zoom | | Magnification of the scene ### Default settings The `r indexfns("r3dDefaults")` list and the `r indexfns("getr3dDefaults")` function control defaults in new windows opened by `r linkfn("open3d")`. The function looks for the variable in the user's global environment, and if not found there, finds the one in the `rgl` namespace. This allows the user to override the default settings for new windows. Once found, the `r3dDefaults` list provides initial values for `r linkfn("par3d")` parameters, as well as defaults for `r linkfn("material3d")` and `r linkfn("bg3d")` in components `"material"` and `"bg"` respectively. ## Meshes: Constructing Shapes `rgl` includes a number of functions to construct and display various solid shapes. These generate objects of class `"shape3d"`, `"mesh3d"` or `"shapelist3d"`. The details of the classes are described below. We start with functions to generate them. ### Specific solids These functions generate specific shapes. Optional arguments allow attributes such as colour or transformations to be specified. Function | Description ------------------------------------ | ----------- `r indexfns(c("tetrahedron3d", "cube3d", "octahedron3d", "dodecahedron3d", "icosahedron3d"))`: | Platonic solids `r indexfns(c("cuboctahedron3d", "oh3d"))`: | other solids ```{r} cols <- rainbow(7) layout3d(matrix(1:16, 4,4), heights=c(1,3,1,3)) text3d(0,0,0,"tetrahedron3d"); next3d() shade3d(tetrahedron3d(col=cols[1])); next3d() text3d(0,0,0,"cube3d"); next3d() shade3d(cube3d(col=cols[2])); next3d() text3d(0,0,0,"octahedron3d"); next3d() shade3d(octahedron3d(col=cols[3])); next3d() text3d(0,0,0,"dodecahedron3d"); next3d() shade3d(dodecahedron3d(col=cols[4])); next3d() text3d(0,0,0,"icosahedron3d"); next3d() shade3d(icosahedron3d(col=cols[5])); next3d() text3d(0,0,0,"cuboctahedron3d"); next3d() shade3d(cuboctahedron3d(col=cols[6])); next3d() text3d(0,0,0,"oh3d"); next3d() shade3d(oh3d(col=cols[7])) ``` A very large collection of polyhedra is contained in the `r linkfn("Rpolyhedra-package", text = "Rpolyhedra", pkg = "Rpolyhedra")` package. ### Generating new shapes These functions generate new shapes: Function | Description ------------------------------------ | ----------- `r indexfns("cylinder3d")`: | generate a tube or cylinder `r indexfns("polygon3d")`: | generate a flat polygon by triangulation `r indexfns("extrude3d")`: | generate an "extrusion" of a polygon `r indexfns("turn3d")`: | generate a solid of rotation `r indexfns("ellipse3d")`: | generate an ellipsoid in various ways `r indexfns("mesh3d")`: | generate a shape from indexed vertices `r indexfns("shapelist3d")`: | generate a shape by combining other shapes `as.mesh3d`: | a generic function; see below A related function is `r indexfns("triangulate")`, which takes a two dimensional polygon and divides it up into triangles using the "ear-clipping" algorithm. The generic function `r indexfns("as.mesh3d")` is provided to allow data structures produced by other code to be converted to mesh structures. Currently the following classes are supported: Class | Package | Description ----- | ------- | ----------- `r indexfns("deldir", pkg = "deldir")` | `deldir` | Delaunay triangulations of irregular point clouds `r indexfns("triSht", pkg = "interp")` | `interp` | Also Delaunay triangulations `r indexfns("tri", pkg = "tripack")` | `tripack` | Generalized Delaunay triangulations `r indexfns("ashape3d", pkg = "alphashape3d")` | `alphashape3d` | Alpha-shapes `r linkfn("rglId")` | `rgl` | `rgl` object identifiers The `r indexfns("checkDeldir")` function checks that a compatible version of the `deldir` package is installed. The default `r indexfns("as.mesh3d.default")` method is a simple way to construct a mesh from a matrix of vertices; it can use `r indexfns("mergeVertices")` (which can also be used on its own) to merge repeated vertices within the matrix, allowing `r linkfn("addNormals")` to be used to give a smooth appearance. The `r indexfns("as.tmesh3d")` generic is a variation that guarantees the resulting object will have no quad entries. Functions `r indexfns(c("tmesh3d","qmesh3d"))` are now obsolete; use `r linkfn("mesh3d")` instead. ### The underlying class structure for shapes `"shape3d"` is the basic abstract type. Objects of this class can be displayed by `r indexfns("shade3d")` (which shades faces), `r indexfns("wire3d")` (which draws edges), or `r indexfns("dot3d")` (which draws points at each vertex.) `"mesh3d"` is a descendant type. Objects of this type contain the following fields: Field | Meaning ------------ | --------------- vb | A 4 by n matrix of vertices in homogeneous coordinates. Each column is a point. ip | (optional) A vector of vertex indices for points. is | (optional) A 2 by s matrix of vertex indices. Each column is a line segment. it | (optional) A 3 by t matrix of vertex indices. Each column is a triangle. ib | (optional) A 4 by q matrix of vertex indices. Each column is a quadrilateral. material | (optional) A list of material properties. normals | (optional) A matrix of the same shape as vb, containing normal vectors at each vertex. texcoords | (optional) A 2 by n matrix of texture coordinates corresponding to each vertex. values | (optional) A vector of length n holding values at each vertex meshColor | (optional) A text value indicating how colors and texture coordinates should be interpreted. ### Contouring shapes These functions compute and plot contours of functions on surfaces, or clip objects along a contour of a function. Function | Description -------------------------------- | ----------- `r indexfns("contourLines3d")`: | draw contour lines on surface `r indexfns("filledContour3d")`: | fill between contours on surface `r indexfns("clipMesh3d")`: | clip mesh object using curved boundary `r indexfns("clipObj3d")`: | clip general object using curved boundary ### Manipulating shapes These functions manipulate and modify mesh objects: Function | Description ------------------------------------ | ----------- `r indexfns("addNormals")`: | add normal vectors to make a shape look smooth `r indexfns("subdivision3d")`: | add extra vertices to make it look even smoother `r indexfns("merge.mesh3d", backticked("merge"))`: | merge mesh objects `r indexfns("facing3d")`: | subset of mesh facing "up" `r indexfns("getBoundary3d")`: | get the boundary of a mesh object The individual steps in `r linkfn("subdivision3d")` are also available: `r indexfns(c("deform.mesh3d", "divide.mesh3d", "normalize.mesh3d"))`. These are mainly intended for internal use. ## Multi-figure Layouts `rgl` has several functions to support displaying multiple different "subscenes" in the same window. The high level functions are Function | Description ------------------------- | ----------- `r indexfns("mfrow3d")`: | Multiple figures (like `r linkfn("par", text = 'par("mfrow")', pkg="graphics")` `r indexfns("layout3d")`: | Multiple figures (like `r linkfn("layout", pkg="graphics")`) `r indexfns("next3d")`: | Move to the next figure (like `r linkfn("plot.new", pkg="graphics")` or `r linkfn("frame", pkg="graphics")`) `r indexfns("subsceneList")`: | List all the subscenes in the current layout `r indexfns("clearSubsceneList")`: | Clear the current list and revert to the previous one There are also lower level functions. Function | Description ---------------------------------- | ----------- `r indexfns("newSubscene3d")`: | Create a new subscene, with fine control over what is inherited from the parent `r indexfns("currentSubscene3d")`: | Report on the active subscene `r indexfns("subsceneInfo")`: | Get information on current subscene `r indexfns("useSubscene3d")`: | Make a different subscene active `r indexfns(c("addToSubscene3d", "delFromSubscene3d"))`: | Add objects to a subscene, or delete them `r indexfns("gc3d")`: | Do "garbage collection": delete objects that are not displayed in any subscene ## Documents with `rgl` Scenes The `rgl` package can produce output that can be embedded in other documents. The recommended way to do this has changed several times over the years. We will start with the current recommendation, then list older methods. ### The recommended method Currently the best way to embed an `rgl` scene in a document is to produce the document in HTML using R Markdown. Early in the document, you should have code like this in one of the setup code chunks: ````markdown `r ''````{r echo=FALSE, include=FALSE} library(rgl) setupKnitr(autoprint = TRUE) ``` ```` The call to `setupKnitr()` will install a number of hooks and set options in `knitr` so that `rgl` code is handled properly. The `autoprint = TRUE` argument makes `rgl` act in the document almost the same way it would act in the console, or the way base graphics are handled by `knitr`: If you print the value of high level `rgl` functions, a plot will be inserted into the output, but maybe only after low level modifications to it are complete. For example, this code block prints both triangles and spheres in a single plot at the end: ```{r} xyz <- matrix(rnorm(27), ncol = 3) triangles3d(xyz, col = rainbow(9)) spheres3d(xyz, col = rainbow(9), radius = 0.1) ``` There are a few differences if you have a complicated situation: - The mechanism depends on the result of the `rgl` function calls being automatically printed. If the calls are in a loop or other code block where automatic printing doesn't happen, you'll need some trickery to get things to print. For example, this will print three plots: ```{r eval = FALSE} plots <- NULL for (i in 1:3) { plot3d(rnorm(10), rnorm(10), rnorm(10)) plots <- htmltools::tagList(plots, rglwidget()) close3d() } plots ``` - It also depends on the fact that `rgl` functions return results using `lowlevel()` or `highlevel()` to mark which kind of plot they are. If you are using a function from another package to produce the plot, you may need to insert an explicit call to one of those to get it to print. Use `lowlevel()` if the function just modifies an existing plot, `highlevel()` if it starts a new one. For example, ```{r eval = FALSE} foreignHigh() # Produces a high level plot, but doesn't return # an appropriate value highlevel() foreignLow() # Modifies the previous plot lowlevel() ``` This should display the output at the end of the code chunk, when modifications are assumed complete. ### Producing PDF output While some PDF previewers support interactive 3D graphics, most don't. To produce a screenshot of an `rgl` scene in an R Markdown document with PDF output, simply follow the directions given above. The auto-printing will detect PDF output and use `snapshot3d` to produce a PNG file to insert. (See below if you want to insert a different format of graphic.) If you really need interactive output, see the `r linkfn("writeASY")` function. ### Manual insertion of plots You may not want to use the `setupKnitr(autoprint = TRUE)` method described above. It is very new, and may still have bugs; you may have an older document and not want to edit it to work that way. In this case, you can insert plots manually. Use setup code ````markdown `r ''````{r echo=FALSE, include=FALSE} library(rgl) setupKnitr() ``` ```` and call `rglwidget()` at top level whenever you want to insert a plot. There are a couple of other differences in default behaviour if you are not using `autoprint`: - By default, each code chunk continues the `rgl` scene from earlier chunks. You'll need an explicit `r linkfn("open3d")` call to get a clean window. - Also by default, the `rgl` window is not closed at the end of the chunk. This probably doesn't matter, but you may find you run out of memory if your scenes are really big. ### Older methods The original way to insert an `rgl` scene in a document was to use the `r indexfns("writeWebGL")` function to write HTML code to insert in a document. Later, `Sweave` and `knitr` hooks were added. These are no longer maintained, and it is recommended that you update old documents to use the newer methods. See the `r linkfn("writeWebGL")`, `r linkfn("rgl.Sweave")` and `r linkfn("hook_rgl")` help topics for details on these if you must use them. If you are reading documents that suggest using those methods, let the author know they need updating! ## Utility Functions ### User interaction By default, `rgl` detects and handles mouse clicks within your scene, and uses these to control its appearance. You can find out the current handlers using the following code: ```{r} par3d("mouseMode") ``` The labels `c("left", "right", "middle")` refer to the buttons on a three button mouse, or simulations of them on other mice. `"wheel"` refers to the mouse wheel, and `"none"` refers to actions that take place when the mouse is moved without pressing any button. The button actions generally correspond to click and drag operations. Possible values for `r indexfns("mouseMode", '"mouseMode"')` for the mouse pointer or wheel are as follows: Mode | Description -------------- | --------- `"none"` | No action `"trackball"` | The mouse acts as a virtual trackball. Clicking and dragging rotates the scene `"xAxis"`, `"yAxis"`, `"zAxis"` | Like `"trackball"`, but restricted to rotation about one axis `"polar"` | The mouse affects rotations by controlling polar coordinates directly `"selecting"` | The mouse is being used by the `r linkfn("select3d")` function `"zoom"` | The mouse zooms the display `"fov"` | The mouse affects perspective by changing the field of view `"pull"` | Rotating the mouse wheel towards the user "pulls the scene closer" `"push"` | The same rotation "pushes the scene away" `"user"` | A user action set by `r indexfns(c("setUserCallbacks", "rgl.setMouseCallbacks", "rgl.setWheelCallback"))`. Use `r indexfns("rgl.getMouseCallbacks")` and `r indexfns("rgl.getWheelCallback")` to retrieve. The following functions make use of the mouse for selection within a scene. Function | Description ---------------------------- | ----------- `r indexfns("identify3d")`: | like the classic graphics `r linkfn("identify", pkg="graphics")` function `r indexfns("select3d")`: | returns a function that tests whether a coordinate was selected `r indexfns("selectpoints3d")`: | selects from specific objects `r indexfns("selectionFunction3d")` produces the selection function from information about the projection and mouse selection region; it is used internally in the functions above. The `r indexfns("rgl.select3d")` function is an obsolete version of `select3d`, and `r indexfns("rgl.select")` is a low-level support function. ### Animations `rgl` has several functions that can be used to construct animations. These are based on functions that update the scene according to the current real-world time, and repeated calls to those. The functions are: Function | Description ---------------------- | ------------- `r indexfns("play3d")`: | Repeatedly call the update function `r indexfns("spin3d")`: | Update the display by rotating at a constant rate `r indexfns("par3dinterp")`: | Compute new values of some `r linkfn("par3d")` parameters by interpolation over time See the `r linkfn("movie3d")` function for a way to output an animation to a file on disk. Animations are not currently supported in the HTML written by `r linkfn("rglwidget")`, though the `playwidget` function provides equivalent functionality. ### Integration with TCL/TK There are three functions in `rgl` that support control of an `rgl` scene using the TCL/TK framework. Function | Description ---------------------- | ------------- `r indexfns("tkspin3d")`: | Set up buttons in a window to control a scene `r indexfns("tkspinControl")`: | Embed the control buttons in a separate TCL/TK frame `r indexfns("tkpar3dsave")`: | Create a dialog to interactively save mouse actions These functions were formerly contained (without the `tk` prefixes on their names) in the `tkrgl` package. That package is now deprecated. ### Exporting and importing scenes `rgl` contains several functions to write scenes to disk for use by other software, or to read them in. In order from highest fidelity to lowest, the functions are: Function | Description ----------- | ------------- `r indexfns("scene3d")`: | Save a scene to an R variable, which can be saved and reloaded `r indexfns("rglwidget")`: | Prints as HTML and Javascript to display a scene in a web browser. (See also [User Interaction in WebGL](WebGL.html).) `r linkfn("writeWebGL")`: | Deprecated. `r indexfns("writeASY")`: | Write files for Asymptote `r indexfns("writePLY")`: | Write PLY files (commonly used in 3D printing) `r indexfns(c("readOBJ", "writeOBJ"))`: | Read or write OBJ files (commonly used in 3D graphics) `r indexfns(c("readSTL", "writeSTL"))`: | Read or write STL files (also common in 3D printing) `r indexfns("as.rglscene")`: | Generic function, no methods in `rgl` The [`rgl2gltf`](https://dmurdoch.github.io/rgl2gltf/dev/) package can read or write GLTF and GLB files. It includes an `as.rglscene` method to convert GLTF objects to `rgl` scenes. The code in `rgl`'s `r indexfns("Buffer")` R6 class is based on the GLTF format. It is used by `r linkfn("rglwidget")` to make output webpages somewhat smaller than they were previously. There are also functions to save snapshots or other recordings of a scene, without any 3D information being saved: Function | Description ------------ | ------------- `r indexfns("snapshot3d")`: | Save a PNG file bitmap of the scene `r indexfns("rgl.postscript")`: | Save a Postscript, LaTeX, PDF, SVG or PGF vector rendering of the scene `r indexfns("movie3d")`: | Save a series of bitmaps to be assembled into a movie `r indexfns("rgl.pixels")`: | Obtain pixel-level information about the scene in an R variable `r indexfns("rgl.Sweave")`: | Driver function for inserting a snapshot into a Sweave document. `r indexfns(c("hook_rgl", "hook_webgl"))`: | `knitr` hook functions for inserting images into a document. `r indexfns("setupKnitr")`: | Function to set up `knitr` hooks The `r indexfns("rgl.snapshot")` function is a low level version of `snapshot3d()`; it requires that the `rgl` display be onscreen and copies from there. `snapshot3d()` tries to use the `webshot2` package so it will work even with no display. The functions `r indexfns(c("rgl.Sweave.off", "Sweave.snapshot"))` are involved in Sweave processing and not normally called by users. ### Default display There are two ways in which `rgl` scenes are normally displayed within R. The older one is in a dedicated window. In Unix-alikes this is an X11 window; it is a native window in Microsoft Windows. On macOS, the XQuartz system (see https://www.xquartz.org) needs to be installed to support this. To suppress this display, set `options(rgl.useNULL = TRUE)` before opening a new `rgl` window. See the help page for the `r indexfns("rgl.useNULL")` function for how to set this before starting R. The newer way to display a scene is by using WebGL in a browser window or in the Viewer pane in RStudio. To select this, set `options(rgl.printRglwidget = TRUE)`. Each operation that would change the scene will return a value which triggers a new WebGL display when printed. ### Working with WebGL scenes You should use the following scheme for exporting a scene to a web page. There's also an older scheme, which is no longer supported. The recommended approach works with the `htmlwidgets` framework (see http://www.htmlwidgets.org/). In an R Markdown document in `knitr`, use the `r linkfn("rglwidget")` function. (You can also use chunk option `webgl=TRUE`; we recommend the explicit use of `rglwidget`.) This approach also allows display of `rgl` scenes in [RStudio](https://www.rstudio.com/). Besides `rgl` scenes, various controls for them can be displayed, and there are a few utility functions that can be useful: Function | Description ------------------------------------ | ------------- `r indexfns("propertyControl")`: | set individual properties `r indexfns("clipplaneControl")`: | control a clipping plane `r indexfns("subsetControl")`: | control which objects are displayed `r indexfns("ageControl")`: | "age" vertices of an object `r indexfns("vertexControl")`: | control properties of vertices `r indexfns("par3dinterpControl")`: | WebGL control like `r linkfn("par3dinterp")` `r indexfns("playwidget")`: | display and automate controls `r indexfns("toggleWidget")`: | display a button to toggle some items `r documentedfns <- c(documentedfns, "%>%");indexfns("pipe", text="%>%")`: | `magrittr` pipe `r indexfns(c("figHeight", "figWidth"))`: | Dimensions of figures in R Markdown document `r indexfns("rglShared")`: | share data using `crosstalk` package `r indexfns("rglMouse")`: | change mouse mode in RGL scene `r indexfns("asRow")`: | arrange multiple objects in an HTML display `r indexfns("getWidgetId")`: | get the `elementId` from a widget These functions work with the above scheme in Shiny apps: Function | Description ------------------------------------ | ------------- `r indexfns("sceneChange")`: | used in `Shiny` for large scene changes `r indexfns(c("shinyGetPar3d", "shinySetPar3d"))`: | get or set `r linkfn("par3d")` values from Shiny `r indexfns("shinyResetBrush")`: | reset the mouse brush in Shiny The `r linkfn("selectionFunction3d")` function is also likely to be involved in mouse interactions when using Shiny. Some functions are mainly for internal use: `r indexfns(c("elementId2Prefix", "playwidgetOutput", "renderPlaywidget", "rglwidgetOutput", "renderRglwidget", "registerSceneChange"))`. More details are given in the vignette [User Interaction in WebGL](WebGL.html). The functions `r indexfns(c("lowlevel", "highlevel", "rglId"))` are also for internal use, marking function results for automatic printing. Finally, the experimental function `r indexfns("setUserShaders")` allows you to use hand-written shaders in WebGL. The older approach uses the `r linkfn("writeWebGL")` function to export a scene to HTML and Javascript code. These functions write HTML and Javascript for working with the exported scene: `r indexfns("propertySlider")`, `r indexfns("clipplaneSlider")`, `r indexfns("subsetSlider")`, `r indexfns("toggleButton")`, `r indexfns("propertySetter")`, `r indexfns("subsetSetter")`, `r indexfns("ageSetter")`, `r indexfns("par3dinterpSetter")`, `r indexfns("vertexSetter")`, `r indexfns("matrixSetter")`. Use the newer functions instead. ### Working with the scene `rgl` maintains internal structures for all the scenes it displays. The following functions allow users to find information about them and manipulate them. In cases where there are both `*3d` and `rgl.*` versions of functions, most users should use the `*3d` version: the `rgl.*` functions are more primitive and are mainly intended for internal use. Function | Description ------------------------------------ | ----------- `r indexfns("open3d")`: | open a new window `r indexfns(c("close3d", "rgl.close"))`: | close the current window `r indexfns(c("cur3d", "rgl.cur"))`: | id of the active device `r indexfns(c("set3d", "rgl.set"))`: | set a particular device to be active `r indexfns(c("pop3d", "rgl.pop"))`: | delete objects from the scene `r indexfns(c("clear3d", "rgl.clear"))`: | delete all objects of certain classes `r indexfns(c("ids3d", "rgl.ids"))`: | ids, types and tags of current objects `r indexfns("tagged3d")`: | find tags or objects with tags These functions are mainly intended for programming, and have no corresponding `*3d` counterparts: Function | Description ------------- | ----------- `r indexfns("rgl.bringtotop")`: | bring the current window to the top `r indexfns("rgl.dev.list")`: | ids of all active devices `r indexfns(c("rgl.attrib", "rgl.attrib.info", "rgl.attrib.count"))`: | attributes of objects in the scene `r indexfns("rgl.projection")`: | return information about the current projection `r indexfns(c("rgl.user2window", "rgl.window2user"))`: | convert between coordinates in the current projection The `r indexfns("as.triangles3d")` generic function is intended to extract coordinates in a form suitable for passing to `r linkfn("triangles3d")`. Currently a method is provided for `r linkfn("rglId")` objects. In addition to these, there are some other related functions which should rarely be called by users: `r indexfns(c("rgl.init", "rgl.open", "rgl.quit"))`. ### Working with 3-D vectors Most `rgl` functions work internally with "homogeneous" coordinates. In this system, 3-D points are represented with 4 coordinates, generally called (x, y, z, w). The corresponding Euclidean point is (x/w, y/w, z/w), if w is nonzero; zero values of w correspond to "points at infinity". The advantage of this system is that affine transformations including translations and perspective shifts become linear transformations, with multiplication by a 4 by 4 matrix. `rgl` has the following functions to work with homogeneous coordinates: Function | Description ------------------------------------ | ----------- `r indexfns(c("asEuclidean", "asHomogeneous"))`: | convert between homogeneous and Euclidean coordinates when x, y and z are columns `r indexfns(c("asEuclidean2", "asHomogeneous2"))`: | convert when x, y and z are rows `r indexfns(c("rotate3d", "scale3d", "translate3d"))`: | apply a transformation `r indexfns("transform3d")`: | apply a general transformation `r indexfns(c("rotationMatrix", "scaleMatrix", "translationMatrix"))`: | compute the transformation matrix `r indexfns("identityMatrix")`: | return a 4 x 4 identity matrix `r indexfns("projectDown")`: | a 3D to 2D projection down a vector There is also a function `r indexfns("GramSchmidt")`, mainly for internal use: it does a Gram-Schmidt orthogonalization of a 3x3 matrix, with some specializations for its use in `r linkfn("cylinder3d")`. ### Working with other packages Sometimes it may be convenient to interactively rotate a scene to a particular view, then display it in `lattice` or base graphics. The `r indexfns("rglToLattice")` and `r indexfns("rglToBase")` functions support this. For example, we first display the volcano data in `rgl`: ```{r echo = 2:3} close3d() persp3d(volcano, col = "green") ``` This display is interactive, but we can reproduce the initial view using the `lattice` `r linkfn("wireframe", pkg = "lattice")` or base graphics `r linkfn("persp", pkg = "graphics")` functions: ```{r} lattice::wireframe(volcano, col = "green", screen = rglToLattice()) angles <- rglToBase() persp(volcano, col = "green", shade = TRUE, theta = angles$theta, phi = angles$phi) ``` Note that the `orientlib` package must be available for these functions to work. ### Creating `pkgdown` websites The ["Using RGL in pkgdown web sites"](pkgdown.html) vignette describes how to use `rgl` in a `pkgdown` web site. The utility function `r indexfns("in_pkgdown_example")` can be used to detect that `pkgdown` is being used. ### Working with `testthat` The `testthat` package is widely used for unit tests in packages. Such tests are hard to write with `rgl`, because the output is visual and interactive rather than a simple value. The `r indexfns("expect_known_scene")`, `r indexfns("compare_proxy.mesh3d")` and `r indexfns("all.equal.mesh3d")` functions help with this by removing system-dependent features of `rgl` output. ### Working with Javascript The WebGL displays created using `r linkfn("rglwidget")` rely on a large body of Javascript code included in this package. To help in development of this code, the `r indexfns("makeDependency")` function was written. It may be useful in other packages that include Javascript. ### Other functions This section is for miscellaneous functions that don't fall in any of the other categories in this document. The `r indexfns("setGraphicsDelay")` function is designed to work around what appears to be a bug on macOS: if a standard plot window is opened too quickly after an `rgl` window, R can crash. This function inserts a one second delay when it appears to be needed. ## Warning: Work in Progress! This vignette is always a work in progress. Some aspects of the `rgl` package are not described, or do not have examples. There may even be functions that are missed completely, if the following list is not empty: ```{r echo=FALSE} setdiff(ls("package:rgl"), documentedfns) ``` ## Index of Functions The following functions and constants are described in this document:
```{r echo=FALSE, results="asis"} writeIndex(cols = if (knitr::is_html_output()) 5 else 4) ``` rgl/vignettes/pkgdown.Rmd0000644000176200001440000000772014145464133015176 0ustar liggesusers--- title: "Using RGL in pkgdown web sites" author: "Duncan Murdoch" output: rmarkdown::html_vignette: fig_height: 5 fig_width: 5 toc: yes pdf_document: fig_height: 5 fig_width: 5 toc: yes html_document: default vignette: > %\VignetteIndexEntry{Using RGL in pkgdown web sites} %\VignetteEngine{knitr::rmarkdown} --- ```{r setup, include=FALSE} if (!requireNamespace("rmarkdown", quietly = TRUE) || !rmarkdown::pandoc_available("1.14")) { warning(call. = FALSE, "These vignettes assume rmarkdown and pandoc version 1.14. These were not found. Older versions will not work.") knitr::knit_exit() } knitr::opts_chunk$set(echo = TRUE) library(rgl) options(rgl.useNULL = TRUE) setupKnitr(autoprint = TRUE) ``` ## What is the problem? [pkgdown](https://pkgdown.r-lib.org/) is an R package that makes it easy to build a web site for your package. However, the current version 1.6.1 on CRAN doesn't work so well for packages whose examples use RGL or other packages like [leaflet](http://rstudio.github.io/leaflet/) that use [htmlwidgets](http://www.htmlwidgets.org). This document describes current progress in supporting both of these. The main problem for [pkgdown](https://pkgdown.r-lib.org/) support is that RGL and other [htmlwidgets](http://www.htmlwidgets.org) users require multiple Javascript libraries to be linked to each web page. `pkgdown` 1.6.1 can't do this, but the current development version on Github adds support for additional dependent libraries. This also require [downlit](https://downlit.r-lib.org/) version 0.4.0 or higher. ## Installing the changes Installing the changes is fairly easy. Make sure you have the [remotes](https://remotes.r-lib.org/) package installed, then run ```{r eval=FALSE} remotes::install_github(c("rstudio/webshot2", "rstudio/chromote", "r-lib/pkgdown")) ``` With these development version packages installed, you should see RGL or `leaflet` output appear automatically in examples. The RGL output is set up to mimic what would happen in a `knitr` document that uses ```{r eval=FALSE} setupKnitr(autoprint = TRUE) ``` i.e. the output RGL commands will automatically be included in the display. Low-level changes will be collected into a single display: ```{r} # Show regression plane with z as dependent variable library(rgl) open3d() x <- rnorm(100) y <- rnorm(100) z <- 0.2*x - 0.3*y + rnorm(100, sd = 0.3) fit <- lm(z ~ x + y) plot3d(x, y, z, type = "s", col = "red", size = 1) # No plot here, because of the planes3d() call below coefs <- coef(fit) a <- coefs["x"] b <- coefs["y"] c <- -1 d <- coefs["(Intercept)"] planes3d(a, b, c, d, alpha = 0.5) ``` ## Specifying the size of figures By default, pkgdown generates standard plots which are wider than they are high (according to the golden ratio). Often RGL plots look better with equal width and height, since the contents may be rotated by the user. To specify the size of plots in pkgdown, you use the `figures` entry in `_pkgdown.yml`. The defaults are similar to ``` figures: dev: ragg::agg_png dpi: 96 dev.args: [] fig.ext: png fig.width: 7 fig.height: ~ fig.retina: 2 fig.asp: 1.618 bg: NA other.parameters: [] ``` By default RGL uses these parameters as well, but allows you to override any of `fig.width`, `fig.height` and `fig.asp` by specifying an `rgl` entry in `other.parameters`. For example: ``` figures: fig.width: 5 other.parameters: rgl: fig.asp: 1 ``` This will make all plots have a width of 5 inches and will make RGL plots square. ## Is this safe to use? These are development versions of the packages, so they may contain bugs, either in my changes or in other unreleased changes. I don't recommend you use them in regular production code. To re-install released versions of the packages, run ```{r eval=FALSE} install.packages(c("pkgdown", "rgl")) ``` If you do use them and notice any bugs, please [report them](https://github.com/dmurdoch/rgl/issues)! rgl/vignettes/transparency.Rmd0000644000176200001440000001474314100762641016235 0ustar liggesusers--- title: "A Note on Transparency" author: "Duncan Murdoch" date: "24/10/2020" output: rmarkdown::html_vignette: fig_height: 5 fig_width: 5 toc: yes pdf_document: fig_height: 5 fig_width: 5 toc: yes html_document: default vignette: > %\VignetteIndexEntry{A Note on Transparency} %\VignetteEngine{knitr::rmarkdown} --- ```{r setup, include=FALSE} if (!requireNamespace("rmarkdown", quietly = TRUE) || !rmarkdown::pandoc_available("1.14")) { warning(call. = FALSE, "These vignettes assume rmarkdown and pandoc version 1.14. These were not found. Older versions will not work.") knitr::knit_exit() } knitr::opts_chunk$set(echo = TRUE) library(rgl) options(rgl.useNULL = TRUE) setupKnitr(autoprint = TRUE) M <- structure(c(0.997410774230957, 0.0707177817821503, -0.0130676832050085, 0, -0.0703366547822952, 0.99714070558548, 0.02762770652771, 0, 0.0149840852245688, -0.0266370177268982, 0.999532878398895, 0, 0, 0, 0, 1), .Dim = c(4L, 4L)) ``` ## Introduction When drawing transparent surfaces, `rgl` tries to sort objects from back to front to get better rendering of transparency. However, it doesn't sort each pixel separately, so some pixels end up drawn in the incorrect order. This note describes the consequences of that error, and suggests remedies. ## Correct Drawing We'll assume that the standard `glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)` blending is used. That is, when drawing with transparency $\alpha$, the new colour is mixed at proportion $\alpha$ with the colour previously drawn (which gets weight $1-\alpha$.) This note is concerned with what happens when two transparent objects are drawn at the same location. We suppose the further one has transparency $\alpha_1$, and the closer one has transparency $\alpha_2$. If they are drawn in the correct order (further first), the three colours (background, further object, closer object) should end up mixed in proportions $C = [(1-\alpha_1)(1-\alpha_2), \alpha_1(1-\alpha_2), \alpha_2]$ respectively. ## Incorrect sorting If the objects are drawn in the wrong order, the actual proportions of each colour will be $N = [(1-\alpha_1)(1-\alpha_2), \alpha_1, \alpha_2(1-\alpha_1)]$ if no masking occurs. `rgl` currently defaults to depth masking using `glDepthMask(GL_TRUE)`. This means that depths are saved when the objects are drawn, and if an attempt is made to draw the further object after the closer one (i.e. as here), the further object will be culled, and the proportions will be $M = [(1-\alpha_2), 0, \alpha_2]$. ## Mask or Not? The question is: which is better, `glDepthMask(GL_TRUE)` or `glDepthMask(GL_FALSE)`? One way to measure this is to measure the distance between $C$ and the incorrect proportions. (This is unlikely to match perceptual distance, which will depend on the colours as well, but we need something. Some qualitative comments below.) So we have \[|C-N|^2 = 2\alpha_1^2\alpha_2^2\], and \[|C-M|^2 = 2\alpha_1^2(1-\alpha_2)^2\]. Thus the error is larger with $N$ when $\alpha_2 > 1/2$, and larger with $M$ when $\alpha_2 < 1/2$. The value of $\alpha_1$ doesn't affect the preference, though small values of $\alpha_1$ will be associated with smaller errors. Depending on the colours of the background and the two objects, this recommendation could be modified. For example, if the two objects are the same colour (or very close), it doesn't really matter how the 2nd and 3rd proportions are divided up, and $N$ will be best because it gets the background proportion exactly right. ## Recommendation Typically in `rgl` we don't know which object will be closer and which one will be further, so we can't base our choice on a single $\alpha_i$. The recommendation would be to use all small levels of `alpha` and disable masking, or use all large values of `alpha` and retain masking. ## Example The classic example of an impossible to sort scene involves three triangles arranged cyclicly so each one is behind one and in front of one of the others (based on https://paroj.github.io/gltut/Positioning/Tut05%20Overlap%20and%20Depth%20Buffering.html). ```{r} theta <- 2*pi*c(0:2, 4:6, 8:10)/12 x <- cos(theta) y <- sin(theta) z <- rep(c(0,0,1), 3) xyz <- cbind(x, y, z) xyz <- xyz[c(1,2,6, 4,5,9, 7,8,3),] open3d() par3d(userMatrix = M) triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3)) ``` To see the effect of the calculations above, consider the following four displays. ```{r fig.width=8} open3d() par3d(userMatrix = M) layout3d(matrix(1:9, ncol = 3, byrow=TRUE), widths = c(1,2,2), heights = c(1, 3,3), sharedMouse = TRUE) text3d(0,0,0, " ") next3d() text3d(0,0,0, "depth_mask = TRUE") next3d() text3d(0,0,0, "depth_mask = FALSE") next3d() text3d(0,0,0, "alpha = 0.7") next3d() triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3), alpha = 0.7, depth_mask = TRUE) next3d() triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3), alpha = 0.7, depth_mask = FALSE) next3d() text3d(0,0,0, "alpha = 0.3") next3d() triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3), alpha = 0.3, depth_mask = TRUE) next3d() triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3), alpha = 0.3, depth_mask = FALSE) ``` As you rotate the figures, you can see imperfections in rendering. On the right, the last drawn appears to be on top, while on the left, the first drawn appears more opaque than it should. In the figure below, the three triangles each have different transparency, and each use the recommended setting: ```{r} open3d() par3d(userMatrix = M) triangles3d(xyz[1:3,], col = "red", alpha = 0.3, depth_mask = FALSE) triangles3d(xyz[4:6,], col = "green", alpha = 0.7, depth_mask = TRUE) triangles3d(xyz[7:9,], col = "blue", depth_mask = TRUE) ``` In this figure, all three triangles are the same colour, only lighting affects the display: ```{r fig.width=8} open3d() par3d(userMatrix = M) layout3d(matrix(1:9, ncol = 3, byrow=TRUE), widths = c(1,2,2), heights = c(1, 3,3), sharedMouse = TRUE) text3d(0,0,0, " ") next3d() text3d(0,0,0, "depth_mask = TRUE") next3d() text3d(0,0,0, "depth_mask = FALSE") next3d() text3d(0,0,0, "alpha = 0.7") next3d() triangles3d(xyz, col = "red", alpha = 0.7, depth_mask = TRUE) next3d() triangles3d(xyz, col = "red", alpha = 0.7, depth_mask = FALSE) next3d() text3d(0,0,0, "alpha = 0.3") next3d() triangles3d(xyz, col = "red", alpha = 0.3, depth_mask = TRUE) next3d() triangles3d(xyz, col = "red", alpha = 0.3, depth_mask = FALSE) ``` Here `depth_mask = FALSE` seems to be the right choice in both cases.rgl/vignettes/WebGL.Rmd0000644000176200001440000004006514145464133014464 0ustar liggesusers--- title: "User Interaction in WebGL (updated)" author: "Duncan Murdoch" date: "`r format(Sys.time(), '%B %d, %Y')`" output: rmarkdown::html_vignette: toc: yes fig_width: 5 fig_height: 5 vignette: > %\VignetteIndexEntry{User Interaction in WebGL (updated)} %\VignetteEngine{knitr::rmarkdown} --- ```{r setup, echo=FALSE, results="asis"} source("setup.R") setupKnitr(autoprint = FALSE) set.seed(123) ``` ## Introduction This document describes how to embed `rgl` scenes in HTML documents and use embedded Javascript to control a WebGL display in an HTML document. For more general information about `rgl`, see [rgl Overview](rgl.html). We assume that the HTML document is produced from R markdown source using `knitr` or `rmarkdown`. This format mixes text with Markdown markup with chunks of R code. There is a limited amount of discussion of other methods. There are two ways to embed an `rgl` scene in the document. The newest one is recommended: call `r linkfn("setupKnitr")` with argument `autoprint = TRUE` early in the document. This will set things up to be quite similar to the way standard 2D graphics are included by `knitr`, i.e. it will detect the fact that you've drawn something, and just include it automatically. If `autoprint = FALSE` is used or no call is made to `setupKnitr()`, an explicit call to `r linkfn("rglwidget")` will produce a "widget" which can be embedded into your document by printing it. This document uses that method. Older methods (e.g. `writeWebGL` or various hooks) that were used before `rgl` version 0.102.0 are no longer supported. ## Browser support Most browsers now support WebGL, but in some browsers it may be disabled by default. See https://get.webgl.org for help on a number of different browsers. ## Examples We start with a simple plot of the iris data. We insert a code chunk and call the `r linkfn("rglwidget")` function with optional argument `elementId`. This allows later Javascript code to refer to the image. We also save the object ids from the plot, so that they can be manipulated later. (The first example in [Controls](#controls) uses tags instead of saving the ids.) ```{r} library(rgl) plotids <- with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length, type="s", col=as.numeric(Species))) rglwidget(elementId = "plot3drgl") ``` Next we insert a button to toggle the display of the data. ```{r} toggleWidget(sceneId = "plot3drgl", ids = plotids["data"], label = "Data") ``` The `sceneId` is the same as the `elementId` we used in `rglwidget()`, the `ids` are the object ids of the objects that we'd like to toggle, and the `label` is the label shown on the button. To find the names in the `plotids` variable, apply `names()` or `unclass()`: ```{r} names(plotids) unclass(plotids) ``` ## Using `magrittr` or base pipes It can be error-prone to set the `elementId` in the `rglwidget()` to match the `sceneId` in the `toggleWidget()` (or `playwidget()`, described below). In the usual case where both are intended to appear together, [`magrittr`](https://CRAN.R-project.org/package=magrittr)-style pipes can be used quite flexibly: the first argument of the control widget accepts the result of `rglwidget()` (or other control widgets), and the `controllers` argument of `rglwidget()` accepts control widgets. In R 4.1.0, the new base pipe operator `|>` should be usable in the same way. For example, ```{r} rglwidget() %>% toggleWidget(ids = plotids["data"], label = "Data") ``` If you have R 4.1.0 or greater, this should do the same: ```{r eval=FALSE} rglwidget() |> toggleWidget(ids = plotids["data"], label = "Data") ``` You can swap the order of button and scene; use the `magrittr` dot (or the `=>` syntax in base pipes) to pass the `toggleWidget` to `rglwidget` in the `controllers` argument: ```{r} toggleWidget(NA, ids = plotids["data"], label = "Data") %>% rglwidget(controllers = .) ``` or using R 4.1.0 or later, ```{r eval=FALSE} toggleWidget(NA, ids = plotids["data"], label = "Data") |> w => rglwidget(controllers = w) ``` ## Controls We have seen how to change the contents of the plot using `r indexfns("toggleWidget")`. We can do more elaborate displays. For example, we can redo the previous plot, but with the three species as separate "spheres" objects and buttons to toggle them: ```{r} clear3d() # Remove the earlier display with(subset(iris, Species == "setosa"), spheres3d(Sepal.Length, Sepal.Width, Petal.Length, col=as.numeric(Species), radius = 0.211, tag = "setosa")) with(subset(iris, Species == "versicolor"), spheres3d(Sepal.Length, Sepal.Width, Petal.Length, col=as.numeric(Species), radius = 0.211, tag = "versicolor")) with(subset(iris, Species == "virginica"), spheres3d(Sepal.Length, Sepal.Width, Petal.Length, col=as.numeric(Species), radius = 0.211, tag = "virginica")) aspect3d(1,1,1) decorate3d(tag = "axes") rglwidget() %>% toggleWidget(tags = "setosa") %>% toggleWidget(tags = "versicolor") %>% toggleWidget(tags = "virginica") %>% toggleWidget(tags = "axes") %>% asRow(last = 4) ``` Since we skipped the `label` argument, the buttons are labelled with the values of the tags. The `asRow` function is discussed `r linkfn("asRow", "below")`. `toggleWidget()` is actually a convenient wrapper for two functions: `r indexfns("playwidget")` and `r indexfns("subsetControl")`. `playwidget()` adds the button to the web page (and can also add sliders, do animations, etc.), while `subsetControl()` chooses a subset of objects to display. ### `subsetControl` For a more general example, we could use a slider to select several subsets of the data in the iris display. For example, ```{r} rglwidget() %>% playwidget(start = 0, stop = 3, interval = 1, subsetControl(1, subsets = list( Setosa = tagged3d("setosa"), Versicolor = tagged3d("versicolor"), Virginica = tagged3d("virginica"), All = tagged3d(c("setosa", "versicolor", "virginica")) ))) ``` There are several other "control" functions. ### `par3dinterpControl` `r indexfns("par3dinterpControl")` approximates the result of `r linkfn("par3dinterp")`. For example, the following code (similar to the `r linkfn("play3d")` example) rotates the scene in a complex way. ```{r} M <- r3dDefaults$userMatrix fn <- par3dinterp(time = (0:2)*0.75, userMatrix = list(M, rotate3d(M, pi/2, 1, 0, 0), rotate3d(M, pi/2, 0, 1, 0)) ) rglwidget() %>% playwidget(par3dinterpControl(fn, 0, 3, steps=15), step = 0.01, loop = TRUE, rate = 0.5) ``` Some things to note: The generated Javascript slider has 300 increments, so that motion appears smooth. However, storing 300 `userMatrix` values would take up a lot of space, so we use interpolation in the Javascript code. However, the Javascript code can only do linear interpolation, not the more complex spline-based SO(3) interpolation done by `r linkfn("par3dinterp")`. Because of this, we need to output 15 steps from `r linkfn("par3dinterpControl")` so that the distortions of linear interpolation are not visible. ### `propertyControl` `r indexfns("propertyControl")` is a more general function to set the value of properties of the scene. Currently most properties are supported, but use does require knowledge of the internal implementation. ### `clipplaneControl` `r indexfns("clipplaneControl")` allows the user to control the location of a clipping plane by moving a slider. ### `vertexControl` Less general than `r linkfn("propertyControl")` is `r indexfns("vertexControl")`. This function sets attributes of individual vertices in a scene. For example, to set the x-coordinate of the closest point in the setosa group, and modify its colour from black to white, ```{r} setosavals <- subset(iris, Species == "setosa") which <- which.min(setosavals$Sepal.Width) init <- setosavals$Sepal.Length[which] rglwidget() %>% playwidget( vertexControl(values = matrix(c(init, 0, 0, 0, 8, 1, 1, 1), nrow = 2, byrow = TRUE), attributes = c("x", "red", "green", "blue"), vertices = which, tag = "setosa"), step = 0.01) ``` ### `ageControl` A related function is `r indexfns("ageControl")`, though it uses a very different specification of the attributes. It is used when the slider controls the "age" of the scene, and attributes of vertices change with their age. To illustrate we will show a point moving along a curve. We give two `ageControl` calls in a list; the first one controls the colour of the trail, the second controls the position of the point: ```{r} time <- 0:500 xyz <- cbind(cos(time/20), sin(time/10), time) lineid <- plot3d(xyz, type="l", col = "black")["data"] sphereid <- spheres3d(xyz[1, , drop=FALSE], radius = 8, col = "red") rglwidget() %>% playwidget(list( ageControl(births = time, ages = c(0, 0, 50), colors = c("gray", "red", "gray"), objids = lineid), ageControl(births = 0, ages = time, vertices = xyz, objids = sphereid)), start = 0, stop = max(time) + 20, rate = 50, components = c("Reverse", "Play", "Slower", "Faster", "Reset", "Slider", "Label"), loop = TRUE) ``` ### `rglMouse` While not exactly a control in the sense of the other functions in this section, the `r indexfns("rglMouse")` function is used to add an HTML control to a display to allow the user to select the mouse mode. For example, the display below initially allows selection of particular points, but the mouse mode may be changed to let the user rotate the display for a another view of the scene. ```{r eval = requireNamespace("crosstalk")} # This example requires the crosstalk package # We skip it if crosstalk is not available. ids <- with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length, type="s", col=as.numeric(Species))) par3d(mouseMode = "selecting") rglwidget(shared = rglShared(ids["data"])) %>% rglMouse() ``` The `rglShared()` call used here is described `r linkfn("rglShared", "below")`. ## Layout of the display Many `rgl` displays will contain several elements: one or more `rgl` scenes and controls. Internally `rgl` uses the `combineWidgets` function from the [`manipulateWidget`](https://github.com/rte-antares-rpackage/manipulateWidget) package. The `rgl` package provides 3 convenience functions for arranging displays. We have already met the first: the `magrittr` pipe, `%>%`. When the display is constructed as a single object using pipes, the objects in the pipeline will be arranged in a single column. The second convenience function is `r indexfns("asRow")`. This takes as input a list of objects or a `combineWidgets` object (perhaps the result of a pipe), and rearranges (some of) them into a horizontal row. As in the `r linkfn("toggleWidget", "toggleWidget example")`, the `last` argument can be used to limit the actions of `asRow` to the specified number of components. (If `last = 0`, all objects are stacked: this can be useful if some of them are not from the `rgl` package, so piping doesn't work for them.) Finally, `r indexfns("getWidgetId")` can be used to extract the HTML element ID from an HTML widget. This is useful when combining widgets that are not all elements of the same pipe, as in the `crosstalk` example below. If these convenience functions are not sufficient, you can call `r linkfn("combineWidgets", text = "manipulateWidget::combineWidgets", pkg = "manipulateWidget")` or other functions from `manipulateWidget` for more flexibility in the display arrangements. ## Integration with `crosstalk` The [`crosstalk`](https://rstudio.github.io/crosstalk/) package allows widgets to communicate with each other. Currently it supports selection and filtering of observations. `rgl` can send, receive and display these messages. An `rgl` display may have several subscenes, each displaying different datasets. Each object in the scene is potentially a shared dataset in the `crosstalk` sense. The linking depends on the `r indexfns("rglShared")` function. Calling `rglShared(id)`, where `id` is the `rgl` id value for an object in the current scene, creates a shared data object containing the coordinates of the vertices of the `rgl` object. This object is passed to `r linkfn("rglwidget")` in the `shared` argument. It can also be passed to other widgets that accept shared data, linking the two displays. If a shared data object has been created in some other way, it can be linked to a particular `rgl` `id` value by copying its `key` and `group` properties as shown in the example below. ```{r eval=requireNamespace("crosstalk")} # This example requires the crosstalk package. # We skip it if crosstalk is not available. library(crosstalk) sd <- SharedData$new(mtcars) ids <- plot3d(sd$origData(), col = mtcars$cyl, type = "s") # Copy the key and group from existing shared data rglsd <- rglShared(ids["data"], key = sd$key(), group = sd$groupName()) rglwidget(shared = rglsd) %>% asRow("Mouse mode: ", rglMouse(getWidgetId(.)), "Subset: ", filter_checkbox("cylinderselector", "Cylinders", sd, ~ cyl, inline = TRUE), last = 4, colsize = c(1,2,1,2), height = 60) ``` If multiple objects in the `rgl` scene need to be considered as shared data, you can pass the results of several `rglShared()` calls in a list, i.e. `rglwidget(shared = )`. The key values will be assumed to be shared across datasets; if this is not wanted, use a prefix or some other means to make sure they differ between objects. If the same `rgl` id is used in more than one `rglShared()` object, it will respond to messages from all of them. This may lead to undesirable behaviour as one message cancels the previous one. ## Low level controls We repeat the initial plot from this document: ```{r plot3d2} plotids <- with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length, type="s", col=as.numeric(Species))) subid <- currentSubscene3d() rglwidget(elementId="plot3drgl2") ``` We might like a button on the web page to cause a change to the display, e.g. a rotation of the plot. First we add buttons, with the "onclick" event set to a function described below: which produces these buttons: We stored the subscene number that is currently active in `subid` in the code chunk above, and use it as `r rinline("subid")` in the script below. `knitr` substitutes the value when it processes the document. The `rotate()` function uses the Javascript function `document.getElementById` to retrieve the `
` component of the web page containing the scene. It will have a component named `rglinstance` which contains information about the scene that we can modify: If we had used `webGL=TRUE` in the chunk header, the `knitr` WebGL support would create a global object with a name of the form `rgl`. For example, if the code chunk was named `plot3d2`, the object would be called `plot3d2rgl`, and this code would work: ## Index The following functions are described in this document:
```{r echo=FALSE, results="asis"} writeIndex(cols = 5) ``` rgl/configure.win0000644000176200001440000000004414100762640013534 0ustar liggesusers# No configuration needed on Windowsrgl/COPYING0000644000176200001440000004311214100762640012072 0ustar liggesusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. rgl/R/0000755000176200001440000000000014146473375011255 5ustar liggesusersrgl/R/triangulate.R0000644000176200001440000002141614100762640013705 0ustar liggesusers pointInPoly <- function(poly, pt) { # polygon is 2 x n, columns are vertices # point is 2 vector n <- ncol(poly) i1 <- seq_len(n) i2 <- i1 %% n + 1 x <- poly[1,i1] + (poly[1,i2] - poly[1,i1])*(pt[2] - poly[2,i1])/(poly[2,i2] - poly[2,i1]) crossings <- ((poly[2,i1] < pt[2]) & (pt[2] <= poly[2,i2]) | (poly[2,i2] < pt[2]) & (pt[2] <= poly[2,i1])) & pt[1] < x sum(crossings) %% 2 == 1 } intersectSegSeg <- function(seg1,seg2) { # do segments intersect? # both segments have endpoints as columns coeffs <- try(solve(cbind(seg1[,2]-seg1[,1], seg2[,1]-seg2[,2]), seg2[,1]-seg1[,1]), silent=TRUE) if (inherits(coeffs, "try-error")) return(FALSE) all(zapsmall(coeffs) >= 0) && all(zapsmall(1-coeffs) >= 0) } intersectTriSeg <- function(tri, seg) { # intersect a triangle with a segment # tri is 2 x 3, columns are vertices # seg is 2 x 2, columns are endpoints coeffs <- try(solve(rbind(tri,1), rbind(seg,1)), silent=TRUE) if (inherits(coeffs, "try-error")) return(TRUE) coeffs <- zapsmall(coeffs) if (any(apply(coeffs <= 0, 1, all))) return(FALSE) if (any(apply(coeffs > 0, 2, all))) return(TRUE) up <- coeffs[,1] < 0 dn <- coeffs[,2] < 0 lb <- max( -coeffs[up,1]/(coeffs[up,2]-coeffs[up,1]) ) ub <- 1 - max( -coeffs[dn,2]/(coeffs[dn,1] - coeffs[dn,2]) ) lb <= ub } triangulateSimple <- function(x,y, random=TRUE, plot=FALSE, partial=NA) { n <- length(x) stopifnot(n == length(y)) stopifnot(n > 2) it <- matrix(NA_integer_, nrow=3, ncol=n-2) verts <- seq_len(n) while((m <- length(verts)) > 3) { i1 <- 1:m i2 <- i1 %% m + 1 i3 <- i2 %% m + 1 theta3 <- atan2(y[verts[i3]]-y[verts[i1]], x[verts[i3]]-x[verts[i1]]) theta2 <- atan2(y[verts[i2]]-y[verts[i1]], x[verts[i2]]-x[verts[i1]]) diff <- ( (theta3-theta2)/pi + 4 ) %% 2 convex <- which(diff < 1) if (random && length(convex) > 1) convex <- sample(convex) good <- FALSE # just in case none are convex for (k in convex) { i <- c(i1[k],i2[k],i3[k]) tri <- rbind(x[verts[i]], y[verts[i]]) good <- TRUE for (j in 2:(m-1)) { i4 <- (i1[k] + j - 1) %% m + 1 i5 <- (i1[k] + j) %% m + 1 j <- c(i4,i5) if (intersectTriSeg(tri, rbind(x[verts[j]], y[verts[j]]))) { good <- FALSE break } } if (good) { if (plot) polygon(x[verts[i]], y[verts[i]], col=m) it[, m-2] <- verts[i] verts <- verts[-i2[k]] break } } if (!good) break } if (!good) { if (is.na(partial)) { warning("Triangulation is incomplete") partial <- TRUE } if (partial) it <- it[,seq_len(n-m)+m-2, drop=FALSE] else it <- NULL } else { if (plot) polygon(x[verts], y[verts], col=3) it[, 1] <- verts } it } triangulate <- function(x, y = NULL, z = NULL, random=TRUE, plot=FALSE, partial=NA) { xyz <- xyz.coords(x, y, z) if (xyz$xlab == "Index" && is.null(z) && (is.null(ncol(x)) || ncol(x) == 2L)) { x <- xyz$y y <- xyz$z } else { x <- xyz$x y <- xyz$y if (!diff(range(x))) x <- xyz$z else if (!diff(range(y))) y <- xyz$z } nesting <- nestPolys(x, y) verts <- nesting$verts nextvert <- rep(NA, length(x)) processInside <- function(v) { for (i in nesting$nesting[[v]]) processOutside(i) } processOutside <- function(fwd) { fwd1 <- verts[[fwd]] nextvert[fwd1] <<- c(fwd1[-1], fwd1[1]) reversed <- nesting$nesting[[fwd]] for (rev in reversed) { rev1 <- rev(verts[[rev]]) nextvert[rev1] <<- c(rev1[-1], rev1[1]) processInside(rev) done <- FALSE # we know at least one point of rev is in fwd, so merge them. # If this fails, the polygons are messed up. # We look for a segment from fwd to rev that intersects no other segments # in either loop. pairs <- expand.grid(seq_along(fwd1), seq_along(rev1)) if (random) pairs <- pairs[sample(nrow(pairs)),] for (p in seq_len(nrow(pairs))) { i <- fwd1[pairs[p,1]] j <- rev1[pairs[p,2]] seg <- cbind( c(x[i], y[i]), c(x[j], y[j]) ) clear <- TRUE for (q in seq_along(verts)) { i1 <- verts[[q]] if (!length(i1)) next i2 <- c(i1[-1], i1[1]) for (v in seq_along(i1)) if (length(intersect(c(i1[v], i2[v]), c(i,j))) == 0 && intersectSegSeg(seg, cbind( c(x[i1[v]], y[i1[v]]), c(x[i2[v]], y[i2[v]]) ))) { clear <- FALSE break } if (!clear) break } if (clear) { # Found a segment that doesn't intersect anything, so join the two polys i <- pairs[p,1] j <- pairs[p,2] ind <- c(fwd1[seq_len(i)], rev1[j:length(rev1)], rev1[seq_len(j)]) if (i < length(fwd1)) ind <- c(ind, fwd1[i:length(fwd1)]) verts[[fwd]] <<- fwd1 <- ind verts[[rev]] <<- integer(0) done <- TRUE break } } if (!done) stop("Cannot simplify polygon") } ind <- verts[[fwd]] tri <- triangulateSimple(x[ind], y[ind], random, plot, partial=FALSE) if (is.null(tri)) stop("Cannot triangulate polygon") # Convert back to original numbering dim <- dim(tri) tri <- ind[tri] dim(tri) <- dim # Put in place as triangulation of the forward poly subtri[[fwd]] <<- tri } subtri <- list() for (i in nesting$toplevel) processOutside(i) # Done all polys, now combine res <- matrix(nrow=3, ncol=0) for (i in seq_along(subtri)) res <- cbind(res, subtri[[i]]) attr(res, "nextvert") <- nextvert res } # Rewrite a complex polygon as a list of the individual parts, oriented correctly, # with attribute showing nesting nestPolys <- function(x,y = NULL) { xy <- xy.coords(x, y) x <- xy$x y <- xy$y n <- length(x) nas <- c(which(is.na(x) | is.na(y)), n + 1L) prev <- 0L verts <- list() for (i in seq_along(nas)) { verts[[i]] <- ind <- (prev + 1L):(nas[i] - 1L) tri <- triangulateSimple(x[ind], y[ind], random=TRUE, plot=FALSE, partial=FALSE) if (is.null(tri)) verts[[i]] <- rev(verts[[i]]) prev <- nas[i] } # nesting is a list of vectors # of poly numbers that are directly nested within the corresponding element of verts # The last one at length(verts)+1 lists polys not nested anywhere nesting <- rep(list(integer()), length(verts)+1) place <- function(new, toplevel) { placed <- FALSE contains <- integer() if (length(nesting[[toplevel]])) { newverts <- rbind(x[verts[[new]]], y[verts[[new]]]) for (j in nesting[[toplevel]]) { prev <- rbind(x[verts[[j]]], y[verts[[j]]]) if (pointInPoly(prev, newverts[,1])) { place(new, j) placed <- TRUE break } if (pointInPoly(newverts, prev[,1])) contains <- c(contains, j) } } if (!placed) { nesting[[toplevel]] <<- c(setdiff(nesting[[toplevel]], contains), new) nesting[[new]] <<- contains } } for (i in seq_along(verts)) { place(i, length(verts)+1) } list(verts=verts, nesting=nesting[-length(nesting)], toplevel=nesting[length(nesting)]) } extrude3d <- function(x,y = NULL, thickness=1, smooth=FALSE, ...) { xy <- xy.coords(x, y) x <- xy$x y <- xy$y it <- triangulate(x, y, partial=FALSE) nextvert <- attr(it, "nextvert") n <- length(x) res <- tmesh3d(rbind(c(x,x), c(y,y), c(rep(thickness,n), rep(0,n)), 1), cbind(it, it[c(1,3,2),]+n), ...) i1 <- seq_len(n) i2 <- nextvert i3 <- i2 + n i4 <- i1 + n keep <- !is.na(nextvert) res$ib <- rbind(i4,i3,i2,i1)[,keep] if (smooth) { res$ib <- res$ib + ncol(res$vb) res$vb <- cbind(res$vb, res$vb) i3 <- nextvert[nextvert] diff <- cbind(x[i3] - x[i1], y[i3] - y[i1]) len <- sqrt(apply(diff^2, 1, sum)) diff <- diff/len res$normals <- cbind( rbind(0,0,c(rep(1, n), rep(-1, n))) ) res$normals <- cbind(res$normals, res$normals) i2 <- c(i2 + 2*n, i2 + 3*n) keep <- !is.na(i2) res$normals[,i2[keep]] <- rbind(rep(diff[,2], 2), -rep(diff[,1], 2), 0)[,keep] } res } polygon3d <- function(x, y = NULL, z = NULL, fill = TRUE, plot = TRUE, coords = 1:2, random = TRUE, ...) { xyz <- xyz.coords(x,y,z) if (!fill) { n <- length(xyz$x) nas <- with(xyz, c(which(is.na(x) | is.na(y) | is.na(z)), n + 1L)) prev <- 0L loop <- integer() for (i in seq_along(nas)) { loop <- c(loop, if (i > 1) NA, (prev + 1L):(nas[i] - 1L), prev + 1L) prev <- nas[i] } res <- cbind(xyz$x[loop], xyz$y[loop], xyz$z[loop]) if (plot) lines3d(res, ...) else res } else { cnames <- c("x", "y", "z") x <- xyz[[cnames[coords[1]]]] y <- xyz[[cnames[coords[2]]]] tri <- triangulate(x, y, random = random) shape <- tmesh3d(rbind(xyz$x, xyz$y, xyz$z, 1), indices = tri) if (plot) shade3d(shape, ...) else shape } } rgl/R/tkspin3d.R0000644000176200001440000001563214100762640013130 0ustar liggesusers tkspinControl <- function(base, dev = cur3d(), continue=FALSE, speed=30, scale=100, ...) { if (!requireNamespace("tcltk", quietly = TRUE)) stop("This function requires 'tcltk'.") slider <- tcltk::tclVar(speed) getZooms <- function() { old <- cur3d() on.exit(set3d(old)) result <- numeric(max(dev)) for (device in dev) { set3d(device) result[device] <- par3d("zoom") } result } zooms <- getZooms() scale <- tcltk::tclVar(scale) continuous <- tcltk::tclVar(as.numeric(continue)) buttonPress <- NULL direction <- NULL lastTime <- proc.time()[3] timeDiff <- 0 rotateUp <- function() { angle <- timeDiff*as.numeric(tcltk::tclObj(slider))*pi/180 par3d(userMatrix = rotationMatrix(-angle, 1,0,0) %*% par3d("userMatrix")) } rotateLeft <- function() { angle <- timeDiff*as.numeric(tcltk::tclObj(slider))*pi/180 par3d(userMatrix = rotationMatrix(-angle, 0,1,0) %*% par3d("userMatrix")) } rotateRight <- function() { angle <- timeDiff*as.numeric(tcltk::tclObj(slider))*pi/180 par3d(userMatrix = rotationMatrix(angle, 0,1,0) %*% par3d("userMatrix")) } rotateSpin <- function() { angle <- timeDiff*as.numeric(tcltk::tclObj(slider))*pi/180 par3d(userMatrix = rotationMatrix(-angle, 0,0,1) %*% par3d("userMatrix")) } rotateDown <- function() { angle <- timeDiff*as.numeric(tcltk::tclObj(slider))*pi/180 par3d(userMatrix = rotationMatrix(angle, 1,0,0) %*% par3d("userMatrix")) } rotate <- function() { old <- cur3d() on.exit(set3d(old)) if (buttonPress) { if ((currentTime <- proc.time()[3]) > lastTime) { timeDiff <<- currentTime - lastTime lastTime <<- currentTime for (device in dev) { set3d(device) if (direction == "up") rotateUp() if (direction == "left") rotateLeft() if (direction == "spin") rotateSpin() if (direction == "right") rotateRight() if (direction == "down") rotateDown() } } tcltk::tcl("after",5,rotate) } } # rotation button callback functions # note that "..." argument is necessary upButtonPress <- function(...) { buttonPress <<- TRUE lastTime <<- proc.time()[3] direction <<- "up" rotate() } leftButtonPress <- function(...) { buttonPress <<- TRUE lastTime <<- proc.time()[3] direction <<- "left" rotate() } spinButtonPress <- function(...) { buttonPress <<- TRUE lastTime <<- proc.time()[3] direction <<- "spin" rotate() } rightButtonPress <- function(...) { buttonPress <<- TRUE lastTime <<- proc.time()[3] direction <<- "right" rotate() } downButtonPress <- function(...) { buttonPress <<- TRUE lastTime <<- proc.time()[3] direction <<- "down" rotate() } onIdle <- function(...) { buttonPress <<- TRUE rotate() buttonPress <<- FALSE if (as.numeric(tcltk::tclObj(continuous))) tcltk::tcl("after", "idle", onIdle) } buttonRelease <- function(...) { buttonPress <<- FALSE if (as.numeric(tcltk::tclObj(continuous))) tcltk::tcl("after", "idle", onIdle) } resetAxis <- function(...) { old <- cur3d() on.exit(set3d(old)) for (device in dev) { set3d(device) par3d(userMatrix = diag(4)) } } setScale <- function(...) { old <- cur3d() on.exit(set3d(old)) scale <- as.numeric(tcltk::tclObj(scale)) for (device in dev) { set3d(device) par3d(zoom = 10^((scale - 100)/50)*zooms[device]) } } spec.frm <- tcltk::tkframe(base, ...) first.frm <- tcltk::tkframe(spec.frm) second.frm <- tcltk::tkframe(spec.frm) third.frm <- tcltk::tkframe(spec.frm) fourth.frm <- tcltk::tkframe(spec.frm) # rotations buttons upButton <- tcltk::tkbutton(first.frm, text=" ^ ") leftButton <- tcltk::tkbutton(first.frm, text=" < ") spinButton <- tcltk::tkbutton(first.frm, text=" O ") rightButton <- tcltk::tkbutton(first.frm, text=" > ") downButton <- tcltk::tkbutton(first.frm, text=" v ") tcltk::tkgrid(tcltk::tklabel(first.frm, text=" "), upButton, tcltk::tklabel(first.frm, text=" ")) tcltk::tkgrid(leftButton,spinButton,rightButton) tcltk::tkgrid(tcltk::tklabel(first.frm, text=" "), downButton, tcltk::tklabel(first.frm, text=" ")) tcltk::tkbind(upButton, "", upButtonPress) tcltk::tkbind(leftButton, "", leftButtonPress) tcltk::tkbind(spinButton, "", spinButtonPress) tcltk::tkbind(rightButton, "", rightButtonPress) tcltk::tkbind(downButton, "", downButtonPress) tcltk::tkbind(upButton,"", buttonRelease) tcltk::tkbind(leftButton,"", buttonRelease) tcltk::tkbind(spinButton,"", buttonRelease) tcltk::tkbind(rightButton,"", buttonRelease) tcltk::tkbind(downButton,"", buttonRelease) # control buttons frameAxis <- tcltk::tkframe(second.frm,borderwidth=2) tcltk::tkpack(frameAxis) buttonAxis <- tcltk::tkbutton(frameAxis,text=" Reset Axis ",command=resetAxis) contBox <- tcltk::tkcheckbutton(frameAxis,text="Continue rotating", variable=continuous) tcltk::tkpack(contBox, buttonAxis,fill="x") #control scale frame frameControl <- tcltk::tkframe(third.frm,borderwidth=4) tcltk::tkpack(frameControl) frameControlSpeed <- tcltk::tkframe(frameControl) sliderSpeed <- tcltk::tkscale(frameControlSpeed, showvalue=FALSE, orient="horiz", from=0, to=400,resolution=1,variable=slider) tcltk::tkpack(tcltk::tklabel(frameControlSpeed,text="Speed:"),sliderSpeed,side="left") frameControlScale <- tcltk::tkframe(frameControl) sliderScale <- tcltk::tkscale(frameControlScale,showvalue=FALSE,orient="horiz", from=0, to=200,resolution=1, variable=scale, command=setScale) tcltk::tkpack(tcltk::tklabel(frameControlScale,text="Scale:"),sliderScale,side="left") tcltk::tkpack(frameControlSpeed,frameControlScale) tcltk::tkpack(first.frm, second.frm, third.frm, fourth.frm) tcltk::tkpack(spec.frm,expand=TRUE) spec.frm } tkspin3d <- function(dev = cur3d(), ...) { if (!requireNamespace("tcltk", quietly = TRUE)) stop("This function requires 'tcltk'.") args <- list(...) controlargs <- list() if (length(args)) { controlargindices <- which(names(args) %in% names(formals(tkspinControl))) if (length(controlargindices)) { args <- args[-controlargindices] controlargs <- args[controlargindices] } } base <- do.call(tcltk::tktoplevel, args) tcltk::tkwm.title(base, "Spin") spin <- do.call(tkspinControl, c(list(base = base, dev = dev), controlargs)) quit <- tcltk::tkbutton(base,text="Quit", command=function()tcltk::tkdestroy(base)) tcltk::tkpack(spin, quit) } rgl/R/rglwidget.R0000644000176200001440000003766614145464133013401 0ustar liggesusers rmarkdownOutput <- function() { if (requireNamespace("rmarkdown", quietly = TRUE)) { output <- rmarkdown::metadata$output if (length(output)) if (is.character(output)) return(output[1]) else if (is.list(output) && length(names(output))) return(names(output)[1]) } NULL } rglShared <- function(id, key = NULL, group = NULL, deselectedFade = 0.1, deselectedColor = NULL, selectedColor = NULL, selectedIgnoreNone = TRUE, filteredFade = 0, filteredColor = NULL) { if (!requireNamespace("crosstalk")) stop("This function requires crosstalk.") data <- as.data.frame(rgl.attrib(id, "vertices")) attr(data, "rglId") <- as.integer(id) attr(data, "rglOptions") <- list(deselectedFade = deselectedFade, deselectedColor = if (!is.null(deselectedColor)) as.numeric(col2rgb(deselectedColor, alpha = TRUE)/255), selectedColor = if (!is.null(selectedColor)) as.numeric(col2rgb(selectedColor, alpha = TRUE)/255), selectedIgnoreNone = selectedIgnoreNone, filteredFade = filteredFade, filteredColor = if (!is.null(filteredColor)) as.numeric(col2rgb(filteredColor, alpha = TRUE)/255)) n <- nrow(data) if (!n) stop("No vertices in object ", id) if (!is.null(key) && (n != length(key) || anyDuplicated(key))) stop("'key' must have exactly one unique value for each vertex") result <- if (is.null(group)) crosstalk::SharedData$new(data, key) else crosstalk::SharedData$new(data, key, group) structure(result, class = c("rglShared", class(result))) } CSStoPixels <- function(x, DPI = 100) { if (is.null(x)) return(x) num <- function(x) as.numeric(sub("[^[:digit:].]*$", "", x)) units <- function(x) sub("^[[:digit:].]+", "", x) if (!is.numeric(x)) { units <- units(x) if (units == "auto") stop("Only fixed CSS sizes allowed") val <- num(x) if (units != "") val <- switch(units, "px" = val, "in" = val * DPI, "cm" = val * DPI / 2.54, "mm" = val * DPI / 254, "pt" = val * DPI / 72, "pc" = val * DPI / 6, stop("Only fixed CSS sizes allowed") ) } else val <- x val } # These sizes are taken from htmlwidgets/R/sizing.R DEFAULT_WIDTH <- 960 DEFAULT_HEIGHT <- 500 DEFAULT_PADDING <- 40 DEFAULT_WIDTH_VIEWER <- 450 DEFAULT_HEIGHT_VIEWER <- 350 DEFAULT_PADDING_VIEWER <- 15 # For widgets, we use the sizingPolicy to see how it would be # displayed resolveHeight <- function(x, inViewer = TRUE, default = 40) { if (inViewer) refsize <- DEFAULT_HEIGHT_VIEWER else refsize <- DEFAULT_HEIGHT result <- x$height if (is.null(result) && !is.null(policy <- x$sizingPolicy)) { if (inViewer) { viewer <- policy$viewer if (isTRUE(viewer$fill)) result <- refsize else result <- viewer$defaultHeight } else result <- NULL if (is.null(result) && isTRUE(policy$fill)) result <- refsize if (is.null(result)) result <- policy$defaultHeight if (is.null(result)) result <- refsize } if (is.null(result)) result <- default CSStoPixels(result, refsize) } getWidgetId <- function(widget) { if (inherits(widget, "htmlwidget")) widget$elementId else { NULL } } # Get information from previous objects being piped into # this one, and modify a copy of them as necessary getHeights <- function(objects, defaultHeight = 40) { if (inherits(objects, "combineWidgets")) heights <- objects$params$rowsize else { if (inherits(objects, c("shiny.tag", "htmlwidget")) || !is.list(objects)) objects <- tagList(objects) heights <- rep(defaultHeight, length(objects)) for (i in seq_along(objects)) { tag <- objects[[i]] if (inherits(tag, "rglWebGL") && is.null(tag$height)) heights[i] <- tag$x$height else if (inherits(tag, "htmlwidget")) heights[i] <- resolveHeight(tag) else if (is.list(tag) && !is.null(tag$height) && !is.na(height <- suppressWarnings(as.numeric(tag$height)))) heights[i] <- height } } heights } processUpstream <- function(upstream, elementId = NULL, playerId = NULL) { rowsizes <- getHeights(upstream) if (inherits(upstream, "combineWidgets")) upstream <- upstream$widgets if (inherits(upstream, "knit_image_paths") && length(upstream)) upstream <- img(src = image_uri(upstream[1])) if (inherits(upstream, c("shiny.tag", "htmlwidget"))) upstream <- tagList(upstream) if (is.character(upstream) && !is.na(upstream)) return(list(prevRglWidget = upstream)) if (is.list(upstream)) { # Objects upstream of the current one may need to know about an rgl widget, # or this object may need to know about an upstream rgl widget. Stop when # you find one. lookForRglWidget <- function(upstream) { prevRglWidget <- NULL players <- character() for (i in rev(seq_along(upstream))) { tag <- upstream[[i]] if (inherits(tag, "rglWebGL")) { prevRglWidget <- tag$elementId if (is.null(prevRglWidget)) prevRglWidget <- tag$elementId <- upstream[[i]]$elementId <- newElementId("rgl") if (!is.null(playerId) && !(playerId %in% tag$x$players)) upstream[[i]]$x$players <- c(tag$x$players, playerId) } else if (inherits(tag, "rglPlayer") && is.null(tag$x$sceneId)) { players <- c(players, tag$elementId) if (!is.null(elementId)) upstream[[i]]$x$sceneId <- elementId } else if (inherits(tag, "shiny.tag") && !tagHasAttribute(tag, "rglSceneId")) { upstream[[i]] <- tagAppendAttributes(tag, rglSceneId = elementId) } else if (inherits(tag, "combineWidgets")) { temp <- lookForRglWidget(tag$widgets) players <- c(players, temp$players) prevRglWidget <- temp$prevRglWidget upstream[[i]]$widgets <- temp$objects } if (!is.null(prevRglWidget)) break } list(objects = upstream, players = players, prevRglWidget = prevRglWidget) } result <- lookForRglWidget(upstream) result$rowsizes <- rowsizes } else result <- list(objects = upstream, players = if (is.character(upstream)) upstream else character(), prevRglWidget = if (is.character(upstream)) upstream, rowsizes = rowsizes) result } asRow <- function(..., last = NA, height = NULL, colsize = 1) { if (!requireNamespace("manipulateWidget", quietly = TRUE)) { warning("asRow requires the 'manipulateWidget' package.", call. = FALSE) last <- NA } args <- list(...) if ((length(args) == 1 && inherits(args[[1]], "combineWidgets")) || !requireNamespace("manipulateWidget", quietly = TRUE)) { orig <- args[[1]] } else { orig <- do.call(manipulateWidget::combineWidgets, c(args, list(ncol = 1, rowsize = getHeights(args)))) } origlen <- length(orig$widgets) for (i in seq_len(origlen)) if (inherits(orig$widgets[[i]], "knit_image_paths")) orig$widgets[[i]] <- img(src = image_uri(orig$widgets[[i]])) if (is.na(last)) last <- origlen else if (last > origlen) stop("'last' must be no more than the number of widgets") keep <- seq_len(origlen - last) inrow <- seq_len(last) + origlen - last origRowsizes <- rep_len(orig$params$rowsize, origlen) if (length(inrow)) { maxinrow <- max(origRowsizes[inrow]) if (is.null(height)) height <- maxinrow } else if (is.null(height)) height <- 0 orig$params$rowsize <- c(origRowsizes[keep], height) if (requireNamespace("manipulateWidget", quietly = TRUE)) { row <- do.call(manipulateWidget::combineWidgets, c(orig$widgets[inrow], list(nrow = 1, colsize = colsize))) orig$widgets <- c(orig$widgets[keep], list(row)) } orig } newElementId <- function(prefix) paste0(prefix, p_sample(100000, 1)) knitrNeedsSnapshot <- function(options = knitr::opts_current$get()) { if (!is.null(options$snapshot)) return(options$snapshot) if (isFALSE(options$screenshot.force)) return(FALSE) force <- isTRUE(options$screenshot.force) fmt <- pandoc_to() if (!length(fmt) || force) return(TRUE) html_format <- fmt %in% c("html", "html4", "html5", "revealjs", "s5", "slideous", "slidy") !html_format } rglwidget <- local({ function(x = scene3d(minimal), width = figWidth(), height = figHeight(), controllers = NULL, elementId = NULL, reuse = FALSE, webGLoptions = list(preserveDrawingBuffer = TRUE), shared = NULL, minimal = TRUE, webgl, snapshot, shinyBrush = NULL, ..., oldConvertBBox = FALSE) { if (missing(snapshot)) { if (missing(webgl)) { if (in_knitr()) snapshot <- knitrNeedsSnapshot() else snapshot <- FALSE } else snapshot <- !webgl } else { if (!is.logical(snapshot)) { stop("snapshot must be TRUE or FALSE") } } if (missing(webgl)) webgl <- !snapshot if (webgl == snapshot || is.na(webgl) || is.na(snapshot)) stop("Must specify either 'snapshot' or 'webgl' but not both") origScene <- x force(shared) # It might plot something... if (is.null(elementId) && (!inShiny() || # If in Shiny, all of the classes below need the ID inherits(controllers, c("combineWidgets", "shiny.tag", "htmlwidget")))) elementId <- newElementId("rgl") if (!is.null(shinyBrush)) { if (!is.character(shinyBrush) || length(shinyBrush) != 1) stop("'shinyBrush' must be a single character value") if (!inShiny()) warning("'shinySelectionInput' is only used in Shiny") else x$selectionInput <- shinyBrush } if (!inherits(x, "rglscene")) stop("First argument should be an rgl scene.") if (!is.null(shared) && !is.list(shared)) shared <- list(shared) if (length(shared) && !requireNamespace("crosstalk", quietly = TRUE)) stop("'shared' requires the crosstalk package.") dependencies <- list(rglDependency, CanvasMatrixDependency) if (length(shared) && isNamespaceLoaded("crosstalk")) { x$crosstalk <- list(key = vector("list", length(shared)), group = character(length(shared)), id = integer(length(shared)), options = vector("list", length(shared))) dependencies <- c(dependencies, crosstalk::crosstalkLibs()) } else { x$crosstalk <- list(key = list(), group = character(), id = integer(), options = list()) } for (i in seq_along(shared)) { s <- shared[[i]] if (crosstalk::is.SharedData(s) && inherits(s, "rglShared")) { x$crosstalk$key[[i]] <- s$key() x$crosstalk$group[i] <- s$groupName() x$crosstalk$id[i] <- attr(s$origData(), "rglId") x$crosstalk$options[[i]] <- attr(s$origData(), "rglOptions") } else if (!is.null(s)) stop("'shared' must be an object produced by rglShared() or a list of these") } if (!is.null(width)) width <- CSStoPixels(width) if (!is.null(height)) height <- CSStoPixels(height) x <- convertScene(x, width, height, elementId = elementId, webgl = webgl, snapshot = snapshot, oldConvertBBox = oldConvertBBox) upstream <- processUpstream(controllers, elementId = elementId) if (webgl) { x$players <- upstream$players x$webGLoptions <- webGLoptions # create widget attr(x, "TOJSON_ARGS") <- list(na = "string") result <- structure(htmlwidgets::createWidget( name = 'rglWebGL', x = x, width = width, height = height, package = 'rgl', elementId = elementId, dependencies = dependencies, ... ), origScene = origScene) } else { if (is.list(upstream$objects)) { result <- img(src = image_uri(x), width = width, height = height) } else result <- x } if (is.list(upstream$objects)) { if (requireNamespace("manipulateWidget", quietly = TRUE)) result <- do.call(manipulateWidget::combineWidgets, c(upstream$objects, list(result, rowsize = c(upstream$rowsizes, height), ncol = 1))) else warning("Combining widgets requires the 'manipulateWidget' package.", call. = FALSE) } result }}) print.rglMouseSelection <- function(x, verbose = FALSE, ...) { if (!is.null(x$region)) { cat("Mouse selection:\n") if (verbose) { cat("p1=[", x$region[1], ",", x$region[2], "] p2=[", x$region[3], ",", x$region[4],"]\n") cat("Projection data included: ", !is.null(x$model) && !is.null(x$proj) && !is.null(x$view), "\n") } } else cat("Inactive mouse selection.\n") invisible(x) } # Create the local dependencies makeDependency <- function(name, src, script = NULL, package, version = packageVersion(package), minifile = paste0(basename(src), ".min.js"), debugging = FALSE, ...) { if (!is.null(script) && requireNamespace("js", quietly = TRUE) && packageVersion("js") >= "1.2") { if (debugging) { for (f in script) { hints <- js::jshint(readLines(file.path(system.file(src, package = package), f)), undef = TRUE, bitwise = TRUE, eqeqeq = TRUE, latedef = TRUE, browser = TRUE, devel = TRUE, globals = list(CanvasMatrix4 = FALSE, WebGLFloatArray = FALSE, rglwidgetClass = FALSE, rgltimerClass = FALSE, Shiny = FALSE )) for (i in seq_len(NROW(hints))) warning(f, "#", hints[i, "line"], ": ", hints[i, "reason"], call. = FALSE, immediate. = TRUE) } } minified <- js::uglify_files(file.path(system.file(src, package = package), script)) writeLines(minified, file.path(system.file(src, package = package), minifile)) if (!debugging) script <- minifile } htmlDependency(name = name, src = src, package = package, version = version, script = script, all_files = FALSE, ...) } CanvasMatrixDependency <- makeDependency("CanvasMatrix4", src = "htmlwidgets/lib/CanvasMatrix", script = "CanvasMatrix.src.js", package = "rgl", debugging = isTRUE(as.logical(Sys.getenv("RGL_DEBUGGING", "FALSE")))) rglDependency <- makeDependency("rglwidgetClass", src = "htmlwidgets/lib/rglClass", script = c("rglClass.src.js", "utils.src.js", "buffer.src.js", "subscenes.src.js", "shaders.src.js", "textures.src.js", "projection.src.js", "mouse.src.js", "init.src.js", "pieces.src.js", "draw.src.js", "controls.src.js", "selection.src.js", "rglTimer.src.js", "pretty.src.js", "axes.src.js"), stylesheet = "rgl.css", package = "rgl", debugging = isTRUE(as.logical(Sys.getenv("RGL_DEBUGGING", "FALSE")))) rgl/R/cylinder3d.R0000644000176200001440000001566514100762640013437 0ustar liggesusersGramSchmidt <- function(v1, v2, v3, order=1:3) { A <- rbind(v1, v2, v3) A <- A[order,] v1 <- A[1,] v2 <- A[2,] v3 <- A[3,] if (isTRUE(all.equal(as.numeric(v1), c(0,0,0)))) v1 <- xprod(v2, v3) v1 <- normalize(v1) v2 <- v2 - sum(v2*v1)*v1 if (isTRUE(all.equal(as.numeric(v2), c(0,0,0)))) v2 <- xprod(v3, v1) v2 <- normalize(v2) v3 <- v3 - sum(v3*v1)*v1 - sum(v3*v2)*v2 if (isTRUE(all.equal(as.numeric(v3), c(0,0,0)))) v3 <- xprod(v1, v2) v3 <- normalize(v3) rbind(v1, v2, v3)[order(order),] } cylinder3d <- function(center, radius = 1, twist = 0, e1 = NULL, e2 = NULL, e3 = NULL, sides = 8, section = NULL, closed = 0, rotationMinimizing = is.null(e2) && is.null(e3), debug = FALSE, keepVars = FALSE) { force(rotationMinimizing) # Need this since e2 and e3 get changed later center <- as.matrix(as.data.frame(xyz.coords(center)[c("x", "y", "z")])) n <- nrow(center) inds <- seq_len(n) if (closed > 0) { ind0 <- c(n-1-closed, n-closed, inds) ind1 <- c(n-closed, inds, 1+closed) # nolint ind2 <- c(inds, 1+closed, 2+closed) } else { ind0 <- c(1, 1, inds) ind1 <- c(1, inds, n) # nolint ind2 <- c(inds, n, n) } missings <- c(e1=is.null(e1), e2=is.null(e2), e3=is.null(e3)) fixup <- function(coord) { usable <- apply(coord, 1, function(v) all(is.finite(v)) & (veclen(v) > 0)) if (!any(usable) ) stop(gettextf("No usable coordinate values in '%s'", deparse(substitute(coord))), domain = NA) firstgood <- min(which(usable)) inds <- seq_len(n) if (firstgood > 1) { coord[inds[inds < firstgood],] <- coord[rep(firstgood,firstgood-1),] usable[seq_len(firstgood)] <- TRUE } for (i in inds[-1]) inds[i] <- ifelse(usable[i], inds[i], inds[i-1]) coord[inds,] } if (!is.null(e1)) { e1 <- as.matrix(as.data.frame(xyz.coords(e1)[c("x", "y", "z")])) e1 <- e1[rep(seq_len(nrow(e1)), len=n),] } else e1 <- (center[ind2,] - center[ind0,])[inds,] # Fix up degenerate cases by repeating existing ones, or using arbitrary ones zeros <- rowSums(e1^2) == 0 if (all(zeros)) { e1[,1] <- 1 zeros <- FALSE } else if (any(zeros)) { e1[1,] <- e1[which(!zeros)[1],] zeros[1] <- FALSE if (any(zeros)) { zeros <- which(zeros) for (i in zeros) e1[i,] <- e1[i-1,] } } if (!is.null(e2)) { e2 <- as.matrix(as.data.frame(xyz.coords(e2)[c("x", "y", "z")])) e2 <- e2[rep(seq_len(nrow(e2)), len=n),] } else e2 <- (e1[ind2,] - e1[ind0,])[inds,] # Fix up degenerate e2's similarly, then force different than e1 zeros <- rowSums(e2^2) == 0 if (all(zeros)) { e2[,2] <- 1 zeros <- FALSE } else if (any(zeros)) { e2[1,] <- e2[which(!zeros)[1],] zeros[1] <- FALSE if (any(zeros)) { zeros <- which(zeros) for (i in zeros) e2[i,] <- e2[i-1,] } } parallel <- sapply(inds, function(i) all(xprod(e1[i,], e2[i,]) == 0)) if (any(parallel)) { # rotate in the xy plane e2[parallel,] <- cbind(-e2[parallel,2], e2[parallel,1], e2[parallel,3]) parallel <- sapply(inds, function(i) all(xprod(e1[i,], e2[i,]) == 0)) if (any(parallel)) { # if any are still parallel, they must be the z axis e2[parallel,1] <- 1 e2[parallel,3] <- 0 } } if (!is.null(e3)) { e3 <- as.matrix(as.data.frame(xyz.coords(e3)[c("x", "y", "z")])) e3 <- e3[rep(seq_len(nrow(e3)), len=n),] } else { e3 <- matrix(NA_real_, n, 3) for (i in inds) e3[i,] <- xprod(e1[i,], e2[i,]) } for (i in inds) { A <- GramSchmidt(e1[i,], e2[i,], e3[i,], order=order(missings)) e1[i,] <- A[1,] e2[i,] <- A[2,] e3[i,] <- A[3,] } e1 <- fixup(e1) e2 <- fixup(e2) e3 <- fixup(e3) if (rotationMinimizing) { # Keep e1 and the first entries in e2 and e3, # modify the rest according to Wang et al (2008). t <- e1 r <- e2 s <- e3 for (i in seq_len(n-1)) { v1 <- center[i+1,] - center[i,] c1 <- sum(v1^2) rL <- r[i,] - (2/c1)*sum(v1*r[i,])*v1 tL <- t[i,] - (2/c1)*sum(v1*t[i,])*v1 v2 <- t[i+1,] - tL c2 <- sum(v2^2) r[i+1,] <- rL - (2/c2)*sum(v2*rL)*v2 s[i+1,] <- xprod(t[i+1,], r[i+1,]) } e2 <- r e3 <- s } radius <- rep(radius, len=n) twist <- rep(twist, len=n) if (debug) { for (i in inds) { segments3d(rbind(center[i,],center[i,]+e3[i,]*radius[i]*1.5, center[i,],center[i,]+e2[i,]*radius[i]*1.5, center[i,],center[i,]+e1[i,]*radius[i]*1.5), col=rep(c("red", "green", "blue"), each=2)) text3d(center, texts=inds) } } if (closed > 0) { n <- n - closed + 1 if (isTRUE(all.equal(e1[1,], e1[n,]))) { # Need to match starting and ending e2 as # well. angle <- atan2(sum(xprod(e2[1,], e2[n,])*e1[1,]), sum(e2[1,]*e2[n,])) twist <- twist + (twist[n] - twist[1] - angle)*(seq_len(n) - 1)/(n-1) } } if (is.null(section)) { theta <- seq(0, 2*pi, len=sides+1)[-1] section <- cbind(cos(theta), sin(theta), 0) } else sides <- nrow(section) vertices <- matrix(0, 3, sides*n) indices <- matrix(0, 4, sides*(n-1)) if (ncol(section) == 2) section <- cbind(section, 0) for (i in seq_len(n-1)) { transform <- rbind(e3[i,], e2[i,], e1[i,]) p <- rotate3d(section, twist[i], 0,0,1) p <- radius[i] * p %*% transform p[,1] <- p[,1] + center[i,"x"] p[,2] <- p[,2] + center[i,"y"] p[,3] <- p[,3] + center[i,"z"] vertices[,(i-1)*sides+seq_len(sides)] <- t(p) for (j in seq_len(sides)) indices[, (i-1)*sides + j] <- (c(0,0,1,1) + j) %% sides + 1 + c((i-1)*sides, i*sides, i*sides, (i-1)*sides) } transform <- rbind(e3[n,], e2[n,], e1[n,]) p <- rotate3d(section, twist[n], 0,0,1) p <- radius[n] * p %*% transform p[,1] <- p[,1] + center[n,"x"] p[,2] <- p[,2] + center[n,"y"] p[,3] <- p[,3] + center[n,"z"] vertices[,(n-1)*sides+seq_len(sides)] <- t(p) # Add end cap at start if (closed < 0) { vertices <- cbind(vertices, center[1,]) triangles <- rbind(ncol(vertices), seq_len(sides), c(2:sides, 1)) } # Add end cap at end if (closed < -1) { vertices <- cbind(vertices, center[n,]) triangles <- cbind(triangles, rbind(ncol(vertices), c(2:sides, 1) + (n-1)*sides, seq_len(sides) + (n-1)*sides)) } result <- qmesh3d(vertices, indices, homogeneous=FALSE) if (closed > 0) { # Look for repeated vertices, and edit the links nv <- ncol(result$vb) for (i in seq_len(sides)) { dupe <- which(apply(result$vb[,(nv-sides+1):nv,drop=FALSE], 2, function(x) isTRUE(all.equal(x, result$vb[,i]))))+nv-sides for (j in dupe) { f <- result$ib == j result$ib[f] <- i } } } else if (closed < 0) result$it <- triangles if (keepVars) attr(result, "vars") <- environment() result } rgl/R/saveURI.R0000644000176200001440000000063014100762640012677 0ustar liggesuserssaveURI <- function(uri, con) { if (!grepl("^data:", uri)) stop("Does not appear to be a data URI") header <- sub(",.*", "", uri) type <- sub(";.*", "", sub("^data:", "", header)) encoding <- sub("^.*;", "", header) if (encoding != "base64") stop("Not encoded in base64") payload <- sub(paste0(header, ","), "", uri, fixed = TRUE) writeBin(base64_dec(payload), con) invisible(type) } rgl/R/mesh3d.R0000644000176200001440000003436514145464133012565 0ustar liggesusersensureMatrix <- function(x, nrow) { if (!is.matrix(x)) x <- matrix(x, nrow = nrow) x } mesh3d <- function( x, y = NULL, z = NULL, vertices, material = NULL, normals = NULL, texcoords = NULL, points = NULL, segments = NULL, triangles = NULL, quads = NULL, meshColor = c("vertices", "edges", "faces", "legacy")) { if (missing(vertices)) { xyz <- xyz.coords(x, y, z, recycle=TRUE) if (length(xyz$x) && length(xyz$y) && length(xyz$z)) vertices <- rbind(xyz$x, xyz$y, xyz$z, 1) else vertices <- matrix(numeric(), nrow = 4) } else vertices <- asHomogeneous2(vertices) # Remove dimnames dimnames(vertices) <- NULL if (missing(meshColor) && !is.null(material) && !is.null(material$meshColor)) { meshColor <- material$meshColor material$meshColor <- NULL } meshColor <- match.arg(meshColor) if (is.null(texcoords) && !is.null(material) && !is.null(material$texcoords)) { texcoords <- material$texcoords material$texcoords <- NULL } nvertex <- ncol(vertices) if ( !is.null(normals) ) { normals <- xyz.coords(normals, recycle=TRUE) x <- rep(normals$x, len = nvertex) y <- rep(normals$y, len = nvertex) z <- rep(normals$z, len = nvertex) normals <- rgl.vertex(x, y, z) } if ( !is.null(texcoords) ) { texcoords <- xy.coords(texcoords, recycle = TRUE) x <- rep(texcoords$x, len = nvertex) y <- rep(texcoords$y, len = nvertex) texcoords <- rbind(x, y) } object <- list( vb = vertices, material = .getMaterialArgs(material = material), normals = normals, texcoords = texcoords, meshColor = meshColor ) if (!is.null(points)) object$ip <- ensureMatrix(points, 1) if (!is.null(segments)) object$is <- ensureMatrix(segments, 2) if (!is.null(triangles)) object$it <- ensureMatrix(triangles, 3) if (!is.null(quads)) object$ib <- ensureMatrix(quads, 4) register_compare_proxy() class(object) <- c("mesh3d", "shape3d") object } register_compare_proxy <- local({ registered <- FALSE function() { if (!registered && isNamespaceLoaded("waldo")) { if ("path" %in% names(formals(waldo::compare_proxy))) { # appeared after 0.2.5 registerS3method("compare_proxy", "mesh3d", compare_proxy.mesh3d, envir = asNamespace("waldo")) registerS3method("compare_proxy", "rglscene", compare_proxy.rglscene, envir = asNamespace("waldo")) } else { registerS3method("compare_proxy", "mesh3d", old_compare_proxy.mesh3d, envir = asNamespace("waldo")) registerS3method("compare_proxy", "rglscene", old_compare_proxy.rglscene, envir = asNamespace("waldo")) } registered <<- TRUE } } }) compare_proxy.mesh3d <- function(x, path = "x") { list(object = old_compare_proxy.mesh3d(x), path = paste0("compare_proxy(", path, ")")) } old_compare_proxy.mesh3d <- function(x) { for (n in names(x)) # Some elements are NULL, some are not there if (is.null(x[[n]])) x[[n]] <- NULL if (is.null(x$material) || length(x$material$color) < 2) x$meshColor <- NULL # It doesn't matter. for (n in c("ip", "is", "it", "ib")) if (!is.null(x[[n]])) x[[n]] <- as.numeric(x[[n]]) x$primitivetype <- NULL # Not used since before 0.100.x x[sort(names(x))] } # # triangle mesh object # tmesh3d <- function( vertices, indices, homogeneous=TRUE, material=NULL, normals=NULL, texcoords = NULL, meshColor = c("vertices", "edges", "faces", "legacy")) { if (missing(meshColor) && !is.null(material$meshColor)) meshColor <- material$meshColor meshColor <- match.arg(meshColor) if (is.null(dim(vertices))) vertices <- matrix(vertices, nrow = if (homogeneous) 4 else 3) # For back-compatibility: colnames(indices) <- NULL mesh3d(vertices = vertices, triangles = indices, material = material, normals = normals, texcoords = texcoords, meshColor = meshColor) } # # R 3d object : quad mesh # qmesh3d <- function( vertices, indices, homogeneous=TRUE, material=NULL, normals=NULL, texcoords=NULL, meshColor = c("vertices", "edges", "faces", "legacy")) { if (missing(meshColor) && !is.null(material$meshColor)) meshColor <- material$meshColor meshColor <- match.arg(meshColor) if (is.null(dim(vertices))) vertices <- matrix(vertices, nrow = if (homogeneous) 4 else 3) # For back-compatibility colnames(indices) <- NULL mesh3d(vertices = vertices, quads = indices, material = material, normals = normals, texcoords = texcoords, meshColor = meshColor) } as.mesh3d <- function(x, ...) UseMethod("as.mesh3d") as.mesh3d.deldir <- function(x, col = "gray", coords = c("x", "y", "z"), smooth = TRUE, normals = NULL, texcoords = NULL, ...) { checkDeldir(error = TRUE) if (!identical(sort(coords), c("x", "y", "z"))) stop(sQuote("coords"), " should be a permutation of c('x', 'y', 'z')") if (!all(coords %in% names(x$summary))) stop("The 'deldir' object needs x, y, and z coordinates.") if (smooth && !is.null(normals)) { warning("'smooth' ignored as 'normals' was specified.") smooth <- FALSE } pointnames <- as.numeric(rownames(x$summary)) points <- matrix(NA, max(pointnames), 3) points[pointnames, ] <- as.matrix(x$summary[, coords]) points <- t(points) triangs <- do.call(rbind, deldir::triang.list(x)) if (!is.null(texcoords)) texcoords <- texcoords[triangs$ptNum, ] material <- .getMaterialArgs(...) material$color <- col result <- mesh3d(vertices = asHomogeneous2(points), triangles = triangs$ptNum, normals = normals, texcoords = texcoords, material = material) if (smooth) result <- addNormals(result) result } as.mesh3d.triSht <- as.mesh3d.tri <- function(x, z, col = "gray", coords = c("x", "y", "z"), smooth = TRUE, normals = NULL, texcoords = NULL, ...) { if (inherits(x, "tri")) triangles <- tripack::triangles else if (inherits(x, "triSht")) { triangles <- interp::triangles } if (!identical(sort(coords), c("x", "y", "z"))) stop(sQuote("coords"), " should be a permutation of c('x', 'y', 'z')") if (!is.numeric(z) || length(z) != x$n) stop("z should be a numeric vector with one entry per node of x") if (smooth && !is.null(normals)) { warning("'smooth' ignored as 'normals' was specified.") smooth <- FALSE } points <- rbind(x$x, x$y, z) rownames(points) <- c("x", "y", "z") points <- points[coords,] triangs <- t(triangles(x)[, 1:3]) if (inherits(x, "tri") && x$nc) { constraintIndex <- min(x$lc) keep <- apply(triangs, 2, function(col) any(col < constraintIndex)) triangs <- triangs[, keep] } if (!is.null(texcoords)) texcoords <- texcoords[triangs, ] material <- .getMaterialArgs(...) material$color <- col result <- mesh3d(vertices = asHomogeneous2(points), triangles = triangs, normals = normals, texcoords = texcoords, material = material) if (smooth) result <- addNormals(result) result } # rendering support dot3d.mesh3d <- function(x, ..., front = "points", back = "points") { if (missing(front) && !is.null(x$material$front)) front <- x$material$front if (missing(back) && !is.null(x$material$back)) back <- x$material$back shade3d.mesh3d(x, ..., front = front, back = back) } wire3d.mesh3d <- function(x, ..., front = "lines", back = "lines") { if (missing(front) && !is.null(x$material$front)) front <- x$material$front if (missing(back) && !is.null(x$material$back)) back <- x$material$back shade3d.mesh3d(x, ..., front = front, back = back) } allowedMeshColor <- function(meshColor, modes) { meshColor != "edges" || (modes[1] == modes[2] && modes[1] == "lines") } shade3d.mesh3d <- function( x, override = TRUE, meshColor = c("vertices", "edges", "faces", "legacy"), texcoords = NULL, ..., front = "filled", back = "filled") { if (missing(front) && !is.null(x$material$front)) front <- x$material$front if (missing(back) && !is.null(x$material$back)) back <- x$material$back argMaterial <- c(list(front = front, back = back), .getMaterialArgs(...)) xHasColor <- !is.null(x$material) && !is.null(x$material$color) hasMeshColor <- !missing(meshColor) if ( override ) { material <- x$material if (is.null(material)) material <- list() material[names(argMaterial)] <- argMaterial if (hasMeshColor || is.null(x$meshColor)) meshColor <- match.arg(meshColor) else meshColor <- x$meshColor if (is.null(texcoords) && !is.null(x$texcoords)) texcoords <- t(x$texcoords) } else { material <- argMaterial material[names(x$material)] <- x$material if (is.null(x$meshColor)) meshColor <- match.arg(meshColor) else meshColor <- x$meshColor if (!is.null(x$texcoords)) texcoords <- t(x$texcoords) } normals <- x$normals if (!is.null(normals)) normals <- t(normals) modes <- c(front, back) if (!allowedMeshColor(meshColor, modes)) stop("'meshColor = ", meshColor, "' not supported.") if (meshColor != "legacy") { if (is.null(material$color)) material$color <- material3d("color") if (is.null(material$alpha)) material$alpha <- material3d("alpha") } vertices <- t(asEuclidean2(x$vb)) result <- integer(0) prev <- 0 doVertices <- function(vals, inds, setPrev) { inds <- as.numeric(inds) if (length(unique(vals)) > 1) { vals <- rep_len(vals, max(inds)) vals[inds] } else vals } doLegacy <- function(vals, inds, setPrev) { inds <- as.numeric(inds) + prev if (setPrev) prev <<- prev + length(inds) if (length(unique(vals)) > 1) vals <- rep_len(vals, length(inds)) vals } doFaces <- function(vals, inds, setPrev) { if (!is.matrix(inds)) inds <- matrix(inds, nrow = 1) inds <- inds + prev if (setPrev) prev <<- prev + ncol(inds) vals <- rep_len(vals, ncol(inds)) rep(vals, each = nrow(inds)) } doEdges <- function(vals, inds, setPrev) { if (!is.matrix(inds)) inds <- matrix(inds, nrow = 1) inds <- inds + prev if (setPrev) prev <<- prev + length(inds) newlen <- ncol(inds) if (nrow(inds) > 1) newlen <- newlen * nrow(inds) / 2 vals <- rep_len(vals, newlen) if (nrow(inds) > 1) vals <- rep(vals, each = 2) vals } getArgs <- function(inds) { args <- c(list(x = vertices[as.numeric(inds),]), material) if (!is.null(texcoords)) args$texcoords <- texcoords[as.numeric(inds),] if (!is.null(normals)) args$normals <- normals[as.numeric(inds),] args$color <- repfn(args$color, inds, FALSE) args$alpha <- repfn(args$alpha, inds, TRUE) args } repfn <- switch(meshColor, vertices = doVertices, legacy = doLegacy, faces = doFaces, doLegacy) if (length(x$ip)) { args <- getArgs(x$ip) result <- c(result, points = do.call(points3d, args = args )) } if (length(x$is)) { args <- getArgs(x$is) result <- c(result, segments = do.call(segments3d, args = args )) } if (length(x$it)) { if (meshColor == "edges") { x$it <- x$it[c(1,2,2,3,3,1),] fn <- segments3d } else fn <- triangles3d args <- getArgs(x$it) result <- c(result, triangles = do.call(fn, args = args )) } if (length(x$ib)) { if (meshColor == "edges") { x$ib <- x$ib[c(1,2,2,3,3,4,4,1),] fn <- segments3d } else fn <- quads3d args <- getArgs(x$ib) result <- c(result, quads = do.call(fn, args = args )) } lowlevel(result) } # transformation support translate3d.mesh3d <- function( obj, x, y, z, ... ) { obj$vb <- t(translate3d(t(obj$vb), x, y, z)) return(obj) } rotate3d.mesh3d <- function( obj,angle,x,y,z,matrix, ... ) { obj$vb <- t(rotate3d(t(obj$vb), angle, x, y, z, matrix)) if ( !is.null(obj$normals) ) { if ( missing(matrix) ) obj$normals <- rotate3d(t(obj$normals), angle, x, y, z) else { if (nrow(matrix) == 4) matrix[4,1:3] <- 0 if (ncol(matrix) == 4) matrix[1:3,4] <- 0 obj$normals <- rotate3d(t(obj$normals), angle, x, y, z, t(solve(matrix))) } obj$normals <- t( obj$normals/sqrt(apply(obj$normals^2, 1, sum)) ) } return(obj) } scale3d.mesh3d <- function( obj, x, y, z, ... ) { obj$vb <- t(scale3d(t(obj$vb), x, y, z)) if ( !is.null(obj$normals) ) { obj$normals <- scale3d(t(obj$normals), 1/x, 1/y, 1/z) obj$normals <- t( obj$normals/sqrt(apply(obj$normals[,1:3]^2, 1, sum)) ) if (nrow(obj$normals) == 4) obj$normals[4,] <- 1 } return(obj) } # for debugging showNormals <- function(obj, scale = 1) { v <- obj$vb n <- obj$normals if (is.null(n)) { warning("No normals found.") return() } save <- par3d(skipRedraw = TRUE) on.exit(par3d(save)) for (i in seq_len(ncol(n))) { p0 <- v[1:3, i]/v[4, i] p1 <- p0 + n[1:3, i]*scale if (all(is.finite(c(p0, p1)))) arrow3d(p0, p1, type = "lines") } } print.mesh3d <- function(x, prefix = "", ...) { cat(prefix, " mesh3d object with ", ncol(x$vb), " vertices, ", paste(c( if (length(x$ip)) paste(length(x$ip), "points"), if (length(x$is)) paste(ncol(x$is), "segments"), if (length(x$it)) paste(ncol(x$it), "triangles"), if (length(x$ib)) paste(ncol(x$ib), "quads")), collapse = ", "), ".\n", sep = "") } match_names <- function(x, reference) { if (!is.null(x)) structure(x[names(reference)], class = class(x)) } # Compare old and new meshes all.equal.mesh3d <- function(target, current, ...) { if (inherits(current, "mesh3d")) all.equal(compare_proxy.mesh3d(target), compare_proxy.mesh3d(current), ...) else "'current' is not a mesh3d object" } rgl/R/filledContour3d.R0000644000176200001440000000375414100762640014433 0ustar liggesusersfilledContour3d <- function(obj, ...) UseMethod("filledContour3d") filledContour3d.rglId <- function(obj, plot = TRUE, replace = plot, ...) { mesh <- as.mesh3d(obj) result <- filledContour3d(mesh, plot = plot, ...) if (replace) pop3d(id = obj) result } if (getRversion() < "3.6.0") { hcl.colors <- function(n, ...) grDevices::cm.colors(n) } else hcl.colors <- grDevices::hcl.colors filledContour3d.mesh3d <- function(obj, fn = "z", nlevels = 20, levels = pretty(range(values), nlevels), color.palette = function(n) hcl.colors(n, "YlOrRd", rev = TRUE), col = color.palette(length(levels) - 1), minVertices = 0, plot = TRUE, keepValues = FALSE, ...) { nverts <- ncol(obj$vb) oldnverts <- nverts - 1 while (nverts < minVertices && oldnverts < nverts) { oldnverts <- nverts obj <- subdivision3d(obj, deform = FALSE, normalize = TRUE) nverts <- ncol(obj$vb) } if (is.null(fn)) fn <- obj$values if (is.null(fn)) stop("'fn' can only be NULL if 'obj' contains values.") verts <- asEuclidean(t(obj$vb)) if (is.numeric(fn)) values <- fn else { fn <- .getVertexFn(fn, parent.frame()) values <- fn(verts) } if (length(levels) < 2) stop("Must have at least 2 levels.") reverse <- levels[1] > levels[2] if (any((levels[-length(levels)] > levels[-1]) != reverse)) stop("Levels must be monotone increasing or decreasing") if (is.null(obj$material)) obj$material <- list() obj$material$color <- NA obj$values <- values result <- list() ivals <- seq_along(col) if (reverse) ivals <- rev(ivals) for (i in ivals) { r <- range(levels[c(i, i+1)]) obj <- clipMesh3d(obj, NULL, bound = r[1], keepValues = TRUE) strip <- clipMesh3d(obj, NULL, bound = r[2], greater = FALSE, keepValues = keepValues && !plot) strip$material$color <- col[i] result[[i]] <- cleanMesh3d(strip, rejoin = TRUE) } result <- do.call(merge, result) if (plot) shade3d(result, ...) else result } rgl/R/matrices.R0000644000176200001440000000712314145464133013201 0ustar liggesusers# Functions for creating 4x4 graphics matrices identityMatrix <- function() diag(nrow=4) scaleMatrix <- function(x,y,z) diag(c(x,y,z,1)) translationMatrix <- function(x,y,z) { result <- diag(4) result[4,1:3] <- c(x,y,z) result } rotationMatrix <- function(angle,x,y,z,matrix) { if (missing(matrix)) { if (angle == 0) return(identityMatrix()) u <- c(x,y,z)/sqrt(x^2+y^2+z^2) cosa <- cos(angle) sina <- sin(angle) matrix <- (1-cosa)*outer(u,u) matrix <- matrix + diag(3)*cosa matrix[1,2] <- matrix[1,2] - sina*u[3] matrix[1,3] <- matrix[1,3] + sina*u[2] matrix[2,1] <- matrix[2,1] + sina*u[3] matrix[2,3] <- matrix[2,3] - sina*u[1] matrix[3,1] <- matrix[3,1] - sina*u[2] matrix[3,2] <- matrix[3,2] + sina*u[1] } if (identical(all.equal(dim(matrix), c(3,3)), TRUE)) matrix <- cbind(rbind(matrix,c(0,0,0)),c(0,0,0,1)) return(matrix) } # Coordinate conversions asHomogeneous <- function(x) { if (is.matrix(x)) { if (ncol(x) == 3) return(cbind(x,1)) if (ncol(x) == 4) return(x) } else { if (length(x) %% 3 == 0) return(cbind(matrix(x, ncol = 3, byrow = TRUE),1)) if (length(x) %% 4 == 0) return(matrix(x, ncol = 4, byrow = TRUE)) } stop("Don't know how to convert x") } asHomogeneous2 <- function(x) { if (is.matrix(x)) { if (nrow(x) == 3) return(rbind(x,1)) if (nrow(x) == 4) return(x) } else { if (length(x) %% 3 == 0) return(rbind(matrix(x, nrow = 3), 1)) if (length(x) %% 4 == 0) return(matrix(x, nrow = 4)) } stop("Don't know how to convert x") } asEuclidean <- function(x) { if (is.matrix(x)) { if (ncol(x) == 4) return(x[, 1:3, drop = FALSE]/x[, 4]) if (ncol(x) == 3) return(x) } else { if (length(x) %% 4 == 0) return(asEuclidean(matrix(x, ncol = 4, byrow = TRUE))) if (length(x) %% 3 == 0) return(matrix(x, ncol = 3, byrow = TRUE)) } stop("Don't know how to convert x") } asEuclidean2 <- function(x) { if (is.matrix(x)) { if (nrow(x) == 4) return(rbind(x[1,]/x[4,], x[2,]/x[4,], x[3,]/x[4,])) if (nrow(x) == 3) return(x) } else { if (length(x) %% 4 == 0) return(asEuclidean2(matrix(x, nrow = 4))) if (length(x) %% 3 == 0) return(matrix(x, nrow = 3)) } stop("Don't know how to convert x") } # Default implementations of transformations translate3d.default <- function(obj,x,y,z,...) { if (is.matrix(obj)) n <- dim(obj)[1] else n <- 1 if (length(obj) == 3 || (is.matrix(obj) && dim(obj)[2] == 3)) return(obj + cbind(rep(x,n), rep(y,n), rep(z,n))) else if (length(obj) == 4 || (is.matrix(obj) && dim(obj)[2] == 4)) return(obj %*% translationMatrix(x,y,z)) else stop("Unsupported object for translation") } scale3d.default <- function(obj,x,y,z,...) { if (is.matrix(obj)) n <- dim(obj)[1] else n <- 1 if (length(obj) == 3 || (is.matrix(obj) && dim(obj)[2] == 3)) return(obj * cbind(rep(x,n), rep(y,n), rep(z,n))) else if (length(obj) == 4 || (is.matrix(obj) && dim(obj)[2] == 4)) return(obj %*% scaleMatrix(x,y,z)) else stop("Unsupported object for scaling") } rotate3d.default <- function(obj,angle,x,y,z,matrix,...) { if (length(obj) == 3 || (is.matrix(obj) && dim(obj)[2] == 3)) return(asEuclidean(asHomogeneous(obj) %*% rotationMatrix(angle,x,y,z,matrix))) else if (length(obj) == 4 || (is.matrix(obj) && dim(obj)[2] == 4)) return(obj %*% rotationMatrix(angle,x,y,z,matrix)) else stop("Unsupported object for rotation") } rgl/R/callbacks.R0000644000176200001440000000235114100762640013302 0ustar liggesusersrgl.setMouseCallbacks <- function(button, begin=NULL, update=NULL, end=NULL, dev = cur3d(), subscene = currentSubscene3d(dev)) { invisible(.Call(rgl_setMouseCallbacks, as.integer(button), begin, update, end, as.integer(dev), as.integer(subscene))) } rgl.getMouseCallbacks <- function(button, dev = cur3d(), subscene = currentSubscene3d(dev)) .Call(rgl_getMouseCallbacks, as.integer(button), as.integer(dev), as.integer(subscene)) rgl.setWheelCallback <- function(rotate=NULL, dev = cur3d(), subscene = currentSubscene3d(dev)) { invisible(.Call(rgl_setWheelCallback, rotate, as.integer(dev), as.integer(subscene))) } rgl.getWheelCallback <- function(dev = cur3d(), subscene = currentSubscene3d(dev)) .Call(rgl_getWheelCallback, as.integer(dev), as.integer(subscene)) rgl.setAxisCallback <- function(axis, draw = NULL, dev = cur3d(), subscene = currentSubscene3d(dev)) { stopifnot(length(axis) == 1, axis %in% 1:3) .Call(rgl_setAxisCallback, draw, as.integer(dev), as.integer(subscene), as.integer(axis - 1)) invisible(NULL) } rgl.getAxisCallback <- function(axis, dev = cur3d(), subscene = currentSubscene3d(dev)) { .Call(rgl_getAxisCallback, as.integer(dev), as.integer(subscene), as.integer(axis - 1)) } rgl/R/getscene.R0000644000176200001440000003516614145464133013177 0ustar liggesusersscene3d <- function(minimal = TRUE) { saveSubscene <- currentSubscene3d() on.exit(useSubscene3d(saveSubscene)) defaultmaterial <- material3d() matdiff <- function(mat) { for (m in names(mat)) { if (identical(mat[[m]], defaultmaterial[[m]])) mat[[m]] <- NULL } mat } getObject <- function(id, type) { result <- list(id=id, type=type) if (!(type %in% c("light", "clipplanes"))) { mat <- rgl.getmaterial(id=id) lit <- mat$lit result$material <- matdiff(mat) } else lit <- FALSE attribs <- c("vertices", "colors", "texcoords", "dim", "texts", "cex", "adj", "radii", "ids", "usermatrix", "types", "offsets", "centers", "family", "font", "pos", "axes", "indices") if (lit || !minimal || type %in% c("light", "clipplanes", "planes")) attribs <- c(attribs, "normals") for (a in attribs) if (rgl.attrib.count(id, a)) result[[a]] <- rgl.attrib(id, a) flags <- rgl.attrib(id, "flags") if (length(flags)) { if ("ignoreExtent" %in% rownames(flags)) result$ignoreExtent <- flags["ignoreExtent", 1] if ("fixedSize" %in% rownames(flags)) result$fixedSize <- flags["fixedSize", 1] if ("fastTransparency" %in% rownames(flags)) result$fastTransparency <- flags["fastTransparency", 1] if ("flipped" %in% rownames(flags)) result$flipped <- flags["flipped", 1] } if (!is.null(result$ids)) { objlist <- vector("list", nrow(result$ids)) for (i in seq_len(nrow(result$ids))) objlist[[i]] <- getObject(result$ids[i,1], result$types[i,1]) result$objects <- objlist } if (type == "background") { flags <- rgl.attrib(id, "flags") result$sphere <- flags["sphere", 1] result$fogtype <- if (flags["linear_fog", 1]) "linear" else if (flags["exp_fog", 1]) "exp" else if (flags["exp2_fog", 1]) "exp2" else "none" result$fogscale <- as.numeric(rgl.attrib(id, "fogscale")) } else if (type == "bboxdeco") { flags <- rgl.attrib(id, "flags") result$draw_front <- flags["draw_front", 1] } else if (type == "light") { flags <- rgl.attrib(id, "flags") result$viewpoint <- flags["viewpoint", 1] result$finite <- flags["finite", 1] } class(result) <- c(paste0("rgl", type), "rglobject") result } getSubscene <- function(id) { useSubscene3d(id) result <- list(id = id, type = "subscene", par3d = par3d()) result$embeddings <- subsceneInfo()$embeddings objs <- ids3d(c("background", "bboxdeco", "shapes", "lights")) result$objects <- objs$id if (nrow(obj <- ids3d("subscene", subscene = id))) { subscenes <- vector("list", nrow(obj)) ids <- obj$id for (i in seq_len(nrow(obj))) subscenes[[i]] <- getSubscene(ids[i]) result$subscenes <- subscenes } class(result) <- c("rglsubscene", "rglobject") result } result <- list() result$material <- defaultmaterial result$rootSubscene <- getSubscene(rootSubscene()) objs <- ids3d(c("shapes", "lights", "background", "bboxdeco"), subscene=0) objlist <- vector("list", nrow(objs)) ids <- objs$id types <- as.character(objs$type) for (i in seq_len(nrow(objs))) { objlist[[i]] <- getObject(ids[i], types[i]) names(objlist)[i] <- as.character(ids[i]) } result$objects <- objlist # If there are user callbacks for the mouse, they'll # be recorded in rgl.callback.env devname <- paste0("dev", cur3d()) callbacks <- rgl.callback.env[[devname]] if (!is.null(callbacks)) { for (name in names(callbacks)) { subscene <- sub("^sub", "", name) sub <- findSubscene(result$rootSubscene, subscene) if (!is.null(sub)) { sub$callbacks <- callbacks[[name]] result$rootSubscene <- replaceSubscene(result$rootSubscene, subscene, sub) } bboxid <- sub("^bbox", "", name) bbox <- result$objects[[bboxid]] if (!is.null(bbox)) { bbox$callbacks <- callbacks[[name]] result$objects[[bboxid]] <- bbox } } result$javascript <- callbacks$javascript } class(result) <- "rglscene" result } print.rglscene <- function(x, ...) { cat(gettext("RGL scene containing:\n")) if (!is.null(x$par3d)) cat(gettext(" par3d:\tscene information\n")) if (!is.null(x$material)) cat(gettext(" material:\tdefault material properties\n")) if (!is.null(x$objects)) { cat(gettextf(" objects:\tlist of %d object(s):\n", length(x$objects))) cat(" \t", sapply(x$objects, function(obj) obj$type), "\n") } if (!is.null(x$root)) cat(gettext(" root:\ta root subscene\n")) invisible(x) } summary.rglscene <- function(object, ...) { result <- list() nobjs <- length(object$objects) if (nobjs) result$objects <- data.frame(type=sapply(object$objects, function(obj) obj$type)) if (!is.null(object$rootSubscene)) result$subscenes <- summary(object$rootSubscene) result } summary.rglsubscene <- function(object, ...) { result <- data.frame(id = object$id, parent = NA, objects = 0) result$objects <- list(object$objects) if (length(object$subscenes)) { children <- do.call(rbind, lapply(object$subscenes, summary)) children[is.na(children$parent),"parent"] <- object$id result <- rbind(result, children) } result } print.rglobject <- function(x, ...) { cat(gettextf("RGL object of type %s containing components\n", x$type)) cat(" ") cat(names(x), sep=", ") cat("\n") } print.rglsubscene <- function(x, ...) { cat(gettext("RGL subscene containing components\n")) cat(" ") cat(names(x), sep=", ") cat("\n") } plot3d.rglscene <- function(x, add=FALSE, ...) { root <- x$rootSubscene if (is.null(root)) root <- x # Should work with pre-subscene objects if (!add) { params <- getr3dDefaults() if (!is.null(x$material)) { if (is.null(params$material)) params$material <- list() params$material[names(x$material)] <- x$material } if (!is.null(root$bg)) { if (is.null(params$bg)) params$bg <- list() params$bg[names(params$material)] <- params$material params$bg[names(x$bg$material)] <- x$bg$material x$bg$material <- x$bg$id <- x$bg$type <- NULL params$bg[names(x$bg)] <- x$bg } if (!is.null(root$par3d)) { ind <- !(names(root$par3d) %in% .Par3d.readonly) params[names(root$par3d)[ind]] <- root$par3d[ind] } open3d(params = params) # Some older scenes might not have a light in them, so only clear if one is there for (i in seq_along(x$objects)) { obj <- x$objects[[i]] if (obj$type == "light") { clear3d("lights") break } } } save <- par3d(skipRedraw = TRUE) on.exit(par3d(save)) if (is.null(x$rootSubscene)) { results <- NULL for (i in seq_along(x$objects)) { obj <- x$objects[[i]] results <- c(results, plot3d(obj)) } if (!is.null(obj <- x$bbox)) plot3d(obj) } else results <- plot3d(root, x$objects, root = TRUE, ...) highlevel(results) } plot3d.rglsubscene <- function(x, objects, root = TRUE, ...) { if (root) { if (!is.null(x$embeddings)) { info <- subsceneInfo(embeddings = x$embeddings) subscene <- info$id } else subscene <- currentSubscene3d() if (!is.null(x$par3d$viewport)) par3d(viewport = x$par3d$viewport) } else subscene <- newSubscene3d(viewport = x$embeddings["viewport"], projection = x$embeddings["projection"], model = x$embeddings["model"], newviewport = x$par3d$viewport, copyLights = FALSE) if (!is.null(x$par3d$scale)) par3d(scale = x$par3d$scale) listeners <- list(x$par3d$listeners) # list contains old ids names(listeners) <- subscene # names are new ids results <- subscene names(results) <- paste0("subscene", as.character(x$id)) objs <- x$objects for (id in as.character(objs)) { obj <- objects[[id]] if (is.null(obj$newid)) results <- c(results, objects[[id]]$newid <- plot3d(obj, ...)) else addToSubscene3d(obj$newid) } for (i in seq_along(x$subscenes)) { useSubscene3d(subscene) res <- plot3d(x$subscenes[[i]], objects, root=FALSE, ...) results <- c(results, res$results) listeners <- c(listeners, res$listeners) objects <- res$objects } if (root) { # Translate all the listener values dotranslations <- function(id) { info <- subsceneInfo(id = id) oldlisteners <- listeners[[as.character(id)]] par3d(listeners = results[paste0("subscene", oldlisteners)], subscene = id) for (child in info$children) dotranslations(child) } dotranslations(subscene) return(results) } else return(list(results=results, objects=objects, listeners=listeners)) } plot3d.rglobject <- function(x, ...) { type <- x$type fn <- switch(type, points = points3d, lines = segments3d, linestrip = lines3d, triangles = triangles3d, quads = quads3d, text = texts3d, spheres = spheres3d, abclines = abclines3d, planes = planes3d, surface = surface3d, sprites = sprites3d, light = light3d, clipplanes = clipplanes3d, NULL) if (is.null(fn)) { warning(gettextf("Object type '%s' not handled.", type), domain = NA) return() } if (!is.null(x$ignoreExtent)) { save <- par3d(ignoreExtent = x$ignoreExtent) on.exit(par3d(save)) } args <- list() args$x <- x$vertices args$normals <- x$normals args$texcoords <- x$texcoords args$texts <- x$texts args$cex <- x$cex args$adj <- x$adj args$radius <- x$radii args$d <- x$offsets args$indices <- x$indices switch(type, abclines = { odd <- seq_len(nrow(args$x)) %% 2 == 1 ends <- args$x[odd,,drop=FALSE] args$a <- args$x[!odd,,drop=FALSE] - ends args$x <- ends }, planes =, clipplanes = { args$a <- args$normals args$x <- NULL args$normals <- NULL }, surface = { dim <- x$dim args$y <- matrix(args$x[,2], dim[1], dim[2]) args$z <- matrix(args$x[,3], dim[1], dim[2]) args$x <- matrix(args$x[,1], dim[1], dim[2]) if (!is.null(args$normals)) { args$normal_x <- matrix(args$normals[,1], dim[1], dim[2]) args$normal_y <- matrix(args$normals[,2], dim[1], dim[2]) args$normal_z <- matrix(args$normals[,3], dim[1], dim[2]) args$normals <- NULL } if (!is.null(args$texcoords)) { args$texture_s <- matrix(args$texcoords[,1], dim[1], dim[2]) args$texture_t <- matrix(args$texcoords[,2], dim[1], dim[2]) args$texcoords <- NULL } }, sprites = { save2 <- par3d(skipRedraw = TRUE) on.exit(par3d(save2), add=TRUE) if (!is.null(x$objects)) { ids <- numeric(length(x$objects)) for (i in seq_along(ids)) ids[i] <- plot3d(x$objects[[i]]) args$shapes <- ids } args$userMatrix <- x$usermatrix }) mat <- x$material if (is.null(mat)) mat <- list() if (!is.null(col <- x$colors)) { mat$color <- rgb(col[,1], col[,2], col[,3]) mat$alpha <- col[,4] } if (type == "light") { if (!x$finite) { args$x <- NULL vx <- x$vertices[1] vy <- x$vertices[2] vz <- x$vertices[3] args$phi <- atan2(vy, sqrt(vx^2 + vz^2))*180/pi args$theta <- atan2(vx, vz)*180/pi } args$viewpoint.rel <- x$viewpoint args$ambient <- mat$color[1] args$diffuse <- mat$color[2] args$specular <- mat$color[3] } else args <- c(args, mat) do.call(fn, args) } plot3d.rglbboxdeco <- function(x, ...) { args <- list() v <- x$vertices t <- x$texts ind <- is.na(v[,2]) & is.na(v[,3]) if (any(ind)) { args$xat <- v[ind,1] if (!is.null(t)) args$xlab <- t[ind] else args$xlab <- signif(args$xat, 4) } ind <- is.na(v[,1]) & is.na(v[,3]) if (any(ind)) { args$yat <- v[ind,2] if (!is.null(t)) args$ylab <- t[ind] else args$ylab <- signif(args$yat, 4) } ind <- is.na(v[,1]) & is.na(v[,2]) if (any(ind)) { args$zat <- v[ind,3] if (!is.null(t)) args$zlab <- t[ind] else args$zlab <- signif(args$zat, 4) } args$draw_front <- x$draw_front args <- c(args, x$material) do.call("bbox3d", args) } plot3d.rglbackground <- function(x, ...) { mat <- x$material if (is.null(mat)) mat <- list() if (!is.null(col <- x$colors)) { mat$color <- rgb(col[,1], col[,2], col[,3]) mat$alpha <- col[,4] } args <- c(list(sphere = x$sphere, fogtype = x$fogtype), mat) do.call("bg3d", args) } plot3d.rglWebGL <- function(x, ...) { plot3d(attr(x, "origScene"), ...) } compare_proxy.rglscene <- function(x, path = "x") { list(object = old_compare_proxy.rglscene(x), path = paste0("compare_proxy(", path, ")")) } old_compare_proxy.rglscene <- function(x) { doSubscene <- function(obj) { if (!is.null(obj$par3d)) { rect <- obj$par3d$windowRect if (!is.null(rect)) { rect <- rect - rect[1:2] obj$par3d$windowRect <- rect } } ids <<- c(ids, obj$id) if (is.list(obj$subscenes)) obj$subscenes <- lapply(obj$subscenes, doSubscene) } ids <- c(x$rootSubscene$id, sapply(x$objects, function(obj) obj$id)) x$rootSubscene <- doSubscene(x$rootSubscene) ids <- unique(ids) newids <- ids - min(ids) + 1 names(newids) <- ids newid <- function(id) { result <- if (is.null(id)) NULL else unname(newids[as.character(id)]) if (any(is.na(result))) stop("id gives NA") result } newidc <- function(id) as.character(newid(id)) fixvec <- function(vec) { if (is.list(vec)) lapply(vec, fixobj) else newid(vec) } fixobj <- function(obj) { obj$id <- newid(obj$id) obj$objects <- fixvec(obj$objects) obj$ids <- fixvec(obj$ids) if (!is.null(obj$par3d)) { obj$par3d$listeners <- newid(obj$par3d$listeners) obj$par3d$fontname <- NULL obj$par3d$maxClipPlanes <- NULL obj$par3d$glVersion <- NULL } if (!is.null(obj$material)) { obj$material$texture <- NULL } obj$subscenes <- fixvec(obj$subscenes) obj } x$rootSubscene <- fixobj(x$rootSubscene) x$objects <- lapply(x$objects, fixobj) names(x$objects) <- newidc(names(x$objects)) class(x) <- NULL x } # Compare old and new scenes all.equal.rglscene <- function(target, current, ...) { if (inherits(current, "rglscene")) { target <- compare_proxy.rglscene(target) current <- compare_proxy.rglscene(current) result <- all.equal(target, current, ...) if (!isTRUE(result) && isNamespaceLoaded("waldo")) result <- waldo::compare(target, current) result } else "'current' is not an rglscene object" } as.rglscene <- function(x, ...) { UseMethod("as.rglscene") } rgl/R/subdivision.mesh3d.R0000644000176200001440000001566414100762640015116 0ustar liggesusers# # subdivision.mesh3d # # an *efficient* algorithm for subdivision of mesh3d objects # using addition operations and homogenous coordinates # by Daniel Adler # # edgemap <- function( size ) { data<-vector( mode="numeric", length=( size*(size+1) )/2 ) data[] <- -1 return(data) } edgeindex <- function( from, to, size, row=min(from,to), col=max(from,to) ) return( row*size - ( row*(row+1) )/2 - (size-col) ) divide.mesh3d <- function(mesh,vb=mesh$vb, ib=mesh$ib, it=mesh$it ) { nv <- dim(vb)[2] inds <- seq_len(nv) nq <- if (is.null(ib)) 0 else dim(ib)[2] nt <- if (is.null(it)) 0 else dim(it)[2] primout <- character() nvmax <- nv + nq + ( nv*(nv+1) )/2 outvb <- matrix(data=0,nrow=4,ncol=nvmax) # copy old points outvb[,seq_len(nv)] <- vb vcnt <- nv em <- edgemap( nv ) if (!is.null(mesh$normals)) { if (NROW(mesh$normals) == 4) mesh$normals <- t(asEuclidean(t(mesh$normals))) newnormals <- matrix(data=0,nrow=3,ncol=nvmax) newnormals[,inds] <- mesh$normals } else newnormals <- NULL if (!is.null(mesh$texcoords)) { newtexcoords <- matrix(data=0,nrow=2,ncol=nvmax) newtexcoords[,inds] <- mesh$texcoords } else newtexcoords <- NULL if (!is.null(newnormals) || !is.null(newtexcoords)) { newcount <- rep(0, nvmax) newcount[inds] <- 1 } result <- structure(list(material=mesh$material), class="mesh3d") if (nq) { newnq <- nq*4 outib <- matrix(nrow=4,ncol=newnq) vcnt <- vcnt + nq for (i in 1:nq ) { isurf <- nv + i for (j in 1:4 ) { iprev <- ib[((j+2)%%4) + 1, i] ithis <- ib[j,i] inext <- ib[ (j%%4) + 1, i] # get or alloc edge-point this->next mindex <- edgeindex(ithis, inext, nv) enext <- em[mindex] if (enext == -1) { vcnt <- vcnt + 1 enext <- vcnt em[mindex] <- enext } # get or alloc edge-point prev->this mindex <- edgeindex(iprev, ithis, nv) eprev <- em[mindex] if (eprev == -1) { vcnt <- vcnt + 1 eprev <- vcnt em[mindex] <- eprev } # gen grid outib[, (i-1)*4+j ] <- c( ithis, enext, isurf, eprev ) # calculate surface point outvb[,isurf] <- outvb[,isurf] + vb[,ithis] # calculate edge point outvb[,enext] <- outvb[,enext] + vb[,ithis] outvb[,eprev] <- outvb[,eprev] + vb[,ithis] if (!is.null(newnormals)) { thisnorm <- mesh$normals[,ithis] newnormals[,isurf] <- newnormals[,isurf] + thisnorm newnormals[,enext] <- newnormals[,enext] + thisnorm newnormals[,eprev] <- newnormals[,eprev] + thisnorm } if (!is.null(newtexcoords)) { thistexcoord <- mesh$texcoords[,ithis] newtexcoords[,isurf] <- newtexcoords[,isurf] + thistexcoord newtexcoords[,enext] <- newtexcoords[,enext] + thistexcoord newtexcoords[,eprev] <- newtexcoords[,eprev] + thistexcoord } if (!is.null(newnormals) || !is.null(newtexcoords)) { newcount[isurf] <- newcount[isurf] + 1 newcount[enext] <- newcount[enext] + 1 newcount[eprev] <- newcount[eprev] + 1 } } } primout <- "quad" result$ib <- outib } if (nt) { newnt <- nt*4 outit <- matrix(nrow=3,ncol=newnt) for (i in 1:nt ) { for (j in 1:3 ) { iprev <- it[((j+1)%%3) + 1, i] ithis <- it[j,i] inext <- it[ (j%%3) + 1, i] # get or alloc edge-point this->next mindex <- edgeindex(ithis, inext, nv) enext <- em[mindex] if (enext == -1) { vcnt <- vcnt + 1 enext <- vcnt em[mindex] <- enext } # get or alloc edge-point prev->this mindex <- edgeindex(iprev, ithis, nv) eprev <- em[mindex] if (eprev == -1) { vcnt <- vcnt + 1 eprev <- vcnt em[mindex] <- eprev } # gen grid outit[, (i-1)*4+j ] <- c( ithis, enext, eprev ) # calculate edge point outvb[,enext] <- outvb[,enext] + vb[,ithis] outvb[,eprev] <- outvb[,eprev] + vb[,ithis] if (!is.null(newnormals)) { thisnorm <- mesh$normals[,ithis] newnormals[,enext] <- newnormals[,enext] + thisnorm newnormals[,eprev] <- newnormals[,eprev] + thisnorm } if (!is.null(newtexcoords)) { thistexcoord <- mesh$texcoords[,ithis] newtexcoords[,enext] <- newtexcoords[,enext] + thistexcoord newtexcoords[,eprev] <- newtexcoords[,eprev] + thistexcoord } if (!is.null(newnormals) || !is.null(newtexcoords)) { newcount[enext] <- newcount[enext] + 1 newcount[eprev] <- newcount[eprev] + 1 } } # Now central triangle outit[, (i-1)*4+4 ] <- c( em[edgeindex(ithis, inext, nv)], em[edgeindex(inext, iprev, nv)], em[edgeindex(iprev, ithis, nv)] ) } primout <- c(primout, "triangle") result$it <- outit } if (!is.null(newnormals) || !is.null(newtexcoords)) newcount <- newcount[seq_len(vcnt)] if (!is.null(newnormals)) newnormals <- newnormals[, seq_len(vcnt)]/rep(newcount, each=3) if (!is.null(newtexcoords)) newtexcoords <- newtexcoords[, seq_len(vcnt)]/rep(newcount, each=2) result$vb <- outvb[,seq_len(vcnt)] result$normals <- newnormals result$texcoords <- newtexcoords return( result ) } normalize.mesh3d <- function(mesh) { mesh$vb[1,] <- mesh$vb[1,]/mesh$vb[4,] mesh$vb[2,] <- mesh$vb[2,]/mesh$vb[4,] mesh$vb[3,] <- mesh$vb[3,]/mesh$vb[4,] mesh$vb[4,] <- 1 return(mesh) } deform.mesh3d <- function( mesh, vb=mesh$vb, ib=mesh$ib, it=mesh$it ) { nv <- dim(vb)[2] nq <- if (is.null(ib)) 0 else dim(ib)[2] nt <- if (is.null(it)) 0 else dim(it)[2] out <- matrix(0, nrow=4, ncol=nv ) if (nq) { for ( i in 1:nq ) { for (j in 1:4 ) { iprev <- ib[((j+2)%%4) + 1, i] ithis <- ib[j,i] inext <- ib[ (j%%4) + 1, i] out[ ,ithis ] <- out[ , ithis ] + vb[,iprev] + vb[,ithis] + vb[,inext] } } mesh$vb <- out } if (nt) { for ( i in 1:nt ) { for (j in 1:3 ) { iprev <- it[((j+1)%%3) + 1, i] ithis <- it[j,i] inext <- it[ (j%%3) + 1, i] out[ ,ithis ] <- out[ , ithis ] + vb[,iprev] + vb[,ithis] + vb[,inext] } } mesh$vb <- out } return(mesh) } subdivision3d.mesh3d <- function(x,depth=1,normalize=FALSE,deform=TRUE,...) { mesh <- x if (depth) { mesh <- divide.mesh3d(mesh) if (normalize) mesh <- normalize.mesh3d(mesh) if (deform) mesh <- deform.mesh3d(mesh) mesh<-subdivision3d.mesh3d(mesh,depth-1,normalize,deform) } return(mesh) } rgl/R/plot3d.R0000644000176200001440000002525214145464133012602 0ustar liggesusersplot3d <- function(x, ...) UseMethod("plot3d") plot3d.default <- function(x, y = NULL, z = NULL, xlab = NULL, ylab = NULL, zlab = NULL, type = 'p', col = material3d("color")[1], size = material3d("size"), lwd = material3d("lwd"), radius = avgscale*size/60, add = FALSE, aspect = !add, xlim = NULL, ylim = NULL, zlim = NULL, forceClipregion = FALSE, decorate = !add, ...) { if (!add) next3d() skip <- par3d(skipRedraw=TRUE) on.exit(par3d(skip)) xlabel <- if (!missing(x)) deparse(substitute(x)) ylabel <- if (!missing(y)) deparse(substitute(y)) zlabel <- if (!missing(z)) deparse(substitute(z)) xyz <- xyz.coords(x,y,z, xlab=xlabel, ylab=ylabel, zlab=zlabel, recycle=TRUE) x <- xyz$x y <- xyz$y z <- xyz$z if (is.null(xlab)) xlab <- xyz$xlab if (is.null(ylab)) ylab <- xyz$ylab if (is.null(zlab)) zlab <- xyz$zlab if (type == "s" && missing(radius)) { xvals <- x yvals <- y zvals <- z if (add && diff(bbox <- par3d("bbox"))[1] > 0) { xvals <- c(x, bbox[1:2]) yvals <- c(y, bbox[3:4]) zvals <- c(z, bbox[5:6]) } if (!add) { if (!is.null(xlim)) xvals <- xlim if (!is.null(ylim)) yvals <- ylim if (!is.null(zlim)) zvals <- zlim } avgscale <- sqrt(sum(c(diff(range(xvals,na.rm=TRUE)), diff(range(yvals,na.rm=TRUE)), diff(range(zvals,na.rm=TRUE)))^2/3)) } savesubscene <- currentSubscene3d() result <- setClipregion(xlim, ylim, zlim, forceClipregion) result <- c(result, data=switch(type, p = points3d(x, y, z, color=col, size=size, ...), s = spheres3d(x, y, z, radius=radius, color=col, ...), l = lines3d(x, y, z, color=col, lwd=lwd, ...), h = segments3d(rep(x,rep(2,length(x))), rep(y,rep(2,length(y))), rbind(rep(0,length(z)),z), color = rep(col, rep(2,length(col))), lwd=lwd, ...), # this is a hack to plot invisible segments n = if (!add) segments3d(rep(range(x, na.rm=TRUE), c(2,2)), rep(range(y, na.rm=TRUE), c(2,2)), rep(range(z, na.rm=TRUE), c(2,2)))) ) useSubscene3d(savesubscene) if (decorate) result <- c(result, decorate3d(xlab=xlab, ylab=ylab, zlab=zlab, aspect = aspect, xlim=xlim, ylim=ylim, zlim=zlim, ...)) if (!add) highlevel(result) else lowlevel(result) } plot3d.mesh3d <- function(x, xlab = "x", ylab = "y", zlab = "z", type = c("shade", "wire", "dots"), add = FALSE, aspect = !add, ...) { if (!add) next3d() skip <- par3d(skipRedraw=TRUE) on.exit(par3d(skip)) if (missing(xlab) && !is.null(x$xlab)) xlab <- x$xlab if (missing(ylab) && !is.null(x$ylab)) ylab <- x$ylab if (missing(zlab) && !is.null(x$zlab)) zlab <- x$zlab result <- switch(match.arg(type), shade = shade3d(x, ...), wire = wire3d(x, ...), dots = dot3d(x, ...)) if (!add) { result <- c(result, decorate3d(xlab = xlab, ylab = ylab, zlab = zlab, aspect = aspect, ...)) highlevel(result) } else lowlevel(result) } decorate3d <- function(xlim = NULL, ylim = NULL, zlim = NULL, xlab = "x", ylab = "y", zlab = "z", box = TRUE, axes = TRUE, main = NULL, sub = NULL, top = TRUE, aspect = FALSE, expand = 1.03, tag = material3d("tag"), ...) { if (is.logical(aspect)) { autoscale <- aspect aspect <- c(1,1,1) } else autoscale <- TRUE result <- numeric(0) if (length(c(xlim, ylim, zlim))) { ranges <- .getRanges() if (is.null(xlim)) xlim <- ranges$xlim if (is.null(ylim)) ylim <- ranges$ylim if (is.null(zlim)) zlim <- ranges$zlim ind <- c(1,1,2,2) result <- c(result, strut=segments3d(xlim[ind], ylim[ind], zlim[ind], tag = tag)) } if (autoscale) aspect3d(aspect) if (axes) result <- c(result, axes=axes3d(box=box, expand=expand, tag = tag)) result <- c(result, title3d(xlab = xlab, ylab = ylab, zlab = zlab, main = main, sub = sub, tag = tag)) if (top) rgl.bringtotop() lowlevel(result) } plot3d.function <- function(x, ...) persp3d(x, ...) plot3d.deldir <- function(x, ...) persp3d(x, ...) plot3d.triSht <- plot3d.tri <- function(x, z, ...) persp3d(x, z, ...) plot3d.formula <- function(x, data = NULL, xlab = xyz$xlab, ylab = xyz$ylab, zlab = xyz$zlab, ...) { if (!is.null(data)) environment(x) <- list2env(data, envir = environment(x)) xyz <- xyz.coords(x) plot3d(xyz, xlab = xlab, ylab = ylab, zlab = zlab, ...) } plot3d.lm <- function(x, which = 1, plane.col = "gray", plane.alpha = 0.5, sharedMouse = TRUE, use_surface3d, do_grid = TRUE, grid.col = "black", grid.alpha = 1, grid.steps = 5, sub.steps = 4, vars = get_all_vars(terms(x), x$model), clip_to_density = 0, ...) { stopifnot(which %in% 1:3) dots <- list(...) n <- length(which) if (clip_to_density > 0) { if (!requireNamespace("MASS", quietly = TRUE)) { warning("'clip_to_density' requires the MASS package.") clip_to_density <- 0 } if (!requireNamespace("akima", quietly = TRUE)) { warning("'clip_to_density' requires the akima package.") clip_to_density <- 0 } } result <- NULL if (n > 1) { cols <- ceiling(sqrt(n)) rows <- ceiling(n/cols) mfrow3d(rows, cols, sharedMouse = sharedMouse) } fit <- x missing_vars <- missing(vars) cols <- ncol(vars) if (cols < 3) stop("Model has only ", cols, " variables.") if (cols > 3) warning("Model has ", cols, " variables; first 3 used.") observed <- vars[, c(2, 3, 1)] names <- colnames(observed) if (is.null(dots$xlab)) dots$xlab <- names[1] if (is.null(dots$ylab)) dots$ylab <- names[2] if (is.null(dots$zlab)) dots$zlab <- names[3] if (missing(use_surface3d)) use_surface3d <- !identical(class(fit), "lm") || ncol(as.matrix(model.frame(fit))) > 3 if (clip_to_density > 0) { densityVals <- MASS::kde2d(observed[,1], observed[,2]) densityVals$z <- with(densityVals, z/max(z)) # nolint density <- function(xyz) { with(densityVals, akima::bilinear(x, y, z, xyz[,1], xyz[,2])$z) # nolint } } plotGrid <- function(i, x, y, x0, y0, z) { dots$color <- grid.col dots$alpha <- grid.alpha dots$color <- grid.col dots$alpha <- grid.alpha dots$front <- dots$back <- dots$polygon_offset <- dots$type <- NULL lenx <- length(x) lenx0 <- length(x0) leny <- length(y) leny0 <- length(y0) x <- c(rep(x0, each = leny + 1), rep(c(x, NA), leny0)) y <- c(rep(c(y, NA), lenx0), rep(y0, each = lenx + 1)) if (missing(z)) { newdat <- data.frame(x, y) names(newdat) <- names[1:2] z <- predict(fit, newdata = newdat) } grid <- do.call(lines3d, c(list(x, y, z), dots)) if (clip_to_density > 0) grid <- clipObj3d(grid, density, clip_to_density, minVertices = 1000) names(grid) <- paste0("grid.", i) grid } plotPoints <- function(i, points, zlab) { dots$zlab <- zlab plot <- do.call(plot3d, c(list(x = points), dots)) names(plot) <- paste0(names(plot), ".", i) plot } plotSurface <- function(i) { bbox <- par3d("bbox") xlim <- c(bbox[1], bbox[2]) x0 <- pretty(xlim, grid.steps) ylim <- c(bbox[3], bbox[4]) y0 <- pretty(ylim, grid.steps) if (sub.steps > 1) { x <- rep(x0, each = sub.steps) + seq(0, diff(x0[1:2]), length.out = sub.steps + 1)[-(sub.steps + 1)] y <- rep(y0, each = sub.steps) + seq(0, diff(y0[1:2]), length.out = sub.steps + 1)[-(sub.steps + 1)] } else { x <- x0 y <- y0 } x <- c(xlim[1], x[xlim[1] < x & x < xlim[2]], xlim[2]) y <- c(ylim[1], y[ylim[1] < y & y < ylim[2]], ylim[2]) newdat <- expand.grid(x = x, y = y) names(newdat) <- names[1:2] z <- try(matrix(predict(fit, newdat), length(x), length(y))) if (inherits(z, "try-error") && !missing_vars) { stop("vars should be in order: response, pred1, pred2", call. = FALSE) } dots$color <- plane.col dots$alpha <- plane.alpha if (is.null(dots$polygon_offset)) dots$polygon_offset <- 1 dots$type <- NULL surface <- do.call("surface3d", c(list(x, y, z), dots)) if (clip_to_density > 0) surface <- clipObj3d(surface, density, clip_to_density, minVertices = 1000) names(surface) <- paste0("surface.", i) grid <- if (do_grid) { x0 <- x0[xlim[1] <= x0 & x0 <= xlim[2]] y0 <- y0[ylim[1] <= y0 & y0 <= ylim[2]] plotGrid(i, x, y, x0, y0) } c(surface, grid) } plotPlane <- function(i, a, b, d) { c <- -1 if (is.na(d)) d <- 0 dots$color <- plane.col dots$alpha <- plane.alpha if (is.null(dots$polygon_offset)) dots$polygon_offset <- 1 dots$type <- NULL plane <- do.call("planes3d", c(list(a = a, b = b, c = c, d = d), dots)) if (clip_to_density > 0) plane <- clipObj3d(plane, density, clip_to_density, minVertices = 1000) names(plane) <- paste0("plane.", i) grid <- if (do_grid) { bbox <- par3d("bbox") xlim <- c(bbox[1], bbox[2]) x0 <- pretty(xlim, grid.steps) ylim <- c(bbox[3], bbox[4]) y0 <- pretty(ylim, grid.steps) x0 <- x0[xlim[1] <= x0 & x0 <= xlim[2]] y0 <- y0[ylim[1] <= y0 & y0 <= ylim[2]] if (isTRUE(all.equal(c(a,b,d), c(0, 0, 0)))) plotGrid(i, xlim, ylim, x0, y0, z = 0) else plotGrid(i, xlim, ylim, x0, y0) } c(plane, grid) } for (i in seq_along(which)) { type <- which[i] if (type == 1L) { plot <- plotPoints(i, observed, dots$zlab) if (use_surface3d) { plane <- plotSurface(i) } else { coefs <- coef(fit) plane <- plotPlane(i, coefs[names[1]], coefs[names[2]], coefs["(Intercept)"]) } } else if (type == 2L) { plot <- plotPoints(i, cbind(observed[,1:2], residuals(fit)), "Residuals") plane <- plotPlane(i, 0, 0, 0) } else if (type == 3L) { plot <- plotPoints(i, cbind(observed[,1:2], predict(fit)), dots$zlab) if (use_surface3d) { plane <- plotSurface(i) } else { coefs <- coef(fit) plane <- plotPlane(i, coefs[names[1]], coefs[names[2]], coefs["(Intercept)"]) } } result <- c(result, plot, plane) } highlevel(result) } rgl/R/setUserCallbacks.R0000644000176200001440000001362414137472630014631 0ustar liggesusersrgl.callback.env <- new.env(parent = emptyenv()) findSubscene <- function(subscene, id) { if (subscene$id == id) return(subscene) subscenes <- subscene$subscenes if (!is.null(subscenes)) { for (i in seq_along(subscenes)) { if (!is.null(result <- findSubscene(subscenes[[i]]))) return(result) } } NULL } findBboxdeco <- function(scene, subscene, root = scene$rootSubscene, guess = NULL) { active <- root for (id in active$objects) if (scene$objects[[as.character(id)]]$type == "bboxdeco") guess <- id if (active$id == subscene) if (is.null(guess)) return(NULL) else return(scene$objects[[as.character(guess)]]) for (sub in active$subscenes) if (!is.null(bbox <- findBboxdeco(scene, subscene, sub, guess))) return(bbox) return(NULL) } replaceSubscene <- function(subscene, id, newvalue) { if (as.character(subscene$id) == id) return(newvalue) subscenes <- subscene$subscenes if (!is.null(subscenes)) for (i in seq_along(subscenes)) if (!is.null(result <- replaceSubscene(subscenes[[i]], id, newvalue))) { subscene$subscenes[[i]] <- result return(subscene) } NULL } getfn <- function(fn, up = 2) { if (is.character(fn)) result <- eval(parse(text = fn), envir = parent.frame(up)) else result <- fn if (!is.function(result)) stop(fn, " is not a function.") result } setUserCallbacks <- function(button = NULL, begin = NULL, update = NULL, end = NULL, rotate = NULL, javascript = NULL, subscene = scene$rootSubscene$id, scene = scene3d(minimal = FALSE), applyToScene = TRUE, applyToDev = missing(scene)) { force(applyToDev) stopifnot(inherits(scene, "rglscene")) subscene <- as.character(subscene) sub <- findSubscene(scene$rootSubscene, subscene) if (is.null(sub)) stop("subscene ", subscene, " not found.") if (is.null(sub$par3d) || is.null(sub$par3d$mouseMode) || is.null(sub$embeddings)) stop("Internal error: subscene missing mouseMode or embeddings") if (is.null(sub$callbacks)) sub$callbacks <- list() if (!is.null(button)) { if (is.numeric(button)) button <- c("none", "left", "right", "middle", "wheel")[button + 1] sub$par3d$mouseMode[button] <- "user" sub$callbacks[[button]] <- list(begin = begin, update = update, end = end, rotate = rotate) sub$embeddings["mouse"] <- "replace" } javascript <- paste(c(scene$javascript, javascript), collapse = "\n") if (applyToScene) { scene$rootSubscene <- replaceSubscene(scene$rootSubscene, subscene, sub) scene$javascript <- javascript } if (applyToDev) { dev <- cur3d() devname <- paste0("dev", dev) callbacks <- rgl.callback.env[[devname]] if (is.null(callbacks)) callbacks <- list() callbacks[[paste0("sub", subscene)]] <- sub$callbacks callbacks$javascript <- javascript rgl.callback.env[[devname]] <- callbacks if (dev > 0) { callbacks <- sub$callbacks if (!is.null(button)) { fns <- callbacks[[button]] if (!is.null(fns)) { for (f in c("begin", "update", "end", "rotate")) if (!is.null(fns[[f]])) fns[[f]] <- getfn(fns[[f]]) callbacks[[button]] <- fns if (button == "wheel" && is.function(fns$rotate)) rgl.setWheelCallback(rotate = fns$rotate, dev = dev, subscene = subscene) fns$rotate <- NULL if (any(vapply(fns, is.function, TRUE))) do.call(rgl.setMouseCallbacks, c(list(button = c(none = 0, left = 1, right = 2, middle = 3, wheel = 4)[button], dev = dev, subscene = subscene), fns)) } } } } invisible(scene) } setAxisCallbacks <- function(axes, fns, javascript = NULL, subscene = scene$rootSubscene$id, scene = scene3d(minimal = FALSE), applyToScene = TRUE, applyToDev = missing(scene)) { force(applyToDev) stopifnot(inherits(scene, "rglscene")) subscene <- as.character(subscene) if (!is.character(axes)) axes <- c("x", "y", "z")[axes] else axes <- tolower(axes) stopifnot(all(axes %in% c("x", "y", "z"))) if (!is.list(fns)) fns <- list(fns) n <- max(length(axes), length(fns)) axes <- rep(axes, length = n) fns <- rep(fns, length = n) # Call each function once to set things up before grabbing # the scene for (i in seq_len(n)) getfn(fns[[i]])(paste0(axes[i], "--")) sub <- findSubscene(scene$rootSubscene, subscene) if (is.null(sub)) stop("subscene ", subscene, " not found.") bbox <- findBboxdeco(scene, subscene) if (is.null(bbox)) stop("No bbox decoration found.") if (is.null(bbox$callbacks)) bbox$callbacks <- list() for (i in seq_len(n)) bbox$callbacks[[axes[i]]] <- fns[[i]] javascript <- paste(c(scene$javascript, javascript), collapse = "\n") if (applyToScene) { scene$objects[[as.character(bbox$id)]] <- bbox scene$javascript <- javascript } if (applyToDev) { dev <- cur3d() devname <- paste0("dev", dev) callbacks <- rgl.callback.env[[devname]] if (is.null(callbacks)) callbacks <- list() callbacks[[paste0("bbox", bbox$id)]] <- bbox$callbacks callbacks$javascript <- javascript rgl.callback.env[[devname]] <- callbacks if (dev > 0) { callbacks <- bbox$callbacks for (i in seq_len(n)) { fn <- getfn(fns[[i]]) rgl.setAxisCallback(match(axes[i], c("x", "y", "z")), fn, dev = dev, subscene = subscene) } } } invisible(scene) } rgl/R/thigmophobe3d.R0000644000176200001440000000171214100762640014117 0ustar liggesusersthigmophobe3d <- function(x, y = NULL, z = NULL, P = par3d("projMatrix"), M = par3d("modelMatrix"), windowRect = par3d("windowRect")) { if (!requireNamespace("plotrix", quietly = TRUE) || packageVersion("plotrix") < "3.7-3") stop("This function requires the plotrix package, version 3.7-3 or higher.") xyz <- xyz.coords(x, y, z) pts3d <- rbind(xyz$x, xyz$y, xyz$z, 1) pts2d <- asEuclidean(t(P %*% M %*% pts3d)) w <- diff(windowRect[c(1,3)]) h <- diff(windowRect[c(2,4)]) pts2d <- cbind(w*pts2d[,1], h*pts2d[,2]) if (packageVersion("plotrix") < "3.7.6") plotrix::thigmophobe(pts2d, plot.span = c(-w, w, -h, h), xlog = FALSE, ylog = FALSE) else plotrix::thigmophobe(pts2d, usr = c(-w, w, -h, h), xlog = FALSE, ylog = FALSE, pin = c(w, h)/50) # This doesn't seem to matter... } rgl/R/zzz.R0000644000176200001440000001437514145464133012236 0ustar liggesusers## ## R source file ## This file is part of rgl ## ## ## ## ===[ SECTION: package entry/exit point ]=================================== ## ## ## entry-point ## ## .onLoad <- function(lib, pkg) { in_pkgload_loadall <- function() { caller <- deparse(sys.call(-4)) isNamespaceLoaded("pkgload") && grepl("load_all", caller) } getDir <- function(useNULL) { if (in_pkgload_loadall()) { dir <- if (useNULL) "inst/useNULL" else "src" } else { dir <- if (useNULL) "useNULL" else "libs" if (nchar(.Platform$r_arch)) dir <- paste0(dir, "/", .Platform$r_arch) } dir } getDynlib <- function(dir) system.file(paste0(dir, "/rgl", .Platform$dynlib.ext), package = pkg, lib.loc = lib, mustWork = TRUE) # OS-specific initValue <- 0 onlyNULL <- noOpenGL || rgl.useNULL() useNULL <- onlyNULL && !noOpenGL && .Platform$OS.type != "windows" dir <- getDir(useNULL) unixos <- "none" if (.Platform$OS.type == "unix") { unixos <- system("uname", intern=TRUE) if (!length(unixos)) unixos <- "unknown" } dll <- try(dyn.load(dynlib <- getDynlib(dir))) if (inherits(dll, "try-error")) { warning(paste("\tLoading rgl's DLL failed.", if (unixos == "Darwin" && !onlyNULL) { paste("\n\tThis build of rgl depends on XQuartz, which failed to load.\n", "See the discussion in https://stackoverflow.com/a/66127391/2554330") }), call. = FALSE) if (!onlyNULL) { dir <- getDir(TRUE) warning("Trying without OpenGL...", call. = FALSE) noOpenGL <<- TRUE dll <- try(dyn.load(dynlib <- getDynlib(dir))) } if (inherits(dll, "try-error")) stop("Loading failed.") } routines <- getDLLRegisteredRoutines(dll, addNames = FALSE) ns <- asNamespace(pkg) for(i in 1:4) lapply(routines[[i]], function(sym) assign(sym$name, sym, envir = ns)) if ( !noOpenGL && .Platform$OS.type == "windows" && !onlyNULL) { frame <- getWindowsHandle("Frame") # nolint ## getWindowsHandle was numeric pre-2.6.0 if ( !is.null(frame) ) initValue <- getWindowsHandle("Console") # nolint } if (onlyNULL) { rglFonts(serif = rep("serif", 4), sans = rep("sans", 4), mono = rep("mono", 4), symbol = rep("symbol", 4)) } else { rglFonts(serif = rep(system.file("fonts/FreeSerif.ttf", package="rgl"), 4), sans = rep(system.file("fonts/FreeSans.ttf", package="rgl"), 4), mono = rep(system.file("fonts/FreeMono.ttf", package="rgl"), 4), symbol = rep(system.file("fonts/FreeSerif.ttf", package="rgl"), 4)) if (requireNamespace("extrafont", quietly = TRUE)) suppressWarnings( rglExtrafonts(sans = c("rglHelvetica", "Arial"), serif = c("Times", "Times New Roman"), mono = c("Courier", "Courier New"))) } register_compare_proxy() .rglEnv$subsceneList <- NULL # Workaround for incompatibility with quartz device # By default only run this if we'll be using the X11 display on macOS # and we're not on R.app. options("rgl.startQuartz") can # override this. # Then we need to start quartz() before starting rgl. # See https://github.com/dmurdoch/rgl/issues/27 if (getOption("rgl.startQuartz", !onlyNULL && interactive() && unixos == "Darwin" && !(.Platform$GUI %in% c("AQUA", "RStudio"))) && exists("quartz", getNamespace("grDevices"))) { grDevices::quartz() dev.off() } ret <- rgl.init(initValue, onlyNULL) if (!ret) { warning("'rgl.init' failed, running with 'rgl.useNULL = TRUE'.", call. = FALSE) options(rgl.useNULL = TRUE) rgl.init(initValue, TRUE) } if (!rgl.useNULL()) setGraphicsDelay(unixos = unixos) # handle pkgdown_print and fig_settings before they are in the CRAN version if (requireNamespace("pkgdown", quietly = TRUE)) { if ("pkgdown_print" %in% getNamespaceExports("pkgdown")) { pkgdown_print <<- getExportedValue("pkgdown", "pkgdown_print") } if ("fig_settings" %in% getNamespaceExports("pkgdown")) pkgdown_fig_settings <<- getExportedValue("pkgdown", "fig_settings") } } # Do we need a delay opening graphics? # Work around bug in MacOS Catalina: if base plotting happens # too quickly after first call to quartz, R crashes. # This inserts a delay after the # first call to the graphics device. The default is # no delay, unless on Catalina with no graphics device # currently open, when a 1 second delay will be introduced. # Use "RGL_SLOW_DEV = value" to change the delay from # the default to "value" seconds. setGraphicsDelay <- function(delay = Sys.getenv("RGL_SLOW_DEV", 0), unixos = "none") { if (unixos == "Darwin") { version <- try(numeric_version(system("uname -r", intern = TRUE))) if (missing(delay) && !inherits(version, "try-error") && !is.na(version) && version >= "19.0.0" && dev.cur() == 1 && identical(getOption("device"), grDevices::quartz)) delay <- Sys.getenv("RGL_SLOW_DEV", 1) } delay <- suppressWarnings(as.numeric(delay)) if (is.na(delay)) delay <- 1 if (delay > 0) { olddev <- getOption("device") if (is.character(olddev)) { if (exists(olddev, globalenv(), mode = "function")) olddev <- get(olddev, envir = globalenv(), mode = "function") else if (exists(olddev, asNamespace("grDevices"), mode = "function")) olddev <- get(olddev, asNamespace("grDevices"), mode = "function") } if (is.function(olddev)) options(device = function(...) { olddev(...) Sys.sleep(delay) options(device = olddev) }) } } rgl.init <- function(initValue = 0, onlyNULL = FALSE, debug = getOption("rgl.debug", FALSE)) .Call( rgl_init, initValue, onlyNULL, environment(rgl.init), debug ) .onAttach <- function(libname, pkgname) { if (noOpenGL) packageStartupMessage( "This build of rgl does not include OpenGL functions. Use rglwidget() to display results, e.g. via options(rgl.printRglwidget = TRUE).") } ## ## exit-point ## ## .onUnload <- function(libpath) { unregisterShinyHandlers() # shutdown .C( rgl_quit, success=FALSE ) } rgl/R/rglcontroller.R0000644000176200001440000002134514145464133014264 0ustar liggesusers subsetControl <- function(value = 1, subsets, subscenes = NULL, fullset = Reduce(union, subsets), accumulate = FALSE) { subsets <- lapply(subsets, as.integer) fullset <- as.integer(fullset) if (length(names(subsets))) labels <- names(subsets) else labels <- NULL structure(list(type = "subsetSetter", value = value - 1, subsets = unname(subsets), subscenes = subscenes, fullset = fullset, accumulate = accumulate, labels = labels), class = "rglControl") } propertyControl <- function(value = 0, entries, properties, objids = tagged3d(tags), tags, values = NULL, param = seq_len(NROW(values)) - 1, interp = TRUE) { objids <- as.integer(objids) structure(list(type = "propertySetter", value = value, values = values, entries = entries, properties = properties, objids = objids, param = param, interp = interp), class = "rglControl") } clipplaneControl <- function(a=NULL, b=NULL, c=NULL, d=NULL, plane = 1, clipplaneids = tagged3d(tag), tag, ...) { values <- cbind(a = a, b = b, c = c, d = d) col <- which(colnames(values) == letters[1:4]) - 1 propertyControl(values = values, entries = 4*(plane-1) + col, properties = "vClipplane", objids = clipplaneids, ...) } ageControl <- function(births, ages, objids = tagged3d(tags), tags, value = 0, colors = NULL, alpha = NULL, radii = NULL, vertices = NULL, normals = NULL, origins = NULL, texcoords = NULL, x = NULL, y = NULL, z = NULL, red = NULL, green = NULL, blue = NULL) { lengths <- c(colors = NROW(colors), alpha = length(alpha), radii = length(radii), vertices = NROW(vertices), normals = NROW(normals), origins = NROW(origins), texcoords = NROW(texcoords), x = length(x), y = length(y), z = length(z), red = length(red), green = length(green), blue = length(blue)) lengths <- lengths[lengths > 0] n <- unique(lengths) stopifnot(length(n) == 1, n == length(ages), all(diff(ages) >= 0)) ages <- c(-Inf, ages, Inf) rows <- c(1, 1:n, n) result <- list(type = "ageSetter", objids = as.integer(objids), value = value, births = births, ages = ages) if (!is.null(colors)) { colors <- col2rgb(colors)/255 colors <- as.numeric(colors[,rows]) result <- c(result, list(colors = colors)) } if (!is.null(alpha)) result <- c(result, list(alpha = alpha[rows])) if (!is.null(radii)) result <- c(result, list(radii = radii[rows])) if (!is.null(vertices)) { stopifnot(ncol(vertices) == 3) result <- c(result, list(vertices = as.numeric(t(vertices[rows,])))) } if (!is.null(normals)) { stopifnot(ncol(normals) == 3) result <- c(result, list(normals = as.numeric(t(normals[rows,])))) } if (!is.null(origins)) { stopifnot(ncol(origins) == 2) result <- c(result, list(origins = as.numeric(t(origins[rows,])))) } if (!is.null(texcoords)) { stopifnot(ncol(texcoords) == 2) result <- c(result, list(texcoords = as.numeric(t(texcoords[rows,])))) } if (!is.null(x)) result <- c(result, list(x = x[rows])) if (!is.null(y)) result <- c(result, list(y = y[rows])) if (!is.null(z)) result <- c(result, list(z = z[rows])) if (!is.null(red)) result <- c(result, list(red = red[rows])) if (!is.null(green)) result <- c(result, list(green = green[rows])) if (!is.null(blue)) result <- c(result, list(blue = blue[rows])) structure(result, class = "rglControl") } vertexControl <- function(value = 0, values = NULL, vertices = 1, attributes, objid = tagged3d(tag), tag, param = seq_len(NROW(values)) - 1, interp = TRUE) { attributes <- match.arg(attributes, choices = c("x", "y", "z", "red", "green", "blue", "alpha", "radii", "nx", "ny", "nz", "ox", "oy", "oz", "ts", "tt", "offset"), several.ok = TRUE) if (!is.null(values)) { ncol <- max(length(vertices), length(attributes)) if (is.matrix(values)) stopifnot(ncol == ncol(values)) else { stopifnot(ncol == 1) values <- matrix(values, ncol = 1) } # Repeat first and last values to make search simpler. param <- c(-Inf, param, Inf) values <- rbind(values[1,], values, values[nrow(values),]) } structure(list(type = "vertexSetter", value = value, values = values, vertices = vertices - 1, # Javascript 0-based indexing attributes = attributes, objid = as.integer(objid), param = param, # Javascript 0-based indexing interp = interp), class = "rglControl") } par3dinterpControl <- function(fn, from, to, steps, subscene = NULL, omitConstant = TRUE, ...) { rename <- character() times <- seq(from, to, length.out = steps+1) fvals <- lapply(times, fn) f0 <- fvals[[1]] entries <- numeric(0) properties <- character(0) values <- NULL props <- c("FOV", "userMatrix", "scale", "zoom") for (i in seq_along(props)) { prop <- props[i] propname <- rename[prop] if (is.na(propname)) propname <- prop if (!is.null(value <- f0[[prop]])) { newvals <- sapply(fvals, function(e) as.numeric(e[[prop]])) if (is.matrix(newvals)) newvals <- t(newvals) rows <- NROW(newvals) cols <- NCOL(newvals) stopifnot(rows == length(fvals)) entries <- c(entries, seq_len(cols)-1) properties <- c(properties, rep(propname, cols)) values <- cbind(values, newvals) } } if (omitConstant) keep <- apply(values, 2, var) > 0 else keep <- TRUE if (is.null(subscene)) subscene <- f0$subscene propertyControl(values = c(t(values[,keep])), entries = entries[keep], properties = properties[keep], objids = subscene, param = times, ...) } # This is a bridge to the old system # In the old system, the rglClass object was a global named # rgl, and controls install methods on it. In the # new system, the rglClass object is just a field of a
# element. The R code below creates an empty global for the # controls to modify, then the Javascript code in oldBridge # imports those into the real scene object. elementId2Prefix <- function(elementId, prefix = elementId) { .Deprecated("", msg = "This function is not needed if you use rglwidget().") cat(paste0("")) playwidget(elementId, structure(list(type = "oldBridge", prefix = prefix), class = "rglControl"), components = character(0)) } # This puts together a custom message for a more extensive change sceneChange <- function(elementId, x = scene3d(minimal), delete = NULL, add = NULL, replace = NULL, material = FALSE, rootSubscene = FALSE, delfromSubscenes = NULL, skipRedraw = FALSE, minimal = TRUE) { allSubscenes <- function() { result <- numeric() for (obj in scene$objects) if (obj$type == "subscene") result <- c(result, obj$id) result } inSubscenes <- function(id, subs) { result <- numeric() for (sub in subs) if (id %in% sub$objects) result <- c(result, sub$id) result } delete <- unique(c(delete, replace)) add <- unique(c(add, replace)) scene <- convertScene(x) allsubids <- allSubscenes() allsubs <- scene$objects[as.character(allsubids)] for (id in add) scene$objects[[as.character(id)]]$inSubscenes <- inSubscenes(id, allsubs) scene$elementId <- elementId allIds <- names(scene$objects) dontSend <- setdiff(allIds, as.character(add)) scene$objects[dontSend] <- NULL if (!length(scene$objects)) scene$objects <- NULL if (!material) scene$material <- NULL if (!rootSubscene) scene$rootSubscene <- NULL scene$delete <- delete if (is.null(delfromSubscenes)) delfromSubscenes <- allsubids scene$delfromSubscenes <- as.numeric(delfromSubscenes) if (is.na(skipRedraw)) scene$redrawScene <- FALSE else { scene$redrawScene <- !skipRedraw scene$skipRedraw <- skipRedraw } scene } registerSceneChange <- function() { tags$script(rglDependency, ' Shiny.addCustomMessageHandler("sceneChange", rglwidgetClass.prototype.sceneChangeHandler); ') } rgl/R/contourLines3d.R0000644000176200001440000000476214100762640014306 0ustar liggesusers contourLines3d <- function(obj, ...) UseMethod("contourLines3d") contourLines3d.rglId <- function(obj, ...) contourLines3d(as.mesh3d(obj), ...) contourLines3d.mesh3d <- function(obj, fn = "z", nlevels = 10, levels = NULL, minVertices = 0, plot = TRUE, ... ) { obj <- as.tmesh3d(obj) nverts <- ncol(obj$vb) oldnverts <- nverts - 1 while (nverts < minVertices && oldnverts < nverts) { oldnverts <- nverts obj <- subdivision3d(obj, deform = FALSE, normalize = TRUE) nverts <- ncol(obj$vb) } verts <- asEuclidean(t(obj$vb)) if (is.null(fn)) fn <- obj$values if (is.null(fn)) stop("'fn' can only be NULL if 'obj' contains values") if (is.character(fn)) fn <- structure(as.list(fn), names = fn) else if (is.function(fn) || is.numeric(fn)) fn <- list(fn) funnames <- names(fn) if (is.null(funnames)) funnames <- seq_along(fn) result <- data.frame(x = numeric(), y = numeric(), z = numeric(), fn = funnames[0], level = numeric()) for (i in seq_along(fn)) { if (is.numeric(fn[[i]])) values <- fn[[i]] else { fun <- .getVertexFn(fn[[i]], parent.env()) values <- fun(verts) } if (is.null(levels)) levs <- pretty(range(values, na.rm = TRUE), nlevels) else levs <- levels for (lev in levs) { greater <- matrix(values[as.numeric(obj$it)] > lev, nrow = 3) counts <- colSums(greater) crossings <- which(counts %in% 1:2) if (length(crossings)) { greater <- greater[,crossings, drop = FALSE] counts <- counts[crossings] # Find the single vertex on one side of the contour # line (v1), and the other two on the other side # (v2, v3) r1 <- ifelse(counts == 1, apply(greater, 2, which.max), apply(greater, 2, which.min)) v1 <- obj$it[cbind(r1, crossings)] r2 <- r1 %% 3 + 1 v2 <- obj$it[cbind(r2, crossings)] r3 <- (r1 + 1) %% 3 + 1 v3 <- obj$it[cbind(r3, crossings)] p1 <- (lev - values[v2])/(values[v1] - values[v2]) i1 <- p1*verts[v1,] + (1 - p1)*verts[v2,] p2 <- (lev - values[v3])/(values[v1] - values[v3]) i2 <- p2*verts[v1,] + (1 - p2)*verts[v3,] xyz <- matrix(t(cbind(i1, i2)), ncol = 3, byrow = TRUE) result <- rbind(result, data.frame(x = xyz[,1], y = xyz[,2], z = xyz[,3], fn = funnames[i], level = lev)) } } } if (plot) segments3d(result, ...) else result } rgl/R/conversions.R0000644000176200001440000000107314100762640013733 0ustar liggesusersrglToLattice <- function(rotm = par3d("userMatrix")) { if (!requireNamespace("orientlib", quietly = TRUE)) stop("The orientlib package is needed for this function") e <- -orientlib::eulerzyx(orientlib::rotmatrix(rotm[1:3, 1:3]))@x*180/pi list(z = e[1], y = e[2], x = e[3]) } rglToBase <- function(rotm = par3d("userMatrix")) { if (!requireNamespace("orientlib", quietly = TRUE)) stop("The orientlib package is needed for this function") e <- (orientlib::eulerzyx(orientlib::rotmatrix((rotm[1:3,1:3]))))@x*180/pi list(theta = e[1], phi = 90 - e[3]) } rgl/R/persp3d.R0000644000176200001440000001444114145464133012753 0ustar liggesuserspersp3d <- function(x, ...) UseMethod("persp3d") persp3d.default <- function(x = seq(0, 1, len = nrow(z)), y = seq(0, 1, len = ncol(z)), z, xlim = NULL, ylim = NULL, zlim = NULL, xlab = NULL, ylab = NULL, zlab = NULL, add = FALSE, aspect = !add, forceClipregion = FALSE, ...) { if (!add) next3d() skip <- par3d(skipRedraw=TRUE) on.exit(par3d(skip)) if (is.null(xlab)) xlab <- if (!missing(x)) deparse(substitute(x)) else "X" if (is.null(ylab)) ylab <- if (!missing(y)) deparse(substitute(y)) else "Y" if (is.null(zlab)) zlab <- if (!missing(z)) deparse(substitute(z)) else "Z" ## labcex is disregarded since we do NOT yet put ANY labels... if (missing(z)) { if (!missing(x)) { if (is.list(x)) { z <- x$z y <- x$y x <- x$x } else { z <- x x <- seq(0, 1, len = nrow(z)) } } else stop("No 'z' matrix specified") } else if (is.list(x)) { y <- x$y x <- x$x } if ( (!is.matrix(x) && any(diff(x) <= 0)) || (!is.matrix(y) && any(diff(y) <= 0))) stop("Increasing 'x' and 'y' values expected") savesubscene <- currentSubscene3d() result <- setClipregion(xlim, ylim, zlim, forceClipregion) result <- c(result, surface=surface3d(x,y,z,...)) useSubscene3d(savesubscene) if (!add) { result <- c(result, decorate3d(xlim = xlim, ylim = ylim, zlim = zlim, xlab = xlab, ylab = ylab, zlab = zlab, aspect = aspect, ...)) highlevel(result) } else lowlevel(result) } setClipregion <- function(xlim = NULL, ylim = NULL, zlim = NULL, force = FALSE) { if (force || length(c(xlim, ylim, zlim))) { listeners <- par3d("listeners") result <- c(clipregion = newSubscene3d("inherit", "inherit", "inherit")) par3d(listeners = listeners) normals <- matrix(nrow = 0, ncol = 3) offsets <- numeric() if (length(xlim)) { normals <- rbind(normals, matrix(c(1, 0, 0, -1, 0, 0), nrow = 2, byrow = TRUE)) offsets <- c(offsets, -xlim[1], xlim[2]) } if (length(ylim)) { normals <- rbind(normals, matrix(c(0, 1, 0, 0, -1, 0), nrow = 2, byrow = TRUE)) offsets <- c(offsets, -ylim[1], ylim[2]) } if (length(zlim)) { normals <- rbind(normals, matrix(c(0, 0, 1, 0, 0, -1), nrow = 2, byrow = TRUE)) offsets <- c(offsets, -zlim[1], zlim[2]) } keep <- is.finite(offsets) if (length(offsets[keep])) result <- c(result, clipplanes = clipplanes3d(normals[keep,], d = offsets[keep])) } else result <- integer() lowlevel(result) } persp3d.function <- function(x, xlim = c(0,1), ylim = c(0,1), slim = NULL, tlim = NULL, n = 101, xvals = seq.int(min(xlim), max(xlim), length.out = n[1]), yvals = seq.int(min(ylim), max(ylim), length.out = n[2]), svals = seq.int(min(slim), max(slim), length.out = n[1]), tvals = seq.int(min(tlim), max(tlim), length.out = n[2]), xlab = NULL, ylab = NULL, zlab = NULL, col = "gray", otherargs = list(), normal = NULL, texcoords = NULL, ...) { f <- x n <- rep(n, length.out = 2) parametric <- !is.null(slim) || !is.null(tlim) if (!parametric) { n1 <- length(xvals) n2 <- length(yvals) xvals <- matrix(xvals, n1, n2) yvals <- matrix(yvals, n1, n2, byrow = TRUE) args <- c(list(c(xvals), c(yvals)), otherargs) zvals <- do.call(f, args) dim(zvals) <- dim(xvals) argnames <- names(as.list(f)) if (is.null(xlab)) xlab <- argnames[1] if (is.null(ylab)) ylab <- argnames[2] if (is.null(zlab)) zlab <- deparse(substitute(x)) } else { if (is.null(slim)) slim <- c(0,1) if (is.null(tlim)) tlim <- c(0,1) n1 <- length(svals) n2 <- length(tvals) svals <- matrix(svals, n1, n2) tvals <- matrix(tvals, n1, n2, byrow = TRUE) args <- c(list(as.numeric(svals), as.numeric(tvals)), otherargs) allvals <- do.call(f, args) xvals <- matrix(allvals[,1], n1, n2) yvals <- matrix(allvals[,2], n1, n2) zvals <- matrix(allvals[,3], n1, n2) if (!is.null(colnames <- colnames(allvals))) { if (is.null(xlab)) xlab <- colnames[1] if (is.null(ylab)) ylab <- colnames[2] if (is.null(zlab)) zlab <- colnames[3] } } if (is.function(col)) { zmin <- min(zvals, na.rm = TRUE) zscale <- 1/(max(zvals, na.rm = TRUE) - zmin) colfn <- colorRamp(col(100)) colrgba <- colfn(c((zvals - zmin)*zscale)) colrgba[is.na(colrgba)] <- 0 col <- rgb(colrgba, maxColorValue = 255) dim(col) <- dim(zvals) } if (is.function(normal)) normal <- do.call(normal, args) if (is.function(texcoords)) texcoords <- do.call(texcoords, args) args <- list(xvals, yvals, zvals, col = col, xlab = xlab, ylab = ylab, zlab = zlab, ...) if (is.matrix(normal)) args <- c(args, list(normal_x = matrix(normal[,1], n1, n2), normal_y = matrix(normal[,2], n1, n2), normal_z = matrix(normal[,3], n1, n2))) if (is.matrix(texcoords)) args <- c(args, list(texture_s = matrix(texcoords[,1], n1, n2), texture_t = matrix(texcoords[,2], n1, n2))) if (parametric) args <- c(args, list(xlim = if (!missing(xlim)) xlim, ylim = if (!missing(ylim)) ylim)) do.call(persp3d, args) } persp3d.deldir <- function(x, ..., add = FALSE) { plot3d(as.mesh3d(x, ...), add = add, ...) } persp3d.triSht <- persp3d.tri <- function(x, z, ..., add = FALSE) { plot3d(as.mesh3d(x, z, ...), add = add, ...) } persp3d.formula <- function(x, data=NULL, xlab = xyz$xlab, ylab = xyz$ylab, zlab = xyz$zlab, ...) { checkDeldir(error = TRUE) if (!is.null(data)) environment(x) <- list2env(data, envir = environment(x)) xyz <- xyz.coords(x) dxyz <- with(xyz, deldir::deldir(x, y, z = z, suppressMsge = TRUE)) # nolint persp3d(dxyz, xlab = xlab, ylab = ylab, zlab = zlab, ...) } rgl/R/scene.R0000644000176200001440000006254014146446052012474 0ustar liggesusers## ## R source file ## This file is part of rgl ## ## ## ## ===[ SECTION: scene management ]=========================================== ## ## ## clear scene ## ## rgl.clear <- function( type = "shapes", subscene = 0 ) { if (is.na(subscene)) subscene <- currentSubscene3d() typeid <- rgl.enum.nodetype(type) userviewpoint <- 4 %in% typeid material <- 5 %in% typeid modelviewpoint <- 8 %in% typeid drop <- typeid %in% c(4:5, 8) typeid <- typeid[!drop] type <- names(typeid) if (subscene == 0) { idata <- as.integer(c(length(typeid), typeid)) ret <- .C( rgl_clear, success = FALSE, idata )$success } else { sceneids <- ids3d(type=type, subscene = 0)$id thisids <- ids3d(type=type, subscene = subscene)$id if (length(thisids)) { delFromSubscene3d(ids = thisids, subscene = subscene) gc3d(protect = setdiff(sceneids, thisids)) } ret <- 1 } if ( userviewpoint || modelviewpoint) rgl.viewpoint(type = c("userviewpoint", "modelviewpoint")[c(userviewpoint, modelviewpoint)]) if ( material ) rgl.material() if (! ret) stop("'rgl_clear' failed") lowlevel() } ## ## pop node ## ## pop3d <- rgl.pop <- function( type = "shapes", id = 0, tag = NULL) { if (!is.null(tag)) { if (!missing(id)) stop("Only one of 'id' and 'tag' should be specified.") allids <- ids3d(intersect(c("shapes", "bboxdeco"), type)) id <- allids$id[allids$tag %in% tag] } type <- rgl.enum.nodetype(type) save <- par3d(skipRedraw = TRUE) on.exit(par3d(save)) for (i in id) { idata <- as.integer(c(type, i)) ret <- .C( rgl_pop, success = FALSE, idata ) if (! ret$success) stop(gettextf("'rgl.pop' failed for id %d", i), domain = NA) } lowlevel() } ids3d <- rgl.ids <- function( type = "shapes", subscene = NA, tags = FALSE) { type <- c(rgl.enum.nodetype(type), 0) if (is.na(subscene)) subscene <- currentSubscene3d() count <- .C( rgl_id_count, as.integer(type), count = integer(1), subscene = as.integer(subscene))$count result <- as.data.frame( .C( rgl_ids, as.integer(type), id=integer(count), type=rep("",count), subscene = as.integer(subscene) )[2:3] ) if (tags) { result$tag <- rep("", nrow(result)) if (NROW(result)) { hasmaterial <- !(result$type %in% c("light", "userviewpoint", "background", "modelviewpoint", "subscene")) result$tag[hasmaterial] <- vapply(result$id[hasmaterial], function(id) { rgl.getmaterial(0, id = id)$tag }, "") } } result } rgl.attrib.count <- function( id, attrib ) { stopifnot(length(attrib) == 1) if (is.character(attrib)) attrib <- rgl.enum.attribtype(attrib) result <- integer(length(id)) for (i in seq_along(id)) result[i] <- .C( rgl_attrib_count, as.integer(id[i]), as.integer(attrib), count = integer(1))$count names(result) <- names(id) result } rgl.attrib.ncol.values <- c(vertices=3, normals=3, colors=4, texcoords=2, dim=2, texts=1, cex=1, adj=3, radii=1, centers=3, ids=1, usermatrix=4, types=1, flags=1, offsets=1, family=1, font=1, pos=1, fogscale=1, axes=3, indices=1) rgl.attrib.info <- function( id = ids3d("all", 0)$id, attribs = NULL, showAll = FALSE) { ncol <- rgl.attrib.ncol.values if (is.null(attribs)) attribs <- names(ncol) else if (is.numeric(attribs)) attribs <- names(ncol)[attribs] na <- length(attribs) ni <- length(id) if (!ni) result <- data.frame(id = numeric(0), attrib = character(0), nrow = numeric(0), ncol = numeric(0), stringsAsFactors = FALSE) else result <- data.frame(id = rep(id, each = na), attrib = rep(attribs, ni), nrow = 0, ncol = rep(ncol[attribs], ni), stringsAsFactors = FALSE) for (j in seq_len(ni)) for (i in seq_len(na)) result$nrow[i + na*(j - 1)] <- rgl.attrib.count(id[j], result$attrib[i]) if (!showAll) result <- result[result$nrow != 0,] rownames(result) <- NULL result } rgl.attrib <- function( id, attrib, first=1, last=rgl.attrib.count(id, attrib) ) { stopifnot(length(attrib) == 1 && length(id) == 1 && length(first) == 1) if (is.character(attrib)) attrib <- rgl.enum.attribtype(attrib) ncol <- rgl.attrib.ncol.values[attrib] count <- max(last - first + 1, 0) if (attrib %in% c(6, 13, 16)) { # texts, types and family if (count) result <- .C(rgl_text_attrib, as.integer(id), as.integer(attrib), as.integer(first-1), as.integer(count), result = character(count*ncol))$result else result <- character(0) } else { if (count) result <- .C(rgl_attrib, as.integer(id), as.integer(attrib), as.integer(first-1), as.integer(count), result = numeric(count*ncol))$result else result <- numeric(0) } if (attrib == 14) # flags result <- as.logical(result) result <- matrix(result, ncol=ncol, byrow=TRUE) colnames(result) <- list(c("x", "y", "z"), # vertices c("x", "y", "z"), # normals c("r", "g", "b", "a"), # colors c("s", "t"), # texcoords c("r", "c"), # dim "text", # texts "cex", # cex c("x", "y", "z"), # adj "r", # radii c("x", "y", "z"), # centers "id", # ids c("x", "y", "z", "w"), # usermatrix "type", # types "flag", # flags "offset", # offsets "family", # family "font", # font "pos", # pos "fogscale", # fogscale c("x", "y", "z"), # axes "vertex" # indices )[[attrib]] if (attrib == 14 && count) # flags if (id %in% ids3d("lights", subscene = 0)$id) rownames(result) <- c("viewpoint", "finite")[first:last] else if (id %in% ids3d("background", subscene = 0)$id) rownames(result) <- c("sphere", "linear_fog", "exp_fog", "exp2_fog")[first:last] else if (id %in% ids3d("bboxdeco", subscene = 0)$id) rownames(result) <- c("draw_front", "marklen_rel")[first:last] else if (id %in% (ids <- ids3d("shapes", subscene = 0))$id) { type <- ids$type[ids$id == id] rownames(result) <- c("ignoreExtent", if (type == "surface") "flipped" else if (type == "spheres") "fastTransparency" else "fixedSize")[first:last] } if (attrib == 20 && count) { # axes rownames(result) <- c("mode", "step", "nticks", "marklen", "expand") result <- result[first:last,] result <- as.data.frame(t(result)) result$mode <- c("custom", "fixednum", "fixedstep", "pretty", "user", "none")[result$mode + 1] } result } ## ## ===[ SECTION: environment ]================================================ ## ## ## set viewpoint ## ## rgl.viewpoint <- function( theta = 0.0, phi = 15.0, fov = 60.0, zoom = 1.0, scale = par3d("scale"), interactive = TRUE, userMatrix, type = c("userviewpoint", "modelviewpoint") ) { zoom <- rgl.clamp(zoom,0,Inf) phi <- rgl.clamp(phi,-90,90) fov <- rgl.clamp(fov,0,179) type <- match.arg(type, several.ok = TRUE) polar <- missing(userMatrix) if (polar) userMatrix <- diag(4) idata <- as.integer(c(interactive,polar, "userviewpoint" %in% type, "modelviewpoint" %in% type)) ddata <- as.numeric(c(theta,phi,fov,zoom,scale,userMatrix[1:16])) ret <- .C( rgl_viewpoint, success = FALSE, idata, ddata ) if (! ret$success) stop("'rgl_viewpoint' failed") } ## ## set background ## ## rgl.bg <- function(sphere=FALSE, fogtype="none", color=c("black","white"), back="lines", fogScale = 1, ... ) { rgl.material( color=color, back=back, ... ) fogtype <- rgl.enum.fogtype(fogtype) idata <- as.integer(c(sphere,fogtype)) fogScale <- as.numeric(fogScale) stopifnot(length(fogScale) == 1, fogScale > 0) ret <- .C( rgl_bg, success = as.integer(FALSE), idata, fogScale ) if (! ret$success) stop("'rgl_bg' failed") lowlevel(ret$success) } ## ## bbox ## ## rgl.bbox <- function( xat=NULL, xlab=NULL, xunit=0, xlen=5, yat=NULL, ylab=NULL, yunit=0, ylen=5, zat=NULL, zlab=NULL, zunit=0, zlen=5, marklen=15.0, marklen.rel=TRUE, expand=1, draw_front=FALSE, ...) { rgl.material( ... ) if (is.null(xat)) xlab <- NULL else { xlen <- length(xat) if (is.null(xlab)) xlab <- format(xat) else xlab <- rep(xlab, length.out=xlen) } if (is.null(yat)) ylab <- NULL else { ylen <- length(yat) if (is.null(ylab)) ylab <- format(yat) else ylab <- rep(ylab, length.out=ylen) } if (is.null(zat)) zlab <- NULL else { zlen <- length(zat) if (is.null(zlab)) zlab <- format(zat) else zlab <- rep(zlab,length.out=length(zat)) } xticks <- length(xat) yticks <- length(yat) zticks <- length(zat) if (identical(xunit, "pretty")) xunit <- -1 if (identical(yunit, "pretty")) yunit <- -1 if (identical(zunit, "pretty")) zunit <- -1 length(xlen) <- 1 length(ylen) <- 1 length(zlen) <- 1 length(marklen.rel) <- 1 length(draw_front) <- 1 length(xunit) <- 1 length(yunit) <- 1 length(zunit) <- 1 length(marklen) <- 1 length(expand) <- 1 idata <- as.integer(c(xticks,yticks,zticks, xlen, ylen, zlen, marklen.rel, draw_front)) ddata <- as.numeric(c(xunit, yunit, zunit, marklen, expand)) ret <- .C( rgl_bbox, success = as.integer(FALSE), idata, ddata, as.numeric(xat), as.character(xlab), as.numeric(yat), as.character(ylab), as.numeric(zat), as.character(zlab) ) if (! ret$success) stop("'rgl_bbox' failed") lowlevel(ret$success) } ## ## set lights ## ## rgl.light <- function( theta = 0, phi = 0, viewpoint.rel = TRUE, ambient = "#FFFFFF", diffuse = "#FFFFFF", specular = "#FFFFFF", x = NULL, y = NULL, z = NULL) { ambient <- rgl.color(ambient) diffuse <- rgl.color(diffuse) specular <- rgl.color(specular) # if a complete set of x, y, z is given, the light source is assumed to be part of the scene, theta and phi are ignored # else the light source is infinitely far away and its direction is determined by theta, phi (default) if ( !is.null(x) ) { if ( !missing(theta) || !missing(phi) ) warning("'theta' and 'phi' ignored when 'x' is present") xyz <- xyz.coords(x,y,z) x <- xyz$x y <- xyz$y z <- xyz$z if (length(x) > 1) stop("A light can only be in one place at a time") finite.pos <- TRUE } else { if ( !is.null(y) || !is.null(z) ) warning("'y' and 'z' ignored, spherical coordinates used") finite.pos <- FALSE x <- 0 y <- 0 z <- 0 } idata <- as.integer(c(viewpoint.rel, ambient, diffuse, specular, finite.pos)) ddata <- as.numeric(c(theta, phi, x, y, z)) ret <- .C( rgl_light, success = as.integer(FALSE), idata, ddata ) if (! ret$success) stop("Too many lights; maximum is 8 sources per scene") lowlevel(ret$success) } ## ## ===[ SECTION: shapes ]===================================================== ## ## ## add primitive ## ## rgl.primitive <- function( type, x, y=NULL, z=NULL, normals=NULL, texcoords=NULL, indices=NULL, ... ) { rgl.material( ... ) type <- rgl.enum.primtype(type) xyz <- xyz.coords(x,y,z,recycle=TRUE) x <- xyz$x y <- xyz$y z <- xyz$z vertex <- rgl.vertex(x,y,z) nvertex <- rgl.nvertex(vertex) if (is.null(indices)) { nindices <- 0 indices <- 0 # to avoid pointing out of range } else { nindices <- length(indices) if (!all(indices > 0 & indices <= nvertex)) stop("indices out of range") } if (nvertex > 0) { perelement <- c(points=1, lines=2, triangles=3, quadrangles=4, linestrips=1)[type] if (nindices > 0) { if (nindices %% perelement) stop("Illegal number of indices") } else if (nvertex %% perelement) stop("Illegal number of vertices") idata <- as.integer( c(type, nvertex, !is.null(normals), !is.null(texcoords), nindices, indices - 1 ) ) if (is.null(normals)) normals <- 0 else { normals <- xyz.coords(normals, recycle=TRUE) x <- rep(normals$x, len=nvertex) y <- rep(normals$y, len=nvertex) z <- rep(normals$z, len=nvertex) normals <- rgl.vertex(x,y,z) } if (is.null(texcoords)) texcoords <- 0 else { texcoords <- xy.coords(texcoords, recycle=TRUE) s <- rep(texcoords$x, len=nvertex) t <- rep(texcoords$y, len=nvertex) texcoords <- rgl.texcoords(s,t) } ret <- .C( rgl_primitive, success = as.integer(FALSE), as.integer(idata), as.numeric(vertex), as.numeric(normals), as.numeric(texcoords), NAOK = TRUE ) if (! ret$success) stop("'rgl_primitive' failed") lowlevel(ret$success) } } rgl.points <- function( x, y=NULL, z=NULL, ... ) { rgl.primitive( "points", x, y, z, ... ) } rgl.lines <- function(x, y=NULL, z=NULL, ... ) { rgl.primitive( "lines", x, y, z, ... ) } rgl.triangles <- function(x, y=NULL, z=NULL, normals=NULL, texcoords=NULL, ... ) { rgl.primitive( "triangles", x, y, z, normals, texcoords, ... ) } rgl.quads <- function( x, y=NULL, z=NULL, normals=NULL, texcoords=NULL, ... ) { rgl.primitive( "quadrangles", x, y, z, normals, texcoords, ... ) } rgl.linestrips<- function( x, y=NULL, z=NULL, ... ) { rgl.primitive( "linestrips", x, y, z, ... ) } ## ## add surface ## ## # Utility function: # calculates the parity of a permutation of integers perm_parity <- function(p) { x <- seq_along(p) result <- 0 for (i in x) { if (x[i] != p[i]) { x[x==p[i]] <- x[i] result <- result+1 } } return(result %% 2) } rgl.surface <- function( x, z, y, coords=1:3, ..., normal_x=NULL, normal_y=NULL, normal_z=NULL, texture_s=NULL, texture_t=NULL) { rgl.material(...) flags <- rep(FALSE, 4) if (is.matrix(x)) { nx <- nrow(x) flags[1] <- TRUE if ( !identical( dim(x), dim(y) ) ) stop(gettextf("Bad dimension for %s", "rows"), domain = NA) } else nx <- length(x) if (is.matrix(z)) { nz <- ncol(z) flags[2] <- TRUE if ( !identical( dim(z), dim(y) ) ) stop(gettextf("Bad dimension for %s", "cols"), domain = NA) } else nz <- length(z) ny <- length(y) if ( nx*nz != ny) stop("'y' length != 'x' rows * 'z' cols") if ( nx < 2 ) stop("rows < 2") if ( nz < 2 ) stop("cols < 2") if ( length(coords) != 3 || !identical(all.equal(sort(coords), 1:3), TRUE) ) stop("'coords' must be a permutation of 1:3") nulls <- c(is.null(normal_x), is.null(normal_y), is.null(normal_z)) if (!all( nulls ) ) { if (any( nulls )) stop("All normals must be supplied") if ( !identical(dim(y), dim(normal_x)) || !identical(dim(y), dim(normal_y)) || !identical(dim(y), dim(normal_z)) ) stop(gettextf("Bad dimension for %s", "normals"), domain = NA) flags[3] <- TRUE } nulls <- c(is.null(texture_s), is.null(texture_t)) if (!all( nulls ) ) { if (any( nulls )) stop("Both texture coordinates must be supplied") if ( !identical(dim(y), dim(texture_s)) || !identical(dim(y), dim(texture_t)) ) stop(gettextf("Bad dimension for %s", "textures"), domain = NA) flags[4] <- TRUE } idata <- as.integer( c( nx, nz ) ) parity <- (perm_parity(coords) + (x[2] < x[1]) + (z[2] < z[1]) ) %% 2 ret <- .C( rgl_surface, success = as.integer(FALSE), idata, as.numeric(x), as.numeric(z), as.numeric(y), as.numeric(normal_x), as.numeric(normal_z), as.numeric(normal_y), as.numeric(texture_s), as.numeric(texture_t), as.integer(coords), as.integer(parity), as.integer(flags), NAOK=TRUE ) if (! ret$success) stop("'rgl_surface' failed") lowlevel(ret$success) } ## ## add spheres ## rgl.spheres <- function( x, y=NULL, z=NULL, radius=1.0, fastTransparency = TRUE, ...) { rgl.material(...) vertex <- rgl.vertex(x,y,z) nvertex <- rgl.nvertex(vertex) radius <- rgl.attr(radius, nvertex) nradius <- length(radius) if (!nradius) stop("No radius specified") idata <- as.integer( c( nvertex, nradius ) ) ret <- .C( rgl_spheres, success = as.integer(FALSE), idata, as.numeric(vertex), as.numeric(radius), as.integer(fastTransparency), NAOK=TRUE ) if (! ret$success) stop("'rgl_spheres' failed") lowlevel(ret$success) } ## ## add planes ## rgl.planes <- function( a, b=NULL, c=NULL, d=0,...) { rgl.material(...) normals <- rgl.vertex(a, b, c) nnormals <- rgl.nvertex(normals) noffsets <- length(d) idata <- as.integer( c( nnormals, noffsets ) ) ret <- .C( rgl_planes, success = as.integer(FALSE), idata, as.numeric(normals), as.numeric(d), NAOK=TRUE ) if (! ret$success) stop("'rgl_planes' failed") lowlevel(ret$success) } ## ## add clip planes ## rgl.clipplanes <- function( a, b=NULL, c=NULL, d=0) { normals <- rgl.vertex(a, b, c) nnormals <- rgl.nvertex(normals) noffsets <- length(d) idata <- as.integer( c( nnormals, noffsets ) ) ret <- .C( rgl_clipplanes, success = as.integer(FALSE), idata, as.numeric(normals), as.numeric(d), NAOK=TRUE ) if (! ret$success) stop("'rgl_clipplanes' failed") lowlevel(ret$success) } ## ## add abclines ## rgl.abclines <- function(x, y=NULL, z=NULL, a, b=NULL, c=NULL, ...) { rgl.material(...) bases <- rgl.vertex(x, y, z) nbases <- rgl.nvertex(bases) directions <- rgl.vertex(a, b, c) ndirs <- rgl.nvertex(directions) idata <- as.integer( c( nbases, ndirs ) ) ret <- .C( rgl_abclines, success = as.integer(FALSE), idata, as.numeric(bases), as.numeric(directions), NAOK=TRUE ) if (! ret$success) stop("'rgl_abclines' failed") lowlevel(ret$success) } ## ## add texts ## rgl.texts <- function(x, y=NULL, z=NULL, text, adj = 0.5, pos = NULL, offset = 0.5, family=par3d("family"), font=par3d("font"), cex=par3d("cex"), useFreeType=par3d("useFreeType"), ... ) { rgl.material( ... ) vertex <- rgl.vertex(x,y,z) nvertex <- rgl.nvertex(vertex) if (!is.null(pos)) { npos <- length(pos) stopifnot(all(pos %in% 0:6)) stopifnot(length(offset) == 1) adj <- offset } else { pos <- 0 npos <- 1 } if (length(adj) > 3) warning("Only the first three entries of 'adj' are used") adj <- c(adj, 0.5, 0.5, 0.5)[1:3] if (!length(text)) { if (nvertex) warning("No text to plot") return(invisible(integer(0))) } text <- rep(text, length.out=nvertex) idata <- as.integer(nvertex) nfonts <- max(length(family), length(font), length(cex)) family <- rep(family, len=nfonts) font <- rep(font, len=nfonts) cex <- rep(cex, len=nfonts) family[font == 5] <- "symbol" font <- ifelse( font < 0 | font > 4, 1, font) ret <- .C( rgl_texts, success = as.integer(FALSE), idata, as.double(adj), as.character(text), as.numeric(vertex), as.integer(nfonts), as.character(family), as.integer(font), as.numeric(cex), as.integer(useFreeType), as.integer(npos), as.integer(pos), NAOK=TRUE ) if (! ret$success) stop("'rgl_texts' failed") lowlevel(ret$success) } ## ## add sprites ## rgl.sprites <- function( x, y=NULL, z=NULL, radius=1.0, shapes=NULL, userMatrix=diag(4), fixedSize = FALSE, adj = 0.5, pos = NULL, offset = 0.25, ... ) { rgl.material(...) center <- rgl.vertex(x,y,z) ncenter <- rgl.nvertex(center) radius <- rgl.attr(radius, ncenter) nradius <- length(radius) pos <- as.integer(pos) npos <- length(pos) if (npos) { pos <- rep(pos, length.out = ncenter) adj <- offset } adj <- c(adj, 0.5, 0.5, 0.5)[1:3] if (!nradius) stop("No radius specified") if (length(shapes) && length(userMatrix) != 16) stop("Invalid 'userMatrix'") if (length(fixedSize) != 1) stop("Invalid 'fixedSize'") idata <- as.integer( c(ncenter,nradius,length(shapes), fixedSize, npos) ) ret <- .C( rgl_sprites, success = as.integer(FALSE), idata, as.numeric(center), as.numeric(radius), as.integer(shapes), as.numeric(t(userMatrix)), as.numeric(adj), pos, as.numeric(offset), NAOK=TRUE ) if (! ret$success) stop("'rgl_sprites' failed") lowlevel(ret$success) } ## ## convert user coordinate to window coordinate ## rgl.user2window <- function( x, y=NULL, z=NULL, projection = rgl.projection()) { xyz <- xyz.coords(x,y,z,recycle=TRUE) points <- rbind(xyz$x,xyz$y,xyz$z,1) v <- asEuclidean(with(projection, t(proj %*% model %*% points))) # nolint viewport <- projection$view cbind( (v[,1]*0.5 + 0.5) + viewport[1]/viewport[3], (v[,2]*0.5 + 0.5) + viewport[2]/viewport[4], (1 + v[,3])*0.5 ) } ## ## convert window coordinate to user coordinate ## rgl.window2user <- function( x, y = NULL, z = 0, projection = rgl.projection()) { xyz <- xyz.coords(x,y,z,recycle=TRUE) viewport <- projection$view normalized <- rbind( 2*xyz$x - 1, 2*(xyz$y - viewport[2]/viewport[4]) - 1, 2*xyz$z - 1, 1 ) asEuclidean(with(projection, t(solve(proj %*% model, normalized)))) # nolint } # Selectstate values msNONE <- 1 msCHANGING <- 2 msDONE <- 3 msABORT <- 4 rgl.selectstate <- function(dev = cur3d(), subscene = currentSubscene3d(dev)) { ret <- .C( rgl_selectstate, as.integer(dev), as.integer(subscene), success = FALSE, state = as.integer(0), mouseposition = double(4) ) if (! ret$success) stop("'rgl_selectstate' failed") return(ret) } rgl.select <- function(button = c("left", "middle", "right"), dev = cur3d(), subscene = currentSubscene3d(dev)) { if (rgl.useNULL()) return(NULL) button <- match.arg(button) newhandler <- par3d("mouseMode", dev = dev, subscene = subscene) newhandler[button] <- "selecting" oldhandler <- par3d(mouseMode = newhandler, dev = dev, subscene = subscene) on.exit(par3d(mouseMode = oldhandler, dev = dev, subscene = subscene)) while ((result <- rgl.selectstate(dev = dev, subscene = subscene))$state < msDONE) Sys.sleep(0.1) rgl.setselectstate("none", dev = dev, subscene = subscene) if (result$state == msDONE) return(result$mouseposition) else return(NULL) } rgl.setselectstate <- function(state = "current", dev = cur3d(), subscene = currentSubscene3d(dev)) { state <- rgl.enum(state, current=0, none = 1, middle = 2, done = 3, abort = 4) idata <- as.integer(c(state)) ret <- .C( rgl_setselectstate, as.integer(dev), as.integer(subscene), success = FALSE, state = idata ) if (! ret$success) stop("'rgl_setselectstate' failed") c("none", "middle", "done", "abort")[ret$state] } rgl.projection <- function(dev = cur3d(), subscene = currentSubscene3d(dev)) { list(model = par3d("modelMatrix", dev = dev, subscene = subscene), proj = par3d("projMatrix", dev = dev, subscene = subscene), view = par3d("viewport", dev = dev, subscene = subscene)) } rgl.select3d <- function(button = c("left", "middle", "right"), dev = cur3d(), subscene = currentSubscene3d(dev)) { rect <- rgl.select(button = button, dev = dev, subscene = subscene) if (is.null(rect)) return(NULL) proj <- rgl.projection(dev = dev, subscene = subscene) llx <- rect[1] lly <- rect[2] urx <- rect[3] ury <- rect[4] selectionFunction3d(proj, region = c(llx, lly, urx, ury)) } selectionFunction3d <- function(proj, region = proj$region) { llx <- region[1] lly <- region[2] urx <- region[3] ury <- region[4] if ( llx > urx ) { temp <- llx llx <- urx urx <- temp } if ( lly > ury ) { temp <- lly lly <- ury ury <- temp } proj$view["x"] <- proj$view["y"] <- 0 function(x,y=NULL,z=NULL) { pixel <- rgl.user2window(x,y,z,projection=proj) x <- pixel[,1] y <- pixel[,2] z <- pixel[,3] (llx <= x) & (x <= urx) & (lly <= y) & (y <= ury) & (0 <= z) & (z <= 1) } } tagged3d <- function(tags = NULL, ids = NULL, full = FALSE, subscene = 0) { if ((missing(tags) + missing(ids)) != 1) stop("Exactly one of 'tags' and 'ids' should be specified.") all <- ids3d("all", subscene = subscene, tags = TRUE) if (!missing(tags)) all <- all[all$tag %in% tags,] else all <- all[match(ids, all$id),] if (full) all else if (!missing(tags) && !is.null(tags)) all$id else if (!missing(ids) && !is.null(ids)) all$tag else NULL } rgl/R/pch3d.R0000644000176200001440000001075714100762640012375 0ustar liggesuserspch3d <- function(x, y = NULL, z = NULL, pch = 1, bg = material3d("color")[1], cex = 1, radius = avgscale*cex/8, color = "black", lit = FALSE, ...) { xyz <- xyz.coords(x, y, z) xyz <- cbind(xyz$x, xyz$y, xyz$z) pch <- rep(pch, length.out = nrow(xyz)) color <- rep(color, length.out = nrow(xyz)) bg <- rep(bg, length.out = nrow(xyz)) basic <- function(p) switch(as.character(p), '0' = { # square theta <- seq(pi/4, 2*pi + pi/4, length.out = 5) cbind(cos(theta), sin(theta), 0) }, '1' = { # circle (actually 16-gon) theta <- seq(0, 2*pi, length.out = 17) cbind(cos(theta), sin(theta), 0)*sqrt(0.75) }, '2' = { # triangle theta <- seq(pi/2, 2*pi + pi/2, length.out = 4) cbind(cos(theta), sin(theta), 0) }, '-2' = { # triangle in square cbind(c(0, -1, 1, 0), c(1, -1, -1, 1), 0)*sqrt(0.5) }, '3' = { # plus theta <- seq(0, 2*pi, length.out = 5) rbind(cbind(cos(theta[c(1,3)]), sin(theta[c(1,3)]), 0), c(NA, NA, NA), cbind(cos(theta[c(2,4)]), sin(theta[c(2,4)]), 0)) }, '4' = { # cross theta <- seq(pi/4, 2*pi + pi/4, length.out = 5) rbind(cbind(cos(theta[c(1,3)]), sin(theta[c(1,3)]), 0), c(NA, NA, NA), cbind(cos(theta[c(2,4)]), sin(theta[c(2,4)]), 0)) }, '5' = { # diamond theta <- seq(0, 2*pi, length.out = 5) cbind(cos(theta), sin(theta), 0) }, '6' = { # nabla theta <- seq(3*pi/2, 2*pi + 3*pi/2, length.out = 4) cbind(cos(theta), sin(theta), 0) })*radius join <- function(s1, s2) rbind(s1, c(NA, NA, NA), s2) if (missing(radius)) avgscale <- sqrt(sum(c(diff(range(xyz[,1],na.rm=TRUE)), diff(range(xyz[,2],na.rm=TRUE)), diff(range(xyz[,3],na.rm=TRUE)))^2/3)) rot <- rotate3d(r3dDefaults$userMatrix, pi/2, 1, 0, 0) draw <- function(s, color) { sprites3d(thisxyz, shapes = lines3d(s, color = color, lit = lit, ...), userMatrix = rot) } fill <- function(s, color) sprites3d(thisxyz, shapes = polygon3d(s, color = color, lit = lit, ...), userMatrix = rot) outline <- function(s, color, bg) { dots <- list(...) dots$color <- bg sprites3d(thisxyz, shapes = c(lines3d(s, color = color, lit = lit, ...), do.call(polygon3d, c(list(s, lit = lit), dots))), userMatrix = rot) } save <- par3d(skipRedraw = TRUE) on.exit(par3d(save)) ids <- numeric() if (is.numeric(pch)) { bg[!(pch %in% 21:25)] <- bg[1] pchcol <- data.frame(pch, color, bg) uniquePchcol <- unique(pchcol) for (i in seq_len(nrow(uniquePchcol))) { p <- uniquePchcol$pch[i] cl <- uniquePchcol$color[i] b <- uniquePchcol$bg[i] thisxyz <- xyz[p == pch & cl == color & b == bg,, drop = FALSE] ids <- c(ids, switch(as.character(p), '0' =, '1' =, '2' =, '3' =, '4' =, '5' =, '6' = draw(basic(p), color = cl), '7' = draw(join(basic(0), basic(4)), color = cl), '8' = draw(join(basic(3), basic(4)), color = cl), '9' = draw(join(basic(3), basic(5)), color = cl), '10' = draw(join(basic(1), basic(3)*sqrt(0.75)), color = cl), '11' = draw(join(basic(2), basic(6)), color = cl), '12' = draw(join(basic(0), basic(3)*sqrt(0.5)), color = cl), '13' = draw(join(basic(1), basic(4)), color = cl), '14' = draw(join(basic(0), basic(-2)), color = cl), '15' = fill(basic(0), color = cl), '16' = fill(basic(1), color = cl), '17' = fill(basic(2), color = cl), '18' = fill(basic(5)/sqrt(2), color = cl), '19' = fill(basic(1), color = cl), '20' = fill(basic(1)*(2/3), color = cl), '21' = outline(basic(1), color = cl, bg = b), '22' = outline(basic(0), color = cl, bg = b), '23' = outline(basic(5), color = cl, bg = b), '24' = outline(basic(2), color = cl, bg = b), '25' = outline(basic(6), color = cl, bg = b))) } letters <- 32 <= pch & pch <= 255 xyz <- xyz[letters,, drop = FALSE] if (nrow(xyz)) { pch <- rawToChar(as.raw(pch[letters]), multiple = TRUE) color <- color[letters] } } if (nrow(xyz)) { pch <- substr(pch, start = 1, stop = 1) ids <- c(ids, text3d(xyz, texts = pch, cex = cex, color = color, ...)) } lowlevel(ids) } rgl/R/subscenes.R0000644000176200001440000002226314145464133013366 0ustar liggesuserscurrentSubscene3d <- function(dev = cur3d()) { .C(rgl_getsubsceneid, id = 1L, dev = as.integer(dev))$id } subsceneInfo <- function(id = NA, embeddings, recursive = FALSE) { if (is.na(id)) id <- currentSubscene3d() else if (is.character(id) && id == "root") id <- .C(rgl_getsubsceneid, id = 0L, dev = as.integer(cur3d()))$id if (!id) stop("No subscene info available.") id <- as.integer(id) result <- list(id = id) parent <- .C(rgl_getsubsceneparent, id = id)$id if (is.na(parent)) stop(gettextf("Subscene %s not found", id), domain = NA) if (!parent) parent <- NULL result[["parent"]] <- parent n <- .C(rgl_getsubscenechildcount, id = id, n = integer(1))$n if (n) { children <- .C(rgl_getsubscenechildren, id = id, children=integer(n))$children if (recursive) { childlist <- list() for (i in seq_len(n)) childlist[[i]] <- subsceneInfo(id = children[i], recursive = TRUE) result[["children"]] <- childlist } else result[["children"]] <- children } embeddingNames <- c("inherit", "modify", "replace") if (!missing(embeddings)) { embeddings <- pmatch(embeddings, embeddingNames, duplicates.ok = TRUE) if (any(is.na(embeddings)) || length(embeddings) != 4) stop(gettextf("Four embeddings must be specified; names chosen from %s", paste(dQuote(embeddingNames), collapse=", ")), domain = NA) if (embeddings[4] == "modify") stop("The mouseMode embedding cannot be 'modify'") .C(rgl_setEmbeddings, id = id, embeddings = as.integer(embeddings)) } embeddings <- .C(rgl_getEmbeddings, id = id, embeddings = integer(4))$embeddings embeddings <- embeddingNames[embeddings] names(embeddings) <- c("viewport", "projection", "model", "mouse") result[["embeddings"]] <- embeddings result } newSubscene3d <- function(viewport = "replace", projection = "replace", model = "replace", mouseMode = "inherit", parent = currentSubscene3d(), copyLights = TRUE, copyShapes = FALSE, copyBBoxDeco = copyShapes, copyBackground = FALSE, newviewport, ignoreExtent) { embedding <- c("inherit", "modify", "replace") viewport <- pmatch(viewport, embedding) projection <- pmatch(projection, embedding) model <- pmatch(model, embedding) mouseMode <- pmatch(mouseMode, embedding) if (missing(ignoreExtent)) ignoreExtent <- model != 1 stopifnot(length(viewport) == 1L, length(projection) == 1L, length(model) == 1L, length(mouseMode) ==1L, mouseMode != 2L, !is.na(viewport), !is.na(projection), !is.na(model)) embedding <- c(viewport, projection, model, mouseMode) id <- .C(rgl_newsubscene, id = integer(1), parent = as.integer(parent), embedding = as.integer(embedding), as.integer(ignoreExtent))$id if (id) { if (copyLights || copyShapes || copyBBoxDeco || copyBackground) { useSubscene3d(parent) ids <- ids3d(type = c("lights", "shapes", "bboxdeco", "background")[c(copyLights, copyShapes, copyBBoxDeco, copyBackground)])$id if (length(ids)) addToSubscene3d(ids, subscene = id) } useSubscene3d(id) if (!missing(newviewport)) { embedding <- subsceneInfo(id)$embeddings if (embedding[1] > 1) par3d(viewport = as.integer(newviewport)) } } else stop("Subscene creation failed") lowlevel(id) } useSubscene3d <- function(subscene) { result <- .C(rgl_setsubscene, id=as.integer(subscene))$id if (!result) stop(gettextf("Subscene %d not found.", subscene), domain = NA) invisible(result) } addToSubscene3d <- function(ids = tagged3d(tags), tags, subscene = currentSubscene3d()) { ids <- as.integer(ids) dups <- intersect(ids, ids3d("all", subscene)$id) if (length(dups)) stop(gettextf("Cannot add %s, already present", paste(dups, collapse = ", ")), domain = NA) result <- .C(rgl_addtosubscene, success = as.integer(subscene), n = as.integer(length(ids)), ids = ids)$success if (!result) stop(gettextf("Failed to add objects to subscene %s", subscene), domain = NA) lowlevel(subscene) } delFromSubscene3d <- function(ids = tagged3d(tags), tags, subscene = currentSubscene3d()) { result <- .C(rgl_delfromsubscene, success = as.integer(subscene), n = as.integer(length(ids)), ids = as.integer(ids))$success if (!result) stop(gettextf("Failed to delete objects from subscene %s", subscene), domain = NA) lowlevel(subscene) } # This destroys any objects that are in the scene but # not in either the protect vector or visible in a subscene gc3d <- function(protect=NULL) { protect <- as.integer(protect) invisible( .C(rgl_gc, n = length(protect), protect)$n ) } subsceneList <- function(value, window = cur3d()) { alllists <- .rglEnv$subsceneLists # This cleans up lists for closed windows: alllists <- alllists[names(alllists) %in% rgl.dev.list()] if (!missing(value)) { if (is.null(alllists)) alllists <- list() alllists[[as.character(window)]] <- value assign("subsceneLists", alllists, envir = .rglEnv) } if (is.null(alllists)) return(NULL) else return(alllists[[as.character(window)]]) } next3d <- function(current = NA, clear = TRUE, reuse = TRUE) { .check3d() if (is.na(current)) current <- currentSubscene3d() subscenes <- subsceneList() while (!is.null(subscenes) && !(current %in% subscenes)) subscenes <- attr(subscenes, "prev") if (is.null(subscenes)) subscenes <- current this <- which(current == subscenes) if (reuse && !nrow(ids3d(subscene = current))) { # do nothing } else if (this == length(subscenes)) this <- 1 else this <- this + 1 repeat{ current <- subscenes[this] result <- try(useSubscene3d(current)) if (inherits(result, "try-error")) { subsceneList(subscenes <- subscenes[-this]) if (length(subscenes) == 0) stop("'subsceneList()' contained no valid subscenes") if (this > length(subscenes)) this <- 1 } else break } if (clear) clear3d(subscene = current) } clearSubsceneList <- function(delete = currentSubscene3d() %in% subsceneList(), window = cur3d()) { if (!missing(window)) set3d(window) thelist <- subsceneList() if (delete && length(thelist)) { parent <- subsceneInfo(thelist[1])$parent if (is.null(parent)) parent <- rootSubscene() pop3d(type="subscene", id=thelist) useSubscene3d(parent) gc3d() } subsceneList(attr(thelist, "prev")) invisible(currentSubscene3d()) } mfrow3d <- function(nr, nc, byrow = TRUE, parent = NA, sharedMouse = FALSE, ...) { stopifnot(nr >= 1, nc >= 1) .check3d() if (missing(parent)) clearSubsceneList() if (is.na(parent)) parent <- currentSubscene3d() useSubscene3d(parent) result <- integer(nr*nc) parentvp <- par3d("viewport") if (byrow) for (i in seq_len(nr)) for (j in seq_len(nc)) { newvp <- c(parentvp[1] + (j - 1)*parentvp[3]/nc, parentvp[2] + (nr - i)*parentvp[4]/nr, parentvp[3]/nc, parentvp[4]/nr) result[(i-1)*nc + j] <- newSubscene3d(newviewport = newvp, parent = parent, ...) } else for (j in seq_len(nc)) for (i in seq_len(nr)) { newvp <- c(parentvp[1] + (j - 1)*parentvp[3]/nc, parentvp[2] + (nr - i)*parentvp[4]/nr, parentvp[3]/nc, parentvp[4]/nr) result[(j-1)*nr + i] <- newSubscene3d(newviewport = newvp, parent = parent, ...) } if (sharedMouse) for (sub in result) par3d(listeners = result, subscene = sub) useSubscene3d(result[1]) attr(result, "prev") <- subsceneList() subsceneList(result) invisible(result) } layout3d <- function(mat, widths = rep.int(1, ncol(mat)), heights = rep.int(1, nrow(mat)), parent = NA, sharedMouse = FALSE, ...) { storage.mode(mat) <- "integer" mat <- as.matrix(mat) num.figures <- max(mat) if (!all(seq_len(num.figures) %in% as.integer(mat))) stop(gettextf("Layout matrix must contain at least one reference\nto each of the values {1 ... %d}\n", num.figures), domain = NA) .check3d() if (missing(parent)) clearSubsceneList() if (is.na(parent)) parent <- currentSubscene3d() useSubscene3d(parent) parentvp <- par3d("viewport") widths <- parentvp["width"]*widths/sum(widths) heights <- parentvp["height"]*heights/sum(heights) xs <- c(0, cumsum(widths)) ys <- rev(c(0, cumsum(rev(heights))))[-1] result <- integer(num.figures) for (i in seq_len(num.figures)) { rows <- range(row(mat)[mat == i]) cols <- range(col(mat)[mat == i]) newvp <- c(xs[cols[1]], ys[rows[2]], sum(widths[cols[1]:cols[2]]), sum(heights[rows[1]:rows[2]])) result[i] <- newSubscene3d(newviewport = newvp, parent = parent, ...) } if (sharedMouse) for (sub in result) par3d(listeners = result, subscene = sub) useSubscene3d(result[1]) attr(result, "prev") <- subsceneList() subsceneList(result) invisible(result) } rgl/R/asy.R0000644000176200001440000003472414145464133012175 0ustar liggesuserswriteASY <- function(scene = scene3d(), title = "scene", outtype = c("pdf", "eps", "asy", "latex", "pdflatex"), prc = TRUE, runAsy = "asy %filename%", defaultFontsize = 12, width = 7, height = 7, ppi = 100, ids = tagged3d(tags), tags = NULL, version = "2.65") { withColors <- TRUE withNormals <- FALSE outtype <- match.arg(outtype) version <- numeric_version(version) writeHeader <- function() { outformat <- c(pdf = "pdf", eps = "eps", asy = "", latex = "eps", pdflatex = "pdf")[outtype] prc <- if (prc) "true" else "false" userMatrix <- get.par3d("userMatrix") defaultObserver <- (c(get.par3d("observer"), 1) %*% userMatrix)[1:3] up <- (c(0, 1, 0, 1) %*% userMatrix)[1:3] FOV <- get.par3d("FOV")*pi/180 if (FOV > 0) { projection <- "perspective" dist <- 0.8/tan(FOV/2) defaultObserver <- defaultObserver*dist/sqrt(sum(defaultObserver^2)) } else projection <- "orthographic" result <<- c(result, subst( '// %title% produced by rgl', title), if (outtype %in% c("pdf", "eps")) subst( 'settings.outformat = "%outformat%";', outformat), subst( 'settings.prc = %prc%; size(%width%inches, %height%inches); import graph3; currentprojection = %projection%(%x%, %y%, %z%, up = (%ux%, %uy%, %uz%)); defaultpen(fontsize(%defaultFontsize%)); ticklabel RGLstrings(real[] at, string[] label) { return new string(real x) { int i = search(at, x); if (i < 0) return ""; else return label[i]; }; } ticklabel RGLScale(real s) { return new string(real x) {return format(s*x);}; }', prc, width, height, x=defaultObserver[1], y=defaultObserver[2], z=defaultObserver[3], ux = up[1], uy = up[2], uz = up[3], projection, defaultFontsize)) } # simulate rgl.attrib get.attrib <- function(id, attrib) { obj <- scene$objects[[as.character(id)]] obj[[attrib]] } # simulate ids3d get.ids <- function(type = "shapes") { ids <- names(scene$objects) types <- vapply(ids, function(x) scene$objects[[x]]$type, "") if (length(s <- which(type %in% "shapes"))) { type <- c(type[-s], "points", "linestrip", "lines", "text", "triangles", "quads", "surface", "spheres", "planes", "abclines", "clipplanes", "sprites") } keep <- types %in% type data.frame(id = as.numeric(ids[keep]), type = types[keep]) } getmaterial <- function(id) { result <- scene$material this <- scene$objects[[as.character(id)]]$material result[names(this)] <- this result } getScaling <- function() { scale <- get.par3d("scale") scale/avgScale() } getCentre <- function() { bbox <- get.par3d("bbox") c(mean(bbox[1:2]), mean(bbox[3:4]), mean(bbox[5:6])) } getVertices <- function(id) { scale <- getScaling() vertices <- scale(get.attrib(id, "vertices"), center=FALSE, scale=1/scale) if (withColors) { colors <- get.attrib(id, "colors") if (nrow(colors) == 1) colors <- colors[rep(1, nrow(vertices)),,drop = FALSE] } if (withNormals) { normals <- get.attrib(id, "normals") if (!nrow(normals)) normals <- 0*vertices } cbind(vertices, if (withColors) colors, if (withNormals) normals) } get.par3d <- function(attr = NULL) { par3d <- scene$rootSubscene$par3d if (!is.null(attr)) par3d <- par3d[[attr]] par3d } rgba <- c("r", "g", "b", "a") lastCol <- c(0,0,0,1) lastSize <- 0.5 setPen <- function(col = lastCol, size = lastSize) { if (any(col[1:3] != lastCol[1:3])) { result <<- c(result, subst( 'currentpen = colorless(currentpen) + rgb(%r%, %g%, %b%);', r = col[1], g = col[2], b = col[3])) lastCol[1:3] <<- col[1:3] } if (col[4] != lastCol[4]) { result <<- c(result, subst( 'currentpen += opacity(%a%);', a = col[4])) lastCol[4] <<- col[4] } if (size != lastSize) { result <<- c(result, subst( 'currentpen += linewidth(%size%);', size)) lastSize <<- size } } writePoly <- function(vertices) { if (any(!is.finite(vertices))) return() setPen(apply(vertices[, rgba], 2, mean)) v <- vertices[1, 1:3] result <<- c(result, subst('draw(surface((%x%, %y%, %z%)', x=v[1], y=v[2], z=v[3])) for (j in seq_len(nrow(vertices))[-1]) { v <- vertices[j, 1:3] result <<- c(result, subst('--(%x%, %y%, %z%)', x=v[1], y=v[2], z=v[3])) } result <<- c(result, '--cycle), light=currentlight);') } writeTriangles <- function(id) { vertices <- getVertices(id) n <- nrow(vertices) %/% 3 for (i in seq_len(n)) writePoly(vertices[3*i-2:0,]) } writeQuads <- function(id) { vertices <- getVertices(id) n <- nrow(vertices) %/% 4 for (i in seq_len(n)) writePoly(vertices[4*i-3:0,]) } writeSurface <- function(id) { vertices <- getVertices(id) dims <- get.attrib(id, "dim") nx <- dims[1] nz <- dims[2] for (i in seq_len(nz)[-nz]) for (j in seq_len(nx)[-nx]) writePoly(vertices[c((i-1)*nx + j, i*nx + j, i*nx + j + 1, (i-1)*nx + j + 1),]) } writeSpheres <- function(id) { vertices <- getVertices(id) n <- nrow(vertices) radii <- get.attrib(id, "radii")/4 radii <- rep(radii, length.out=n) for (i in seq_len(n)) { setPen(vertices[i, rgba]) v <- vertices[i, 1:3] result <<- c(result, subst('draw(shift((%x%, %y%, %z%))*scale3(%r%)*unitsphere);', x = v[1], y = v[2], z = v[3], r = radii[i])) } } avgScale <- function() { bbox <- get.par3d("bbox") ranges <- c(bbox[2]-bbox[1], bbox[4]-bbox[3], bbox[6]-bbox[5]) if (prod(ranges) == 0) 1 else exp(mean(log(ranges))) } writePoints <- function(id) { setPen(size = getmaterial(id)$size) vertices <- getVertices(id) n <- nrow(vertices) for (i in seq_len(n)) { setPen(vertices[i, rgba]) result <<- c(result, subst('draw((%x%, %y%, %z%));', x = vertices[i, 1], y = vertices[i, 2], z = vertices[i, 3])) } } writeText <- function(id) { vertices <- getVertices(id) n <- nrow(vertices) texts <- get.attrib(id, "texts") texts <- rep(texts, length.out = n) adj <- get.attrib(id, "adj") adj <- adj[rep(seq_len(nrow(adj)), length.out = n),, drop = FALSE] for (i in seq_len(n)) { setPen(vertices[i, rgba]) if (all(!is.na(vertices[i, 1:3]))) result <<- c(result, subst('label("%text%", position = (%x%, %y%, %z%), align = (%ax%,%ay%));', x = vertices[i, 1], y = vertices[i, 2], z = vertices[i, 3], text = texts[i], ax = 1-2*adj[i, 1], ay = 1-2*adj[i, 2])) } } writeSegments <- function(id) { setPen(size = getmaterial(id)$lwd) vertices <- getVertices(id) n <- nrow(vertices) %/% 2 for (i in seq_len(n)) { i1 <- 2*i - 1 i2 <- i1 + 1 if (all(!is.na(vertices[c(i1, i2), 1:3]))) { setPen((vertices[i1, rgba] + vertices[i2, rgba])/2) result <<- c(result, subst('draw((%x1%, %y1%, %z1%)--(%x2%, %y2%, %z2%));', x1 = vertices[i1, 1], y1 = vertices[i1, 2], z1 = vertices[i1, 3], x2 = vertices[i2, 1], y2 = vertices[i2, 2], z2 = vertices[i2, 3])) } } } writeLines <- function(id) { setPen(size = getmaterial(id)$lwd) vertices <- getVertices(id) n <- nrow(vertices) open <- FALSE for (i in seq_len(n)) { if (open) { if (any(is.na(vertices[i, 1:3]))) { result <<- c(result, ");") open <- FALSE } else result <<- c(result, subst('--(%x%, %y%, %z%)', x = vertices[i, 1], y = vertices[i, 2], z = vertices[i, 3])) } else if (all(!is.na(vertices[i, 1:3]))) { setPen(vertices[i, rgba]) result <<- c(result, subst('draw((%x%, %y%, %z%)', x = vertices[i, 1], y = vertices[i, 2], z = vertices[i, 3])) open <- TRUE } } if (open) result <<- c(result, ');') } writeBackground <- function(id) { col <- get.attrib(id, "colors") result <<- c(result, subst( 'currentlight.background = rgb(%r%, %g%, %b%);', r = col[1], g=col[2], b=col[3] )) } writeBBox <- function(id) { setPen(size = getmaterial(id)$lwd) bbox <- get.par3d("bbox") scale <- getScaling() vertices <- getVertices(id) ticks <- vertices[,1] ticks <- ticks[!is.na(ticks)] if (length(ticks)) xticks <- subst('Ticks3(1, Ticks = new real[] {%ticks%}, ticklabel = RGLScale(%scale%))', scale = 1/scale[1], ticks = paste(ticks, collapse=",")) else xticks <- subst('Ticks3(1, ticklabel = RGLScale(%scale%))', scale = 1/scale[1]) ticks <- vertices[,2] ticks <- ticks[!is.na(ticks)] if (length(ticks)) yticks <- subst('Ticks3(1, Ticks = new real[] {%ticks%}, ticklabel = RGLScale(%scale%))', scale = 1/scale[2], ticks = paste(ticks, collapse=",")) else yticks <- subst('Ticks3(1, ticklabel = RGLScale(%scale%))', scale = 1/scale[2]) ticks <- vertices[,3] ticks <- ticks[!is.na(ticks)] if (length(ticks)) zticks <- subst('Ticks3(1, Ticks = new real[] {%ticks%}, ticklabel = RGLScale(%scale%))', scale = 1/scale[3], ticks = paste(ticks, collapse=",")) else xticks <- subst('Ticks3(1, ticklabel = RGLScale(%scale%))', scale = 1/scale[3]) bbox <- bbox * rep(scale, each = 2) result <<- c(result, subst( 'xaxis3(axis=YZEquals(y=%ymin%, z=%zmin%), xmin=%xmin%, xmax=%xmax%, ticks = %xticks%); xaxis3(axis=YZEquals(y=%ymin%, z=%zmax%), xmin=%xmin%, xmax=%xmax%); xaxis3(axis=YZEquals(y=%ymax%, z=%zmin%), xmin=%xmin%, xmax=%xmax%); xaxis3(axis=YZEquals(y=%ymax%, z=%zmax%), xmin=%xmin%, xmax=%xmax%); yaxis3(axis=XZEquals(x=%xmin%, z=%zmin%), ymin=%ymin%, ymax=%ymax%, ticks = %yticks%); yaxis3(axis=XZEquals(x=%xmin%, z=%zmax%), ymin=%ymin%, ymax=%ymax%); yaxis3(axis=XZEquals(x=%xmax%, z=%zmin%), ymin=%ymin%, ymax=%ymax%); yaxis3(axis=XZEquals(x=%xmax%, z=%zmax%), ymin=%ymin%, ymax=%ymax%); zaxis3(axis=XYEquals(x=%xmin%, y=%ymin%), zmin=%zmin%, zmax=%zmax%, ticks = %zticks%); zaxis3(axis=XYEquals(x=%xmin%, y=%ymax%), zmin=%zmin%, zmax=%zmax%); zaxis3(axis=XYEquals(x=%xmax%, y=%ymin%), zmin=%zmin%, zmax=%zmax%); zaxis3(axis=XYEquals(x=%xmax%, y=%ymax%), zmin=%zmin%, zmax=%zmax%);', xmin = bbox[1], xmax = bbox[2], ymin=bbox[3], ymax=bbox[4], zmin=bbox[5], zmax=bbox[6], xticks, yticks, zticks)) } writeLights <- function(ids) { if (!length(ids)) result <<- c(result, 'currentlight = nolight;') else { col <- array(NA, c(length(ids), 3, 3)) pos <- matrix(NA, nrow=length(ids), ncol=3) for (i in seq_along(ids)) { col[i,,] <- get.attrib(ids[i], "colors")[1:3, 1:3] pos[i,] <- get.attrib(ids[i], "vertices")[1,] } result <<- c(result, 'currentlight = light(') if (version < "2.50") { cols <- paste(paste0("rgb(", col[, 1, 1], ",", col[, 1, 2], ",", col[, 1, 3], ")"), collapse = ",") result <<- c(result, subst( 'ambient=new pen[] {%cols%},', cols )) } cols <- paste(paste0("rgb(", col[, 2, 1], ",", col[, 2, 2], ",", col[, 2, 3], ")"), collapse = ",") result <<- c(result, subst('diffuse = new pen[] {%cols%},', cols)) cols <- paste(paste0("rgb(", col[, 3, 1], ",", col[, 3, 2], ",", col[, 3, 3], ")"), collapse = ",") result <<- c(result, subst('specular = new pen[] {%cols%},', cols)) pos <- paste(paste0("(", pos[, 1], ",", pos[, 2], ",", pos[, 3], ")"), collapse = ",") result <<- c(result, subst('position = new triple[] {%pos%}', pos)) if (version < "2.47") result <<- c( result, subst( ', viewport = %viewpoint%', pos, viewpoint = if (get.attrib(ids[1], "viewpoint")) "true" else "false" ) ) result <<- c(result, ');') } } knowntypes <- c("points", "linestrip", "lines", "text", "triangles", "quads", "surface", "spheres", "planes", "abclines", "background", "bboxdeco", "light") # Execution starts here! allids <- get.ids(c("shapes", "background", "bboxdeco", "light")) if (is.null(ids)) { ids <- allids types <- as.character(ids$type) ids <- ids$id } else { ind <- match(ids, allids$id) keep <- !is.na(ind) if (any(!keep)) warning(gettextf("Object(s) with id %s not found", paste(ids[!keep], collapse=" ")), domain = NA) ids <- ids[keep] types <- allids$type[ind[keep]] } unknowntypes <- setdiff(types, knowntypes) if (length(unknowntypes)) warning(gettextf("Object type(s) %s not handled", paste("'", unknowntypes, "'", sep="", collapse=", ")), domain = NA) keep <- types %in% knowntypes ids <- ids[keep] types <- types[keep] result <- NULL writeHeader() # Lights are done first. writeLights(ids[types == "light"]) for (i in seq_along(ids)) { result <<- c(result, subst('// %type% object %id%', type = types[i], id = ids[i])) switch(types[i], planes =, triangles = writeTriangles(ids[i]), quads = writeQuads(ids[i]), surface = writeSurface(ids[i]), spheres = writeSpheres(ids[i]), points = writePoints(ids[i]), abclines =, lines = writeSegments(ids[i]), linestrip = writeLines(ids[i]), text = writeText(ids[i]), background = writeBackground(ids[i]), bboxdeco = writeBBox(ids[i]), light = {} # nolint ) } if (outtype %in% c("latex", "pdflatex")) { filename <- paste0(title, ".tex") result <- c("\\begin{asy}", result, "\\end{asy}") } else filename <- paste0(title, ".asy") base::writeLines(result, filename) if (outtype %in% c("pdf", "eps")) { system(subst(runAsy, filename)) filename <- paste0(title, ".", outtype) } invisible(filename) } rgl/R/playwidget.R0000644000176200001440000001165614145464133013551 0ustar liggesusers # Widget output function for use in Shiny playwidgetOutput <- function(outputId, width = '0px', height = '0px') { registerShinyHandlers() shinyWidgetOutput(outputId, 'rglPlayer', width, height, package = 'rgl') } # Widget render function for use in Shiny renderPlaywidget <- function(expr, env = parent.frame(), quoted = FALSE, outputArgs = list()) { registerShinyHandlers() if (!quoted) expr <- substitute(expr) # force quoted shiny::markRenderFunction(playwidgetOutput, shinyRenderWidget(expr, playwidgetOutput, env, quoted = TRUE), outputArgs = outputArgs) } playwidget <- function(sceneId, controls, start = 0, stop = Inf, interval = 0.05, rate = 1, components = c("Reverse", "Play", "Slower", "Faster", "Reset", "Slider", "Label"), loop = TRUE, step = 1, labels = NULL, precision = 3, elementId = NULL, respondTo = NULL, reinit = NULL, buttonLabels = components, pause = "Pause", height = 40, ...) { if (is.null(elementId) && !inShiny()) elementId <- newElementId("rgl-play") # sceneId = NA turns into prevRglWidget = NULL upstream <- processUpstream(sceneId, playerId = elementId) if (!is.null(respondTo)) components <- buttonLabels <- NULL if (length(stop) != 1 || !is.finite(stop)) stop <- NULL if (identical(controls, NA)) stop(dQuote("controls"), " should not be NA.") stopifnot(is.list(controls)) if (inherits(controls, "rglControl")) controls <- list(controls) types <- vapply(controls, class, "") if (any(bad <- types != "rglControl")) { bad <- which(bad)[1] stop("Controls should be of class 'rglControl', control ", bad, " is ", types[bad]) } names(controls) <- NULL if (length(reinit)) { bad <- vapply(controls, function(x) x$type == "vertexSetter" && length(intersect(reinit, x$objid)), FALSE) if (any(bad)) warning("'vertexControl' is incompatible with re-initialization") } if (!length(components)) components <- character() else components <- match.arg(components, c("Reverse", "Play", "Slower", "Faster", "Reset", "Slider", "Label", "Step"), several.ok = TRUE) buttonLabels <- as.character(buttonLabels) pause <- as.character(pause) stopifnot(length(buttonLabels) == length(components), length(pause) == 1) for (i in seq_along(controls)) { control <- controls[[i]] if (!is.null(labels)) labels <- control$labels if (!is.null(control$param)) { start <- min(start, control$param[is.finite(control$param)]) stop <- max(stop, control$param[is.finite(control$param)]) } } if (is.null(stop) && !missing(labels) && length(labels)) { stop <- start + (length(labels) - 1)*step } if (is.null(stop)) { if ("Slider" %in% components) { warning("Cannot have slider with non-finite limits") components <- setdiff(components, "Slider") } labels <- NULL } else { if (stop == start) warning("'stop' and 'start' are both ", start) } control <- list( actions = controls, start = start, stop = stop, value = start, interval = interval, rate = rate, components = components, buttonLabels = buttonLabels, pause = pause, loop = loop, step = step, labels = labels, precision = precision, reinit = reinit, sceneId = upstream$prevRglWidget, respondTo = respondTo) result <- createWidget( name = 'rglPlayer', x = control, elementId = elementId, package = 'rgl', height = height, sizingPolicy = sizingPolicy(defaultWidth = "auto", defaultHeight = "auto"), dependencies = rglDependency, ... ) if (is.list(upstream$objects)) { if (requireNamespace("manipulateWidget", quietly = TRUE)) result <- do.call(manipulateWidget::combineWidgets, c(upstream$objects, list(manipulateWidget::combineWidgets(result, nrow = 1), rowsize = c(upstream$rowsizes, height), ncol = 1))) else warning("Combining widgets requires the 'manipulateWidget' package.", call. = FALSE) } result } toggleWidget <- function(sceneId, ids = tagged3d(tags), tags = NULL, hidden = integer(), subscenes = NULL, label, ...) { if (missing(label)) if (missing(ids)) label <- paste(tags, collapse = ", ") else label <- deparse(substitute(ids)) playwidget(sceneId, subsetControl(subsets = list(ids, hidden), subscenes = subscenes), start = 0, stop = 1, components = "Step", buttonLabels = label, interval = 1, ...) } rgl/R/rgl.bringtotop.R0000644000176200001440000000044014100762640014332 0ustar liggesusers ## ## bring device to top ## ## rgl.bringtotop <- function(stay = FALSE) { if ((.Platform$OS.type != "windows") && stay) warning("'stay' not implemented") ret <- .C( rgl_dev_bringtotop, success=FALSE, as.logical(stay) ) if (! ret$success) stop("'rgl.bringtotop' failed") } rgl/R/par3d.R0000644000176200001440000000622614100762640012401 0ustar liggesusers.Par3d <- c("antialias", "FOV", "ignoreExtent", "listeners", "mouseMode", "observer", "modelMatrix", "projMatrix", "skipRedraw", "userMatrix", "userProjection", "scale", "viewport", "zoom", "bbox", "windowRect", "family", "font", "cex", "useFreeType", "fontname", "maxClipPlanes", "glVersion", "activeSubscene" ) .Par3d.readonly <- c( "antialias", "observer", "modelMatrix", "projMatrix", "bbox", "fontname", "maxClipPlanes", "glVersion", "activeSubscene" ) par3d <- function(..., no.readonly = FALSE, dev = cur3d(), subscene = currentSubscene3d(dev)) { single <- FALSE args <- list(...) if (!length(args)) args <- as.list(if (no.readonly) .Par3d[-match(.Par3d.readonly, .Par3d)] else .Par3d) else { if (is.null(names(args)) && all(unlist(lapply(args, is.character)))) args <- as.list(unlist(args)) if (length(args) == 1) { if (is.list(args[[1]]) | is.null(args[[1]])) args <- args[[1]] else if(is.null(names(args))) single <- TRUE } } if ("dev" %in% names(args)) { if (!missing(dev) && dev != args[["dev"]]) stop("'dev' specified inconsistently") dev <- args[["dev"]] args[["dev"]] <- NULL } if (specifiedSubscene <- ("subscene" %in% names(args))) { if (!missing(subscene) && subscene != args[["subscene"]]) stop("'subscene' specified inconsistently") subscene <- args[["subscene"]] args[["subscene"]] <- NULL } dev <- as.integer(dev) if (!dev) dev <- open3d() subscene <- as.integer(subscene) if ("userMatrix" %in% names(args)) { m <- args$userMatrix svd <- svd(m[1:3, 1:3]) m[1:3, 1:3] <- svd$u %*% t(svd$v) theta <- atan2(-m[1,3], m[1,1]) m <- m %*% rotationMatrix(theta, 0,1,0) svd <- svd(m[1:3, 1:3]) m[1:3,1:3] <- svd$u %*% t(svd$v) phi <- atan2(-m[2,3], m[3,3]) args$.position <- c(theta, phi)*180/pi } if ("mouseMode" %in% names(args)) { m <- args$mouseMode if (is.null(names(m))) { if (length(m) < 5) args$mouseMode <- c("none", m) } else { m0 <- par3d("mouseMode") m0[names(m)] <- m args$mouseMode <- m0 } } if (forceViewport <- ("windowRect" %in% names(args) && !("viewport" %in% names(args)))) { if (specifiedSubscene) warning("Viewport for subscene ", subscene, " will be adjusted; other viewports will not be.") oldviewport <- .Call(rgl_par3d, dev, subscene, list("viewport","windowRect")) } value <- if (single) .Call(rgl_par3d, dev, subscene, args)[[1]] else .Call(rgl_par3d, dev, subscene, args) # The windowRect might be modified by the window manager (if # too large, for example), so we need to read it after the # change if (forceViewport) { oldsize <- oldviewport$windowRect[3:4] - oldviewport$windowRect[1:2] Sys.sleep(0.1) windowRect <- .Call(rgl_par3d, dev, subscene, list("windowRect"))$windowRect newsize <- windowRect[3:4] - windowRect[1:2] .Call(rgl_par3d, dev, subscene, list(viewport = round(oldviewport$viewport*newsize/oldsize))) } if(!is.null(names(args))) invisible(value) else value } rgl/R/ellipse3d.R0000644000176200001440000000447714103457017013264 0ustar liggesusersellipse3d <- function(x, ...) UseMethod("ellipse3d") ellipse3d.default <- function(x, scale = c(1, 1, 1), centre = c(0, 0, 0), level = 0.95, t = sqrt(qchisq(level, 3)), which = 1:3, subdivide = 3, smooth = TRUE, ...) { stopifnot(is.matrix(x)) cov <- x[which, which] chol <- chol(cov) sphere <- subdivision3d(cube3d(...), subdivide) norm <- sqrt( sphere$vb[1,]^2 + sphere$vb[2,]^2 + sphere$vb[3,]^2 ) for (i in 1:3) sphere$vb[i,] <- sphere$vb[i,]/norm sphere$vb[4,] <- 1 if (smooth) sphere$normals <- sphere$vb result <-scale3d(transform3d( sphere, chol), t,t,t) if (!missing(scale)) result <- scale3d(result, scale[1], scale[2], scale[3]) if (!missing(centre)) result <- translate3d(result, centre[1], centre[2], centre[3]) return(result) } ellipse3d.lm <- function(x, which = 1:3, level = 0.95, t = sqrt(3 * qf(level, 3, x$df.residual)), ...) { s <- summary(x) names <- names(x$coefficients[which]) structure(c(ellipse3d.default(s$sigma^2 * s$cov.unscaled[which, which], centre = x$coefficients[which], t = t, ...), xlab=names[1], ylab=names[2], zlab=names[3]), class="mesh3d") } ellipse3d.glm <- function(x, which = 1:3, level = 0.95, t, dispersion, ...) { s <- summary(x) est.disp <- missing(dispersion) & !(x$family$family %in% c('poisson','binomial')) if (missing(dispersion)) dispersion <- s$dispersion if (missing(t)) t <- ifelse(est.disp,sqrt(3 * qf(level, 3, s$df[2])), sqrt(qchisq(level, 3))) names <- names(x$coefficients[which]) structure(c(ellipse3d.default(dispersion * s$cov.unscaled[which, which], centre = x$coefficients[which], t = t, ...), xlab=names[1], ylab=names[2], zlab=names[3]), class="mesh3d") } ellipse3d.nls <- function(x, which = 1:3, level = 0.95, t = sqrt(3 * qf(level, 3, s$df[2])), ...) { s <- summary(x) names <- names(x$m$getPars()[which]) structure(c(ellipse3d.default(s$sigma^2 * s$cov.unscaled[which, which], centre = x$m$getPars()[which], t = t, ...), xlab=names[1], ylab=names[2], zlab=names[3]), class="mesh3d") } rgl/R/material.R0000644000176200001440000001255714145464133013177 0ustar liggesusers## ## R source file ## This file is part of rgl ## ## ## ## ===[ SECTION: generic appearance function ]================================ ## rgl.material <- function( color = "white", alpha = 1.0, lit = TRUE, ambient = "black", specular = "white", emission = "black", shininess = 50.0, smooth = TRUE, texture = NULL, textype = "rgb", texmipmap = FALSE, texminfilter = "linear", texmagfilter = "linear", texenvmap = FALSE, front = "fill", back = "fill", size = 3.0, lwd = 1.0, fog = TRUE, point_antialias = FALSE, line_antialias = FALSE, depth_mask = TRUE, depth_test = "less", polygon_offset = c(0.0, 0.0), margin = "", floating = FALSE, tag = "", ... ) { # solid or diffuse component color <- rgl.mcolor(color) if (length(color) < 1) stop("There must be at least one color") # light properties ambient <- rgl.color(ambient) specular <- rgl.color(specular) emission <- rgl.color(emission) # others rgl.bool(lit) rgl.bool(fog) rgl.bool(smooth) rgl.bool(point_antialias) rgl.bool(line_antialias) rgl.bool(depth_mask) rgl.clamp(shininess,0,128) rgl.numeric(size) rgl.numeric(lwd) depth_test <- rgl.enum.depthtest(depth_test) # side-dependant rendering front <- rgl.enum.polymode(front) back <- rgl.enum.polymode(back) # texture mapping rgl.bool(texmipmap) if (length(texture) > 1) stop("'texture' should be a single character string or NULL") if (is.null(texture)) texture <- "" else texture <- normalizePath(texture) textype <- rgl.enum.textype( textype ) texminfilter <- rgl.enum.texminfilter( texminfilter ) texmagfilter <- rgl.enum.texmagfilter( texmagfilter ) rgl.bool(texenvmap) # polygon offset stopifnot(is.numeric(polygon_offset), length(polygon_offset) <= 2, length(polygon_offset) >= 1) if (length(polygon_offset) == 1) polygon_offset <- c(polygon_offset, polygon_offset) # vector length ncolor <- dim(color)[2] nalpha <- length(alpha) margin <- parseMargin(margin, floating = floating) # user data tag <- as.character(tag) rgl.string(tag) # pack data idata <- as.integer( c( ncolor, lit, smooth, front, back, fog, textype, texmipmap, texminfilter, texmagfilter, nalpha, ambient, specular, emission, texenvmap, point_antialias, line_antialias, depth_mask, depth_test, margin$coord - 1, margin$edge, floating, color) ) cdata <- as.character(c( tag, texture )) ddata <- as.numeric(c( shininess, size, lwd, polygon_offset, alpha )) ret <- .C( rgl_material, success = FALSE, idata, cdata, ddata ) } rgl.getcolorcount <- function() .C( rgl_getcolorcount, count=integer(1) )$count rgl.getmaterial <- function(ncolors, id = NULL) { if (!length(id)) id <- 0L if (missing(ncolors)) ncolors <- if (id) rgl.attrib.count(id, "colors") else rgl.getcolorcount() idata <- rep(-1, 31+3*ncolors) idata[1] <- ncolors idata[11] <- ncolors cdata <- rep(paste(rep(" ", 512), collapse=""), 2) ddata <- rep(0, 5+ncolors) ret <- .C( rgl_getmaterial, success = FALSE, id = as.integer(id), idata = as.integer(idata), cdata = cdata, ddata = as.numeric(ddata) ) if (!ret$success) stop('rgl.getmaterial') polymodes <- c("filled", "lines", "points", "culled") textypes <- c("alpha", "luminance", "luminance.alpha", "rgb", "rgba") minfilters <- c("nearest", "linear", "nearest.mipmap.nearest", "nearest.mipmap.linear", "linear.mipmap.nearest", "linear.mipmap.linear") magfilters <- c("nearest", "linear") depthtests <- c("never", "less", "equal", "lequal", "greater", "notequal", "gequal", "always") idata <- ret$idata ddata <- ret$ddata cdata <- ret$cdata list(color = rgb(idata[29 + 3*(seq_len(idata[1]))], idata[30 + 3*(seq_len(idata[1]))], idata[31 + 3*(seq_len(idata[1]))], maxColorValue = 255), alpha = if (idata[11]) ddata[seq(from=6, length=idata[11])] else 1, lit = idata[2] > 0, ambient = rgb(idata[12], idata[13], idata[14], maxColorValue = 255), specular = rgb(idata[15], idata[16], idata[17], maxColorValue = 255), emission = rgb(idata[18], idata[19], idata[20], maxColorValue = 255), shininess = ddata[1], smooth = idata[3] > 0, texture = if (cdata[2] == "") NULL else cdata[2], textype = textypes[idata[7]], texmipmap = idata[8] == 1, texminfilter = minfilters[idata[9] + 1], texmagfilter = magfilters[idata[10] + 1], texenvmap = idata[21] == 1, front = polymodes[idata[4]], back = polymodes[idata[5]], size = ddata[2], lwd = ddata[3], fog = idata[6] > 0, point_antialias = idata[22] == 1, line_antialias = idata[23] == 1, depth_mask = idata[24] == 1, depth_test = depthtests[idata[25] + 1], isTransparent = idata[26] == 1, polygon_offset = ddata[4:5], margin = deparseMargin(list(coord = idata[27] + 1, edge = idata[28:30])), floating = idata[31] == 1, tag = cdata[1] ) } rgl/R/turn3d.R0000644000176200001440000000332614100762640012605 0ustar liggesusers turn3d <- function(x, y = NULL, n = 12, smooth = FALSE, ...) { xy <- xy.coords(x, y) x <- xy$x y <- zapsmall(xy$y) stopifnot(all(y >= 0)) len <- length(x) inds <- seq_len(len) if (smooth) { nx <- -diff(y) nx <- c(nx, 0) + c(0, nx) ny <- diff(x) ny <- c(ny, 0) + c(0, ny) nlen <- sqrt(nx^2 + ny^2) nlen[nlen == 0] <- 1 nx <- nx/nlen ny <- ny/nlen normals <- matrix(nrow=4, ncol=0) } zero <- y == 0 vb <- matrix(nrow=4, ncol=0) ib <- matrix(nrow=4, ncol=0) it <- matrix(nrow=3, ncol=0) theta <- seq(0, 2*pi, len = n + 1)[-(n + 1)] for (i in inds) { vb <- cbind(vb, rbind(x[i], sin(theta)*y[i], cos(theta)*y[i], 1)) if (smooth) normals <- cbind(normals, rbind(nx[i], sin(theta)*ny[i], cos(theta)*ny[i], 1)) if (i > 1) { if (zero[i] && zero[i-1]) { # do nothing } else if (!zero[i] && zero[i-1]) { # draw triangles prev <- ncol(vb) - n - 0:(n-1) curr <- ncol(vb) - 0:(n-1) curr2 <- curr + 1 curr2[1] <- curr2[1] - n it <- cbind(it, rbind(prev, curr, curr2)) } else if (zero[i] && !zero[i-1]) { # other triangles prev <- ncol(vb) - n - 0:(n-1) curr <- ncol(vb) - 0:(n-1) prev2 <- prev + 1 prev2[1] <- prev2[1] - n it <- cbind(it, rbind(prev, curr, prev2)) } else { # quads prev <- ncol(vb) - n - 0:(n-1) prev2 <- prev + 1 prev2[1] <- prev2[1] - n curr <- ncol(vb) - 0:(n-1) curr2 <- curr + 1 curr2[1] <- curr2[1] - n ib <- cbind(ib, rbind(prev, curr, curr2, prev2)) } } } result <- tmesh3d(vb, it, normals=if(smooth) t(normals), ...) if (length(ib)) result$ib <- ib result } rgl/R/pkgdown.R0000644000176200001440000000706614100762640013044 0ustar liggesusers# Functions related to working in pkgdown pkgdown_rdname <- function() getOption("downlit.rdname", "") in_pkgdown <- function() requireNamespace("pkgdown", quietly = TRUE) && pkgdown::in_pkgdown() # The exists() part of this test are only needed until # CRAN's version of the packages contain my suggested patches. in_pkgdown_example <- function() nchar(pkgdown_rdname()) && requireNamespace("downlit", quietly = TRUE) && exists("is_low_change.default", asNamespace("downlit")) && requireNamespace("pkgdown", quietly = TRUE) && exists("pkgdown_print", asNamespace("pkgdown")) fns <- local({ plotnum <- 0 pkgdown_print.rglId <- function(x, visible = TRUE) { if (inherits(x, "rglHighlevel")) plotnum <<- plotnum + 1 if (visible) { scene <- scene3d() structure(list(plotnum = plotnum, scene = scene), class = c("rglRecordedplot", "otherRecordedplot")) } else invisible() } pkgdown_print.rglOpen3d <- function(x, visible = TRUE) { plotnum <<- plotnum + 1 invisible(x) } list(pkgdown_print.rglId = pkgdown_print.rglId, pkgdown_print.rglOpen3d = pkgdown_print.rglOpen3d) }) pkgdown_print.rglId <- fns[["pkgdown_print.rglId"]] pkgdown_print.rglOpen3d <- fns[["pkgdown_print.rglOpen3d"]] rm(fns) globalVariables("fig.asp") pkgdown_dims <- function() { settings <- pkgdown_fig_settings() rgl <- settings$other.parameters$rgl settings[names(rgl)] <- rgl numparms <- length(intersect(names(rgl), c("fig.width", "fig.height", "fig.asp"))) if (numparms > 0 && numparms < 3) { settings <- within(settings, { if (is.null(rgl$fig.height)) fig.height <- fig.width * fig.asp if (is.null(rgl$fig.width)) fig.width <- fig.height / fig.asp }) } width <- with(settings, dpi*fig.width) height <- with(settings, dpi*fig.height) list(width = width, height = height) } replay_html.rglRecordedplot <- local({ rdname <- "" function(x, ...) { if (pkgdown_rdname() != rdname) rdname <<- pkgdown_rdname() settings <- pkgdown_dims() rendered <- htmltools::renderTags(rglwidget(x$scene, width = settings$width, height = settings$height)) structure(rendered$html, dependencies = rendered$dependencies) } }) pkgdown_info <- local({ info <- NULL function() { if (!is.null(info)) return(info) path <- "." repeat { if (file.exists(file.path(path, "DESCRIPTION"))) { info <<- pkgdown::as_pkgdown(path) return(info) } newpath <- file.path(path, "..") if (normalizePath(newpath) == normalizePath(path)) return(list()) path <- newpath } } }) # These are only needed until CRAN's pkgdown exports pkgdown_print # and fig_settings, # then we should use pkgdown::pkgdown_print and pkgdown::fig_settings pkgdown_print <- function(x, visible = TRUE) "" pkgdown_fig_settings <- function() list(dpi = 96, fig.width = 5, fig.height = 5) register_pkgdown_methods <- local({ registered <- FALSE function(register = in_pkgdown_example()) { if (!registered && register) { registerS3method("replay_html", "rglRecordedplot", replay_html.rglRecordedplot, envir = asNamespace("downlit")) registerS3method("is_low_change", "rglRecordedplot", is_low_change.rglRecordedplot, envir = asNamespace("downlit")) registerS3method("pkgdown_print", "rglId", pkgdown_print.rglId, envir = asNamespace("pkgdown")) registerS3method("pkgdown_print", "rglOpen3d", pkgdown_print.rglOpen3d, envir = asNamespace("pkgdown")) registered <<- TRUE } } }) rgl/R/solids3d.R0000644000176200001440000000670614100762640013117 0ustar liggesusers# # R 3d object : cube3d # cube3d.vb <- c( -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ) cube3d.ib <- c( 1, 3, 4, 2, 3, 7, 8, 4, 2, 4, 8, 6, 1, 5, 7, 3, 1, 2, 6, 5, 5, 6, 8, 7 ) cube3d <- function( trans = identityMatrix(), ... ) { rotate3d( mesh3d( vertices = cube3d.vb, quads = cube3d.ib, material=list(...) ), matrix = trans) } # # tetrahedron # tetra3d.vb <- c( -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0 ) tetra3d.it <- c( 1, 2, 3, 3, 2, 4, 4, 2, 1, 1, 3, 4 ) tetrahedron3d <- function( trans = identityMatrix(), ... ) { rotate3d( mesh3d(vertices = tetra3d.vb, triangles = tetra3d.it, material=list(...) ), matrix = trans) } # # octahedron # octa3d.vb <- c( -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0 ) octa3d.it <- c( 1,5,3, 1,3,6, 1,4,5, 1,6,4, 2,3,5, 2,6,3, 2,5,4, 2,4,6 ) octahedron3d <- function( trans = identityMatrix(), ... ) { rotate3d( mesh3d( vertices = octa3d.vb, triangles = octa3d.it, material=list(...) ), matrix = trans) } # # icosahedron # phi <- (1+sqrt(5))/2 ico3d.vb <- c( 0, 1/phi, 1, 0, 1/phi, -1, 0, -1/phi, 1, 0, -1/phi,-1, 1/phi, 1, 0, 1/phi, -1, 0, -1/phi, 1, 0, -1/phi, -1, 0, 1, 0, 1/phi, -1, 0, 1/phi, 1, 0, -1/phi, -1, 0, -1/phi ) ico3d.it <- c( 1, 3, 9, 1, 9, 5, 1, 5, 7, 1, 7, 10, 1, 10, 3, 4, 12, 2, 4, 2, 11, 4, 11, 6, 4, 6, 8, 4, 8, 12, 9, 3, 6, 5, 9, 11, 7, 5, 2, 10, 7, 12, 3, 10, 8, 2, 12, 7, 11, 2, 5, 6, 11, 9, 8, 6, 3, 12, 8, 10) icosahedron3d <- function( trans = identityMatrix(), ... ) { rotate3d( mesh3d( vertices = ico3d.vb, triangles = ico3d.it, material=list(...) ), matrix = trans) } dodec3d.vb <- c( -1/phi, -1/phi, -1/phi, 1/phi, -1/phi, -1/phi, -1/phi, 1/phi, -1/phi, 1/phi, 1/phi, -1/phi, -1/phi, -1/phi, 1/phi, 1/phi, -1/phi, 1/phi, -1/phi, 1/phi, 1/phi, 1/phi, 1/phi, 1/phi, 0, -1/phi^2, 1, 0, 1/phi^2, 1, 0, -1/phi^2,-1, 0, 1/phi^2,-1, -1/phi^2, 1, 0, 1/phi^2, 1, 0, -1/phi^2,-1, 0, 1/phi^2,-1, 0, 1, 0,-1/phi^2, 1, 0, 1/phi^2, -1, 0,-1/phi^2, -1, 0, 1/phi^2 ) dodec3d.if <- c( 1, 11, 2, 16, 15, 1, 15, 5, 20, 19, 1, 19, 3, 12, 11, 2, 11, 12, 4, 17, 2, 17, 18, 6, 16, 3, 13, 14, 4, 12, 3, 19, 20, 7, 13, 4, 14, 8, 18, 17, 5, 9, 10, 7, 20, 5, 15, 16, 6, 9, 6, 18, 8,10, 9, 7, 10, 8,14, 13) dodecahedron3d <- function( trans = identityMatrix(), ...) { m <- matrix(dodec3d.if, 5, 12) rotate3d( mesh3d( vertices = dodec3d.vb, triangles = c(m[c(1,2,3, 1,3,4, 1,4,5),]), material=list(...) ), matrix=trans) } cuboct3d.vb <- c( -1, -1, 0, -1, 1, 0, 1, -1, 0, 1, 1, 0, -1, 0,-1, -1, 0, 1, 1, 0,-1, 1, 0, 1, 0, -1,-1, 0, -1, 1, 0, 1,-1, 0, 1, 1 ) cuboct3d.ib <- c( 1, 6, 2, 5, 1, 9, 3, 10, 2, 12,4, 11, 3, 7, 4, 8, 5, 11, 7, 9, 6, 10, 8, 12) cuboct3d.it <- c( 1, 5, 9, 1, 10, 6, 2, 11, 5, 2, 6, 12, 3, 9, 7, 3, 8, 10, 4, 7, 11, 4, 12, 8) cuboctahedron3d <- function( trans = identityMatrix(), ...) { rotate3d( mesh3d( vertices = cuboct3d.vb, triangles = cuboct3d.it, quads = cuboct3d.ib, material=list(...) ), matrix = trans) } rgl/R/plotmath3d.R0000644000176200001440000000363014142256754013455 0ustar liggesusersplotmath3d <- function(x, y = NULL, z = NULL, text, cex = par("cex"), adj = 0.5, pos = NULL, offset = 0.5, fixedSize = TRUE, startsize = 480, initCex = 5, ...) { xyz <- xyz.coords(x, y, z) n <- length(xyz$x) if (is.vector(text)) text <- rep(text, length.out = n) cex <- rep(cex, length.out = n) if (!is.null(pos)) pos <- rep_len(pos, n) adj <- c(adj, 0.5, 0.5, 0.5)[1:3] save3d <- par3d(skipRedraw = TRUE) save <- options(device.ask.default = FALSE) on.exit({options(save); par3d(save3d)}) # nolint result <- integer(n) for (i in seq_len(n)) { # Open the device twice. The first one is to measure the text... f <- tempfile(fileext = ".png") png(f, bg = "transparent", width = startsize, height = startsize) par(mar = c(0, 0, 0, 0), xaxs = "i", xaxt = "n", yaxs = "i", yaxt = "n", usr = c(0, 1, 0, 1)) plot.new() if (is.vector(text)) thistext <- text[i] else thistext <- text w <- strwidth(thistext, cex = initCex, ...) w1 <- strwidth("m", cex = initCex, ...) h <- strheight(thistext, cex = initCex, ...) dev.off() # Now make a smaller bitmap expand <- 1.5 size <- round(expand*startsize*max(c(w, h))) png(f, bg = "transparent", width = size, height = size) par(mar = c(0, 0, 0, 0), xaxs = "i", xaxt = "n", yaxs = "i", yaxt = "n", usr = c(0, 1, 0, 1)) plot.new() text(0.5, 0.5, thistext, adj = c(0.5,0.5), cex = initCex, ...) dev.off() # The 0.4 tries to match the text3d offset offseti <- 0.4*offset*h/w posi <- if (is.null(pos)) NULL else pos[i] result[i] <- with(xyz, sprites3d(x[i], y[i], z[i], texture = f, textype = "rgba", col = "white", lit = FALSE, radius = cex[i]*size/initCex/20, adj = adj, pos = posi, offset = offseti, fixedSize = fixedSize)) } lowlevel(result) } rgl/R/Sweave.R0000644000176200001440000000372114100762640012617 0ustar liggesusers## ## Sweave device ## ## rgl.Sweave <- function(name, width, height, options, ...) { if (length(hook <- getHook("on.rgl.close"))) { # test is for compatibility with R < 3.0.0 if (is.list(hook)) hook <- hook[[1]] dev <- environment(hook)$dev set3d(dev) } else { wr <- c(0, 0, width*options$resolution, height*options$resolution) open3d(windowRect=wr) if (is.null(delay <- options$delay)) delay <- 0.1 Sys.sleep(as.numeric(delay)) wrnew <- par3d("windowRect") if (wr[3] - wr[1] != wrnew[3] - wrnew[1] || wr[4] - wr[2] != wrnew[4] - wrnew[2]) stop("rgl window creation error; try reducing resolution, width or height") dev <- cur3d() } snapshotDone <- FALSE # stayOpen is used below in rgl.Sweave.off stayOpen <- isTRUE(options$stayopen) type <- options$outputtype if (is.null(type)) type <- "png" setHook("on.rgl.close", action="replace", function(remove=TRUE) { prev.dev <- cur3d() on.exit(set3d(prev.dev)) if (!snapshotDone) { set3d(dev) switch(type, png = snapshot3d(filename=paste(name, "png", sep=".")), pdf = rgl.postscript(filename=paste(name, "pdf", sep="."), fmt="pdf"), eps = rgl.postscript(filename=paste(name, "eps", sep="."), fmt="eps"), stop(gettextf("Unrecognized rgl outputtype: '%s'", type), domain = NA) ) snapshotDone <<- TRUE } if (remove) setHook("on.rgl.close", action="replace", NULL) }) } rgl.Sweave.off <- function() { if (length(hook <- getHook("on.rgl.close"))) { if (is.list(hook)) hook <- hook[[1]] # test is for R pre-3.0.0 compatibility stayOpen <- environment(hook)$stayOpen if (stayOpen) hook(FALSE) else close3d() } } ## ## Sweave snapshot ## ## Sweave.snapshot <- function() { if (length(hook <- getHook("on.rgl.close"))) { if (is.list(hook)) hook <- hook[[1]] # test is for R pre-3.0.0 compatibility hook(remove = FALSE) } } rgl/R/axes.R0000644000176200001440000002123214137472630012331 0ustar liggesusers# This internal function returns a list with the following components: # xlim, ylim, zlim: the bounding box expanded so no coordinate has zero or negative extent # strut: a boolean indicating whether an expansion was done above # x, y, z: the box above expanded by a factor of expand .getRanges <- function(expand = 1.03, ranges=par3d('bbox')) { ranges <- list(xlim=ranges[1:2], ylim=ranges[3:4], zlim=ranges[5:6]) strut <- FALSE ranges <- lapply(ranges, function(r) { d <- diff(r) if (d > 0) return(r) strut <<- TRUE if (d < 0) return(c(0,1)) else if (r[1] == 0) return(c(-1, 1)) else return(r[1] + 0.4*abs(r[1])*c(-1,1)) }) ranges$strut <- strut ranges$x <- (ranges$xlim - mean(ranges$xlim))*expand + mean(ranges$xlim) ranges$y <- (ranges$ylim - mean(ranges$ylim))*expand + mean(ranges$ylim) ranges$z <- (ranges$zlim - mean(ranges$zlim))*expand + mean(ranges$zlim) ranges } axis3d <- function(edge, at = NULL, labels = TRUE, tick = TRUE, line = 0, pos = NULL, nticks = 5, ...) { save <- par3d(skipRedraw = TRUE, ignoreExtent = TRUE) on.exit(par3d(save)) ranges <- .getRanges() edge <- c(strsplit(edge, '')[[1]], '-', '-')[1:3] coord <- match(toupper(edge[1]), c('X', 'Y', 'Z')) # Put the sign in the appropriate entry of edge if (coord == 2) edge[1] <- edge[2] else if (coord == 3) edge[1:2] <- edge[2:3] range <- ranges[[coord]] if (is.null(at)) { at <- pretty(range, nticks) at <- at[at >= range[1] & at <= range[2]] } if (is.logical(labels)) { if (labels) labels <- format(at) else labels <- NA } mpos <- matrix(NA,3,length(at)) if (edge[1] == '+') mpos[1,] <- ranges$x[2] else mpos[1,] <- ranges$x[1] if (edge[2] == '+') mpos[2,] <- ranges$y[2] else mpos[2,] <- ranges$y[1] if (edge[3] == '+') mpos[3,] <- ranges$z[2] else mpos[3,] <- ranges$z[1] ticksize <- 0.05*(mpos[,1]-c(mean(ranges$x),mean(ranges$y),mean(ranges$z))) ticksize[coord] <- 0 if (!is.null(pos)) mpos <- matrix(pos,3,length(at)) mpos[coord,] <- at x <- c(mpos[1,1],mpos[1,length(at)]) y <- c(mpos[2,1],mpos[2,length(at)]) z <- c(mpos[3,1],mpos[3,length(at)]) if (tick) { x <- c(x,as.double(rbind(mpos[1,],mpos[1,]+ticksize[1]))) y <- c(y,as.double(rbind(mpos[2,],mpos[2,]+ticksize[2]))) z <- c(z,as.double(rbind(mpos[3,],mpos[3,]+ticksize[3]))) } result <- c(ticks=segments3d(x,y,z,...)) if (!all(is.na(labels))) result <- c(result, labels=text3d(mpos[1,]+3*ticksize[1], mpos[2,]+3*ticksize[2], mpos[3,]+3*ticksize[3], labels, ...)) lowlevel(result) } axes3d <- function(edges='bbox', labels=TRUE, tick=TRUE, nticks = 5, box = FALSE, expand = 1.03, ...) { save <- par3d(skipRedraw = TRUE, ignoreExtent = TRUE) on.exit(par3d(save)) if (identical(edges, 'bbox')) { bboxargs <- names(formals(rgl.bbox)) bboxargs <- intersect(bboxargs, names(list(...))) otherargs <- setdiff(names(list(...)), bboxargs) bboxargs <- list(...)[bboxargs] otherargs <- list(...)[otherargs] result <- do.call('bbox3d', c(list(draw_front=box, expand=expand), bboxargs, do.call('.fixMaterialArgs', c(otherargs, list(Params = list(front='lines', back='lines')))))) } else { result <- numeric(0) for (e in edges) result <- c(result, axis3d(e,labels=labels,tick=tick,nticks=nticks, ...)) names(result) <- e } lowlevel(result) } box3d <- function(...) { save <- par3d(ignoreExtent = TRUE) on.exit(par3d(save)) result <- numeric(0) ranges <- .getRanges() if (ranges$strut) { par3d(ignoreExtent = FALSE) result <- c(result, strut=segments3d(rep(ranges$xlim, c(2,2)), rep(ranges$ylim, c(2,2)), rep(ranges$zlim, c(2,2)))) par3d(ignoreExtent = TRUE) } x <- c(rep(ranges$x[1],8),rep(ranges$x,4),rep(ranges$x[2],8)) y <- c(rep(ranges$y,2),rep(ranges$y,c(2,2)),rep(ranges$y,c(4,4)), rep(ranges$y,2),rep(ranges$y,c(2,2))) z <- c(rep(ranges$z,c(2,2)),rep(ranges$z,2),rep(rep(ranges$z,c(2,2)),2), rep(ranges$z,c(2,2)),rep(ranges$z,2)) lowlevel(c(result, lines=segments3d(x,y,z,...))) } # Convert edge code into values: # coord = 1:3 for coordinate # edge = 3 of "+" or "-" for other coords (ignore the one # that matches coord) # floating = TRUE if edge should move as bboxdeco moves # labels parseMargin <- function(code, floating = FALSE) { stopifnot(length(code) == 1) if (!nchar(code)) list(coord = 0, edge = c(0,0,0), floating = floating) else { default <- if (isTRUE(floating)) "+" else "-" edge <- c(strsplit(code, '')[[1]], default, default)[1:3] coord <- match(toupper(edge[1]), c('X', 'Y', 'Z')) edge <- match(edge, c("-", "+"))*2 - 3 # +/- 1 edge[is.na(edge)] <- 0 # Put the sign in the appropriate entry of edge if (coord == 2) edge[1] <- edge[2] else if (coord == 3) edge[1:2] <- edge[2:3] list(coord = coord, edge = edge, floating = floating) } } deparseMargin <- function(margin) { if (margin$coord %in% 1:3) { coord <- margin$coord edge <- margin$edge[-coord] edge <- c("-", ".", "+")[edge + 2] paste(c("x", "y", "z")[coord], edge[1], edge[2], sep = "") } else "" } mtext3d <- function(text, edge, at = NULL, line = 0, level = 0, floating = FALSE, pos = NA, ...) { save <- par3d(ignoreExtent = TRUE) on.exit(par3d(save)) bboxdeco <- rgl.ids("bboxdeco") if (!is.na(floating) && !nrow(bboxdeco)) { dummyBbox() bboxdeco <- rgl.ids("bboxdeco") } if (!nrow(bboxdeco) || (missing(floating) && !missing(pos))) floating <- NA ranges <- .getRanges() newlen <- max(length(text),length(line),length(at)) text <- rep(text, len = newlen) line <- rep(line, len = newlen) if (is.na(floating)) { margin <- parseMargin(edge, floating) coord <- margin$coord if (!(coord %in% 1:3)) stop("Bad edge spec.") range <- ranges[[coord]] if (is.null(at)) at <- mean(range) at <- rep(at, len = newlen) if (all(is.na(pos))) { edge <- margin$edge pos <- matrix(NA,3,length(at)) if (edge[1] == +1) pos[1,] <- ranges$x[2] else pos[1,] <- ranges$x[1] if (edge[2] == +1) pos[2,] <- ranges$y[2] else pos[2,] <- ranges$y[1] if (edge[3] == +1) pos[3,] <- ranges$z[2] else pos[3,] <- ranges$z[1] } else pos <- matrix(pos,3,length(at)) pos[coord,] <- at ticksize <- 0.05*(pos[,1]-c(mean(ranges$x),mean(ranges$y),mean(ranges$z))) ticksize[coord] <- 0 text3d(pos[1,]+3*ticksize[1]*line, pos[2,]+3*ticksize[2]*line, pos[3,]+3*ticksize[3]*line, text, ...) } else { if (!missing(pos)) stop("'pos' is only used with floating = NA") if (is.null(at)) at <- NA text3d(x = cbind(at, line, level), texts = text, margin = edge, floating = floating, ...) } } title3d <- function(main = NULL, sub = NULL, xlab = NULL, ylab = NULL, zlab = NULL, line = NA, level = NA, floating = NULL, ...) { save <- par3d(skipRedraw = TRUE, ignoreExtent = TRUE) on.exit(par3d(save)) if (length(floating)) { floatingtitles <- floating floatinglabels <- floating } else { floatingtitles <- FALSE floatinglabels <- TRUE } result <- numeric(0) if (!is.null(main)) { aline <- ifelse(is.na(line), 2, line) alevel <- ifelse(is.na(level), 2, level) result <- c(result, main=mtext3d(main, 'x++', line = aline, level = alevel, floating = floatingtitles, ...)) } if (!is.null(sub)) { aline <- ifelse(is.na(line), 2, line) alevel <- ifelse(is.na(level), 2, level) result <- c(result, sub=mtext3d(sub, 'x--', line = aline, floating = floatingtitles, ...)) } if (!is.null(xlab)) { aline <- ifelse(is.na(line), 4, line) alevel <- ifelse(is.na(level), 1, level) result <- c(result, xlab=mtext3d(xlab, 'x', line = aline, level = alevel, floating = floatinglabels, ...)) } if (!is.null(ylab)) { aline <- ifelse(is.na(line), 4, line) alevel <- ifelse(is.na(level), 1, level) result <- c(result, ylab=mtext3d(ylab, 'y', line = aline, level = alevel, floating = floatinglabels, ...)) } if (!is.null(zlab)) { aline <- ifelse(is.na(line), 4, line) alevel <- ifelse(is.na(level), 1, level) result <- c(result, zlab=mtext3d(zlab, 'z', line = aline, level = alevel, floating = floatinglabels, ...)) } lowlevel(result) } rgl/R/hooks.R0000644000176200001440000000222014100762640012501 0ustar liggesusers# This file supports auto-printing of RGL scenes in # RStudio # Called just after a low level function has been # called, likely changing an existing display # Returns the ids that were created by the function, # which should be passed as the ids arg. lowlevel <- function(ids = integer()) { structure(ids, class = c("rglLowlevel", "rglId", "numeric")) } # Called just after a high level function (plot3d # or persp3d) has been called, if it wasn't # called with add = TRUE (in which case it would be # treated as low level). # Returns the ids that were created by the function, # which should be passed as the ids arg. highlevel <- function(ids = integer()) { structure(ids, class = c("rglHighlevel", "rglId", "numeric")) } rglId <- function(ids = integer()) { structure(ids, class = "rglId") } print.rglId <- function(x, rglwidget = getOption("rgl.printRglwidget", FALSE), ...) { if (rglwidget) # FIXME: For lowlevel, this should replace the scene, not update the history print(rglwidget(...)) else if (in_pkgdown_example()) pkgdown_print(x) else if (in_pkgdown()) # Must not have pkgdown_print defined cat("") invisible(x) } rgl/R/webGL.R0000644000176200001440000001121314100762640012360 0ustar liggesuserssubst <- function(strings, ..., digits=7) { substitutions <- list(...) names <- names(substitutions) if (is.null(names)) names <- rep("", length(substitutions)) for (i in seq_along(names)) { if ((n <- names[i]) == "") n <- as.character(sys.call()[[i+2]]) value <- substitutions[[i]] if (is.numeric(value)) value <- formatC(unclass(value), digits=digits, width=1) strings <- gsub(paste("%", n, "%", sep=""), value, strings) } strings } convertBBox <- function(id, verts = rgl.attrib(id, "vertices"), text = rgl.attrib(id, "text"), mat = rgl.getmaterial(id = id)) { if (!length(text)) text <- rep("", NROW(verts)) if (length(mat$color) > 1) mat$color <- mat$color[2] # We ignore the "box" colour if(any(missing <- text == "")) text[missing] <- apply(verts[missing,], 1, function(row) format(row[!is.na(row)])) res <- integer(0) if (any(inds <- is.na(verts[,2]) & is.na(verts[,3]))) res <- c(res, do.call(axis3d, c(list(edge = "x", at = verts[inds, 1], labels = text[inds]), mat))) if (any(inds <- is.na(verts[,1]) & is.na(verts[,3]))) res <- c(res, do.call(axis3d, c(list(edge = "y", at = verts[inds, 2], labels = text[inds]), mat))) if (any(inds <- is.na(verts[,1]) & is.na(verts[,2]))) res <- c(res, do.call(axis3d, c(list(edge = "z", at = verts[inds, 3], labels = text[inds]), mat))) res <- c(res, do.call(box3d, mat)) res } rootSubscene <- function() { id <- currentSubscene3d() repeat { info <- subsceneInfo(id) if (is.null(info$parent)) return(id) else id <- info$parent } } writeWebGL <- function(dir="webGL", filename=file.path(dir, "index.html"), template = system.file(file.path("WebGL", "template.html"), package = "rgl"), prefix = "", snapshot = TRUE, commonParts = TRUE, reuse = NULL, font="Arial", width = NULL, height = NULL) { # Lots of utility functions and constants defined first; execution starts way down there... header <- function() if (commonParts) c( as.character(includeScript(system.file("htmlwidgets/lib/CanvasMatrix/CanvasMatrix.src.js", package = "rgl"))), as.character(includeScript(system.file("htmlwidgets/lib/rglClass/rglClass.src.js", package = "rgl"))) ) scriptheader <- function() subst( '
', prefix, elementId, json, width, height) footer <- function() subst('

You must enable Javascript to view this page properly.

', prefix) # Execution starts here! # Do a few checks first elementId <- paste0(prefix, "div") if (!file.exists(dir)) dir.create(dir) if (!file.info(dir)$isdir) stop(gettextf("'%s' is not a directory", dir), domain = NA) if (!is.null(template)) { templatelines <- readLines(template) templatelines <- subst(templatelines, rglVersion = packageVersion("rgl"), prefix = prefix) target <- paste("%", prefix, "WebGL%", sep="") replace <- grep( target, templatelines, fixed=TRUE) if (length(replace) != 1) stop(gettextf("template '%s' does not contain '%s'", template, target), domain = NA) result <- c(templatelines[seq_len(replace-1)], header()) } else result <- header() scene <- convertScene(width = width, height = height, elementId = elementId, snapshot = snapshot) scene$crosstalk <- list(key = list(), group = character(), id = integer(), options = list()) if (is.null(width)) width <- scene$width if (is.null(height)) height <- scene$height json <- toJSON(I(scene), dataframe = "columns", null = "null", na = "string", auto_unbox = TRUE, digits = getOption("shiny.json.digits", 7), use_signif = TRUE, force = TRUE, POSIXt = "ISO8601", UTC = TRUE, rownames = FALSE, keep_vec_names = TRUE) result <- c(result, scriptheader(), footer(), if (!is.null(template)) templatelines[replace + seq_len(length(templatelines)-replace)] else subst("", prefix = prefix) ) cat(result, file=filename, sep="\n") invisible(filename) } rgl/R/clipMesh3d.R0000644000176200001440000005056014145464133013370 0ustar liggesusersas.tmesh3d <- function(x, ...) UseMethod("as.tmesh3d") as.tmesh3d.default <- function(x, drop = FALSE, ...) { as.tmesh3d(as.mesh3d(x, ...), drop = drop) } as.tmesh3d.mesh3d <- function(x, drop = FALSE, ...) { mesh <- x if (!is.null(mesh$ib)) { nquads <- ncol(mesh$ib) mesh$it <- cbind(mesh$it, matrix(mesh$ib[rep(4*(seq_len(nquads) - 1), each = 6) + rep(c(1, 2, 3, 1, 3, 4), nquads)], nrow = 3)) mesh$ib <- NULL } if (drop) { mesh$is <- NULL mesh$ip <- NULL } mesh } .getVertexFn <- function(fn, envir) { if (is.character(fn)) fn <- switch(fn, x = function(xyz) xyz[,1], y = function(xyz) xyz[,2], z = function(xyz) xyz[,3], get(fn, envir = envir, mode = "function")) # Accept functions that take x, y, z as parameters if (all(c("x", "y", "z") %in% names(formals(fn)))) { oldfn <- fn fn <- function(xyz) oldfn(x = xyz[,1], y = xyz[,2], z = xyz[,3]) } fn } clipMesh3d <- function(mesh, fn = "z", bound = 0, greater = TRUE, minVertices = 0, plot = FALSE, keepValues = FALSE) { stopifnot(inherits(mesh, "mesh3d")) # First, convert quads to triangles mesh <- as.tmesh3d(mesh) nverts <- ncol(mesh$vb) oldnverts <- nverts - 1 while (nverts < minVertices && oldnverts < nverts && !is.numeric(fn)) { oldnverts <- nverts mesh <- subdivision3d(mesh, deform = FALSE, normalize = TRUE) nverts <- ncol(mesh$vb) } if (is.null(fn)) fn <- mesh$values if (is.null(fn)) stop("'fn' can only be NULL if 'mesh' contains values") if (is.numeric(fn)) values <- fn else { fn <- .getVertexFn(fn, parent.frame()) verts <- asEuclidean(t(mesh$vb)) values <- fn(verts) } # The bound might be infinite, which messes up the arithmetic. # Force it to a finite value r <- range(values) delta <- max(abs(r)) if (bound < r[1]) bound <- r[1] - delta else if (bound > r[2]) bound <- r[2] + delta values <- values - bound if (!greater) values <- -values if (length(values) != ncol(mesh$vb)) stop("'fn' should give one value per vertex") if (anyNA(values)) stop("'fn' should not include NA values") # Now, set all w values to 1 mesh$vb <- t( cbind(t(mesh$vb[1:3,])/mesh$vb[4,], 1)) if (!is.null(mesh$normals) && nrow(mesh$normals) == 4) mesh$normals <- t(t(mesh$normals[1:3,])/mesh$normals[4,]) newVertices <- integer() getNewVertex <- function(good, bad) { names <- paste0(good, "_", bad) new <- which(!(names %in% names(newVertices))) if (length(new)) { goodvals <- values[good[new]] badvals <- values[bad[new]] alphas <- goodvals/(goodvals - badvals) newverts <- t((1 - alphas)*t(mesh$vb[, good[new]]) + alphas*t(mesh$vb[, bad[new]])) newvertnums <- seq_len(ncol(newverts)) + ncol(mesh$vb) if (!is.null(mesh$normals)) mesh$normals <<- cbind(mesh$normals, t((1 - alphas)*t(mesh$normals[, good[new]]) + alphas*t(mesh$normals[, bad[new]]))) if (!is.null(mesh$texcoords)) mesh$texcoords <<- cbind(mesh$texcoords, t((1 - alphas)*t(mesh$texcoords[, good[new]]) + alphas*t(mesh$texcoords[, bad[new]]))) if (!is.null(mesh$material)) { if (!is.null(mesh$material$color) && length(mesh$material$color) == ncol(mesh$vb)) { rgb <- col2rgb(mesh$material$color) newrgb <- (1 - alphas)*rgb[, good[new],drop = FALSE] + alphas*rgb[, bad[new], drop = FALSE] mesh$material$color <<- c(mesh$material$color, rgb(newrgb["red",], newrgb["green",], newrgb["blue",], maxColorValue = 255)) } if (!is.null(mesh$material$alpha) && length(mesh$material$alpha) == ncol(mesh$vb)) mesh$material$alpha <<- c(mesh$material$alpha, (1-alphas)*mesh$material$alpha[good[new]] + alphas*mesh$material$alpha[bad[new]]) } values <<- c(values, rep(0, ncol(newverts))) mesh$vb <<- cbind(mesh$vb, newverts) newVertices[names[new]] <<- newvertnums } newVertices[names] } keep <- values >= 0 keept <- matrix(keep[mesh$it], nrow = 3) counts <- colSums(keept) # Number of vertices to keep for each triangle singles <- which(counts == 1) if (length(singles)) { theseTriangles <- mesh$it[, singles, drop = FALSE] goodRow <- apply(keept[, singles, drop = FALSE], 2, function(col) which(col)) allcols <- seq_len(ncol(theseTriangles)) goodVertex <- theseTriangles[cbind(goodRow, allcols)] badVertex1 <- theseTriangles[cbind(goodRow %% 3 + 1, allcols)] badVertex2 <- theseTriangles[cbind((goodRow + 1) %% 3 + 1, allcols)] mesh$it[cbind(goodRow %% 3 + 1, singles)] <- getNewVertex(goodVertex, badVertex1) mesh$it[cbind((goodRow + 1) %% 3 + 1, singles)] <- getNewVertex(goodVertex, badVertex2) } doubles <- which(counts == 2) if (length(doubles)) { theseTriangles <- mesh$it[, doubles, drop = FALSE] badRow <- apply(keept[, doubles, drop = FALSE], 2, function(col) which(!col)) allcols <- seq_len(ncol(theseTriangles)) badVertex <- theseTriangles[cbind(badRow, allcols)] goodVertex1 <- theseTriangles[cbind(badRow %% 3 + 1, allcols)] goodVertex2 <- theseTriangles[cbind((badRow + 1) %% 3 + 1, allcols)] newVertex1 <- getNewVertex(goodVertex1, badVertex) newVertex2 <- getNewVertex(goodVertex2, badVertex) mesh$it[cbind(badRow, doubles)] <- newVertex1 mesh$it <- cbind(mesh$it, rbind(newVertex1, goodVertex2, newVertex2)) } zeros <- which(counts == 0) if (length(zeros)) mesh$it <- mesh$it[, -zeros] if (plot) shade3d(mesh) else { if (keepValues) { if (!greater) values <- -values mesh$values <- values + bound } cleanMesh3d(mesh) } } cleanMesh3d <- function(mesh, onlyFinite = TRUE, allUsed = TRUE, rejoin = FALSE) { if (rejoin) { ntriangs <- ncol(mesh$it) oldntriangs <- ntriangs + 1 while (ntriangs < oldntriangs) { oldntriangs <- ntriangs mesh <- rejoinMesh3d(mesh) ntriangs <- ncol(mesh$it) } } nold <- ncol(mesh$vb) keep <- TRUE if (onlyFinite) keep <- keep & apply(mesh$vb, 2, function(col) all(is.finite(col))) if (allUsed) keep <- keep & (seq_len(nold) %in% c(mesh$ip, mesh$is, mesh$it, mesh$ib)) if (!all(keep)) { oldnums <- which(keep) newnums <- rep(NA, nold) nnew <- sum(keep) newnums[oldnums] <- seq_len(nnew) mesh$vb <- mesh$vb[,oldnums] if (!is.null(mesh$ip)) { newcols <- newnums[mesh$ip] dim(newcols) <- dim(mesh$ip) keep <- apply(newcols, 2, function(col) !is.na(col)) mesh$ip <- newcols[,keep, drop = FALSE] } if (!is.null(mesh$is)) { newcols <- newnums[mesh$is] dim(newcols) <- dim(mesh$is) keep <- apply(newcols, 2, function(col) all(!is.na(col))) mesh$is <- newcols[,keep, drop = FALSE] } if (!is.null(mesh$it)) { newcols <- newnums[mesh$it] dim(newcols) <- dim(mesh$it) keep <- apply(newcols, 2, function(col) all(!is.na(col))) mesh$it <- newcols[,keep, drop = FALSE] } if (!is.null(mesh$ib)) { newcols <- newnums[mesh$ib] dim(newcols) <- dim(mesh$ib) keep <- apply(newcols, 2, function(col) all(!is.na(col))) mesh$ib <- newcols[,keep, drop = FALSE] } if (!is.null(mesh$normals)) mesh$normals <- mesh$normals[, oldnums] if (!is.null(mesh$texcoords)) mesh$texcoords <- mesh$texcoords[, oldnums] if (!is.null(mesh$meshColor) && mesh$meshColor == "vertices" && !is.null(mesh$material) && length(mesh$material$color) == nold) mesh$material$color <- mesh$material$color[oldnums] if (!is.null(mesh$values)) mesh$values <- mesh$values[oldnums] } mesh } subdivideLines <- function(x) { nverts <- nrow(x$vertices) newverts <- nverts indices <- rbind(seq_len(nverts), NA, NA) finite <- apply(x$vertices, 1, function(row) all(is.finite(row))) type <- x$type if (type == "lines") { for (j in 2*seq_len(nverts %/% 2)) { i <- j - 1 if (finite[i] && finite[j]) { for (attr in c("vertices", "normals", "colors")) { if (!is.null(x[[attr]]) && nrow(x[[attr]]) > 1) { new <- (x[[attr]][i,] + x[[attr]][j,])/2 while (nrow(x[[attr]]) < newverts + 2) x[[attr]] <- rbind(x[[attr]], x[[attr]]) x[[attr]][newverts + 1,] <- new x[[attr]][newverts + 2,] <- new } } indices[2, i] <- newverts + 1 indices[3, i] <- newverts <- newverts + 2 } } } else if (x$type == "linestrip") { for (j in seq_len(nverts)[-1]) { i <- j - 1 if (finite[i] && finite[j]) { for (attr in c("vertices", "normals", "colors")) { if (!is.null(x[[attr]]) && nrow(x[[attr]]) > 1) { new <- (x[[attr]][i,] + x[[attr]][j,])/2 while (nrow(x[[attr]]) < newverts + 1) x[[attr]] <- rbind(x[[attr]], x[[attr]]) x[[attr]][newverts + 1,] <- new } } indices[2, i] <- newverts <- newverts + 1 } } } if (nverts < newverts) { indices <- c(indices) indices <- indices[!is.na(indices)] for (attr in c("vertices", "normals", "colors")) if (!is.null(x[[attr]]) && nrow(x[[attr]]) > 1) x[[attr]] <- x[[attr]][indices,,drop = FALSE] } x } # Undo subdivision for triangles rejoinMesh3d <- function(x, tol = 1.e-6) { ntriangs <- length(x$it)/3 if (ntriangs < 4) return(x) vals <- if (nrow(x$vb) == 4) asEuclidean(t(x$vb)) else t(x$vb) if (!is.null(x$normals)) vals <- cbind(vals, if(nrow(x$normals) == 4) asEuclidean(t(x$normals)) else t(x$normals)) if (!is.null(x$texcoords)) vals <- cbind(vals, t(x$texcoords)) indices <- seq_len(ntriangs) for (j in seq_len(ntriangs)[-(1:3)]) { i <- j - (3:0) verts <- c(x$it[,i]) if ( !any(is.na(indices[i])) && verts[2] == verts[6] && verts[3] == verts[8] && verts[5] == verts[9] && verts[6] == verts[11] && verts[8] == verts[10] && verts[9] == verts[12] && !(verts[1] %in% verts[-1]) && !(verts[4] %in% verts[-4]) && !(verts[7] %in% verts[-7])) { v1 <- verts[c(1,4,7,2,3,5)] diffs <- c(vals[v1[1],] - vals[v1[2],], vals[v1[1],] - vals[v1[3],], vals[v1[2],] - vals[v1[3],]) use <- !is.na(diffs) & diffs > tol if (any(use)) { p <- c(vals[v1[1],] - vals[v1[4],], vals[v1[1],] - vals[v1[5],], vals[v1[2],] - vals[v1[6],])[use]/diffs[use] if (max(abs(p - 0.5)) < tol) { # Found one! indices[i[-1]] <- NA x$it[,i[1]] <- c(v1[1], v1[2], v1[3]) } } } } indices <- indices[!is.na(indices)] x$it <- x$it[,indices] x } rejoinLines3d <- function(x, tol = 1.e-6) { nverts <- nrow(x$vertices) indices <- seq_len(nverts) finite <- apply(x$vertices, 1, function(row) all(is.finite(row))) type <- x$type hasattrs <- character() for (attr in c("vertices", "normals", "colors")) if (!is.null(x[[attr]]) && nrow(x[[attr]]) > 1) hasattrs <- c(hasattrs, attr) if (type == "lines") { for (j in 2*seq_len(nverts %/% 2)[-1]) { i <- j - (3:0) if (all(finite[i])) { attrs <- matrix(numeric(), nrow = 4, ncol = 0) for (attr in hasattrs) attrs <- cbind(attrs, x[[attr]][i,]) diff <- attrs[4,] - attrs[1,] use <- !is.na(diff) & abs(diff) > tol p <- c((attrs[2,use] - attrs[1,use])/diff[use], (attrs[3,use] - attrs[1,use])/diff[use]) if (all(!is.na(p) & p >= 0 & p <= 1) && diff(range(p)) < tol) { # pts 2 & 3 are equal and are exactly between # pts 1 & 4. Merge them into 3,4. for (attr in hasattrs) x[[attr]][i[3],] <- x[[attr]][i[1],] indices[i[1:2]] <- NA } } } } else if (type == "linestrip") { for (j in seq_len(nverts)[-(1:2)]) { i <- j - (2:0) if (all(finite[i])) { attrs <- matrix(numeric(), nrow = 3, ncol = 0) for (attr in hasattrs) attrs <- cbind(attrs, x[[attr]][i,]) diff <- attrs[3,] - attrs[1,] use <- !is.na(diff) & abs(diff) > tol p <- (attrs[2,use] - attrs[1,use])/diff[use] if (all(!is.na(p) & p >= 0 & p <= 1) && diff(range(p)) < tol) { # pt 2 is exactly between # pts 1 & 3. Move 1 there. for (attr in hasattrs) x[[attr]][i[2],] <- x[[attr]][i[1],] indices[i[1]] <- NA } } } } if (anyNA(indices)) { indices <- indices[!is.na(indices)] for (attr in hasattrs) x[[attr]] <- x[[attr]][indices,] } x } clipObj3d <- function(ids = tagged3d(tags), fn, bound = 0, greater = TRUE, minVertices = 0, replace = TRUE, tags) { getValues <- function(obj) { verts <- obj$vertices nverts <- nrow(verts) values <- rep(NA_real_, nverts) finite <- apply(verts, 1, function(row) all(is.finite(row))) values[finite] <- fn(verts[finite,]) - bound if (!greater) values <- -values values } getKeep <- function(values) { !is.na(values) & values > 0 } applyKeep <- function() { for (attr in c("vertices", "normals", "colors", "texcoords", "centers", "adj")) if (!is.null(obj[[attr]]) && nrow(obj[[attr]]) > 1) obj[[attr]] <- obj[[attr]][keep,,drop = FALSE] for (attr in c("texts", "cex", "adj", "radii", "ids", "types", "flags", "offsets", "pos")) if (length(obj[[attr]]) > 1) obj[[attr]] <- obj[[attr]][keep] obj } scene <- scene3d() if (missing(ids)) ids <- names(scene$objects) names <- names(ids) ids <- as.character(ids) result <- integer() minVertices <- rep(minVertices, length.out = length(ids)) names(minVertices) <- ids fn <- .getVertexFn(fn, parent.frame()) for (id in ids) { obj <- scene$objects[[id]] type <- obj$type nverts <- nrow(obj$vertices) newid <- NA switch(type, triangles=, quads=, planes=, surface= { mesh <- as.mesh3d(obj) mesh <- cleanMesh3d(mesh) clipped <- clipMesh3d(mesh, fn, bound, greater, minVertices[id]) clipped <- cleanMesh3d(clipped, rejoin = TRUE) newid <- shade3d(clipped, override = FALSE) }, points =, text =, spheres =, sprites = { keep <- getKeep(getValues(obj)) if (!all(keep)) { obj <- applyKeep() newid <- plot3d(obj) } }, lines = { oldnverts <- nverts - 1 while (nverts < minVertices[id] && nverts > oldnverts) { oldnverts <- nverts obj <- subdivideLines(obj) nverts <- nrow(obj$vertices) } values <- getValues(obj) keep <- getKeep(values) if (!all(keep)) { for (j in 2*seq_len(nverts %/% 2)) { i <- j - 1 if (is.na(values[i]) || is.na(values[j])) { keep[i] <- keep[j] <- FALSE } else if (!keep[i] && !keep[j]) {# no change } else if (!keep[i]) { p <- 1 - abs(values[i])/(abs(values[i]) + values[j]) obj$vertices[i,] <- p*obj$vertices[i,] + (1-p)*obj$vertices[j,] keep[i] <- TRUE } else if (!keep[j]) { p <- 1 - abs(values[j])/(abs(values[j]) + values[i]) obj$vertices[j,] <- p*obj$vertices[j,] + (1-p)*obj$vertices[i,] keep[j] <- TRUE } } obj <- applyKeep() obj <- rejoinLines3d(obj) newid <- plot3d(obj) } }, linestrip = { oldnverts <- nverts - 1 while (nverts < minVertices[id] && nverts > oldnverts) { oldnverts <- nverts obj <- subdivideLines(obj) nverts <- nrow(obj$vertices) } newverts <- nverts values <- getValues(obj) if (!all(values >= 0, na.rm = TRUE)) { hasattrs <- character() for (attr in c("vertices", "normals", "colors")) if (!is.null(obj[[attr]]) && nrow(obj[[attr]]) > 1) hasattrs <- c(hasattrs, attr) indices <- rbind(seq_len(nverts), NA, NA) for (j in seq_len(nverts)[-1]) { i <- j - 1 # There are lots of cases to consider here. # We could have a point that was already ignored # to create a gap in the linestrip, a point # that should be deleted because it is outside the # range, or a point that should be kept. These # have value NA, negative, or non-negative respectively. # The 9 cases are handled as follows (assuming we # go through (i, j=i+1) pairs in sequence): # i j disposition # NA NA drop i, keep j # NA - drop i, keep j # NA + keep both # - NA drop i, keep j # - - drop i, keep j unless it is last # - + change i to NA (unless it's first, then drop it), insert interpolant, keep j # + NA keep both # + - keep i, insert interpolant then NA, move to j # + + keep both if (is.na(values[i])) { if (is.na(values[j]) || values[j] < 0) indices[1,i] <- NA } else if (values[i] < 0) { if (is.na(values[j]) || values[j] < 0) indices[1,i] <- NA else { indices[2,i] <- newverts + 1 p <- 1 - abs(values[i])/(abs(values[i]) + values[j]) for (attr in hasattrs) { while (nrow(obj[[attr]]) < newverts + 1) obj[[attr]] <- rbind(obj[[attr]], obj[[attr]]) new <- p*obj[[attr]][i,] + (1-p)*obj[[attr]][j,] obj[[attr]][newverts + 1,] <- new } newverts <- newverts + 1 obj$vertices[i,] <- NA if (j == 2) indices[1,i] <- NA } } else { if (!is.na(values[j]) && values[j] < 0) { indices[2,i] <- newverts + 1 indices[3,i] <- newverts + 2 p <- 1 - abs(values[j])/(abs(values[j]) + values[i]) obj$vertices <- rbind(obj$vertices, p*obj$vertices[j,] + (1-p)*obj$vertices[i,], c(NA, NA, NA)) for (attr in hasattrs) { while (nrow(obj[[attr]]) < newverts + 2) obj[[attr]] <- rbind(obj[[attr]], obj[[attr]]) new <- p*obj[[attr]][j,] + (1-p)*obj[[attr]][i,] obj[[attr]][newverts+1,] <- new obj[[attr]][newverts+2,] <- NA } newverts <- newverts + 2 if (j == nverts) indices[1,j] <- NA } } } indices <- c(indices) indices <- indices[!is.na(indices)] for (attr in hasattrs) obj[[attr]] <- obj[[attr]][indices,,drop = FALSE] } obj <- rejoinLines3d(obj) newid <- plot3d(obj) } ) if (!is.na(newid)) { result[id] <- newid if (replace) pop3d(id = id) } else result[id] <- as.integer(id) } if (!is.null(names)) names(result) <- names rglId(result) } rgl/R/shadow3d.R0000644000176200001440000000416614100762640013105 0ustar liggesusers# Project the shadow of one mesh object onto another shadow3d <- function(obj, mesh, plot = TRUE, up = c(0, 0, 1), P = projectDown(up), outside = FALSE, ...) { triangles <- as.triangles3d(mesh) ntri <- nrow(triangles) / 3 P <- t(P) # The convention in rgl is row vectors on the left # but we'll be using column vectors on the right projected <- P %*% rbind(t(triangles), 1) projected <- projected[1:2,]/rep(projected[4,], each = 2) fn <- function(xyz) { result <- rep(-Inf, nrow(xyz)) r <- P %*% rbind(t(xyz), 1) r <- rbind(r[1:2,]/rep(r[4,], each = 2), 1) for (i in 1:ntri) { # For each triangle, find the barycentric parameters # of each point in xyz using relation R lambda = r = (x,y,1)' R <- rbind(projected[,(0:2) + 3*i - 2], 1) lambda <- tryCatch(solve(R, r), error = function(e) matrix(-Inf, 3, ncol(r))) # If the smallest barycentric coord is positive, the point # is in the triangle minlambda <- apply(lambda, 2, min) result <- pmax(result, minlambda) } result } if (outside) levels <- c(Inf, 0, -Inf) else levels <- c(0, Inf) filledContour3d(obj, fn, levels = levels, plot = plot, ...) } projectDown <- function(up) { if (length(up) == 4) up <- up[1:3]/up[4] else if (length(up) != 3) stop("'up' vector should be length 3.") P <- GramSchmidt(up, c(1, 0, 0), c(0, 1, 0)) if (det(P) < 0) P[3,] <- -P[3,] cbind(rbind(t(P[c(2,3,1),]), 0), c(0, 0, 0, 1)) } facing3d <- function(obj, up = c(0, 0, 1), P = projectDown(up), front = TRUE, strict = TRUE) { obj <- as.tmesh3d(obj) P <- t(P) # The convention in rgl is row vectors on the left # but we'll be using column vectors on the right r <- P %*% obj$vb r <- r[1:2,]/rep(r[4,], each = 2) area <- function(i) { x <- r[1,obj$it[,i]] y <- r[2,obj$it[,i]] area <- 0 for (j in 1:3) area <- area + x[j]*y[j %% 3 + 1] - x[j %% 3 + 1]*y[j] area } areas <- vapply(seq_len(ncol(obj$it)), area, 0) if (isTRUE(front)) keep <- areas > 0 else keep <- areas < 0 if (!strict) keep <- keep | areas == 0 obj$it <- obj$it[, keep] cleanMesh3d(obj) } rgl/R/shiny.R0000644000176200001440000000750714145464133012532 0ustar liggesusers# shiny support functions # Shiny objects if the widget sets elementId, so we # need to detect it. Thanks to Joe Cheng for suggesting this code. inShiny <- function() isNamespaceLoaded("shiny") && !is.null(shiny::getDefaultReactiveDomain()) fns <- local({ registered <- FALSE registerShinyHandlers <- function() { if (!registered) { if (requireNamespace("shiny")) { shiny::registerInputHandler("shinyPar3d", convertShinyPar3d, force = TRUE) shiny::registerInputHandler("shinyMouse3d", convertShinyMouse3d, force = TRUE) registered <<- TRUE } else stop("Not in Shiny") } } unregisterShinyHandlers <- function() { if (registered) { shiny::removeInputHandler("shinyPar3d") shiny::removeInputHandler("shinyMouse3d") } } list(registerShinyHandlers = registerShinyHandlers, unregisterShinyHandlers = unregisterShinyHandlers) }) registerShinyHandlers <- fns$registerShinyHandlers unregisterShinyHandlers <- fns$unregisterShinyHandlers rm(fns) # Widget output function for use in Shiny rglwidgetOutput <- function(outputId, width = '512px', height = '512px') { registerShinyHandlers() shinyWidgetOutput(outputId, 'rglWebGL', width, height, package = 'rgl') } # Widget render function for use in Shiny renderRglwidget <- function(expr, env = parent.frame(), quoted = FALSE, outputArgs = list()) { registerShinyHandlers() if (!quoted) expr <- substitute(expr) # force quoted shiny::markRenderFunction(rglwidgetOutput, shinyRenderWidget(expr, rglwidgetOutput, env, quoted = TRUE), outputArgs = outputArgs) } shinySetPar3d <- function(..., session, subscene = currentSubscene3d(cur3d())) { registerShinyHandlers() args <- list(...) argnames <- names(args) if (length(args) == 1 && is.null(argnames)) { args <- args[[1]] } # We might have been passed modified shinyGetPar3d output; # clean it up. args[["subscene"]] <- NULL args[["tag"]] <- NULL argnames <- names(args) if (is.null(argnames) || any(argnames == "")) stop("Parameters must all be named") badargs <- argnames[!(argnames %in% .Par3d) | argnames %in% .Par3d.readonly] if (length(badargs)) stop("Invalid parameter(s): ", badargs) for (arg in argnames) { session$sendCustomMessage("shinySetPar3d", list(subscene = subscene, parameter = arg, value = args[[arg]])) } } shinyGetPar3d <- function(parameters, session, subscene = currentSubscene3d(cur3d()), tag = "") { registerShinyHandlers() badargs <- parameters[!(parameters %in% .Par3d)] if (length(badargs)) stop("invalid parameter(s): ", badargs) session$sendCustomMessage("shinyGetPar3d", list(tag = tag, subscene = subscene, parameters = parameters)) } convertShinyPar3d <- function(par3d, ...) { for (parm in c("modelMatrix", "projMatrix", "userMatrix", "userProjection")) if (!is.null(par3d[[parm]])) par3d[[parm]] <- matrix(unlist(par3d[[parm]]), 4, 4) for (parm in c("mouseMode", "observer", "scale", "viewport", "bbox", "windowRect")) if (!is.null(par3d[[parm]])) par3d[[parm]] <- unlist(par3d[[parm]]) par3d } shinyResetBrush <- function(session, brush) { registerShinyHandlers() session$sendCustomMessage("resetBrush", brush) } convertShinyMouse3d <- function(mouse3d, ...) { for (parm in c("model", "proj")) if (!is.null(mouse3d[[parm]])) mouse3d[[parm]] <- matrix(unlist(mouse3d[[parm]]), 4, 4) if (length(unlist(mouse3d$view)) == 4) mouse3d$view <- structure(unlist(mouse3d$view), names = c("x", "y", "width", "height")) if (all(c("p1", "p2") %in% names(mouse3d$region))) mouse3d$region <- with(mouse3d$region, c(x1 = (p1$x + 1)/2, y1 = (p1$y + 1)/2, x2 = (p2$x + 1)/2, y2 = (p2$y + 1)/2)) structure(mouse3d, class = "rglMouseSelection") } rgl/R/as.triangles3d.R0000644000176200001440000000536214100762640014211 0ustar liggesusersas.triangles3d <- function(obj, ...) UseMethod("as.triangles3d") as.triangles3d.mesh3d <- function(obj, attribute = c("vertices", "normals", "texcoords", "colors"), ...) { indices <- NULL if (!is.null(obj$it)) { indices <- c(obj$it) } if (!is.null(obj$ib)) { indices <- c(indices, c(obj$ib[1:3,], obj$ib[c(1,3,4),])) } if (!is.null(indices)) switch(match.arg(attribute), vertices = t(obj$vb[1:3, indices])/obj$vb[4,indices], normals = if (!is.null(obj$normals)) if (nrow(obj$normals) == 4) t(obj$normals[1:3, indices]/obj$normals[4,indices]) else t(obj$normals[, indices]), texcoords = if (!is.null(obj$texcoords)) t(obj$texcoords[, indices]), colors = if (!is.null(obj$material) && !is.null(obj$material$color)) { col <- t(col2rgb(rep(obj$material$color, length.out = max(indices)))) alpha <- if (is.null(obj$material$alpha)) 1 else obj$material$alpha alpha <- rep(alpha, length.out = max(indices)) cbind(col, alpha)[indices,] }) } as.triangles3d.rglId <- function(obj, attribute = c("vertices", "normals", "texcoords", "colors"), subscene = NA, ...) { attribute <- match.arg(attribute) ids <- ids3d(subscene = subscene) ids <- ids[ids$id %in% obj,] result <- NULL for (i in seq_len(nrow(ids))) { id <- ids[i, "id"] nvert <- rgl.attrib.count(id, "vertices") attrib <- rgl.attrib(id, attribute) if (nrow(attrib)) { if (nrow(attrib) < nvert) attrib <- apply(attrib, 2, function(col) rep(col, len = nvert)) type <- ids[i, "type"] result <- rbind(result, switch(as.character(type), triangles =, planes = attrib, quads = { nquads <- nrow(attrib)/4 attrib[4*rep(seq_len(nquads) - 1, each = 6) + c(1,2,3,1,3,4),,drop=FALSE] }, surface = { dim <- rgl.attrib(id, "dim") ul <- rep(2:dim[1], dim[2]-1) + dim[1]*rep(0:(dim[2]-2), each=dim[1]-1) if (rgl.attrib(id, "flags")["flipped",]) indices <- c(rbind(c(ul-1, ul-1+dim[1]), c(ul, ul), c(ul-1+dim[1], ul+dim[1]))) else indices <- c(rbind(c(ul, ul), c(ul-1, ul-1+dim[1]), c(ul-1+dim[1], ul+dim[1]))) attrib[indices,,drop = FALSE] }, NULL)) } } result } rgl/R/drape3d.R0000644000176200001440000001266214100762640012713 0ustar liggesusersdrape3d <- function(obj, ...) UseMethod("drape3d") drape3d.default <- function(obj, ...) drape3d(as.mesh3d(obj), ...) drape3d.mesh3d <- function(obj, x, y = NULL, z = NULL, plot = TRUE, up = c(0, 0, 1), P = projectDown(up), ...) { # Takes segment number as input; returns # NULL if in no triangle, otherwise matrix of projected locations and triangle numbers. ztri <- function(i) { p <- psegs[,i] oo <- p[1] < TRI[1,1,] | p[1] > TRI[2,1,] | p[2] < TRI[1,2,] | p[2] > TRI[2,2,] result <- NULL lam <- numeric(3) for(j in which(!oo)) { ## get barycentric coords of p in projected triangle v <- pverts[,obj$it[,j]] ## v[i,] vertices of projected triangle i D <- (v[2,2]-v[2,3]) * (v[1,1]-v[1,3]) + (v[1,3]-v[1,2]) * (v[2,1]-v[2,3]) if (D == 0) next l <- (v[2,2]-v[2,3]) * (p[1] -v[1,3]) + (v[1,3]-v[1,2]) * (p[2] -v[2,3]) lam[1] <- l/D if (lam[1] < 0 || lam[1] > 1) next ## not in this triangle l <- (v[2,3]-v[2,1]) * (p[1] -v[1,3]) + (v[1,1]-v[1,3]) * (p[2] -v[2,3]) lam[2] <- l/D if (lam[2] < 0 || lam[2] > 1) next ## not in this triangle lam[3] <- 1-sum(lam[1:2]) if (lam[3] < 0 || lam[3] > 1) next ## not in this triangle v <- matrix(verts[,obj$it[,j]], 3,3) ## Now v is vertices of original triangle result <- rbind(result, c(v %*% lam, j)) } result } op <- function(v) v[if(v[1] > v[2]) c(2,1) else c(1,2)] ## orders pair obj <- as.tmesh3d(obj) verts <- obj$vb segs <- xyz.coords(x, y, z, recycle=TRUE) segs <- rbind(segs$x, segs$y, segs$z, 1) if (length(dim(P)) != 2 || !all(dim(P) == 4)) stop("P should be a homogeneous coordinate matrix.") P <- t(P) # The convention in rgl is row vectors on the left # but we'll be using column vectors on the right # Project the vertices, then get 1st two Euclidean coords pverts <- P %*% verts pverts <- pverts[1:2,]/rep(pverts[4,], each = 2) # and switch verts to Euclidean: verts <- verts[1:3,]/rep(verts[4,], each = 3) psegs <- P %*% segs # projected segments psegs <- psegs[1:2,]/rep(psegs[4,], each = 2) ## get unique point pairs making a triangle side tri <- matrix(NA,nrow=3*ncol(obj$it),ncol=2) n <- 0 for (j in seq_len(ncol(obj$it))) { v <- obj$it[,j] tri[n<-n+1,] <- v[c(1,2)] tri[n<-n+1,] <- v[c(2,3)] tri[n<-n+1,] <- v[c(3,1)] } TRI <- array(NA,c(2,2,ncol(obj$it))) for(j in seq_len(ncol(obj$it))) { v <- obj$it[,j] ## vertices of triangle TRI[,,j] <- matrix(c(range(pverts[1,v]),range(pverts[2,v])),2,2) } ## now TRI[,1,i] is x coord range for projected triangle i ## now TRI[,2,i] is y coord range for projected triangle i result <- matrix(numeric(), ncol = 3) p2 <- NA p2tri <- NULL for (i in seq_len(ncol(psegs))) { p1 <- p2 p1tri <- p2tri if (!length(p1tri)) zs <- NULL else zs <- cbind(p1tri, 0) # First point p2 <- psegs[,i] if (any(is.na(p2))) { p2tri <- NULL next } else { p2tri <- ztri(i) zs <- rbind(zs, cbind(p2tri, 1)) # Last point } if (any(is.na(p1))) next ## add middle points p21 <- p2 - p1 s <- matrix(c(p1,p2),2,2) ## speedup: winnow futile intersection calcs s <- t(apply(s,1,op)) ## triangle seg x extent is all below or above line seg x extent sx <- (pverts[1,tri[,1]] < s[1,1] & pverts[1,tri[,2]] < s[1,1]) | (pverts[1,tri[,1]] > s[1,2] & pverts[1,tri[,2]] > s[1,2]) ## triangle seg y extent is all below or above line seg y extent sy <- (pverts[2,tri[,1]] < s[2,1] & pverts[2,tri[,2]] < s[2,1]) | (pverts[2,tri[,1]] > s[2,2] & pverts[2,tri[,2]] > s[2,2]) for(j in which(!sx & !sy)) { ## possible intersections p3 <- pverts[,tri[j,1]] p4 <- pverts[,tri[j,2]] p43 <- p4-p3 p31 <- p3-p1 D <- -p21[1]*p43[2] + p21[2]*p43[1] if (D == 0) next ## parallel line segs T1<- -p31[1]*p43[2] + p31[2]*p43[1] t1 <- T1/D if (t1 < 0 || t1 > 1) next ## not within p1 ... p2 T2<- p21[1]*p31[2] - p21[2]*p31[1] t2 <- T2/D if (t2 < 0 || t2 > 1) next ## not within p3 ... p4 v3 <- verts[,tri[j,1]] v43 <- verts[,tri[j,2]] - v3 k <- (j+2)%/%3 # triangle number zs <- rbind(zs, c(v3+t2*v43, k, t1))## t1 along line seg & point value } if (length(zs)) { # Order by triangle to group them, then by t # within triangle o <- order(zs[,4], zs[,5]) zs <- zs[o, , drop = FALSE] # Only keep cases that are on the same triangle # Rounding may give us 1 or 3 intersections with a # triangle; discard singletons, use first and last # for triples. k <- zs[,4] dup <- duplicated(k) nextdup <- c(dup[-1], FALSE) keep <- xor(dup, nextdup) # The first or last for a triangle zs <- zs[keep,,drop = FALSE] # Order by t value finish <- 2*seq_len(nrow(zs)/2) start <- finish - 1 o <- order(zs[start, 5]) start <- start[o] finish <- finish[o] # Drop zero length segments keep <- zs[start, 5] < zs[finish, 5] start <- start[keep] finish <- finish[keep] both <- as.numeric(rbind(start, finish)) result <- rbind(result, zs[both, -(4:5), drop = FALSE]) } } if (plot) segments3d(result, ...) else result } rgl/R/shapelist3d.R0000644000176200001440000000551414100762640013612 0ustar liggesusersshapelist3d <- function(shapes,x=0,y=NULL,z=NULL,size=1,matrix=NULL,override=TRUE, ..., plot=TRUE) { # This function gets an element with recycling e <- function(x, i) x[[ (i-1) %% length(x) + 1 ]] xyz <- xyz.coords(x, y, z, recycle = TRUE) x <- xyz$x y <- xyz$y if (length(y) == 0) y <- 0 z <- xyz$z if (length(z) == 0) z <- 0 if (inherits(shapes, "shape3d")) shapes <- list(shapes) material <- list(...) if (!is.null(matrix)) { if (!is.list(matrix)) matrix <- list(matrix) len <- length(matrix) } else len <- 0 len <- max(len, length(x), length(shapes), length(size), length(override)) if (length(material)) len <- max(len, sapply(material, length)) result <- vector("list", len) class(result) <- c("shapelist3d", "shape3d") for (i in seq_len(len)) { if (is.null(matrix)) this <- e(shapes, i) else this <- rotate3d(e(shapes,i), matrix=e(matrix,i)) thissize <- e(size, i) this <- translate3d(scale3d(this, thissize, thissize, thissize), e(x,i), e(y,i), e(z,i)) thismaterial <- lapply(material, function(item) e(item,i)) if (!e(override,i)) thismaterial[names(this$material)] <- this$material this$material[names(thismaterial)] <- thismaterial result[[i]] <- this } if (plot) { shade3d(result) lowlevel(result) } else invisible(result) } dot3d.shapelist3d <- function(x, override = TRUE, ...) { .check3d() save <- par3d(skipRedraw = TRUE) on.exit(par3d(save)) lowlevel(unlist(sapply( x, function(item) dot3d(item, override=override, ...) ) ) ) } wire3d.shapelist3d <- function(x, override = TRUE, ...) { .check3d() save <- par3d(skipRedraw = TRUE) on.exit(par3d(save)) lowlevel(unlist(sapply( x, function(item) wire3d(item, override=override, ...) ) ) ) } shade3d.shapelist3d <- function(x, override = TRUE, ...) { .check3d() save <- par3d(skipRedraw = TRUE) on.exit(par3d(save)) lowlevel(unlist(sapply( x, function(item) shade3d(item, override=override, ...) ) ) ) } translate3d.shapelist3d <- function( obj, x, y, z, ... ) { structure(lapply( obj, function(item) translate3d(item, x, y, z, ...) ), class = class(obj)) } rotate3d.shapelist3d <- function( obj,angle,x,y,z,matrix, ... ) { structure(lapply( obj, function(item) rotate3d(item, x,y,z,matrix,...) ), class = class(obj)) } scale3d.shapelist3d <- function( obj, x, y, z, ... ) { structure(lapply( obj, function(item) scale3d(item, x,y,z,...) ), class = class(obj)) } addNormals.shapelist3d <- function( x, ... ) { structure(lapply( x, function(item) addNormals(item, ...) ), class = class(x)) } print.shapelist3d <- function(x, prefix = "", ...) { cat(prefix, " shapelist3d object with ", length(x), " items:\n", sep = "") for (i in seq_along(x)) print(x[[i]], prefix = paste0(prefix, "[[", i, "]]")) } rgl/R/ashape3d.R0000644000176200001440000000725214100762640013060 0ustar liggesusers# Support for objects from alphashape3d package persp3d.ashape3d <- function(x, ..., add = FALSE) { plot3d(as.mesh3d(x, ...), add = add, ...) } plot3d.ashape3d <- function(x, ...) persp3d(x, ...) reOrient <- function(vertices) { warned <- FALSE # Count how many other triangles touch each edge of this one, in order 2-3, 1-3, 1-2: edgeCounts <- function(index) { triangle <- vertices[,index] result <- integer(3) for (i in 1:3) { result[i] <- sum(apply(vertices, 2, function(col) all(triangle[-i] %in% col))) } result - 1 } polys <- ncol(vertices) verts <- nrow(vertices) fixed <- 0L for (i in seq_len(polys - 1)) { fixed <- max(i, fixed) # Get all polygons touching polygon i thistriangle <- vertices[,i] if (any(is.na(thistriangle))) next touches <- which(matrix(vertices %in% thistriangle,nrow=3), arr.ind = TRUE) if (!nrow(touches)) next counts <- table(touches[,2L]) # Get col number of all polygons sharing an edge with i shared <- as.numeric(names(counts)[counts > 1L]) shared <- shared[shared != i] if (!length(shared)) next otherverts <- vertices[, shared, drop=FALSE] # FIXME: otherverts may include multiple triangles sharing the # same edge, because ashape3d sometimes embeds # tetrahedrons (or larger polyhedra?) in the surfaces # it produces. It doesn't appear to be safe to just # delete these if (!warned && length(shared) > 1L && any( edgeCounts(i) > 1)) { warning("Surface may not be simple; smoothing may not be possible.") warned <- TRUE } shared <- shared[shared > fixed] if (!length(shared)) next otherverts <- vertices[, shared, drop=FALSE] for (m in seq_len(ncol(otherverts))) { # m is intersection number # For each vertex in i, see if it is in the shared one, and # if they have opposite orientations as we need for (j in seq_len(verts)) { # Where is j in the others? jother <- which(otherverts[,m] == vertices[j,i]) if (!length(jother)) next k <- j %% verts + 1L # k follows j kother <- jother %% verts + 1L # kother is entry following jother if (vertices[k, i] == otherverts[kother, m]) { otherverts[, m] <- rev(otherverts[, m]) break } } } # Now move all of shared to the front unshared <- (fixed+1L):max(shared) unshared <- unshared[!(unshared %in% shared)] if (length(unshared)) vertices[, (fixed+length(shared)+1L):max(shared)] <- vertices[,unshared] vertices[, fixed + seq_along(shared)] <- otherverts fixed <- fixed + length(shared) } vertices } as.mesh3d.ashape3d <- function(x, alpha = x$alpha[1], tri_to_keep = 2L, col = "gray", smooth = FALSE, normals = NULL, texcoords = NULL, ...) { whichAlpha <- which(alpha == x$alpha)[1] if (!length(whichAlpha)) stop("'alpha = ", alpha, "' not found in ", deparse(substitute(x))) triangles <- x$triang keep <- triangles[,8 + whichAlpha] %in% tri_to_keep triangs <- t(triangles[keep, 1:3]) points <- t(x$x) if (!is.null(texcoords)) texcoords <- texcoords[triangs, ] material <- .getMaterialArgs(...) material$color <- col result <- tmesh3d(points, triangs, homogeneous = FALSE, normals = normals, texcoords = texcoords, material = material) if (smooth) { if (is.null(normals)) { result$it <- reOrient(result$it) result <- addNormals(result) } else warning("smoothing ignored when 'normals' specified") } result } rgl/R/buffer.R0000644000176200001440000003467714146202555012660 0ustar liggesuserstypeSignedByte <- 5120 typeUnsignedByte <- 5121 typeSignedShort <- 5122 typeUnsignedShort <- 5123 typeSignedInt <- 5124 # Not supported in glTF typeUnsignedInt <- 5125 typeFloat <- 5126 typeDouble <- 5130 # Not supported in glTF getType <- function(x, useDouble = FALSE) { r <- range(x, na.rm = TRUE) if (is.integer(x) && !any(is.na(x))) { if (r[1] < 0) { if (-128 <= r[1] && r[2] <= 127) typeSignedByte else if (-32768 <= r[1] && r[2] <= 32767) typeSignedShort else typeSignedInt } else { if (r[2] <= 255) typeUnsignedByte else if (r[2] <= 65535) typeUnsignedShort else typeUnsignedInt } } else if (is.numeric(x)) { if ((-32768 <= r[1] && r[2] <= 32767 || 0 <= r[1] && r[2] <= 65535) && isTRUE(all(x == as.integer(x)))) getType(as.integer(x)) else if (!useDouble) typeFloat else typeDouble } else stop('Unrecognized type') } #' @title R6 Class for binary buffers in glTF files. #' #' @description #' These files typically have one buffer holding all the #' binary data for a scene. Buffer <- R6Class("Buffer", public = list( #' @param json #' list read from glTF file. #' @param binfile #' optional External binary filename, or raw vector #' initialize = function(json = NULL, binfile = NULL) { if (!is.null(json)) { private$buffers <- json$buffers private$bufferViews <- json$bufferViews private$accessors <- json$accessors } buffer <- self$getBuffer(0) if (is.null(buffer$uri)) { if (is.character(binfile)) buffer$uri <- binfile else if (is.raw(binfile)) buffer$bytes <- binfile } self$setBuffer(0, buffer) }, #' @description #' Load from file. #' #' @param uri Which file to load. #' @param buf Which buffer number to load. #' load = function(uri, buf = 0) { buffer <- self$getBuffer(buf) if (is.null(buffer)) buffer <- list(byteLength = 0) self$closeBuffer(buf) if (is.character(uri)) { bytes <- readBin(uri, "raw", n = file.size(uri)) buffer$uri <- uri } else if (is.raw(uri)) bytes <- uri buffer$byteLength <- length(bytes) buffer$con <- rawConnection(bytes, open = "r+b") self$setBuffer(buf, buffer) }, #' @description #' Write open buffer to connection. #' #' @param con #' Output connection. #' @param buf #' Buffer number. #' saveOpenBuffer = function(con, buf = 0) { buffer <- self$getBuffer(buf) if (is.null(buffer) || is.null(con0 <- buffer$con) || !inherits(con0, "connection") || !isOpen(con0)) stop("buffer ", buf, " is not open.") bytes <- rawConnectionValue(con0) writeBin(bytes, con) }, #' @description #' Get buffer object. #' #' @param buf Buffer number. #' @param default Default buffer object if `buf` not found. #' #' @return A list containing components described here: #' \url{https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-buffer}. #' getBuffer = function(buf, default = list(byteLength = 0)) { buffer <- if (buf + 1 <= length(private$buffers)) private$buffers[[buf + 1]] if (is.null(buffer)) default else structure(buffer, class = "gltfBuffer") }, #' @description #' Set buffer object. #' #' @param buf Buffer number. #' @param buffer New value to insert. #' setBuffer = function(buf, buffer) private$buffers[[buf + 1]] <- unclass(buffer), #' @description #' Open a connection for the data in a buffer. #' #' @param buf Buffer number. #' #' @return An open binary connection. #' openBuffer = function(buf) { buffer <- self$getBuffer(buf) if (is.null(buffer)) stop("no such buffer") if (is.null(buffer$con)) { if (!is.null(bytes <- buffer$bytes)) { buffer$con <- rawConnection(bytes, open = "r+b") buffer$bytes <- NULL self$setBuffer(buf, buffer) } else if (is.null(buffer$uri)) { buffer$con <- rawConnection(raw(0), open = "r+b") self$setBuffer(buf, buffer) } else self$load(buffer$uri, buf = buf) } self$getBuffer(buf)$con }, #' @description #' Write data to buffer. #' #' @param values Values to write. #' @param type Type to write. #' @param size Byte size of each value. #' @param buf Which buffer to write to. #' #' @return Byte offset of start of bytes written. #' writeBuffer = function(values, type, size, buf = 0) { if (is.null(buffer <- self$getBuffer(buf))) self$setBuffer(buf, buffer <- list(byteLength = 0)) byteLength <- buffer$byteLength byteOffset <- byteLength con <- self$openBuffer(buf) seek(con, byteOffset) byteOffset <- bitwAnd(byteOffset + size - 1, bitwNot(size - 1)) if (is.null(byteLength)) browser() if (byteOffset > byteLength) { writeBin(raw(byteOffset - byteLength), con) } if (type %in% c(typeFloat, typeDouble)) values <- as.numeric(values) else values <- as.integer(values) writeBin(values, con, size = size, endian = "little") buffer <- self$getBuffer(buf) buffer$byteLength <- byteOffset + length(values)*size self$setBuffer(buf, buffer) byteOffset }, #' @description #' Close the connection in a buffer. #' #' If there was a connection open, this will save the #' contents in the raw vector `bytes` within the buffer object. #' #' @param buf The buffer number. #' closeBuffer = function(buf) { buffer <- self$getBuffer(buf) if (!is.null(buffer) && !is.null(buffer$con)) { buffer$bytes <- rawConnectionValue(buffer$con) close(buffer$con) buffer$con <- NULL self$setBuffer(buf, buffer) } }, #' @description #' Close any open buffers. #' #' Call this after working with a GLTF file to avoid warnings #' from R about closing unused connections. #' closeBuffers = function() { for (i in seq_along(private$buffers)) { self$closeBuffer(i - 1) } }, #' @description #' Get bufferView object. #' #' @param bufv bufferView number. #' #' @return A list containing components described here: #' \url{https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-bufferview}. #' getBufferview = function(bufv) { bufferview <- private$bufferViews[[bufv+1]] if (is.null(bufferview)) stop("bufferView ", bufv, " not found.") structure(bufferview, class = "gltfBufferview") }, #' @description #' Add a new buffer view. #' #' @param values Values to put in the view. #' @param type Type of values. #' @param size Size of values in bytes. #' @param target Optional target use for values. #' @param buf Which buffer to write to. #' #' @return New bufferView number. #' addBufferView = function(values, type, size, target = NULL, buf = 0) { bufferview <- list() bufferview$buffer <- buf bufferview$byteLength <- size*length(values) buffer <- self$getBuffer(buf) bufferview$byteOffset <- self$writeBuffer(values, type, size, buf) if (!is.null(target)) bufferview$target <- target self$setBufferview(length(private$bufferViews), bufferview) length(private$bufferViews) - 1 }, #' @description #' Open a connecton to a buffer view. #' #' @param bufv Which bufferView. #' #' @return A connection. openBufferview = function(bufv) { bufferview <- self$getBufferview(bufv) con <- self$openBuffer(bufferview$buffer) seek(con, bufferview$byteOffset) con }, #' @description #' Set bufferView object. #' #' @param bufv bufferView number. #' @param bufferView New value to insert. setBufferview = function(bufv, bufferView) private$bufferViews[[bufv + 1]] <- unclass(bufferView), #' @description #' Get accessor object #' #' @param acc Accessor number #' #' @return A list containing components described here: #' \url{https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-accessor} #' getAccessor = function(acc) structure(private$accessors[[acc + 1]], class = "gltfAccessor"), #' @description #' Set accessor object. #' #' @param acc Accessor number. #' @param accessor New value to insert. #' setAccessor = function(acc, accessor) private$accessors[[acc + 1]] <- unclass(accessor), #' @description #' Read data given by accessor object. #' #' @param acc Accessor number. #' #' @return A vector or array as specified in the accessor. #' readAccessor = function(acc) { typenames <- c("5120" = "byte", "5121" = "unsigned_byte", "5122" = "short", "5123" = "unsigned_short", "5125" = "unsigned_int", "5126" = "float") types <- c("5120" = "int", "5121" = "int", "5122" = "int", "5123" = "int", "5125" = "int", "5126" = "double") sizes <- c("5120" = 1, "5121" = 1, "5122" = 2, "5123" = 2, "5125" = 4, "5126" = 4) signeds <- c("5120" = TRUE, "5121" = FALSE, "5122" = TRUE, "5123" = FALSE, "5125" = TRUE, # not really, but make readBin happy "5126" = TRUE) lens <- c(SCALAR = 1, VEC2 = 2, VEC3 = 3, VEC4 = 4, MAT2 = 4, MAT3 = 9, MAT4 = 16) if (acc + 1 > length(private$accessors)) stop("No such accessor") accessor <- self$getAccessor(acc) view <- self$getBufferview(accessor$bufferView) con <- self$openBufferview(accessor$bufferView) ctype <- as.character(accessor$componentType) atype <- accessor$type type <- types[ctype] len <- lens[atype] size <- sizes[ctype] signed <- signeds[ctype] count <- accessor$count if (is.null(view$byteStride)) { skip <- 0 } else skip <- len*size - view$byteStride if (is.null(byteOffset <- accessor$byteOffset)) byteOffset <- 0 start <- seek(con) + byteOffset if (skip == 0) { seek(con, start) values <- readBin(con, type, n = len*count, size = size, signed = signed, endian = "little") } else { values <- numeric(count*len) for (i in seq_len(count)) { seek(con, start + (i-1)*view$byteStride) values[(i-1)*len + seq_len(len)] <- readBin(con, type, n = len, size = size, signed = signed, endian = "little") } } if (ctype == "5125") { # fix up unsigned integers values[is.na(values)] <- 2^31 values[values < 0] <- values[values < 0] + 2^32 } if (!is.null(accessor$normalized) && accessor$normalized) values <- switch(ctype, "5120" = (values + 128)/255 - 1, # byte "5121" = values/255, # u byte "5122" = (values + 2^15)/65535 - 1, # short "5123" = values/65535, # u short values) # default if (len > 1) if (grepl("MAT", atype)) { values <- matrix(values, ncol = sqrt(len), byrow = TRUE) } else values <- matrix(values, ncol = len, byrow = TRUE) values }, #' @description #' Write values to accessor, not including `min` and `max`. #' #' @param values Values to write. #' @param target Optional target use for values. #' @param glTF Whether this is for glTF use. #' @param useDouble Whether to write doubles or singles. #' #' @return New accessor number addAccessor = function(values, target = NULL, useDouble = FALSE) { componentType <- getType(values, useDouble) size <- switch(as.character(componentType), "5120" =, # typeSignedByte "5121" = 1, # typeUnsignedByte = 1, "5122" =, # typeSignedShort =, "5123" = 2, # typeUnsignedShort = 2, "5124" =, # typeUnsignedInt =, "5125" =, # typeSignedInt =, "5126" = 4, # typeFloat = 4, "5130" = 8) # typeDouble = 8) bufferView <- self$addBufferView(c(values), componentType, size = size, target = target) if (is.matrix(values) && nrow(values) > 1) { count <- ncol(values) type <- paste0("VEC", nrow(values)) } else { count <- length(values) type <- "SCALAR" } accessor <- list(bufferView = bufferView, componentType = componentType, count = count, type = type) private$accessors <- c(private$accessors, list(accessor)) length(private$accessors) - 1 }, #' @description #' Convert buffer to data URI. #' #' @param buf Buffer to convert. #' #' @return String containing data URI. dataURI = function(buf = 0) { self$closeBuffer(buf) buffer <- self$getBuffer(buf) if (is.null(buffer)) stop("Buffer ", buf, " does not exist.") bytes <- buffer$bytes if (is.null(bytes)) { if (is.null(buffer$uri)) return(dataURI(raw(0), mime = "application/octet-stream")) else { self$load(buffer$uri, buf) self$closeBuffer(buf) buffer <- self$getBuffer(buf) bytes <- buffer$bytes } } base64enc::dataURI(bytes, mime = "application/octet-stream") }, #' @description Convert to list. #' @return List suitable for writing using JSON. as.list = function() { result <- list() for (n in names(private)) { thelist <- private[[n]] if (is.list(thelist) && length(thelist)) { for (i in seq_along(thelist)) thelist[[i]] <- unclass(thelist[[i]]) result[[n]] <- thelist } } result } ), private = list( buffers = list(), bufferViews = list(), accessors = list() # , # # finalize = function() { # self$closeBuffers() # } ) ) rgl/R/grid3d.R0000644000176200001440000000370014100762640012536 0ustar liggesusersgrid3d <- function(side, at = NULL, col="gray", lwd = 1, lty = 1, n = 5) { save <- par3d(skipRedraw = TRUE, ignoreExtent = TRUE) on.exit(par3d(save)) if (!missing(side) && length(side)>1) return(lowlevel(sapply(side,grid3d,at=at,col=col,lwd=lwd,lty=lty,n=n))) ranges <- .getRanges() side <- c(strsplit(side, '')[[1]], '-')[1:2] coord <- match(toupper(side[1]), c('X', 'Y', 'Z')) spos <- match(side[2],c('-','+')) sidenames <- c('x', 'y', 'z') sides <- 1:3 sides <- sides[-coord] if (is.null(at)) at <- list() else if (is.numeric(at)) { at <- list(x=at, y=at, z=at) at[[coord]] <- NULL } result <- integer() for (cside in sides) { range <- ranges[[cside]] if (is.null(at1 <- at[[sidenames[cside]]])) at1 <- pretty(range, n) at1 <- at1[at1 >= range[1] & at1 <= range[2]] mpos1 <- matrix(rep(c(ranges$x[1],ranges$y[1],ranges$z[1]), each=length(at1)), ncol=3) mpos2 <- matrix(rep(c(ranges$x[2],ranges$y[2],ranges$z[2]), each=length(at1)), ncol=3) mpos1[,cside] <- mpos2[,cside] <- at1 if (is.null(at[[sidenames[coord]]])) mpos1[,coord] <- mpos2[,coord] <- ranges[c("x","y","z")][[coord]][spos] else { # may need to duplicate temp1 <- temp2 <- matrix(NA, nrow=0, ncol=3) planes <- at[[sidenames[coord]]] planes <- planes[planes >= ranges[[coord]][1] & planes <= ranges[[coord]][2]] for (at2 in planes) { mpos1[,coord] <- mpos2[,coord] <- at2 temp1 <- rbind(temp1, mpos1) temp2 <- rbind(temp2, mpos2) } mpos1 <- temp1 mpos2 <- temp2 } if (nrow(mpos1) + nrow(mpos2) > 0) result[sidenames[cside]] <- segments3d(x=c(rbind(mpos1[,1],mpos2[,1])), y=c(rbind(mpos1[,2],mpos2[,2])), z=c(rbind(mpos1[,3],mpos2[,3])), lwd=lwd,color=col) } lowlevel(result) } rgl/R/arrow3d.R0000755000176200001440000000655614100762640012762 0ustar liggesusers## Original by Barry Rowlingson, R-help, 1/10/2010 ## Modified by Michael Friendly: added barblen (to specify absolute barb length) ## Modified by DJM: multiple changes arrow3d <- function(p0=c(1,1,1), p1=c(0,0,0), barblen, s=1/3, theta=pi/12, type = c("extrusion", "lines", "flat", "rotation"), n = 3, width = 1/3, thickness = 0.618*width, spriteOrigin = NULL, plot = TRUE, ...) { ## p0: start point ## p1: end point ## barblen: length of barb ## s: length of barb as fraction of line length (unless barblen is specified) ## theta: opening angle of barbs ## type: type of arrow to draw ## n: number of barbs ## width: width of shaft as fraction of barb width ## thickness: thickness of shaft as fraction of barb width ## spriteOrigin: origin if drawn as sprite ## ...: args passed to lines3d for line styling ## ## Returns (invisibly): integer ID(s) of the shape added to the scene type <- match.arg(type) nbarbs <- if (type == "lines") n else 2 ## Work in isometric display coordinates save <- par3d(FOV = 0) # Compute the center line in window # coordinates xyz <- rgl.user2window(rbind(p0, p1)) p0 <- xyz[1,] p1 <- xyz[2,] ## rotational angles of barbs phi <- seq(pi/nbarbs, 2*pi-pi/nbarbs, len = nbarbs) ## length of line lp <- sqrt(sum((p1-p0)^2)) if (missing(barblen)) barblen <- s*lp else s <- barblen/lp ## point down the line where the barb ends line up cpt <- p1 + s*cos(theta)*(p0-p1) ## need to find a right-angle to the line. gs <- GramSchmidt(p1-p0, c(0,0,-1), c(1,0,0)) r <- gs[2,] ## now compute the barb end points and draw: for(i in seq_along(phi)) { ptb <- rotate3d(r,phi[i],(p1-p0)[1],(p1-p0)[2],(p1-p0)[3]) xyz <- rbind(xyz, p1, cpt + barblen*sin(theta)*ptb) } if (type != "lines") { xyz <- xyz[c(3, # 1 head 6, # 2 end of barb 1 6, # 3 end of barb 1 again (to be shrunk) 1, # 4 end of line (to be pushed out) 1, # 5 end of line 1, # 6 end of line (to be pushed the other way) 4, # 7 end of barb 2 (to be shrunk) 4, # 8 end of barb 2 3),] # 9 head mid <- (xyz[2,] + xyz[8,])/2 xyz[3,] <- mid + width*(xyz[2,] - mid) xyz[7,] <- mid + width*(xyz[8,] - mid) xyz[4,] <- xyz[4,] + xyz[3,] - mid xyz[6,] <- xyz[6,] + xyz[7,] - mid } if (type %in% c("extrusion", "rotation")) { xyz <- xyz %*% t(gs) if (type == "extrusion") { thickness <- thickness*sqrt(sum((xyz[2,]-xyz[8,])^2)) ext <- extrude3d(xyz[,c(1,3)], thickness = thickness) } else { mid <- xyz[1,3] xyz[,3] <- abs(xyz[,3] - mid) xyz <- xyz[5:9,] ext <- turn3d(xyz[,c(1,3)], n = n) ext$vb[2,] <- ext$vb[2,] + mid thickness <- 0 } ext$vb <- ext$vb[c(1,3,2,4),] ext$vb[2,] <- ext$vb[2,] + xyz[1,2] - thickness/2 ext$vb[1:3,] <- t(gs) %*% ext$vb[1:3,] ext$vb[1:3,] <- t(rgl.window2user(t(ext$vb[1:3,]))) } else xyz <- rgl.window2user(xyz) par3d(save) if (plot) { if (type == "flat") id <- polygon3d(xyz, ...) else if (type %in% c("extrusion", "rotation")) id <- shade3d(ext, ...) else id <- segments3d(xyz, ...) if (is.null(spriteOrigin)) lowlevel(id) else sprites3d(spriteOrigin, shapes=id) } else { if (type %in% c("extrusion", "rotation")) ext else xyz } } rgl/R/fonts.R0000644000176200001440000000407314100762640012517 0ustar liggesusers# The rgl font database is only used when rgl is configured for FreeType. # Since 0.105.13 this is always true on Windows, but since 0.106.2 # r3dDefaults sets useFreeType to FALSE, so the windowsFonts() are used instead. # This code is closely modelled on the Quartz font database. .rglEnv <- new.env() assign(".rglFonts", list(), envir = .rglEnv) # Check that the font has the correct structure and information checkrglFont <- function(font) { if (!is.character(font) || length(font) != 4) stop("Invalid rgl font: must be 4 filenames") font } setrglFonts <- function(fonts, fontNames) { fonts <- lapply(fonts, checkrglFont) fontDB <- get(".rglFonts", envir=.rglEnv) existingFonts <- fontNames %in% names(fontDB) if (sum(existingFonts) > 0) fontDB[fontNames[existingFonts]] <- fonts[existingFonts] if (sum(existingFonts) < length(fontNames)) fontDB <- c(fontDB, fonts[!existingFonts]) assign(".rglFonts", fontDB, envir=.rglEnv) } printFont <- function(font) { paste(font, "\n", sep="") } printFonts <- function(fonts) { cat(paste(names(fonts), ": ", unlist(lapply(fonts, printFont)), sep="", collapse="")) } # If no arguments spec'ed, return entire font database # If no named arguments spec'ed, all args should be font names # to get info on them from the database # Else, must specify new fonts to enter into database (all # of which must be valid filenames and # all of which must be named args) rglFonts <- function(...) { ndots <- length(fonts <- list(...)) if (ndots==0) { get(".rglFonts", .rglEnv) } else { fontNames <- names(fonts) nnames <- length(fontNames) if (nnames == 0) { if (!all(sapply(fonts, is.character))) { stop("Invalid arguments in 'rglFonts' (must be font names)") } else { get(".rglFonts", .rglEnv)[unlist(fonts)] } } else { if (ndots != nnames) { stop("Invalid arguments in 'rglFonts' (need named args)") } setrglFonts(fonts, fontNames) } } } rglFont <- function(family) { checkrglFont(family) } rgl/R/enum.R0000644000176200001440000000424514145464133012340 0ustar liggesusers# enumerations rgl.enum <- function( name, ..., multi = FALSE) { choices <- list( ... ) names <- attr(choices,"names") if (multi) pos <- pmatch( name, c(names, "all") ) else pos <- pmatch( name, names ) max <- length(names) if ( any( is.na(pos) ) ) stop(gettextf("Symbolic value must be chosen from: %s", list(names)), domain = NA) else if ( (max+1) %in% pos ) pos <- seq_along(names) id <- unlist(choices[pos]) if ( length(id) > 1 && !multi ) stop("Multiple choices not allowed") return( id ) } rgl.enum.nodetype <- function(type) rgl.enum( type, shapes=1, lights=2, bboxdeco=3, userviewpoint=4, material=5, background=6, subscene=7, modelviewpoint=8, multi = TRUE ) rgl.enum.attribtype <- function(attrib) rgl.enum( attrib, vertices=1, normals=2, colors=3, texcoords=4, dim=5, texts=6, cex=7, adj=8, radii=9, centers=10, ids=11, usermatrix=12, types=13, flags=14, offsets=15, family=16, font=17, pos=18, fogscale=19, axes=20, indices=21) rgl.enum.pixfmt <- function(fmt) rgl.enum( fmt, png=0 ) rgl.enum.polymode <- function(mode) rgl.enum( mode, filled=1, lines=2, points=3, culled=4) rgl.enum.textype <- function(textype) rgl.enum( textype, alpha=1, luminance=2, luminance.alpha=3, rgb=4, rgba=5 ) rgl.enum.fogtype <- function(fogtype) rgl.enum(fogtype, none=1, linear=2, exp=3, exp2=4) rgl.enum.primtype <- function(primtype) rgl.enum( primtype, points=1, lines=2, triangles=3, quadrangles=4, linestrips=5 ) rgl.enum.texminfilter <- function(minfiltertype) rgl.enum(minfiltertype, nearest=0, linear=1, nearest.mipmap.nearest=2, nearest.mipmap.linear=3, linear.mipmap.nearest=4, linear.mipmap.linear=5) rgl.enum.texmagfilter <- function(magfiltertype) rgl.enum(magfiltertype, nearest=0, linear=1) rgl.enum.gl2ps <- function(postscripttype) rgl.enum(postscripttype, ps=0, eps=1, tex=2, pdf=3, svg=4, pgf=5) rgl.enum.pixelcomponent <- function(component) rgl.enum(component, red=0, green=1, blue=2, alpha=3, depth=4, luminance=5) rgl.enum.depthtest <- function(depthtest) rgl.enum(depthtest, never=0, less=1, equal=2, lequal=3, greater=4, notequal=5, gequal=6, always= 7) rgl/R/device.R0000644000176200001440000000633414100762640012627 0ustar liggesusers## ## R source file ## This file is part of rgl ## ## ## ## ===[ SECTION: device management ]========================================== ## rgl.useNULL <- function() { if (noOpenGL) return(TRUE) opt <- getOption("rgl.useNULL", Sys.getenv("RGL_USE_NULL")) if (is.logical(opt)) return(opt) opt <- as.character(opt) if (nchar(opt)) { opt <- pmatch(tolower(opt), c("yes", "true"), nomatch=3) return(c(TRUE, TRUE, FALSE)[opt]) } FALSE } ## ## open device ## ## rgl.open <- function(useNULL = rgl.useNULL()) { ret <- .C( rgl_dev_open, success=FALSE, useNULL=useNULL ) if (! ret$success) stop("'rgl.open' failed") } ## ## close device ## ## rgl.close <- function() { if (length(hook <- getHook("on.rgl.close"))) { if (is.list(hook)) hook <- hook[[1]] # test is for compatibility with R < 3.0.0 hook() } ret <- .C( rgl_dev_close, success=FALSE ) if (! ret$success) stop("No device opened") } ## ## get current device ## ## rgl.cur <- function() { .Call( rgl_dev_getcurrent ) } ## ## get all devices ## ## rgl.dev.list <- function() { .Call( rgl_dev_list ) } ## ## set current device ## ## rgl.set <- function(which, silent = FALSE) { idata <- c( as.integer(which), as.integer(silent) ) ret <- .C( rgl_dev_setcurrent, success=FALSE, idata ) if (! ret$success) stop(gettextf("No device opened with id %s", which), domain = NA) } ## ## export image ## ## rgl.snapshot <- function( filename, fmt="png", top=TRUE ) { if (top) rgl.bringtotop() idata <- as.integer(rgl.enum.pixfmt(fmt)) if (length(filename) != 1) stop("filename is length ", length(filename)) filename <- normalizePath(filename, mustWork = FALSE) ret <- .C( rgl_snapshot, success=FALSE, idata, filename ) if (! ret$success) warning("'rgl.snapshot' failed") invisible(filename) } ## ## export postscript image ## ## rgl.postscript <- function( filename, fmt="eps", drawText=TRUE ) { idata <- as.integer(c(rgl.enum.gl2ps(fmt), as.logical(drawText))) if (length(filename) != 1) stop("filename is length ", length(filename)) ret <- .C( rgl_postscript, success=FALSE, idata, normalizePath(filename, mustWork = FALSE, winslash = "/") ) if (! ret$success) warning("Postscript conversion failed") } ## ## read image ## ## rgl.pixels <- function(component = c("red", "green", "blue"), viewport = par3d("viewport"), top=TRUE ) { if (top) rgl.bringtotop() compnum <- as.integer(sapply(component, rgl.enum.pixelcomponent)) stopifnot(length(viewport) == 4) ll <- as.integer(viewport[1:2]) stopifnot(all(!is.na(ll)), all(ll >= 0)) size <- as.integer(viewport[3:4]) stopifnot(all(!is.na(size), all(size >= 0))) result <- array(NA_real_, dim=c(size[1], size[2], length(component))) dimnames(result) <- list(NULL, NULL, component) if (length(result) > 0) for (i in seq_along(compnum)) { ret <- .C( rgl_pixels, success=FALSE, ll, size, compnum[i], values = double(size[1]*size[2])) if (! ret$success) warning(gettextf("Error reading component '%s'", component[i]), domain = NA) result[,,i] <- ret$values } if (length(component) > 1) return(result) else return(result[,,1]) } rgl/R/webGLcontrols.R0000644000176200001440000005305214100762640014153 0ustar liggesusers # This displays an HTML5 input widget to show a subset of objects. It assigns a random id # and returns that invisibly. subsetSlider <- function(subsets, labels = names(subsets), fullset = Reduce(union, subsets), subscenes = currentSubscene3d(), prefixes = "", accumulate = FALSE, ...) { .Deprecated("subsetControl") propertySlider(subsetSetter(subsets, fullset = fullset, subscenes = subscenes, prefixes = prefixes, accumulate = accumulate), labels = labels, ...) } subsetSetter <- function(subsets, subscenes = currentSubscene3d(), prefixes = "", fullset = Reduce(union, subsets), accumulate = FALSE) { .Deprecated("subsetControl") nsubs <- max(length(subscenes), length(prefixes)) subscenes <- rep(subscenes, length.out = nsubs) prefixes <- rep(prefixes, length.out = nsubs) result <- subst( 'function(value) { var i, ids = [%vals%], fullset = [%fullset%], entries, f = function(x) { return fullset.indexOf(x) < 0; }; value = Math.round(value);', vals = paste(paste0("[", sapply(subsets, function(i) paste(i, collapse=",")), "]"), collapse=","), fullset = paste(fullset, collapse=",")) for (i in seq_len(nsubs)) result <- c(result, subst( ' if (typeof %prefix%rgl.getObj === "undefined") return; entries = %prefix%rgl.getObj(%subscene%).objects; entries = entries.filter(f);', prefix = prefixes[i], subscene = subscenes[i]), if (accumulate) ' for (i=0; i<=value; i++) entries = entries.concat(ids[i]);' else ' entries = entries.concat(ids[value]);', subst(' %prefix%rgl.setSubsceneEntries(entries, %subscene%);', prefix = prefixes[i], subscene = subscenes[i])) result <- c(result, '}') structure(paste(result, collapse = "\n"), param = seq_along(subsets) - 1, prefixes = prefixes, class = "propertySetter") } toggleButton <- function(subset, subscenes = currentSubscene3d(), prefixes = "", label = deparse(substitute(subset)), id = paste0(basename(tempfile("input"))), name = id) { .Deprecated("toggleWidget") nsubs <- max(length(subscenes), length(prefixes)) subscenes <- rep(subscenes, length.out = nsubs) prefixes <- rep(prefixes, length.out = nsubs) result <- subst( '', label)) cat(result, sep = "\n") invisible(id) } clipplaneSlider <- function(a=NULL, b=NULL, c=NULL, d=NULL, plane = 1, clipplaneids, prefixes = "", labels = signif(values[,1],3), ...) { .Deprecated("clipplaneControl") values <- cbind(a = a, b = b, c = c, d = d) col <- which(colnames(values) == letters[1:4]) - 1 propertySlider(values = values, entries = 4*(plane-1) + col, properties = "vClipplane", objids = clipplaneids, prefixes = prefixes, labels = labels, ...) } propertySlider <- function(setter = propertySetter, minS = NULL, maxS = NULL, step = 1, init = NULL, labels, id = basename(tempfile("input")), name = id, outputid = paste0(id, "text"), index = NULL, ...) { .Deprecated("propertyControl") displayVals <- function(x) { base <- signif(mean(x), 2) base + signif(x - base, 2) } if (!is.list(setter)) setters <- list(setter) else setters <- setter param <- numeric() prefixes <- character() for (i in seq_along(setters)) { setter <- setters[[i]] if (is.function(setter)) setters[i] <- setter <- setter(...) if (!inherits(setter, "propertySetter")) stop("'setter' must be a propertySetter object") param <- c(param, attr(setter, "param")) prefixes <- c(prefixes, attr(setter, "prefixes")) } prefix <- prefixes[1] if (is.null(minS)) minS <- min(param) if (is.null(maxS)) maxS <- max(param) if (is.null(init)) init <- minS sliderVals <- seq(minS, maxS, by = step) if (missing(labels)) labels <- displayVals(sliderVals) if (is.null(outputid) || is.null(labels)) outputfield <- setoutput <- "" else { outputfield <- subst('%label%', outputid, id, label = labels[round(init-minS)/step + 1]) setoutput <- subst(' label = document.getElementById(\'%outputid%\'); if (label !== null) label.value = labels[lvalue];', outputid) } # We don't want to respond to a change in the middle of a # previous response, but we don't want to lose it either. result <- subst( ' %outputfield%', prefix, id, setoutput, outputfield, minS, maxS, step, init, name, labels = paste0("'", labels, "'", collapse=","))) cat(result, sep="\n") invisible(id) } propertySetter <- function(values = NULL, entries, properties, objids, prefixes = "", param = seq_len(NROW(values)), interp = TRUE, digits = 7) { .Deprecated("propertyControl") direct <- is.null(values) ncol <- length(entries) if (direct) interp <- FALSE else { values <- matrix(values, NROW(values)) stopifnot(ncol(values) == ncol, all(diff(param) > 0)) } prefixes <- rep(prefixes, length.out = ncol) if (!ncol) return(structure("function(value) {}", param = param, prefixes = prefixes, class = "propertySetter")) properties <- rep(properties, length.out = ncol) objids <- rep(objids, length.out = ncol) prefix <- prefixes[1] property <- properties[1] objid <- objids[1] if (interp) values <- rbind(values[1,], values, values[nrow(values),]) get <- if (grepl("^par3d\\.userMatrix", property)) ".getAsArray()" else "" load <- if (grepl("^par3d\\.userMatrix", property)) ".load(propvals)" else "= propvals" result <- c( 'function(value) {', if (!direct) subst( ' var values = [%vals%],', vals = paste(formatC(as.vector(t(values)), digits = digits, width = 1), collapse = ",")), subst( ' propvals = %prefix%rgl.getObj(%objid%).%property%%get%;', prefix, property, objid, get), if (interp) subst( ' var svals = [-Infinity, %svals%, Infinity], v1, v2; for (var i = 1; i < svals.length; i++) if (value <= svals[i]) { var p = (svals[i] - value)/(svals[i] - svals[i-1]);', svals = paste(formatC(param, digits = digits, width = 1), collapse = ",")) else if (!direct) ' value = Math.round(value);') for (j in seq_along(entries)) { newprefix <- prefixes[j] newprop <- properties[j] newget <- if (grepl("^par3d\\.userMatrix", newprop)) ".getAsArray()" else "" newload <- if (grepl("^par3d\\.userMatrix", newprop)) ".load(propvals)" else " = propvals" newid <- objids[j] multiplier <- ifelse(ncol>1, paste0(ncol, "*"), "") offset <- ifelse(j>1, paste0("+", j-1), "") result <- c(result, if (newprefix != prefix || newprop != property || newid != objid) subst( ' %prefix%rgl.getObj(%objid%).%property%%load%; propvals = %newprefix%rgl.getObj(%objid%).%newprop%%newget%;', prefix, property, objid, load, newget, newprefix, newprop, newid), if (interp) subst( ' v1 = values[%multiplier%(i-1)%offset%]; v2 = values[%multiplier%i%offset%]; propvals[%entry%] = p*v1 + (1-p)*v2;', entry=entries[j], multiplier, offset) else if (!direct) subst( ' propvals[%entry%] = values[%multiplier%value%offset%];', entry = entries[j], multiplier, offset) else if (ncol == 1) subst( ' propvals[%entry%] = value;', entry = entries[j], jm1 = j - 1) else subst( ' propvals[%entry%] = value[%jm1%];', entry = entries[j], jm1 = j - 1)) prefix <- newprefix property <- newprop objid <- newid get <- newget load <- newload } result <- c(result, if (interp) ' break; }', subst( ' %prefix%rgl.getObj(%objid%).%property%%load%;', prefix, property, objid, load)) needsBinding <- unique(data.frame(prefixes, objids)[properties == "values",]) if (nrow(needsBinding)) result <- c(result, ' var gl;') for (i in seq_len(nrow(needsBinding))) { prefix <- needsBinding[i, 1] objid <- needsBinding[i, 2] result <- c(result, subst( ' if (typeof %prefix%rgl.getObj(%objid%).buf !== "undefined") { gl = %prefix%rgl.gl; gl.bindBuffer(gl.ARRAY_BUFFER, %prefix%rgl.getObj(%objid%).buf); gl.bufferData(gl.ARRAY_BUFFER, %prefix%rgl.getObj(%objid%).values, gl.STATIC_DRAW); }', prefix, objid)) } result <- c(result, '}') result <- structure(paste(result, collapse = "\n"), prefixes = prefixes, class = "propertySetter") if (!direct) attr(result, "param") <- param result } vertexSetter <- function(values = NULL, vertices = 1, attributes, objid, prefix = "", param = seq_len(NROW(values)), interp = TRUE, digits = 7) { .Deprecated("vertexControl") attribofs <- c(x = 'vofs', y = 'vofs', z = 'vofs', r = 'cofs', g = 'cofs', b = 'cofs', a = 'cofs', nx = 'nofs', ny = 'nofs', nz = 'nofs', radius = 'radofs', ox = 'oofs', oy = 'oofs', oz = 'oofs', ts = 'tofs', tt = 'tofs') attribofsofs <- structure(c(0:2, 0:3, 0:2, 0, 0:2, 0:1), names = names(attribofs)) direct <- is.null(values) ncol <- max(if (is.matrix(values)) ncol(values), length(vertices), length(attributes)) if (direct) interp <- FALSE else { values <- matrix(values, NROW(values)) stopifnot(ncol(values) == ncol, all(diff(param) > 0)) } attributes <- match.arg(attributes, names(attribofs), several.ok = TRUE) stopifnot(length(objid) == 1, length(prefix) == 1, all(attributes %in% names(attribofs)), all(diff(param) > 0)) vertices <- rep(vertices, length.out = ncol) attributes <- rep(attributes, length.out = ncol) if (!ncol) return(structure("function(value) {}", param = param, prefixes = prefix, class = c("vertexSetter", "propertySetter"))) if (interp) values <- rbind(values[1,], values, values[nrow(values),]) result <- c( 'function(value) {', if (direct) ' var ofs;' else subst( ' var ofs, values = [%vals%],', vals = paste(formatC(as.vector(t(values)), digits = digits, width = 1), collapse = ",")), subst( ' propvals = %prefix%rgl.getObj(%objid%).values, stride = %prefix%rgl.getObj(%objid%).vOffsets.stride;', prefix, objid), if (interp) subst( ' var p, v1, v2, svals = [-Infinity, %svals%, Infinity]; for (var i = 1; i < svals.length; i++) if (value <= svals[i]) { p = (svals[i] - value)/(svals[i] - svals[i-1]);', svals = paste(formatC(param, digits = digits, width = 1), collapse = ",")) else if (!direct) ' value = Math.round(value);') for (j in seq_along(vertices)) { multiplier <- ifelse(ncol>1, paste0(ncol, "*"), "") offset <- ifelse(j>1, paste0("+", j-1), "") entry <- ifelse(vertices[j] == 1, 'ofs', subst('%vertexm1%*stride + ofs', vertexm1 = vertices[j]-1)) result <- c(result, subst( ' ofs = %prefix%rgl.getObj(%objid%).vOffsets.%attribofs%; if (ofs < 0) alert("Attribute %attribute% not found in object %objid%");', prefix, objid, attribofs = attribofs[attributes[j]], attribute = attributes[j]), if (attribofsofs[attributes[j]] > 0) subst( ' ofs = ofs + %attribofsofs%;', attribofsofs = attribofsofs[attributes[j]]), if (interp) subst( ' v1 = values[%multiplier%(i-1)%offset%]; v2 = values[%multiplier%i%offset%]; propvals[%entry%] = p*v1 + (1-p)*v2;', entry, multiplier, offset) else if (!direct) subst( ' propvals[%entry%] = values[%multiplier%value%offset%];', entry, multiplier, offset) else if (ncol == 1) subst( ' propvals[%entry%] = value;', entry) else subst( ' propvals[%entry%] = value[%jm1%];', entry, jm1 = j - 1)) } result <- c(result, if (interp) ' break; }', subst( ' %prefix%rgl.getObj(%objid%).values = propvals; if (typeof %prefix%rgl.getObj(%objid%).buf !== "undefined") { var gl = %prefix%rgl.gl; gl.bindBuffer(gl.ARRAY_BUFFER, %prefix%rgl.getObj(%objid%).buf); gl.bufferData(gl.ARRAY_BUFFER, %prefix%rgl.getObj(%objid%).values, gl.STATIC_DRAW); }', prefix, objid)) result <- c(result, '}') structure(paste(result, collapse = "\n"), param = param, prefixes = prefix, class = c("vertexSetter", "propertySetter")) } par3dinterpSetter <- function(fn, from, to, steps, subscene = NULL, omitConstant = TRUE, rename = character(), ...) { .Deprecated("par3dinterpControl") times <- seq(from, to, length.out = steps+1) fvals <- lapply(times, fn) f0 <- fvals[[1]] entries <- numeric(0) properties <- character(0) values <- NULL props <- c("FOV", "userMatrix", "scale", "zoom") for(i in seq_along(props)) { prop <- props[i] propname <- rename[prop] if (is.na(propname)) propname <- prop if (!is.null(value <- f0[[prop]])) { newvals <- sapply(fvals, function(e) as.numeric(e[[prop]])) if (is.matrix(newvals)) newvals <- t(newvals) rows <- NROW(newvals) cols <- NCOL(newvals) stopifnot(rows == length(fvals)) entries <- c(entries, seq_len(cols)-1) properties <- c(properties, rep(propname, cols)) values <- cbind(values, newvals) } } if (omitConstant) keep <- apply(values, 2, var) > 0 else keep <- TRUE if (is.null(subscene)) subscene <- f0$subscene propertySetter(values = values[,keep], entries = entries[keep], properties = paste0("par3d.", properties[keep]), objids = subscene, param = times, ...) } matrixSetter <- function(fns, from, to, steps, subscene = currentSubscene3d(), matrix = "userMatrix", omitConstant = TRUE, prefix = "", ...) { .Deprecated("par3dinterpControl") n <- length(fns) from <- rep(from, length.out = n) to <- rep(to, length.out = n) steps <- rep(steps, length.out = n) settername <- basename(tempfile("fn", "")) propname <- paste0("userMatrix", settername) # Needs to match "^userMatrix" regexp param <- numeric() result <- subst( '%prefix%rgl.%settername% = function(value, index) { var fns = new Array();', prefix, settername) for (i in seq_len(n)) { setter <- par3dinterpSetter(fns[[i]], from[i], to[i], steps[i], omitConstant = TRUE, subscene = i-1, prefixes = prefix, rename = c(userMatrix = propname), ...) result <- c(result, subst( ' fns[%i%] = ', i=i-1), setter) param <- c(param, attr(setter, "param")) } result <- c(result, ' fns[index](value); var newmatrix = new CanvasMatrix4();', paste0(subst( ' newmatrix.multLeft(%prefix%rgl.%propname%[', prefix, propname), 0:(n-1), ']);'), subst( ' %prefix%rgl.%matrix%[%subscene%].load(newmatrix); } %prefix%rgl.%propname% = new Array();', prefix, subscene, propname, matrix), paste0(subst( ' %prefix%rgl.%propname%[', prefix, propname), 0:(n-1), '] = new CanvasMatrix4();')) structure(paste(result, collapse="\n"), param = sort(unique(param)), prefixes = prefix, name = subst('%prefix%rgl.%settername%', prefix, settername), class = c("matrixSetter", "indexedSetter", "propertySetter")) } print.indexedSetter <- function(x, inScript = FALSE, ...) { if (!inScript) cat("") } ageSetter <- function(births, ages, colors = NULL, alpha = NULL, radii = NULL, vertices = NULL, normals = NULL, origins = NULL, texcoords = NULL, objids, prefixes = "", digits = 7, param = seq(floor(min(births)), ceiling(max(births)))) { .Deprecated("ageControl") formatVec <- function(vec) { vec <- t(vec) result <- formatC(vec, digits = digits, width = 1) result[vec == Inf] <- "Infinity" result[vec == -Inf] <- "-Infinity" paste(result, collapse = ",") } if (!is.null(colors)) colors <- t(col2rgb(colors))/255 lengths <- c(colors = NROW(colors), alpha = length(alpha), radii = length(radii), vertices = NROW(vertices), normals = NROW(normals), origins = NROW(origins), texcoords = NROW(texcoords)) lengths <- lengths[lengths > 0] attribs <- names(lengths) n <- unique(lengths) stopifnot(length(n) == 1, n == length(ages), all(diff(ages) >= 0)) nobjs <- max(length(objids), length(prefixes)) prefixes <- rep(prefixes, length.out = nobjs) objids <- rep(objids, length.out = nobjs) result <- subst( ' function(time) { var ages = [-Infinity, %ages%, Infinity], births = [%births%], j = new Array(births.length), p = new Array(births.length), i, age, j0, propvals, stride, ofs;', ages = formatVec(ages), births = formatVec(births)) rows <- c(1,1:n, n) if ("colors" %in% attribs) result <- c(result, subst( ' var colors = [%values%];', values = formatVec(colors[rows,]))) if ("alpha" %in% attribs) result <- c(result, subst( ' var alpha = [%values%];', values = formatVec(alpha[rows]))) if ("radii" %in% attribs) result <- c(result, subst( ' var radii = [%values%];', values = formatVec(radii[rows]))) if ("vertices" %in% attribs) { stopifnot(ncol(vertices) == 3) result <- c(result, subst( ' var vertices = [%values%];', values = formatVec(vertices[rows,]))) } if ("normals" %in% attribs) { stopifnot(ncol(normals) == 3) result <- c(result, subst( ' var normals = [%values%];', values = formatVec(normals[rows,]))) } if ("origins" %in% attribs) { stopifnot(ncol(origins) == 2) result <- c(result, subst( ' var origins = [%values%];', values = formatVec(origins[rows,]))) } if ("texcoords" %in% attribs) { stopifnot(ncol(texcoords) == 2) result <- c(result, subst( ' var texcoords = [%values%];', values = formatVec(texcoords[rows,]))) } result <- c(result, ' for (i = 0; i < births.length; i++) { age = time - births[i]; for (j0 = 1; age > ages[j0]; j0++); if (ages[j0] == Infinity) p[i] = 1; else if (ages[j0] > ages[j0-1]) p[i] = (ages[j0] - age)/(ages[j0] - ages[j0-1]); else p[i] = 0; j[i] = j0; }') for (j in seq_len(nobjs)) { prefix <- prefixes[j] objid <- objids[j] result <- c(result, subst( ' propvals = %prefix%rgl.getObj(%objid%).values; stride = %prefix%rgl.getObj(%objid%).vOffsets.stride;', prefix, objid)) for (a in attribs) { ofs <- c(colors = "cofs", alpha = "cofs", radii = "radofs", vertices = "vofs", normals = "nofs", origins = "oofs", texcoords = "tofs")[a] result <- c(result, subst( ' ofs = %prefix%rgl.getObj(%objid%).vOffsets.%ofs%; if (ofs >= 0) { for (i = 0; i < births.length; i++) {', prefix, objid, ofs)) dim <- c(colors = 3, alpha = 1, radii = 1, vertices = 3, normals = 3, origins = 2, texcoords = 2)[a] if (dim > 1) for (d in seq_len(dim) - 1) result <- c(result, subst( ' propvals[i*stride + ofs + %d1%] = p[i]*%a%[%dim%*(j[i]-1) + %d2%] + (1-p[i])*%a%[%dim%*j[i] + %d2%];', dim, d1 = if (a == "alpha") 3 else d, d2 = d, a)) else result <- c(result, subst( ' propvals[i*stride + ofs%alphaofs%] = p[i]*%a%[j[i]-1] + (1-p[i])*%a%[j[i]];', a, alphaofs = if (a == "alpha") " + 3" else "")) result <- c(result, subst( ' } } else alert("\'%a%\' property not found in object %objid%");', a, objid)) } result <- c(result, subst( ' %prefix%rgl.getObj(%objid%).values = propvals; if (typeof %prefix%rgl.getObj(%objid%).buf !== "undefined") { var gl = %prefix%rgl.gl; gl.bindBuffer(gl.ARRAY_BUFFER, %prefix%rgl.getObj(%objid%).buf); gl.bufferData(gl.ARRAY_BUFFER, %prefix%rgl.getObj(%objid%).values, gl.STATIC_DRAW); }', prefix, objid)) } result <- c(result, ' }') structure(paste(result, collapse = "\n"), param = param, prefixes = prefixes, class = c("ageSetter", "propertySetter")) } rgl/R/selectpoints3d.R0000644000176200001440000000344714100762640014335 0ustar liggesusersselectpoints3d <- function(objects = ids3d()$id, value = TRUE, closest = TRUE, multiple = FALSE, ...) { if (value) result <- cbind(x = numeric(0), y = numeric(0), z = numeric(0)) else result <- cbind(id = integer(0), index = integer(0)) rdist <- I first <- TRUE while (first || is.function(multiple) || multiple) { f <- select3d(...) if (is.null(f)) break e <- environment(f) dist <- Inf prev <- nrow(result) for (id in objects) { verts <- rgl.attrib(id, "vertices") hits <- f(verts) if (any(hits)) dist <- 0 else if (closest && dist > 0 && nrow(verts)) { wincoords <- rgl.user2window(verts, projection = e$proj) wz <- wincoords[,3] keep <- (0 <= wz) && (wz <= 1) wincoords <- wincoords[keep,,drop=FALSE] if (!nrow(wincoords)) next wx <- wincoords[,1] xdist <- ifelse(wx < e$llx, (wx-e$llx)^2, ifelse(wx < e$urx, 0, (wx-e$urx)^2)) wy <- wincoords[,2] ydist <- ifelse(wy < e$lly, (wy-e$lly)^2, ifelse(wy < e$ury, 0, (wy-e$ury)^2)) dists <- xdist + ydist hits <- (dists < dist) & (dists == min(dists)) dist <- min(c(dist, dists)) } if (!any(hits)) next if (prev && nrow(result) > prev && rdist > dist) result <- result[seq_len(prev),,drop=FALSE] if (value) result <- rbind(result, verts[hits,]) else result <- rbind(result, cbind(id, which(hits))) if (is.function(multiple) && nrow(result) > prev && !multiple(result[(prev+1):nrow(result),,drop=FALSE])) break rdist <- dist first <- FALSE } if (value) result <- unique(result) } result } rgl/R/pkgchecks.R0000644000176200001440000000055414145464133013335 0ustar liggesusers# Suggested package checks checkDeldir <- function(error = FALSE) { result <- requireNamespace("deldir", quietly = TRUE) && (packageVersion("deldir") < "1.0.2" || packageVersion("deldir") >= "1.0.4") if (error && !result) stop("This function requires the 'deldir' package (but is not compatible with version 1.0-2).", call. = FALSE) result } rgl/R/ply.R0000644000176200001440000002405014145464133012174 0ustar liggesuserswritePLY <- function(con, format=c("little_endian", "big_endian", "ascii"), pointRadius=0.005, pointShape = icosahedron3d(), lineRadius = pointRadius, lineSides = 20, pointsAsEdges = FALSE, linesAsEdges = pointsAsEdges, withColors = TRUE, withNormals = !(pointsAsEdges || linesAsEdges), ids = tagged3d(tags), tags = NULL) { writeData <- function() { cat("ply\n", file=con) fmt <- switch(format, little_endian = "binary_little_endian", big_endian = "binary_big_endian", ascii = "ascii") cat("format", fmt, "1.0\n", file=con) cat("element vertex", nrow(Vertices), "\n", file=con) cat("property float x property float y property float z\n", file=con) if (withColors) cat("property float red property float green property float blue property float alpha\n", file=con) if (withNormals) cat("property float nx property float ny property float nz\n", file=con) cat("element face", nrow(Triangles)+nrow(Quads), "\n", file=con) cat("property list int int vertex_indices\n", file=con) if (nrow(Edges) > 0) { cat("element edge", nrow(Edges), "\n", file=con) cat("property int vertex1 property int vertex2\n", file=con) } cat("end_header\n", file=con) if (format == "ascii") { for (i in seq_len(nrow(Vertices))) cat(Vertices[i,], "\n", file=con) for (i in seq_len(nrow(Triangles))) cat("3", Triangles[i,], "\n", file=con) for (i in seq_len(nrow(Quads))) cat("4", Quads[i,], "\n", file=con) for (i in seq_len(nrow(Edges))) cat(Edges[i,], "\n", file=con) } else { endian <- if (format == "little_endian") "little" else "big" if (nrow(Vertices)) writeBin(as.numeric(t(Vertices)), con, size=4, endian=endian) if (nrow(Triangles)) writeBin(as.integer(t(cbind(3L, Triangles))), con, size=4, endian=endian) if (nrow(Quads)) writeBin(as.integer(t(cbind(4L, Quads))), con, size=4, endian=endian) if (nrow(Edges)) writeBin(as.integer(t(Edges)), con, size=4, endian=endian) } } Vertices <- matrix(0, 0, 3 + 4*withColors + 3*withNormals) Triangles <- matrix(1L, 0, 3) Quads <- matrix(1L, 0, 4) Edges <- matrix(1L, 0, 2) getVertices <- function(id) { vertices <- rgl.attrib(id, "vertices") if (withColors) { colors <- rgl.attrib(id, "colors") if (nrow(colors) == 1) colors <- colors[rep(1, nrow(vertices)),, drop = FALSE] } if (withNormals) { normals <- rgl.attrib(id, "normals") if (!nrow(normals)) normals <- 0*vertices } cbind(vertices, if (withColors) 255*colors, if (withNormals) normals) } writeTriangles <- function(id) { vertices <- getVertices(id) n <- nrow(vertices) base <- nrow(Vertices) Vertices <<- rbind(Vertices, vertices) Triangles <<- rbind(Triangles, matrix(base + seq_len(n) - 1, ncol=3, byrow=TRUE)) } writeQuads <- function(id) { vertices <- getVertices(id) n <- nrow(vertices) base <- nrow(Vertices) Vertices <<- rbind(Vertices, vertices) Quads <<- rbind(Quads, matrix(base + seq_len(n) - 1, ncol=4, byrow=TRUE)) } writeSurface <- function(id) { vertices <- getVertices(id) dims <- rgl.attrib(id, "dim") nx <- dims[1] nz <- dims[2] base <- nrow(Vertices) Vertices <<- rbind(Vertices, vertices) rows <- seq_len(nx) for (i in seq_len(nz)[-nz]) Triangles <<- rbind(Triangles, matrix(base + (i-1)*nx + c(rows[-nx],rows[-nx], rows[-1]+nx,rows[-nx]+nx, rows[-1],rows[-1]+nx) - 1, ncol=3)) } writeMesh <- function(mesh, scale=1, offset=c(0,0,0)) { vertices <- asEuclidean(t(mesh$vb))*scale vertices <- vertices + rep(offset, each=nrow(vertices)) if (withColors) { colors <- mesh$material$col if (!length(colors)) colors <- material3d("color") colors <- rep(colors, length=nrow(vertices)) colors <- t(col2rgb(colors, alpha=TRUE)) } if (withNormals) normals <- asEuclidean(t(mesh$normals)) base <- nrow(Vertices) Vertices <<- rbind(Vertices, cbind(vertices, if (withColors) colors, if (withNormals) normals)) nt <- length(mesh$it)/3 nq <- length(mesh$ib)/4 if (nt) Triangles <<- rbind(Triangles, t(mesh$it) - 1 + base) if (nq) Quads <<- rbind(Quads, t(mesh$ib) - 1 + base) } writeSpheres <- function(id) { vertices <- rgl.attrib(id, "vertices") n <- nrow(vertices) colors <- rgl.attrib(id, "colors") if (nrow(colors) == 1) colors <- colors[rep(1, n),, drop = FALSE] radii <- rgl.attrib(id, "radii") radii <- rep(radii, length.out=n) x <- subdivision3d(icosahedron3d(),3) r <- sqrt(x$vb[1,]^2 + x$vb[2,]^2 + x$vb[3,]^2) x$vb[4,] <- r x$normals <- x$vb for (i in seq_len(n)) { col <- colors[i,] x$material$col <- rgb(col[1], col[2], col[3], col[4], maxColorValue = 255) writeMesh(x, radii[i], vertices[i,]) } } avgScale <- function() { bbox <- par3d("bbox") ranges <- c(bbox[2]-bbox[1], bbox[4]-bbox[3], bbox[6]-bbox[5]) if (prod(ranges) == 0) 1 else exp(mean(log(ranges))) } writePoints <- function(id) { vertices <- getVertices(id) n <- nrow(vertices) inds <- seq_len(n) if (pointsAsEdges) { base <- nrow(Vertices) Vertices <<- rbind(Vertices, vertices) Edges <<- rbind(Edges, base + cbind(inds, inds) - 1 ) } else { radius <- pointRadius*avgScale() if (withNormals && is.null(pointShape$normals)) pointShape <- addNormals(pointShape) for (i in inds) { if (withColors) { col <- vertices[i,4:7] pointShape$material$col <- rgb(col[1], col[2], col[3], col[4], maxColorValue = 255) } writeMesh(pointShape, radius, vertices[i,1:3]) } } } writeSegments <- function(id) { vertices <- getVertices(id) if (withColors) { colors <- vertices[, 4:7, drop=FALSE] vertices <- vertices[, 1:3, drop=FALSE] } n <- nrow(vertices) n <- n/2 inds <- seq_len(n) if (linesAsEdges) { base <- nrow(Vertices) Vertices <<- rbind(Vertices, vertices) Edges <<- rbind(Edges, base + cbind(2*inds - 2, 2*inds - 1) ) } else { radius <- lineRadius*avgScale() for (i in seq_len(n)) { cyl <- cylinder3d( vertices[(2*i-1):(2*i),1:3], radius = radius, sides = lineSides, closed = -2 ) if (withColors) { col1 <- colors[2*i-1,] col1 <- rgb(col1[1], col1[2], col1[3], col1[4], maxColorValue = 255) col2 <- colors[2*i,] col2 <- rgb(col2[1], col2[2], col2[3], col2[4], maxColorValue = 255) cyl$material$col <- c(rep(col1, lineSides), rep(col2, lineSides), col1, col2) } if (withNormals) cyl <- addNormals(cyl) writeMesh(cyl) } } } writeLines <- function(id) { vertices <- getVertices(id) if (linesAsEdges) { n <- nrow(vertices) inds <- seq_len(n) base <- nrow(Vertices) Vertices <<- rbind(Vertices, vertices) Edges <<- rbind(Edges, base + cbind(inds[-n], inds[-1]) - 1) } else { n <- nrow(vertices) - 1 radius <- lineRadius*avgScale() for (i in seq_len(n)) { cyl <- cylinder3d( vertices[i:(i+1),1:3], radius = radius, sides = lineSides, closed = -2 ) if (withColors) { colors <- vertices[i, 4:7] col1 <- colors[i,] col1 <- rgb(col1[1], col1[2], col1[3], col1[4], maxColorValue = 255) col2 <- colors[i+1,] col2 <- rgb(col2[1], col2[2], col2[3], col2[4], maxColorValue = 255) cyl$material$col <- c(rep(col1, lineSides), rep(col2, lineSides), col1, col2) } if (withNormals) cyl <- addNormals(cyl) writeMesh(cyl) } } } knowntypes <- c("triangles", "quads", "surface", "spheres", "linestrip", "lines", "planes", "points") # Execution starts here! format <- match.arg(format) if (is.character(con)) { con <- file(con, if (format=="ascii") "w" else "wb") on.exit(close(con)) } filename <- summary(con)$description if (NROW(bbox <- ids3d("bboxdeco")) && (is.null(ids) || bbox$id %in% ids)) { ids <- setdiff(ids, bbox$id) save <- par3d(skipRedraw = TRUE) bbox <- convertBBox(bbox$id) on.exit({ pop3d(id=bbox); par3d(save) }, add=TRUE) # nolint dobbox <- TRUE } else dobbox <- FALSE if (is.null(ids)) { ids <- ids3d() types <- as.character(ids$type) ids <- ids$id } else { if (dobbox) ids <- c(ids, bbox) allids <- ids3d() ind <- match(ids, allids$id) keep <- !is.na(ind) if (any(!keep)) warning(gettextf("Object(s) with id %s not found", paste(ids[!keep], collapse=" ")), domain = NA) ids <- ids[keep] types <- allids$type[ind[keep]] } unknowntypes <- setdiff(types, knowntypes) if (length(unknowntypes)) warning(gettextf("Object type(s) %s not handled", paste("'", unknowntypes, "'", sep="", collapse=", ")), domain = NA) keep <- types %in% knowntypes ids <- ids[keep] types <- types[keep] for (i in seq_along(ids)) switch(types[i], planes =, triangles = writeTriangles(ids[i]), quads = writeQuads(ids[i]), surface = writeSurface(ids[i]), spheres = writeSpheres(ids[i]), points = writePoints(ids[i]), lines = writeSegments(ids[i]), linestrip = writeLines(ids[i]) ) writeData() invisible(filename) } rgl/R/merge.mesh3d.R0000644000176200001440000000624114100762640013646 0ustar liggesusersmerge.mesh3d <- function(x, y, ..., attributesMustMatch = FALSE) { fixmesh <- function(m) { stopifnot(inherits(m, "mesh3d")) if (nrow(m$vb) == 3) m$vb <- rbind(m$vb, 1) if (!length(m$ip)) m$ip <- matrix(numeric(), nrow=1, ncol=0) if (!length(m$is)) m$is <- matrix(numeric(), nrow=2, ncol=0) if (!length(m$it)) m$it <- matrix(numeric(), nrow=3, ncol=0) if (!length(m$ib)) m$ib <- matrix(numeric(), nrow=4, ncol=0) if (!is.null(m$normals) && nrow(m$normals) == 3) m$normals <- rbind(m$normals, 1) if (is.null(m$meshColor)) m$meshColor <- "vertices" if (!is.null(m$material)) { n <- ncol(m$vb) if (length(m$material$color) == 1) m$material$color <- rep(m$material$color, n) if (length(m$material$alpha) == 1) m$material$alpha <- rep(m$material$alpha, n) } else m$material <- list() m } z <- fixmesh(x) ylist <- list(...) if (!missing(y)) ylist <- c(list(y), ylist) for (i in seq_along(ylist)) { x <- z y <- fixmesh(ylist[[i]]) if (!attributesMustMatch) { common <- intersect(names(x), names(y)) x <- x[common] y <- y[common] } stopifnot(is.null(x$normals) == is.null(y$normals), is.null(x$texcoords) == is.null(y$texcoords), is.null(x$values) == is.null(y$values)) stopifnot(x$meshColor == y$meshColor) nx <- ncol(x$vb) z <- list(vb = cbind(x$vb, y$vb), ip = if (length(x$ip) || length(y$ip)) cbind(x$ip, y$ip + nx), is = if (length(x$is) || length(y$is)) cbind(x$is, y$is + nx), it = if (length(x$it) || length(y$it)) cbind(x$it, y$it + nx), ib = if (length(x$ib) || length(y$ib)) cbind(x$ib, y$ib + nx), normals = cbind(x$normals, y$normals), texcoords = cbind(x$texcoords, y$texcoords), values = c(x$values, y$values), meshColor = x$meshColor) if (!attributesMustMatch) { common <- intersect(names(x$material), names(y$material)) x$material <- x$material[common] y$material <- y$material[common] for (n in common) { if (!(n %in% c("color", "alpha")) && !identical(x$material[[n]], y$material[[n]])) x$material[[n]] <- NULL } } else { stopifnot(setequal(names(x$material), names(y$material))) for (n in names(x$material)) if (!identical(x$material[[n]], y$material[[n]])) stop("Material ", n, " values don't match") } z$material <- x$material z$material$color <- c(x$material$color, y$material$color) z$material$alpha <- c(x$material$alpha, y$material$alpha) class(z) <- "mesh3d" } if (!is.null(z$material)) { if (length(unique(z$material$color)) == 1) z$material$color <- z$material$color[1] if (length(unique(z$material$alpha)) == 1) z$material$alpha <- z$material$alpha[1] } if (!length(z$material$color)) z$material$color <- NULL if (!length(z$material)) z$material <- NULL if (!length(z$ip)) z$ip <- NULL if (!length(z$is)) z$is <- NULL if (!length(z$it)) z$it <- NULL if (!length(z$ib)) z$ib <- NULL z } rgl/R/noOpenGL.R.in0000644000176200001440000000014514100762640013450 0ustar liggesusers# The RGL_NO_OPENGL setting is TRUE if configured with --disable-opengl noOpenGL <- @RGL_NO_OPENGL@ rgl/R/convertScene.R0000644000176200001440000003432714146202555014035 0ustar liggesusers convertScene <- function(x = scene3d(minimal), width = NULL, height = NULL, elementId = NULL, minimal = TRUE, webgl = TRUE, snapshot = FALSE, oldConvertBBox = FALSE) { # Lots of utility functions and constants defined first; execution starts way down there... getObj <- function(id) { result$objects[[as.character(id)]] } setObj <- function(id, newval) { result$objects[[as.character(id)]] <<- newval } getIdsByType <- function(type, subscene = NULL) { if (is.null(subscene)) ids <- vapply(result$objects, function(x) if (x$type == type) x$id else NA, numeric(1)) else { ids <- vapply(getObj(subscene)$objects, function(x) { obj <- getObj(x) if (obj$type == type) obj$id else NA }, numeric(1)) } ids[!is.na(ids)] } getMaterial <- function(id) { default <- result$material obj <- getObj(id) mat <- obj$material missing <- setdiff(names(default), names(mat)) mat[missing] <- default[missing] mat } # This counts how many clipping planes might affect a particular object countClipplanes <- function(id, minValue = getOption("rgl.minClipplanes", 0)) { recurse <- function(subscene) { count <- 0 ids <- getIdsByType("clipplanes", subscene) for (clipid in ids) count <- count + nrow(getObj(clipid)$normals) subscenes <- getIdsByType("subscene", subscene) for (sub in subscenes) { if (count >= bound) break count <- max(count, recurse(sub)) } count } ids <- getIdsByType("clipplanes") bound <- 0 for (i in seq_along(ids)) bound <- bound + nrow(getObj(ids[i])$normals) if (bound < minValue) return(minValue) max(minValue, recurse(result$rootSubscene)) } makeList <- function(x) { if (is.list(x)) x <- lapply(x, makeList) if (length(names(x))) x <- as.list(x) x } initResult <- function() { result <<- makeList(x) recurse <- function(subscene) { subscenes <- subscene$subscenes for (i in seq_along(subscenes)) { subscenes[[i]]$parent <- subscene$id subscenes[[i]] <- recurse(subscenes[[i]]) } if (length(subscenes)) { subscene$subscenes <- unlist(subscenes) subscene$objects <- c(subscene$objects, subscene$subscenes) } else subscene$subscenes <- numeric(0) setObj(subscene$id, subscene) subscene$id } result$rootSubscene <<- recurse(result$rootSubscene) if (snapshot) result$snapshot <- getSnapshot() } flagnames <- c("is_lit", "is_smooth", "has_texture", "depth_sort", "fixed_quads", "is_transparent", "is_lines", "sprites_3d", "is_subscene", "is_clipplanes", "fixed_size", "is_points", "is_twosided", "fat_lines", "is_brush", "has_fog") getFlags <- function(id) { obj <- getObj(id) if (is.null(obj)) { warning("object", id, " not found.") return(structure(rep(FALSE, length(flagnames)), names = flagnames)) } type <- obj$type if (type == "subscene") return(getSubsceneFlags(id)) result <- structure(rep(FALSE, length(flagnames)), names = flagnames) if (type == "clipplanes") { result["is_clipplanes"] <- TRUE return(result) } if (type == "light") return(result) result["is_transparent"] <- any(obj$colors[,"a"] < 1); # More later... mat <- getMaterial(id) result["is_lit"] <- mat$lit && type %in% c("triangles", "quads", "surface", "planes", "spheres", "sprites", "bboxdeco") result["is_smooth"] <- mat$smooth && type %in% c("triangles", "quads", "surface", "planes", "spheres") result["sprites_3d"] <- sprites_3d <- type == "sprites" && length(obj$ids) result["has_texture"] <- has_texture <- !is.null(mat$texture) && (!is.null(obj$texcoords) || (type == "sprites" && !sprites_3d)) result["is_transparent"] <- is_transparent <- (has_texture && mat$isTransparent) || result["is_transparent"] result["depth_sort"] <- depth_sort <- is_transparent && type %in% c("triangles", "quads", "surface", "spheres", "sprites", "text") result["fixed_quads"] <- type %in% c("text", "sprites") && !sprites_3d result["is_lines"] <- type %in% c("lines", "linestrip", "abclines") result["is_points"] <- type == "points" || "points" %in% c(mat$front, mat$back) result["is_twosided"] <- type %in% c("quads", "surface", "triangles", "spheres", "bboxdeco") && length(unique(c(mat$front, mat$back))) > 1 result["fixed_size"] <- type == "text" || isTRUE(obj$fixedSize) result["fat_lines"] <- mat$lwd != 1 && (result["is_lines"] || "lines" %in% unlist(mat[c("front", "back")])) result["is_brush"] <- !is.na(brushId) && id == brushId result["has_fog"] <- mat$fog result } getSubsceneFlags <- function(id) { result <- structure(rep(FALSE, length(flagnames)), names = flagnames) result["is_subscene"] <- TRUE objs <- getObj(id)$objects for (i in seq_along(objs)) result <- result | getFlags(objs[i]) return(result) } numericFlags <- function(flags) { if (is.matrix(flags)) n <- ncol(flags) else n <- length(flags) unname(flags %*% 2^(seq_len(n)-1)) } expandFlags <- function(numericflags) { result <- matrix(FALSE, nrow = length(numericflags), ncol = length(flagnames), dimnames = list(names(numericflags), flagnames)) for (i in seq_along(flagnames)) { result[,i] <- numericflags %% 2 == 1 numericflags <- numericflags %/% 2 } result } plotClipplanes <- function(subscene) { for (id in subscene$objects) { obj <- getObj(id) if (obj$type == "clipplanes") { class(obj) <- "rglobject" plot3d(obj) } else if (obj$type == "subscene") plotClipplanes(getObj(id)) } } convertBBox <- function(id, subscene) { obj <- getObj(id) verts <- obj$vertices text <- obj$texts if (!length(text)) text <- rep("", NROW(verts)) else text <- text[,"text"] mat <- getMaterial(id) if (length(mat$color) > 1) mat$color <- mat$color[2] # We ignore the "box" colour if(any(missing <- text == "")) text[missing] <- apply(verts[missing,], 1, function(row) format(row[!is.na(row)])) res <- numeric(0) bbox <- subscene$par3d$bbox repeat { # Need to make sure the ids here don't clash with those in the scene tempID <- points3d(bbox[1:2], bbox[3:4], bbox[5:6]) if (tempID > lastID) break else delFromSubscene3d(tempID) } lastID <<- tempID intersect <- function(limits, points) which(limits[1] <= points & points <= limits[2]) # plot the clipping planes as they affect the bounding box plotClipplanes(subscene) mat$front <- mat$back <- "fill" if (any(inds <- is.na(verts[,2]) & is.na(verts[,3])) && length(keep <- intersect(bbox[1:2], verts[inds, 1]))) res <- c(res, do.call(axis3d, c(list(edge = "x", at = verts[inds, 1][keep], labels = text[inds][keep]), mat))) if (any(inds <- is.na(verts[,1]) & is.na(verts[,3])) && length(keep <- intersect(bbox[3:4], verts[inds, 2]))) res <- c(res, do.call(axis3d, c(list(edge = "y", at = verts[inds, 2][keep], labels = text[inds][keep]), mat))) if (any(inds <- is.na(verts[,1]) & is.na(verts[,2])) && length(keep <- intersect(bbox[5:6], verts[inds, 3]))) res <- c(res, do.call(axis3d, c(list(edge = "z", at = verts[inds, 3][keep], labels = text[inds][keep]), mat))) res <- c(res, do.call(box3d, mat)) delFromSubscene3d(c(res, tempID)) res } convertBBoxes <- function(id) { if (!oldConvertBBox) return(NULL) ids <- origIds <- NULL id <- as.character(id) sub <- getObj(id) types <- vapply(sub$objects, function(x) getObj(x)$type, character(1)) names(types) <- as.character(sub$objects) if (length(bboxes <- names(types)[types == "bboxdeco"])) { for (i in bboxes) { newids <- convertBBox(i, sub) sub$objects <- c(sub$objects, as.numeric(newids)) setObj(id, sub) ids <- c(ids, newids) origIds <- c(origIds, rep(i, length(newids))) } } children <- sub$subscenes for (i in children) { childids <- convertBBoxes(i) ids <- c(ids, childids) origIds <- c(origIds, attr(childids, "origIds")) } if (length(origIds)) names(origIds) <- as.character(ids) if (is.null(ids)) ids else structure(ids, origIds = origIds) } createBrush <- function() { repeat { # Need to make sure the id doesn't clash with those in the scene tempID <- lines3d(x = c(0, 1, 1, 0, 0), y = c(0, 0, 1, 1, 0), z = rep(-.999, 5), depth_test = "always", lit = FALSE, alpha = 0.5) if (tempID > lastID) break else delFromSubscene3d(tempID) } lastID <<- tempID } getSnapshot <- function() knitr::include_graphics(snapshot3d(scene = x, width = width, height = height)) knowntypes <- c("points", "linestrip", "lines", "triangles", "quads", "surface", "text", "abclines", "planes", "spheres", "sprites", "clipplanes", "light", "background", "bboxdeco", "subscene") # Execution starts here! # Do a few checks first if (!webgl) return(getSnapshot()) if (is.null(elementId)) elementId <- "" if (is.list(x$rootSubscene)) rect <- x$rootSubscene$par3d$windowRect else rect <- x$objects[[x$rootSubscene]]$par3d$windowRect rwidth <- rect[3] - rect[1] + 1 rheight <- rect[4] - rect[2] + 1 if (!length(width)) { if (!length(height)) { wfactor <- hfactor <- 1 # width = wfactor*rwidth, height = hfactor*rheight } else wfactor <- hfactor <- height/rheight } else { if (!length(height)) { wfactor <- hfactor <- width/rwidth } else { wfactor <- width/rwidth hfactor <- height/rheight } } width <- wfactor*rwidth height <- hfactor*rheight shared <- x$crosstalk$id result <- NULL initResult() result$width <- width result$height <- height types <- vapply(result$objects, function(x) x$type, character(1)) lastID <- max(vapply(result$objects, function(x) x$id, numeric(1))) if (any(types == "bboxdeco")) { saveNULL <- options(rgl.useNULL = TRUE) dev <- cur3d() open3d() ids <- convertBBoxes(result$rootSubscene) origIds <- attr(ids, "origIds") scene <- scene3d(minimal) temp <- lapply(as.character(ids), function(id) { x <- scene$objects[[id]] x$origId <- as.numeric(origIds[id]) x }) result$objects[as.character(ids)] <- temp for (id in unique(origIds)) result$objects[[as.character(id)]]$newIds <- as.numeric(ids[origIds == id]) types <- vapply(result$objects, function(x) x$type, character(1)) close3d() if (dev) set3d(dev) options(saveNULL) } if (length(shared)) { saveNULL <- options(rgl.useNULL = TRUE) dev <- cur3d() open3d() result$brushId <- brushId <- createBrush() brush <- as.character(result$brushId) scene <- scene3d(minimal) result$objects[[brush]] <- scene$objects[[brush]] close3d() if (dev) set3d(dev) options(saveNULL) } else brushId <- NA ids <- vapply(result$objects, function(x) x$id, numeric(1)) flags <- vapply(result$objects, function(obj) numericFlags(getFlags(obj$id)), numeric(1), USE.NAMES = FALSE) unknowntypes <- setdiff(types, knowntypes) if (length(unknowntypes)) warning(gettextf("Object type(s) %s not handled", paste("'", unknowntypes, "'", sep="", collapse=", ")), domain = NA) keep <- types %in% setdiff(knowntypes, c("light")) ids <- ids[keep] cids <- as.character(ids) nflags <- flags[keep] types <- types[keep] flags <- expandFlags(nflags) rownames(flags) <- cids fullviewport <- getObj(result$rootSubscene)$par3d$viewport for (i in seq_along(ids)) { obj <- getObj(cids[i]) obj$flags <- nflags[i] if (obj$type != "subscene") { texturefile <- "" if (!is.null(obj$material) && "texture" %in% names(obj$material)) texture <- obj$material$texture else texture <- result$material$texture if (!is.null(texture) && nchar(texture)) { texturefile <- texture obj$material$uri <- image_uri(texturefile) obj$material$texture <- NULL } if (!is.null(obj$material)) # Never use material$color obj$material$color <- NULL } else if (obj$type == "subscene") { obj$par3d$viewport$x <- obj$par3d$viewport$x/fullviewport$width obj$par3d$viewport$width <- obj$par3d$viewport$width/fullviewport$width obj$par3d$viewport$y <- obj$par3d$viewport$y/fullviewport$height obj$par3d$viewport$height <- obj$par3d$viewport$height/fullviewport$height } if (obj$type == "planes" && nrow(obj$vertices) > 3) { obj$vertices <- obj$vertices[1:3,] # These will be redone # in Javascript } else if (obj$type == "spheres") obj$centers <- obj$vertices if (!is.null(obj$material$margin)) { margin <- parseMargin(obj$material$margin, obj$material$floating) obj$material$margin <- margin$coord - 1 obj$material$floating <- margin$floating obj$material$edge <- margin$edge } setObj(cids[i], obj) } # Put the data into the buffer buffer <- Buffer$new() for (i in seq_along(ids)) { obj <- getObj(cids[i]) # This list needs to match the one in buffer.src.js for (n in c("vertices", "normals", "indices", "texcoords", "colors", "centers")) { if (!is.null(obj[[n]])) obj[[n]] <- as.character(buffer$addAccessor(t(obj[[n]]))) } setObj(cids[i], obj) } result$context <- list(shiny = inShiny(), rmarkdown = rmarkdownOutput()) buffer$closeBuffers() buf <- buffer$as.list() result$buffer <- buf result } rgl/R/r3d.rgl.R0000644000176200001440000003450314145464133012647 0ustar liggesusers# # R3D rendering functions - rgl implementation # # Node Management getr3dDefaults <- function(class = NULL, value = NULL) { result <- r3dDefaults if (exists("r3dDefaults", envir = globalenv())) { user <- get("r3dDefaults", envir=.GlobalEnv) for (n in names(user)) { if (is.list(result[[n]])) result[[n]][names(user[[n]])] <- user[[n]] else result[[n]] <- user[[n]] } } if (!is.null(class)) result <- result[[class]] if (!is.null(result) && !is.null(value)) result <- result[[value]] result } clear3d <- function(type = c("shapes", "bboxdeco", "material"), defaults=getr3dDefaults(), subscene = 0) { .check3d() rgl.clear( type, subscene = subscene ) type <- rgl.enum.nodetype(type) if ( 4 %in% type ) { # userviewpoint do.call("par3d", defaults["FOV"]) } if ( 8 %in% type ) { # modelviewpoint do.call("par3d", defaults["userMatrix"]) } if ( 5 %in% type ) { # material if (length(defaults$material)) do.call("material3d", defaults$material) } if ( 6 %in% type ) { # background do.call("bg3d", as.list(defaults$bg)) } } # Environment .material3d <- c("color", "alpha", "lit", "ambient", "specular", "emission", "shininess", "smooth", "front", "back", "size", "lwd", "fog", "point_antialias", "line_antialias", "texture", "textype", "texmipmap", "texminfilter", "texmagfilter", "texenvmap", "depth_mask", "depth_test", "isTransparent", "polygon_offset", "margin", "floating", "tag") .material3d.readOnly <- "isTransparent" # This function expands a list of arguments by putting # all entries from Params (i.e. the current settings by default) # in place for any entries that are not listed. # Unrecognized args are left in place. .fixMaterialArgs <- function(..., Params = material3d()) { f <- function(...) list(...) formals(f) <- c(Params, formals(f)) names <- as.list(names(Params)) names(names) <- names names <- lapply(names, as.name) b <- as.list(body(f)) body(f) <- as.call(c(b[1], names, b[-1])) f(...) } # This one just gets the material args # If warn is TRUE, give a warning instead of ignoring extras. .getMaterialArgs <- function(..., material = list(), warn = FALSE) { fullyNamed <- as.list(match.call(rgl.material, as.call(c(list(as.name("rgl.material"), ...), material))))[-1] good <- names(fullyNamed) %in% .material3d if (warn && !all(good)) warning("Argument(s) ", paste(names(fullyNamed)[!good], collapse = ", "), " not matched.") fullyNamed[good] } material3d <- function(...) { args <- list(...) argnames <- setdiff(names(args), .material3d.readOnly) if (!length(args)) argnames <- .material3d else { if (is.null(names(args)) && all(unlist(lapply(args, is.character)))) { argnames <- unlist(args) args <- NULL } if (length(args) == 1) { if (is.list(args[[1]]) | is.null(args[[1]])) { args <- args[[1]] argnames <- names(args) } } } value <- rgl.getmaterial()[argnames] if (length(args)) { args <- do.call(".fixMaterialArgs", args) do.call("rgl.material", args) return(invisible(value)) } else if (length(argnames) == 1) return(value[[1]]) else return(value) } bg3d <- function(...) { .check3d(); save <- material3d(); on.exit(material3d(save)) bgid <- ids3d("background")$id if (length(bgid) && nrow(flags <- rgl.attrib(bgid[1], "flags"))) { sphere <- flags["sphere", 1] fogtype <- if (flags["linear_fog", 1]) "linear" else if (flags["exp_fog", 1]) "exp" else if (flags["exp2_fog", 1]) "exp2" else "none" } else { sphere <- FALSE fogtype <- "none" } new <- .fixMaterialArgs(sphere = sphere, fogtype = fogtype, color = c("black", "white"), back = "lines", lit = FALSE, Params = save) do.call("rgl.bg", .fixMaterialArgs(..., Params = new)) } light3d <- function(theta=0,phi=15,x=NULL, ...) { .check3d() if (is.null(x)) rgl.light(theta=theta,phi=phi,x=x, ...) else rgl.light(x=x, ...) } view3d <- function(theta=0,phi=15,...) { .check3d() rgl.viewpoint(theta=theta,phi=phi,...) } bbox3d <- function(xat = NULL, yat = NULL, zat = NULL, xunit = "pretty", yunit = "pretty", zunit = "pretty", expand = 1.03, draw_front = FALSE, ...) { .check3d(); save <- material3d(); on.exit(material3d(save)) do.call("rgl.bbox", c(list(xat=xat, yat=yat, zat=zat, xunit=xunit, yunit=yunit, zunit=zunit, expand=expand, draw_front=draw_front), .fixMaterialArgs(..., Params = save))) } dummyBbox <- function() bbox3d(xat = numeric(), yat = numeric(), zat = numeric(), front = "cull", back = "cull") observer3d <- function(x, y=NULL, z=NULL, auto=FALSE) { if (missing(x)) location <- c(NA, NA, NA) else { xyz <- xyz.coords(x,y,z) location <- c(xyz$x, xyz$y, xyz$z) if (length(location) != 3) stop("A single point must be specified for the observer location") } prev <- .C(rgl_getObserver, success=integer(1), ddata=numeric(3), NAOK = TRUE)$ddata .C(rgl_setObserver, success=as.integer(auto), ddata=as.numeric(location), NAOK = TRUE) lowlevel(prev) } # Shapes points3d <- function(x,y=NULL,z=NULL,...) { .check3d(); save <- material3d(); on.exit(material3d(save)) do.call("rgl.points", c(list(x=x,y=y,z=z), .fixMaterialArgs(..., Params = save))) } lines3d <- function(x,y=NULL,z=NULL,...) { .check3d(); save <- material3d(); on.exit(material3d(save)) do.call("rgl.linestrips", c(list(x=x,y=y,z=z), .fixMaterialArgs(..., Params = save))) } segments3d <- function(x,y=NULL,z=NULL,...) { .check3d(); save <- material3d(); on.exit(material3d(save)) do.call("rgl.lines", c(list(x=x,y=y,z=z), .fixMaterialArgs(..., Params = save))) } triangles3d <- function(x,y=NULL,z=NULL,...) { .check3d(); save <- material3d(); on.exit(material3d(save)) do.call("rgl.triangles", c(list(x=x,y=y,z=z), .fixMaterialArgs(..., Params = save))) } quads3d <- function(x,y=NULL,z=NULL,...) { .check3d(); save <- material3d(); on.exit(material3d(save)) do.call("rgl.quads", c(list(x=x,y=y,z=z), .fixMaterialArgs(..., Params = save))) } text3d <- function(x, y = NULL, z = NULL, texts, adj = 0.5, pos = NULL, offset = 0.5, usePlotmath = is.language(texts), ...) { if (usePlotmath) return(plotmath3d(x = x, y = y, z = z, text = texts, adj = adj, pos = pos, offset = offset, ...)) .check3d(); save <- material3d(); on.exit(material3d(save)) new <- .fixMaterialArgs(..., Params = save) do.call("rgl.texts", c(list(x = x, y = y, z = z, text = texts, adj = adj, pos = pos, offset = offset), new)) } texts3d <- text3d spheres3d <- function(x, y = NULL, z = NULL, radius = 1, fastTransparency = TRUE, ...) { .check3d(); save <- material3d(); on.exit(material3d(save)) do.call("rgl.spheres", c(list(x = x, y = y, z = z, radius = radius, fastTransparency = fastTransparency), .fixMaterialArgs(..., Params = save))) } planes3d <- function(a,b=NULL,c=NULL,d=0,...) { .check3d(); save <- material3d(); on.exit(material3d(save)) do.call("rgl.planes", c(list(a=a,b=b,c=c,d=d), .fixMaterialArgs(..., Params = save))) } clipplanes3d <- function(a,b=NULL,c=NULL,d=0) { .check3d() rgl.clipplanes(a=a,b=b,c=c,d=d) } abclines3d <- function(x,y=NULL,z=NULL,a,b=NULL,c=NULL,...) { .check3d(); save <- material3d(); on.exit(material3d(save)) do.call("rgl.abclines", c(list(x=x,y=y,z=z,a=a,b=b,c=c), .fixMaterialArgs(..., Params = save))) } sprites3d <- function(x, y = NULL, z = NULL, radius = 1, shapes = NULL, userMatrix, fixedSize = FALSE, adj = 0.5, pos = NULL, offset = 0.25, ...) { .check3d(); save <- material3d(); on.exit(material3d(save)) if (missing(userMatrix)) { userMatrix <- getr3dDefaults()$userMatrix if (is.null(userMatrix)) userMatrix <- diag(4) } savepar <- par3d(skipRedraw=TRUE, ignoreExtent=TRUE) on.exit(par3d(savepar), add=TRUE) force(shapes) par3d(ignoreExtent=savepar$ignoreExtent) do.call("rgl.sprites", c(list(x=x,y=y,z=z,radius=radius,shapes=shapes, userMatrix=userMatrix, fixedSize = fixedSize, adj = adj, pos = pos, offset = offset), .fixMaterialArgs(..., Params = save))) } terrain3d <- function(x,y=NULL,z=NULL,...,normal_x=NULL,normal_y=NULL,normal_z=NULL) { .check3d(); save <- material3d(); on.exit(material3d(save)) do.call("rgl.surface", c(list(x=x,y=z,z=y,coords=c(1,3,2), normal_x=normal_x,normal_y=normal_z,normal_z=normal_y), .fixMaterialArgs(..., Params = save))) } surface3d <- terrain3d # Interaction select3d <- function(...) { .check3d() rgl.select3d(...) } # 3D Generic Object Rendering Attributes dot3d <- function(x,...) UseMethod("dot3d") wire3d <- function(x,...) UseMethod("wire3d") shade3d <- function(x,...) UseMethod("shade3d") # 3D Generic transformation translate3d <- function(obj,x,y,z,...) UseMethod("translate3d") scale3d <- function(obj,x,y,z,...) UseMethod("scale3d") rotate3d <- function(obj,angle,x,y,z,matrix,...) UseMethod("rotate3d") transform3d <- function(obj,matrix,...) rotate3d(obj, matrix=matrix, ...) subdivision3d <- function(x,...) UseMethod("subdivision3d") # 3D Custom shapes particles3d <- function(x,y=NULL,z=NULL,radius=1,...) sprites3d( x=x,y=y,z=z,radius=radius, lit=FALSE,alpha=0.2, textype="alpha", texture=system.file("textures/particle.png",package="rgl"), ... ) # r3d default settings for new windows r3dDefaults <- list(userMatrix = rotationMatrix(290*pi/180, 1, 0, 0), mouseMode = c("none", "trackball", "zoom", "fov", "pull"), FOV = 30, bg = list(color="white",fogtype = "none"), family = "sans", material = list(color="black", fog = TRUE)) if (.Platform$OS.type == "windows") r3dDefaults$useFreeType <- FALSE open3d <- function(..., params = getr3dDefaults(), useNULL = rgl.useNULL(), silent = FALSE ) { register_pkgdown_methods() args <- list(...) if (!is.null(args$antialias) || !is.null(args$antialias <- r3dDefaults$antialias)) { saveopt <- options(rgl.antialias = args$antialias) on.exit(options(saveopt)) args$antialias <- NULL } rgl.open(useNULL) if (!is.null(args$material)) { params$material <- do.call(.fixMaterialArgs, c(args$material, Params=list(params$material))) args$material <- NULL } if (length(args) && (is.null(names(args)) || any(nchar(names(args)) == 0))) stop("open3d parameters must be named") params[names(args)] <- args clear3d("material", defaults = params) params$material <- NULL if (!is.null(params$bg)) { do.call("bg3d", params$bg) params$bg <- NULL } do.call("par3d", params) result <- structure(cur3d(), class = "rglOpen3d") if (silent) invisible(result) else result } print.rglOpen3d <- function(x, ...) { print(unclass(x)) } close3d <- function(dev = cur3d(), silent = TRUE) { for (d in dev[dev != 0]) { devname <- paste0("dev", d) rgl.callback.env[[devname]] <- NULL set3d(d, silent = silent) rgl.close() if (!silent) message("Closed device ", d) } invisible(cur3d()) } cur3d <- rgl.cur set3d <- function(dev, silent = FALSE) { prev <- cur3d() rgl.set(dev, silent = silent) prev } .check3d <- function() { if (result<-cur3d()) return(result) else return(open3d()) } requireWebshot2 <- function() { suppressMessages(res <- requireNamespace("webshot2", quietly = TRUE)) res } snapshot3d <- function(filename = tempfile(fileext = ".png"), fmt = "png", top = TRUE, ..., scene, width = NULL, height = NULL, webshot = TRUE) { force(filename) if (webshot && !requireWebshot2()) { warning("webshot = TRUE requires the webshot2 package; using rgl.snapshot() instead") webshot <- FALSE } saveopts <- options(rgl.useNULL = webshot) on.exit(options(saveopts)) # The logic here is a little convoluted: # scene resize webshot getscene1 plot resize getscene2 # no no no # no no yes X # no yes no X # no yes yes X X X X # yes no no X # yes no yes # yes yes no X X # yes yes yes X X X resize <- !is.null(width) || !is.null(height) havescene <- !missing(scene) if (havescene) { if (inherits(scene, "rglWebGL")) { snapshot <- scene$x$snapshot if (!is.null(snapshot) && is.null(width) && is.null(height)) return(saveURI(snapshot, filename)) else scene <- attr(scene, "origScene") } } if (!havescene && webshot) scene <- scene3d() if ((!havescene && resize && webshot) || (havescene && (resize || !webshot))) { open3d() plot3d(scene) on.exit(close3d(), add = TRUE) } if (resize) { saverect <- rect <- par3d("windowRect") on.exit(par3d(windowRect = saverect), add = TRUE) if (!is.null(width)) rect[3] <- rect[1] + width if (!is.null(height)) rect[4] <- rect[2] + height par3d(windowRect = rect) } if (webshot) { if (resize) scene <- scene3d() rect <- par3d("windowRect") f1 <- tempfile(fileext = ".html") on.exit(unlink(f1), add = TRUE) width <- rect[3] - rect[1] height <- rect[4] - rect[2] saveWidget(rglwidget(scene, elementId = "webshot", width = width, height = height, webgl = TRUE), f1) capture.output(webshot2::webshot(f1, file = filename, selector = "#webshot", vwidth = width + 100, vheight = height, ...), type = "message") invisible(filename) } else rgl.snapshot(filename, fmt, top) } rgl/R/as.mesh3d.default.R0000644000176200001440000003705614137472630014614 0ustar liggesusersas.mesh3d.default <- function(x, y = NULL, z = NULL, type = c("triangles", "quads", "segments", "points"), smooth = FALSE, tolerance = sqrt(.Machine$double.eps), notEqual = NULL, merge = TRUE, ..., triangles) { if (missing(x)) { x <- rglId(ids3d()$id) return(as.mesh3d(x, ...)) } xyz <- xyz.coords(x, y, z, recycle = TRUE) x <- xyz$x y <- xyz$y z <- xyz$z if (!missing(triangles)) { warning("Argument 'triangles' is deprecated; please use 'type' instead.") if (missing(type)) { if (triangles) type <- "triangles" else type <- "quads" } } type <- match.arg(type, several.ok = TRUE) pcs <- c(triangles = 3, quads = 4, segments = 2, points = 1) nvert <- length(x) okay <- FALSE for (i in seq_along(type)) { if (nvert %% pcs[type[i]] == 0) { okay <- TRUE break } } if (okay) type <- type[i] else stop("Wrong number of vertices") verts <- rbind(x, y, z) indices <- matrix(seq_along(x), nrow = pcs[type]) if (merge) { if (!is.null(notEqual)) { dim <- dim(notEqual) if (length(dim) != 2 || dim[1] != nvert || dim[2] != nvert) stop("'notEqual' should be a ", nvert, " by ", nvert, " logical matrix.") notEqual <- notEqual | t(notEqual) # Make it symmetric } else notEqual <- matrix(FALSE, nvert, nvert) o <- order(x, y, z) i1 <- seq_len(nvert)[o] for (i in seq_len(nvert)[-1]) { if (isTRUE(all.equal(verts[,i1[i-1]], verts[,i1[i]], tolerance = tolerance)) && (!isTRUE(notEqual[i1[i-1], i1[i]]))) { indices[indices == i1[i]] <- i1[i-1] notEqual[i1[i], ] <- notEqual[i1[i-1], ] <- notEqual[i1[i], ] | notEqual[i1[i-1], ] notEqual[, i1[i]] <- notEqual[, i1[i-1]] <- notEqual[i1[i], ] | notEqual[, i1[i-1]] i1[i] <- i1[i-1] } } i1 <- sort(unique(i1)) keep <- seq_along(i1) for (i in keep) { verts[,i] <- verts[,i1[i]] indices[indices == i1[i]] <- i } } else keep <- seq_len(ncol(verts)) mesh <- mesh3d(vertices = rbind(verts[,keep, drop = FALSE], 1), points = if (type == "points") indices, triangles = if (type == "triangles") indices, quads = if (type == "quads") indices, segments = if (type == "segments") indices, material = list(...)) if (smooth && type != "points") mesh <- addNormals(mesh) mesh } as.mesh3d.rglId <- function(x, type = NA, subscene = NA, ...) { local_t <- function(x) { if (!is.null(x)) t(x) } colorByFaces <- function(mesh) { constColumns <- function(m) all(apply(m, 2, function(col) length(unique(col))) == 1) # See if we can use meshColor = "faces" if (!is.null(mesh$material) && !is.null(mesh$meshColor) && mesh$meshColor == "vertices") { cols <- mesh$material$color alpha <- mesh$material$alpha texcoords <- mesh$texcoords if (length(cols) == 1 && length(alpha) == 1 && is.null(texcoords)) { mesh$meshColor <- "faces" return(mesh) } if (length(cols) == 1) cols <- rep(cols, len = ncol(mesh$vb)) if (length(alpha) == 1) alpha <- rep(alpha, len = ncol(mesh$vb)) prev <- 0 newcols <- NULL newalpha <- NULL newtexcoords <- NULL if (!is.null(mesh$ip)) { inds <- mesh$ip newcols <- cols[inds] newalpha <- alpha[inds] } if (!is.null(mesh$is)) { inds <- as.numeric(mesh$is) cols <- matrix(cols[inds], nrow = 2) alpha <- matrix(alpha[inds], nrow = 2) if (!constColumns(cols) || !constColumns(alpha)) return(mesh) newcols <- c(newcols, cols[1,]) newalpha <- c(newalpha, alpha[1,]) } if (!is.null(mesh$it)) { inds <- as.numeric(mesh$it) cols <- matrix(cols[inds], nrow = 3) alpha <- matrix(alpha[inds], nrow = 3) if (!constColumns(cols) || !constColumns(alpha)) return(mesh) if (!is.null(texcoords)) { tex1 <- matrix(texcoords[1, inds], nrow = 3) tex2 <- matrix(texcoords[2, inds], nrow = 3) if (!constColumns(tex1) || !constColumns(tex2)) return(mesh) } newcols <- c(newcols, cols[1,]) newalpha <- c(newalpha, alpha[1,]) if (!is.null(texcoords)) newtexcoords <- cbind(newtexcoords, rbind(tex1[1,], tex2[1,])) } if (!is.null(mesh$ib)) { inds <- as.numeric(mesh$ib) cols <- matrix(cols[inds], nrow = 3) alpha <- matrix(alpha[inds], nrow = 3) tex1 <- matrix(texcoords[1, inds], nrow = 3) tex2 <- matrix(texcoords[2, inds], nrow = 3) if (!constColumns(cols) || !constColumns(alpha) || !constColumns(tex1) || !constColumns(tex2)) return(mesh) newcols <- c(newcols, cols[1,]) newalpha <- c(newalpha, alpha[1,]) newtexcoords <- cbind(newtexcoords, rbind(tex1[1,], tex2[1,])) } mesh$meshColor <- "faces" mesh$material$color <- if (length(unique(newcols)) == 1) newcols[1] else newcols mesh$material$alpha <- if (length(unique(newalpha)) == 1) newalpha[1] else newalpha mesh$texcoords <- newtexcoords } mesh } mergeMaterials <- function(oldmat, newmat, n, type) { if (length(newmat$color) == 1) newmat$color <- rep(newmat$color, len = n) if (length(newmat$alpha) == 1) newmat$alpha <- rep(newmat$alpha, len = n) # meshColor isn't a material property, but put it here # for now... newmat$meshColor <- "vertices" if (is.null(oldmat)) result <- newmat else { cols <- c(oldmat$color, newmat$color) oldmat$color <- newmat$color <- NULL alpha <- c(oldmat$alpha, newmat$alpha) oldmat$alpha <- newmat$alpha <- NULL same <- all.equal(oldmat, newmat) if (!isTRUE(same)) warning(same, "\nOnly last material used") result <- newmat result$color <- cols result$alpha <- alpha result$meshColor <- "vertices" } result } ids <- ids3d(subscene = subscene) ids <- ids[ids$id %in% x,] # Parts will be drawn in order ip, is, it, ib, # so sort that way now ordered <- c(points = 1, lines = 2, linestrip = 3, triangles = 4, planes = 5, quads = 6, surface = 7) if (!is.na(type)) ids <- ids[ids$type %in% type,] ids <- ids[order(ordered[ids$type]),] ip <- NULL is <- NULL it <- NULL vertices <- NULL normals <- NULL texcoords <- NULL material <- NULL for (i in seq_len(NROW(ids))) { id <- ids[i, "id"] verts <- rgl.attrib(id, "vertices") nvert <- NROW(verts) if (nvert) { type <- ids[i, "type"] prev <- length(vertices)/3 inds <- switch(as.character(type), points = seq_len(nvert) + prev, lines = # from segments3d matrix(1:nvert + prev, nrow = 2), linestrip = # from lines3d rbind(seq_len(nvert - 1), seq_len(nvert - 1) + 1) + prev, triangles =, planes = matrix(1:nvert + prev, nrow = 3), quads = { nquads <- nvert/4 matrix(4*rep(seq_len(nquads) - 1, each = 6) + c(1,2,3,1,3,4) + prev, nrow = 3) }, surface = { dim <- rgl.attrib(id, "dim") ul <- rep(2:dim[1], dim[2]-1) + dim[1]*rep(0:(dim[2]-2), each=dim[1]-1) + prev if (rgl.attrib(id, "flags")["flipped",]) rbind(c(ul-1, ul-1+dim[1]), c(ul, ul), c(ul-1+dim[1], ul+dim[1])) else rbind(c(ul, ul), c(ul-1, ul-1+dim[1]), c(ul-1+dim[1], ul+dim[1])) }, NULL) if (length(inds)) { if (type == "points") { ip <- c(ip, inds) normals <- rbind(normals, matrix(NA, ncol = 3, nrow = nvert)) } else if (type %in% c("lines", "linestrip")) { is <- cbind(is, inds) normals <- rbind(normals, matrix(NA, ncol = 3, nrow = nvert)) } else { it <- cbind(it, inds) normals <- rbind(normals, rgl.attrib(id, "normals")) } vertices <- cbind(vertices, local_t(rgl.attrib(id, "vertices"))) if (rgl.attrib.count(id,"texcoords")) texcoords <- rbind(texcoords, rgl.attrib(id, "texcoords")) else texcoords <- rbind(texcoords, matrix(NA, ncol = 2, nrow = nvert)) mat <- rgl.getmaterial(nvert, id = id) material <- mergeMaterials(material, mat, nvert, type) } } } if (length(vertices)) { if (length(unique(material$color)) == 1) material$color <- material$color[1] if (length(unique(material$alpha)) == 1) material$alpha <- material$alpha[1] meshColor <- material$meshColor material$meshColor <- NULL colorByFaces(mesh3d(vertices = vertices, points = ip, segments = is, triangles = it, material = material, normals = normals, texcoords = if (any(!is.na(texcoords))) texcoords, meshColor = meshColor)) } } as.mesh3d.rglobject <- function(x, ...) { local_t <- function(x) { if (!is.null(x)) t(x) } indices <- NULL vertices <- NULL normals <- NULL texcoords <- NULL verts <- x$vertices nvert <- NROW(verts) if (!is.null(verts)) { type <- x$type inds <- switch(as.character(type), triangles =, planes = matrix(1:nvert, nrow = 3), quads = { nquads <- nvert/4 matrix(4*rep(seq_len(nquads) - 1, each = 6) + c(1,2,3,1,3,4), nrow = 3) }, surface = { dim <- x$dim ul <- rep(2:dim[1], dim[2]-1) + dim[1]*rep(0:(dim[2]-2), each=dim[1]-1) if (x$flipped) rbind(c(ul-1, ul-1+dim[1]), c(ul, ul), c(ul-1+dim[1], ul+dim[1])) else rbind(c(ul, ul), c(ul-1, ul-1+dim[1]), c(ul-1+dim[1], ul+dim[1])) }, NULL) if (length(inds)) { indices <- inds vertices <- local_t(x$vertices) normals <- x$normals texcoords <- x$texcoords material <- x$material } } if (length(vertices)) tmesh3d(vertices, indices, homogeneous = FALSE, material = material, normals = normals, texcoords = texcoords) } mergeVertices <- function(mesh, notEqual = NULL, attribute = "vertices", tolerance = sqrt(.Machine$double.eps)) { dropNormals <- function(mesh) { if (is.null(mesh$normals)) return(FALSE) normals <- mesh$normals v <- with(mesh, rbind(vb[1,]/vb[4,], vb[2,]/vb[4,], vb[3,]/vb[4,])) it <- mesh$it if (!is.null(it)) for (i in seq_len(ncol(it))) { normal <- xprod( v[, it[1, i]] - v[, it[3, i]], v[, it[2, i]] - v[, it[1, i]]) normal <- normal/sqrt(sum(normal^2)) for (j in 1:3) { normij <- normals[, it[j, i]] normij <- normij/sqrt(sum(normij^2)) same <- all.equal(normal, normij, tolerance = tolerance, check.attributes = FALSE) if (!isTRUE(same)) return(FALSE) } } ib <- mesh$ib if (!is.null(ib)) for (i in seq_len(ncol(ib))) { norm1 <- xprod( v[, it[1, i]] - v[, it[3, i]], v[, it[2, i]] - v[, it[1, i]]) norm1 <- norm1/sqrt(sum(norm1^2)) norm2 <- xprod( v[, it[2, i]] - v[, it[4, i]], v[, it[3, i]] - v[, it[2, i]]) norm2 <- norm1/sqrt(sum(norm2^2)) for (j in 1:4) { normij <- normals[, it[j, i]] normij <- normij/sqrt(sum(normij^2)) same1 <- all.equal(norm1, normij, tolerance = tolerance, check.attributes = FALSE) same2 <- all.equal(norm2, normij, tolerance = tolerance, check.attributes = FALSE) if (!isTRUE(same1) || !isTRUE(same2)) return(FALSE) } } TRUE } if (dropNormals(mesh)) mesh$normals <- NULL if (is.null(mesh$vb)) return(mesh) nvert <- ncol(mesh$vb) if (!is.null(notEqual)) { dim <- dim(notEqual) if (length(dim) != 2 || dim[1] != nvert || dim[2] != nvert) stop("'notEqual' should be a ", nvert, " by ", nvert, " logical matrix.") notEqual <- notEqual | t(notEqual) # Make it symmetric } else notEqual <- matrix(FALSE, nvert, nvert) attribute <- match.arg(attribute, choices = c("vertices", "colors", "normals", "texcoords"), several.ok = TRUE) verts <- matrix(numeric(), ncol = 0, nrow = nvert) if ("vertices" %in% attribute) verts <- cbind(mesh$vb[1,]/mesh$vb[4,], mesh$vb[2,]/mesh$vb[4,], mesh$vb[3,]/mesh$vb[4,]) if (!is.null(normals <- mesh$normals) && "normals" %in% attribute) if (nrow(normals) == 3) verts <- cbind(verts, t(normals)) else verts <- cbind(verts, normals[1,]/normals[4,], normals[2,]/normals[4,], normals[3,]/normals[4,]) colors <- NULL if ("colors" %in% attribute && !is.null(mesh$meshColor) && mesh$meshColor == "vertices" && !is.null(mesh$material) && !is.null(colors <- mesh$material$color)) verts <- cbind(verts, t(col2rgb(colors))) if (!is.null(texcoords <- mesh$texcoords) && "texcoords" %in% attribute) verts <- cbind(verts, t(texcoords)) o <- do.call(order, as.data.frame(verts)) indices <- c(mesh$ip, mesh$is, mesh$it, mesh$ib) i1 <- seq_len(nvert)[o] for (i in seq_len(nvert)[-1]) { if (isTRUE(all.equal(verts[i1[i-1],], verts[i1[i],], tolerance = tolerance)) && (!isTRUE(notEqual[i1[i-1], i1[i]]))) { notEqual[i1[i], ] <- notEqual[i1[i-1], ] <- notEqual[i1[i], ] | notEqual[i1[i-1], ] notEqual[, i1[i]] <- notEqual[, i1[i-1]] <- notEqual[i1[i], ] | notEqual[, i1[i-1]] i1[i] <- i1[i-1] } } indices <- i1[order(o)][indices] keep <- sort(unique(i1)) newvals <- numeric(nvert) newvals[keep] <- seq_along(keep) indices <- newvals[indices] mesh$vb <- mesh$vb[,keep] if (!is.null(normals)) mesh$normals <- normals[, keep] if (!is.null(texcoords)) mesh$texcoords <- texcoords[, keep] if (!is.null(colors)) mesh$material$color <- colors[keep] if (np <- length(mesh$ip)) mesh$ip <- indices[seq_len(np)] if (ns <- length(mesh$is)) mesh$is <- matrix(indices[seq_len(ns) + np]) if (nt <- length(mesh$it)) mesh$it <- matrix(indices[seq_len(nt) + np + ns], nrow = 3) if (nq <- length(mesh$ib)) mesh$ib <- matrix(indices[seq_len(nq) + np + ns + nt], nrow = 4) mesh } rgl/R/addNormals.mesh3d.R0000644000176200001440000000323714100762640014635 0ustar liggesusersaddNormals <- function(x, ...) UseMethod("addNormals") addNormals.mesh3d <- function(x, angleWeighted = TRUE, ...) { v <- x$vb # Make sure v is homogeneous with unit w if (nrow(v) == 3) v <- rbind(v, 1) else v <- t( t(v)/v[4,] ) v <- v[1:3,] normals <- v*0 if (is.na(angleWeighted)) { reproduceBug <- TRUE angleWeighted <- FALSE } else reproduceBug <- FALSE dopolys <- function(it, normals) { n <- nrow(it) for (i in seq_len(ncol(it))) { normal <- xprod( v[, it[1, i]] - v[, it[3, i]], v[, it[2, i]] - v[, it[1, i]]) if (reproduceBug) normal <- normalize(normal) if (!any(is.na(normal))) { if (angleWeighted) normal <- normalize(normal) for (j in seq_len(n)) { if (angleWeighted) { jm1 <- (j + n - 2) %% n + 1 jp1 <- j %% n + 1 weight <- angle(v[, it[jm1, i]] - v[, it[j, i]], v[, it[jp1, i]] - v[, it[j, i]]) } else weight <- 1 normals[, it[j,i]] <- normals[, it[j,i]] + normal*weight } } } normals } if (length(x$it)) normals <- dopolys(x$it, normals) if (length(x$ib)) normals <- dopolys(x$ib, normals) normals <- rbind(apply(normals, 2, function(n) n/veclen(n)), 1) x$normals <- normals x } veclen <- function(v) sqrt(sum(v^2)) normalize <- function(v) v/veclen(v) xprod <- function(v, w) c( v[2]*w[3] - v[3]*w[2], v[3]*w[1] - v[1]*w[3], v[1]*w[2] - v[2]*w[1] ) angle <- function(a,b) { dot <- sum(a*b) acos(dot/veclen(a)/veclen(b)) } rgl/R/plugin.R0000644000176200001440000000021114100762640012652 0ustar liggesusers## ## R source file ## This file is part of rgl ## ## ## ## quit R plugin ## ## rgl.quit <- function() { unloadNamespace("rgl") } rgl/R/arc3d.R0000644000176200001440000000511414100762640012357 0ustar liggesusersarc3d <- function(from, to, center, radius, n, circle = 50, base = 0, plot = TRUE, ...) { fixarg <- function(arg) { if (is.matrix(arg)) arg[, 1:3, drop = FALSE] else matrix(arg, 1, 3) } normalize <- function(v) v / veclen(v) getrow <- function(arg, i) { arg[1 + (i - 1) %% nrow(arg),] } from <- fixarg(from) to <- fixarg(to) center <- fixarg(center) m <- max(nrow(from), nrow(to), nrow(center), length(base)) base <- rep_len(base, m) result <- matrix(NA_real_, nrow = 1, ncol = 3) for (j in seq_len(m)) { from1 <- getrow(from, j) to1 <- getrow(to, j) center1 <- getrow(center, j) base1 <- base[j] logr1 <- log(veclen(from1 - center1)) logr2 <- log(veclen(to1 - center1)) A <- normalize(from1 - center1) B <- normalize(to1 - center1) steps <- if (base1 <= 0) 4*abs(base1) + 1 else 4*base1 - 1 for (k in seq_len(steps)) { if (k %% 2) { A1 <- A * (-1)^(k %/% 2) B1 <- B * (-1)^(k %/% 2 + (base1 > 0)) } else { A1 <- B * (-1)^(k %/% 2 + (base1 <= 0)) B1 <- A * (-1)^(k %/% 2) } theta <- acos(sum(A1*B1)) if (isTRUE(all.equal(theta, pi))) warning("Arc ", j, " points are opposite each other! Arc is not well defined.") if (missing(n)) n1 <- ceiling(circle*theta/(2*pi)) else n1 <- n if (missing(radius)) { pretheta <- (k %/% 2)*pi - (k %% 2 == 0)*theta if (k == 1) totaltheta <- (steps %/% 2)*pi - (steps %% 2 == 0)*theta + theta p1 <- pretheta/totaltheta p2 <- (pretheta + theta)/totaltheta radius1 <- exp(seq(from = (1 - p1)*logr1 + p1*logr2, to = (1 - p2)*logr1 + p2*logr2, length.out = n1 + 1)) } else radius1 <- rep_len(radius, n1) arc <- matrix(NA_real_, nrow = n1 + 1, ncol = 3) p <- seq(0, 1, length.out = n1 + 1) arc[1,] <- center1 + radius1[1]*A1 arc[n1 + 1,] <- center1 + radius1[n1 + 1]*B1 AB <- veclen(A1 - B1) for (i in seq_len(n1)[-1]) { ptheta <- p[i]*theta phi <- pi/2 + (0.5 - p[i])*theta q <- (sin(ptheta) / sin(phi))/AB D <- (1-q)*A1 + q*B1 arc[i,] <- center1 + radius1[i] * normalize(D) } if (k == 1) result <- rbind(result, arc) else result <- rbind(result[-nrow(result), ,drop = FALSE], arc) } result <- rbind(result, result[1,]) } if (plot) lines3d(result[c(-1, -nrow(result)), , drop = FALSE], ...) else result[c(-1, -nrow(result)), , drop = FALSE] } rgl/R/setUserShaders.R0000644000176200001440000000114214100762640014324 0ustar liggesuserssetUserShaders <- function(ids, vertexShader = NULL, fragmentShader = NULL, attributes = NULL, uniforms = NULL, scene = scene3d(minimal), minimal = TRUE) { stopifnot(inherits(scene, "rglscene")) for (i in ids) { id <- as.character(i) obj <- scene$objects[[id]] if (!is.null(vertexShader)) obj$userVertexShader <- paste(vertexShader, collapse = "\n") if (!is.null(fragmentShader)) obj$userFragmentShader <- paste(fragmentShader, collapse = "\n") obj$userAttributes <- attributes obj$userUniforms <- uniforms scene$objects[[id]] <- obj } scene } rgl/R/getBoundary.R0000644000176200001440000000210614145464133013651 0ustar liggesusersgetBoundary3d <- function(mesh, sorted = FALSE, simplify = TRUE) { if (!inherits(mesh, "mesh3d")) stop(deparse(substitute(mesh)), " is not a mesh3d object.") edges <- NULL if (length(mesh$it)) edges <- cbind(edges, mesh$it[1:2,], mesh$it[2:3,], mesh$it[c(3,1),]) if (length(mesh$ib)) edges <- cbind(edges, mesh$ib[1:2,], mesh$ib[2:3,], mesh$ib[3:4,], mesh$ib[c(4,1),]) if (ncol(edges)) { # undirect the edges uedges <- t(apply(edges, 2, sort)) dup <- duplicated(uedges) | duplicated(uedges, fromLast = TRUE) edges <- edges[,!dup,drop=FALSE] if (sorted) { order <- rep(NA, ncol(edges)) order[1] <- 1 for (i in seq_len(length(order) - 1)) { j <- which(edges[1,] == edges[2, order[i]]) j <- setdiff(j, order[1:i]) if (length(j)) order[i+1] <- j[1] else order[i+1] <- setdiff(1:length(order), order[1:i]) } edges <- edges[, order, drop = FALSE] } } result <- mesh3d(vertices = mesh$vb, segments = edges) if (simplify) result <- cleanMesh3d(result) result } rgl/R/knitr.R0000644000176200001440000002304514100762640012515 0ustar liggesusersin_knitr <- function() isTRUE(getOption("knitr.in.progress")) ## ## knitr hook functions ## ## fns <- local({ newwindowdone <- FALSE closewindowsdone <- FALSE do_newwindow <- function(options) { if (!newwindowdone) { newwindow <- options$rgl.newwindow if (!is.null(newwindow) && newwindow) open3d() if (!is.null(options$rgl.keepopen)) warning("rgl.keepopen has been replaced by rgl.newwindow") newwindowdone <<- TRUE closewindowsdone <<- FALSE } } do_closewindows <- function(options) { if (!closewindowsdone) { closewindows <- options$rgl.closewindows if (!is.null(closewindows) && closewindows) while (cur3d()) close3d() newwindowdone <<- FALSE closewindowsdone <<- TRUE } } list(do_newwindow = do_newwindow, do_closewindows = do_closewindows) }) do_newwindow <- fns[["do_newwindow"]] do_closewindows <- fns[["do_closewindows"]] rm(fns) hook_webgl <- function(before, options, envir) { if (before) { do_newwindow(options) return() } res <- if (cur3d() != 0) { out_type <- opts_knit$get("out.format") if (!length(intersect(out_type, c("markdown", "html")))) stop("'hook_webgl' is for HTML only. ", "Use 'hook_rgl' instead, or 'setupKnitr(autoprint = TRUE)'.") knit_print(rglwidget(), options = options) } do_closewindows(options) m <- attr(res, 'knit_meta') knit_meta_add(m, if (missing(options)) '' else options$label) res } hook_rgl <- function(before, options, envir) { if (before) { do_newwindow(options) return() } res <- if (cur3d() != 0) { name <- fig_path("", options) margin <- options$rgl.margin if (is.null(margin)) margin <- 100 par3d(windowRect = margin + options$dpi * c(0, 0, options$fig.width, options$fig.height)) Sys.sleep(.05) # need time to respond to window size change dir <- knitr::opts_knit$get("base_dir") if (is.character(dir)) { if (!file_test("-d", dir)) dir.create(dir, recursive = TRUE) owd <- setwd(dir) on.exit(setwd(owd)) } save_rgl(name, options$dev) options$fig.num <- 1L # only one figure in total options$dev <- "png" hook_plot_custom(before, options, envir) } do_closewindows(options) res } hook_rglchunk <- function(before, options, envir) { if (before) do_newwindow(options) else if (is.null(options$webgl) && is.null(options$rgl)) do_closewindows(options) } save_rgl <- function(name, devices) { if (!file_test("-d", dirname(name))) dir.create(dirname(name), recursive = TRUE) # support 3 formats: eps, pdf and png (default) for (dev in devices) switch( dev, eps = , postscript = rgl.postscript(paste0(name, ".eps"), fmt = "eps"), pdf = rgl.postscript(paste0(name, '.pdf'), fmt = "pdf"), snapshot3d(paste0(name, ".png")) ) } # This code is mostly taken from Shiny, which has lots of authors: see # https://github.com/rstudio/shiny/blob/master/R/utils.R # Evaluate an expression using our own private stream of # randomness (not affected by set.seed). withPrivateSeed <- local({ ownSeed <- NULL function(expr) { # Save the old seed if present. if (exists(".Random.seed", envir = .GlobalEnv, inherits = FALSE)) { hasOrigSeed <- TRUE origSeed <- .GlobalEnv$.Random.seed } else { hasOrigSeed <- FALSE } # Swap in the private seed. if (is.null(ownSeed)) { if (hasOrigSeed) { # Move old seed out of the way if present. rm(.Random.seed, envir = .GlobalEnv, inherits = FALSE) } } else { .GlobalEnv$.Random.seed <- ownSeed } # On exit, save the modified private seed, and put the old seed back. on.exit({ ownSeed <<- .GlobalEnv$.Random.seed if (hasOrigSeed) { .GlobalEnv$.Random.seed <- origSeed } else { rm(.Random.seed, envir = .GlobalEnv, inherits = FALSE) } # Shiny had this workaround. I think we don't need it, and have # commented it out. # Need to call this to make sure that the value of .Random.seed gets put # into R's internal RNG state. (Issue #1763) # httpuv::getRNGState() # nolint }) expr } }) # Version of sample that runs with private seed p_sample <- function(...) { withPrivateSeed(sample(...)) } fns <- local({ saveopts <- NULL plotnum <- 0 setupDone <- NULL latex <- FALSE counter <- 0L rgl_counter <- function() { counter <<- counter + 1L counter } setupKnitr <- function(autoprint = FALSE, rgl.newwindow = autoprint, rgl.closewindows = autoprint) { if (!is.null(setupDone)) { if (setupDone$autoprint) { message("undoing setup") options(saveopts) saveopts <<- NULL setupDone <<- NULL } } if (!is.null(setupDone)) { if (setupDone$autoprint != autoprint || setupDone$rgl.newwindow != rgl.newwindow || setupDone$rgl.closewindows != rgl.closewindows) { warning("Already set autoprint = ", setupDone$autoprint, ", rgl.newwindow = ", setupDone$rgl.newwindow, ", rgl.closewindows = ", setupDone$rgl.closewindows) } return() } counter <<- 0L setupDone <<- list(autoprint = autoprint, rgl.newwindow = rgl.newwindow, rgl.closewindows = rgl.closewindows) # R produces multiple vignettes in the same session. knitr::opts_chunk$set(rgl.newwindow = rgl.newwindow, rgl.closewindows = rgl.closewindows, rgl.chunk = TRUE) knit_hooks$set(webgl = hook_webgl) knit_hooks$set(webGL = hook_webgl) knit_hooks$set(rgl = hook_rgl) knit_hooks$set(rgl.chunk = hook_rglchunk) latex <<- identical(opts_knit$get("out.format"), "latex") || identical(opts_knit$get("rmarkdown.pandoc.to"), "latex") if (autoprint) saveopts <<- options(rgl.printRglwidget = TRUE) } knit_print.rglOpen3d <- function(x, options, ...) { print(x, ...) if (getOption("rgl.printRglwidget", FALSE)) { plotnum <<- plotnum + 1 } invisible(x) } knit_print.rglId <- function(x, options, ...) { if (getOption("rgl.printRglwidget", FALSE)) { scene <- scene3d() args <- list(...) if (inherits(x, "rglHighlevel")) plotnum <<- plotnum + 1 structure(list(plotnum = plotnum, scene = scene, width = figWidth(), height = figHeight(), options = options, args = args), class = c("rglRecordedplot", "knit_other_plot")) } else invisible(x) } sew.rglRecordedplot <- function(x, options = list(), ...) { latex <- identical(opts_knit$get("out.format"), "latex") || identical(opts_knit$get("rmarkdown.pandoc.to"), "latex") scene <- x$scene doSnapshot <- knitrNeedsSnapshot(options) content <- rglwidget(scene, width = x$width, height = x$height, webgl = !doSnapshot) if (inherits(content, "knit_image_paths")) { # # We've done a snapshot, put it in the right place. name <- fig_path("-rgl.png", options, rgl_counter()) if (!file_test("-d", dirname(name))) dir.create(dirname(name), recursive = TRUE) file.copy(content, name, overwrite = TRUE) unlink(content) content <- structure(list(file = name, extension = "png"), class = "html_screenshot") } fig.align <- options$fig.align if (length(fig.align) == 1 && fig.align != "default") content <- prependContent(content, tags$style(sprintf( "#%s {%s}", content$elementId, switch(fig.align, center = "margin:auto;", left = "margin-left:0;margin-right:auto;", right = "margin-left:auto;margin-right:0;", "")))) result <- do.call("knit_print", c(list(content, options), x$args)) if (!latex) class(result) <- c(class(result), "knit_asis_htmlwidget") sew(result, options) } list( setupKnitr = setupKnitr, knit_print.rglOpen3d = knit_print.rglOpen3d, knit_print.rglId = knit_print.rglId, sew.rglRecordedplot = sew.rglRecordedplot) }) setupKnitr <- fns[["setupKnitr"]] knit_print.rglId <- fns[["knit_print.rglId"]] knit_print.rglOpen3d <- fns[["knit_print.rglOpen3d"]] sew.rglRecordedplot <- fns[["sew.rglRecordedplot"]] rm(fns) is_low_change.rglRecordedplot <- function(p1, p2) { inherits(p2, "rglRecordedplot") && p1$plotnum == p2$plotnum } figWidth <- function() { if (in_pkgdown_example()) return(pkgdown_dims()$width) else if (in_knitr()) opts <- opts_current$get(c("fig.width", "dpi", "fig.retina")) else opts <- NULL if (length(opts)) { result <- with(opts, fig.width*dpi/fig.retina) result[1] } else NULL } figHeight <- function() { if (in_pkgdown_example()) return(pkgdown_dims()$height) else if (in_knitr()) opts <- opts_current$get(c("fig.height", "dpi", "fig.retina")) else opts <- NULL if (length(opts)) { result <- with(opts, fig.height*dpi/fig.retina) result[1] } else NULL } rgl/R/oh3d.R0000644000176200001440000000367314100762640012230 0ustar liggesusers# # R 3d object : o3d # oh3d.vb <- c( -1.5, -1.5, -0.5, 1.0, # 1 -0.5, -1.5, -0.5, 1.0, # 2 0.5, -1.5, -0.5, 1.0, # 3 1.5, -1.5, -0.5, 1.0, # 4 -1.5, -0.5, -0.5, 1.0, # 5 -0.5, -0.5, -0.5, 1.0, # 6 0.5, -0.5, -0.5, 1.0, # 7 1.5, -0.5, -0.5, 1.0, # 8 -1.5, 0.5, -0.5, 1.0, # 9 -0.5, 0.5, -0.5, 1.0, # 10 0.5, 0.5, -0.5, 1.0, # 11 1.5, 0.5, -0.5, 1.0, # 12 -1.5, 1.5, -0.5, 1.0, # 13 -0.5, 1.5, -0.5, 1.0, # 14 0.5, 1.5, -0.5, 1.0, # 15 1.5, 1.5, -0.5, 1.0, # 16 -1.5, -1.5, 0.5, 1.0, # 17 -0.5, -1.5, 0.5, 1.0, # 18 0.5, -1.5, 0.5, 1.0, # 19 1.5, -1.5, 0.5, 1.0, # 20 -1.5, -0.5, 0.5, 1.0, # 21 -0.5, -0.5, 0.5, 1.0, # 22 0.5, -0.5, 0.5, 1.0, # 23 1.5, -0.5, 0.5, 1.0, # 24 -1.5, 0.5, 0.5, 1.0, # 25 -0.5, 0.5, 0.5, 1.0, # 26 0.5, 0.5, 0.5, 1.0, # 27 1.5, 0.5, 0.5, 1.0, # 28 -1.5, 1.5, 0.5, 1.0, # 29 -0.5, 1.5, 0.5, 1.0, # 30 0.5, 1.5, 0.5, 1.0, # 31 1.5, 1.5, 0.5, 1.0 # 32 ) oh3d.ib <- c( 1, 5, 6, 2, 2, 6, 7, 3, 3, 7, 8, 4, 5, 9, 10, 6, 7, 11, 12, 8, 9, 13, 14, 10, 10, 14, 15, 11, 11, 15, 16, 12, 17, 18, 22, 21, 18, 19, 23, 22, 19, 20, 24, 23, 21, 22, 26, 25, 23, 24, 28, 27, 25, 26, 30, 29, 26, 27, 31, 30, 27, 28, 32, 31, 1, 2, 18, 17, 2, 3, 19, 18, 3, 4, 20, 19, 6, 22, 23, 7, 10, 11, 27, 26, 13, 29, 30, 14, 14, 30, 31, 15, 15, 31, 32, 16, 17, 21, 5, 1, 21, 25, 9, 5, 25, 29, 13, 9, 4, 8, 24, 20, 8, 12, 28, 24, 12, 16, 32, 28, 6, 10, 26, 22, 7, 23, 27, 11 ) oh3d <- function( trans = identityMatrix(), ... ) { return(rotate3d(qmesh3d( oh3d.vb, oh3d.ib, material=list(...) ), matrix=trans)) } rgl/R/testthat.R0000644000176200001440000000036314100762640013224 0ustar liggesusersexpect_known_scene <- function(name, close = TRUE, file = paste0("testdata/", name, ".rds"), ...) { testthat::local_edition(2) result <- testthat::expect_known_value(object = scene3d(), file = file, ...) if (close) close3d() result } rgl/R/extrafont.R0000644000176200001440000000524314100762640013400 0ustar liggesusers# This function is modelled on similar functions in # the extrafont package. loadfonts_rgl <- function(..., quiet = TRUE) { makeRglFont <- function(family) { getIndex <- function(Bold, Italic) 1 + Bold + 2*Italic fontdata <- fontdata[fontdata$FamilyName == family,,drop = FALSE] result <- rep(NA, 4) for (i in seq_len(nrow(fontdata))) { index <- with(fontdata, getIndex(Bold[i], Italic[i])) if (is.na(result[index])) result[index] <- fontdata$fontfile[i] } value <- result[1] # Propagate to more conditions for (i in 2:4) if (is.na(result[i])) result[i] <- result[i-1] # Propagate to fewer for (i in 3:1) if (is.na(result[i])) result[i] <- result[i+1] result } register_family_rgl <- function(family) { # Now we can register the font with rgl with something like this: # rglFonts("Arial" = rglFont("Arial")) if (family %in% cfonts) { if (!quiet) { message(family, " already registered with rglFonts().") } return(NULL) } if (!quiet) { message("Registering font with R using rglFonts(): ", family) } # Since 'family' is a string containing the name of the argument, we # need to use do.call args <- list() args[[family]] <- makeRglFont(family) if (!is.null(args[[family]])) do.call(rglFonts, args) } if (!requireNamespace("extrafont", quietly = TRUE)) stop("This function requires the extrafont package.") fontdata <- extrafont::fonttable() # remove empty FamilyNames fontdata <- fontdata[fontdata$FamilyName != "", , drop = FALSE] families <- unique(fontdata$FamilyName) # If args were given, limit attention to those args <- list(...) if (length(args)) families <- intersect(families, args) cfonts <- names(rglFonts()) lapply(families, register_family_rgl) allfonts <- rglFonts() names <- names(args) for (i in seq_along(names)) { origname <- args[[names[i]]] if (origname %in% names(allfonts)) { font <- allfonts[[origname]] arg <- list() arg[[names[i]]] <- font do.call(rglFonts, arg) } } } rglExtrafonts <- function(..., quiet = TRUE) { if (!requireNamespace("extrafont", quietly = TRUE)) return() args <- list(...) names <- names(args) result <- character() if (is.null(names)) names <- rep("", length(args)) for (i in seq_along(args)) { choices <- args[[i]] if (length(choices)) { font <- extrafont::choose_font(choices) result[i] <- font if (nchar(font)) { arg <- list(quiet = quiet) if (!nchar(names[i])) names[i] <- font arg[[names[i]]] <- font do.call(loadfonts_rgl, arg) } else warning("Fonts ", paste0('"', choices, '"', collapse = ", "), " not found.") } } names(result) <- names invisible(result) } rgl/R/internal.R0000644000176200001440000000423014145464133013202 0ustar liggesusers## ## R source file ## This file is part of rgl ## ## ## ## ===[ SECTION: internal ]=================================================== ## # # rgl.clamp # # clamp value if lower than low or higher than high # rgl.clamp <- function(value, low, high) { if (value < low) { warning( gettextf("Value clamped to %s",low), domain = NA ) result <- low } else if (value > high) { warning( gettextf("Value clamped to %s",high), domain = NA ) result <- high } else { result <- value } return(result) } ## ## types verification ## # # single field bool # rgl.bool <- function( x ) { if (length(x) > 1) stop( gettextf("'%s' must be a single boolean value", deparse(substitute(x))), domain = NA) } # # single field numeric # rgl.numeric <- function( x ) { if (length(x) > 1) stop( gettextf("'%s' must be a single numeric value", deparse(substitute(x))), domain = NA) } # # single string # rgl.string <- function( x ) { if (length(x) != 1) stop( gettextf("'%s' must be a single character value", deparse(substitute(x))), domain = NA) } # # vertex data object # rgl.vertex <- function(x,y=NULL,z=NULL) { xyz <- xyz.coords(x,y,z,recycle=TRUE) return( matrix( rbind(xyz$x,xyz$y,xyz$z), nrow=3, dimnames=list( c("x","y","z"), NULL ) ) ) } # # texture coordinate data object # rgl.texcoords <- function(s,t=NULL) { xy <- xy.coords(s, t, recycle=TRUE) return( matrix( rbind(xy$x, xy$y), nrow=2, dimnames=list( c("s", "t"), NULL ) ) ) } # # obtain number of vertices # rgl.nvertex <- function(vertex) { return( ncol(vertex) ) } # # rgl.color - single field color # rgl.color <- function( color ) { if (length(color) > 1) stop( gettextf("'%s' must be a single color character string", deparse(substitute(color))), domain = NA) else return(col2rgb(color)) } # # rgl.mcolor - multiple field colors # rgl.mcolor <- function( colors ) { return( col2rgb(colors) ) } # # if vattr > 1, recycle data # rgl.attr <- function(vattr, nvertex) { nvattr <- length(vattr) if ((nvattr > 1) && (nvattr != nvertex)) vattr <- rep(vattr,length.out=nvertex) return(vattr) } rgl/R/stl.R0000644000176200001440000001567614145464133012210 0ustar liggesuserswriteSTL <- function(con, ascii=FALSE, pointRadius=0.005, pointShape = icosahedron3d(), lineRadius = pointRadius, lineSides = 20, ids = tagged3d(tags), tags = NULL) { writeHeader <- function() { ident <- paste(filename, " produced by RGL\n") if (ascii) cat("solid ", ident, file=con) else { padding <- paste(rep(" ", 80), collapse="") ident <- substr( paste("binary", ident, padding), 1, 80) writeChar(ident, con, nchars=80, useBytes=TRUE, eos=NULL) writeBin(0L, con, size=4, endian="little") } } triangles <- 0 writeTriangles <- function(vertices) { if (nrow(vertices) %% 3 != 0) stop("Need 3N vertices") n <- nrow(vertices) / 3 for (i in seq_len(n)) { vec0 <- vertices[3*i - 2,] vec1 <- vertices[3*i - 1,] vec2 <- vertices[3*i,] normal <- normalize(xprod(vec2-vec0, vec1-vec0)) if (ascii) { cat("facet normal ", normal, "\n", file=con) cat("outer loop\n", file=con) cat("vertex ", vec0, "\n", file=con) cat("vertex ", vec1, "\n", file=con) cat("vertex ", vec2, "\n", file=con) cat("endloop\n", file=con) cat("endfacet\n", file=con) } else { writeBin(c(normal, vec0, vec1, vec2), con, size=4, endian="little") writeBin(0L, con, size=2, endian="little") } } triangles <<- triangles + n } writeQuads <- function(vertices) { if (nrow(vertices) %% 4 != 0) stop("Need 4N vertices") n <- nrow(vertices) / 4 indices <- rep(seq_len(n)*4, each=6) - rep(c(3, 2, 1, 3, 1, 0), n) writeTriangles( vertices[indices,] ) } writeSurface <- function(id) { vertices <- rgl.attrib(id, "vertices") dims <- rgl.attrib(id, "dim") nx <- dims[1] nz <- dims[2] indices <- integer(0) for (j in seq_len(nx-1) - 1) { v1 <- j + nx*(seq_len(nz) - 1) + 1 indices <- c(indices, rbind(v1[-nz], v1[-nz]+1, v1[-1]+1, v1[-1])) } writeQuads(vertices[indices,]) } writeMesh <- function(mesh, scale=1, offset=c(0,0,0)) { vertices <- asEuclidean(t(mesh$vb))*scale vertices <- vertices + rep(offset, each=nrow(vertices)) nt <- length(mesh$it)/3 nq <- length(mesh$ib)/4 newverts <- matrix(NA, 3*nt+6*nq, 3) if (nt) newverts[1:(3*nt),] <- vertices[c(mesh$it),] if (nq) newverts[3*nt+1:(6*nq),] <- vertices[c(mesh$ib[1:3,], mesh$ib[c(1,3,4),]),] writeTriangles(newverts) } writeSpheres <- function(id) { vertices <- rgl.attrib(id, "vertices") radii <- rgl.attrib(id, "radii") n <- nrow(vertices) radii <- rep(radii, length.out=n) x <- subdivision3d(icosahedron3d(),3) r <- sqrt(x$vb[1,]^2 + x$vb[2,]^2 + x$vb[3,]^2) x$vb[4,] <- r for (i in seq_along(radii)) writeMesh(x, radii[i], vertices[i,]) } avgScale <- function() { bbox <- par3d("bbox") ranges <- c(bbox[2]-bbox[1], bbox[4]-bbox[3], bbox[6]-bbox[5]) if (prod(ranges) == 0) 1 else exp(mean(log(ranges))) } writePoints <- function(id) { vertices <- rgl.attrib(id, "vertices") n <- nrow(vertices) radius <- pointRadius*avgScale() for (i in seq_len(n)) writeMesh(pointShape, radius, vertices[i,]) } writeSegments <- function(id) { vertices <- rgl.attrib(id, "vertices") n <- nrow(vertices)/2 radius <- lineRadius*avgScale() for (i in seq_len(n)) { cyl <- cylinder3d(vertices[(2*i-1):(2*i),], radius = radius, sides = lineSides, closed = -2) writeMesh(cyl) } } writeLines <- function(id) { vertices <- rgl.attrib(id, "vertices") n <- nrow(vertices) - 1 radius <- lineRadius*avgScale() for (i in seq_len(n)) writeMesh( cylinder3d( vertices[i:(i+1),], radius = radius, sides = lineSides, closed = -2) ) } knowntypes <- c("triangles", "quads", "surface", "planes", "spheres", "points", "lines", "linestrip") # Execution starts here! if (is.character(con)) { con <- file(con, if (ascii) "w" else "wb") on.exit(close(con)) } filename <- summary(con)$description if (NROW(bbox <- ids3d("bboxdeco")) && (is.null(ids) || bbox$id %in% ids)) { ids <- setdiff(ids, bbox$id) save <- par3d(skipRedraw = TRUE) bbox <- convertBBox(bbox$id) on.exit({ pop3d(id=bbox); par3d(save) }, add=TRUE) # nolint dobbox <- TRUE } else dobbox <- FALSE if (is.null(ids)) { ids <- ids3d() types <- as.character(ids$type) ids <- ids$id } else { if (dobbox) ids <- c(ids, bbox) allids <- ids3d() ind <- match(ids, allids$id) keep <- !is.na(ind) if (any(!keep)) warning(gettextf("Object(s) with id %s not found", paste(ids[!keep], collapse=" ")), domain = NA) ids <- ids[keep] types <- allids$type[ind[keep]] } unknowntypes <- setdiff(types, knowntypes) if (length(unknowntypes)) warning(gettextf("Object type(s) %s not handled", paste("'", unknowntypes, "'", sep="", collapse=", ")), domain = NA) keep <- types %in% knowntypes ids <- ids[keep] types <- types[keep] writeHeader() for (i in seq_along(ids)) switch(types[i], planes =, triangles = writeTriangles(rgl.attrib(ids[i], "vertices")), quads = writeQuads(rgl.attrib(ids[i], "vertices")), surface = writeSurface(ids[i]), spheres = writeSpheres(ids[i]), points = writePoints(ids[i]), lines = writeSegments(ids[i]), linestrip = writeLines(ids[i]) ) if (!ascii) { seek(con, 80) writeBin(as.integer(triangles), con, size=4, endian="little") } invisible(filename) } readSTL <- function(con, ascii=FALSE, plot=TRUE, ...) { # Utility functions and constants defined first; execution starts way down there... triangles <- NULL readHeader <- function() { if (ascii) { ident <- readLines(con, 1) if (!grepl("^solid ", ident)) stop("This does not appear to be an ASCII STL file") } if (!ascii) { seek(con, 80) triangles <<- readBin(con, "integer", n=1, size=4, endian="little") } } readTriangles <- function(n) { if (ascii) { lines <- readLines(con) if (is.null(n)) n <- lines %/% 7 } vertices <- matrix(NA, 3*n, 3) if (!ascii) { for (i in seq_len(n)) { m <- matrix(readBin(con, "double", n=12, size=4, endian="little"), 4, 3, byrow=TRUE) vertices[3*i + c(-2,-1,0),] <- m[2:4,] count <- readBin(con, "integer", n=1, size=2, endian="little") # nolint } } vertices } # Execution starts here! if (ascii) stop("ASCII input not yet supported") if (is.character(con)) { con <- file(con, if (ascii) "rt" else "rb") on.exit(close(con)) } readHeader() vertices <- readTriangles(triangles) if (plot) triangles3d(vertices, ...) else vertices } rgl/R/tkpar3dsave.R0000644000176200001440000000240514100762640013612 0ustar liggesuserstkpar3dsave <- function(params = c("userMatrix", "scale", "zoom", "FOV"), times = FALSE, dev = cur3d(), ...) { if (!requireNamespace("tcltk", quietly = TRUE)) stop("This function requires 'tcltk'") results <- list() for (n in params) results[[n]] <- list() if (times) { start <- proc.time()[3] results$times <- numeric(0) } RecordParms <- function() { values <- par3d(params) if (length(params) == 1) { values <- list(values) names(values) <- params } for (n in params) results[[n]] <<- c(results[[n]], list(values[[n]])) if (times) results$times <<- c(results$times, proc.time()[3] - start) } base <- tcltk::tktoplevel(...) tcltk::tkwm.title(base, "par3d") text <- tcltk::tklabel(base, text="Click on Record to save par3d parameters.", justify="left", wraplength="2i") frame <- tcltk::tkframe(base) save <- tcltk::tkbutton(frame, text="Record", command=RecordParms) quit <- tcltk::tkbutton(frame,text="Quit", command=function()tcltk::tkdestroy(base)) tcltk::tkpack(save, quit, side="left") tcltk::tkpack(text, frame) tcltk::tkwait.window(base) results } rgl/R/animate.R0000644000176200001440000002133514137472630013013 0ustar liggesusers# These quaternion functions are adapted from the orientlib package # Convert an array of rotation matrices to a matrix of unit quaternions toQuaternions <- function(x) { nicesqrt <- function(x) sqrt(pmax(x,0)) q4 <- nicesqrt((1 + x[1,1,] + x[2,2,] + x[3,3,])/4) # may go negative by rounding zeros <- zapsmall(q4) == 0 q1 <- ifelse(!zeros, (x[2,3,] - x[3,2,])/4/q4, nicesqrt(-(x[2,2,]+x[3,3,])/2)) q2 <- ifelse(!zeros, (x[3,1,] - x[1,3,])/4/q4, ifelse(zapsmall(q1) != 0, x[1,2,]/2/q1, nicesqrt((1-x[3,3,])/2))) q3 <- ifelse(!zeros, (x[1,2,] - x[2,1,])/4/q4, ifelse(zapsmall(q1) != 0, x[1,3,]/2/q1, ifelse(zapsmall(q2) != 0, x[2,3,]/2/q2, 1))) cbind(q1, q2, q3, q4) } # Convert a single quaternion to a rotation matrix toRotmatrix <- function(x) { x <- x/sqrt(sum(x^2)) matrix(c(1-2*x[2]^2-2*x[3]^2, 2*x[1]*x[2]-2*x[3]*x[4], 2*x[1]*x[3]+2*x[2]*x[4], 2*x[1]*x[2]+2*x[3]*x[4], 1-2*x[1]^2-2*x[3]^2, 2*x[2]*x[3] - 2*x[4]*x[1], 2*x[1]*x[3] - 2*x[2]*x[4], 2*x[2]*x[3] + 2*x[1]*x[4], 1 - 2*x[1]^2 - 2*x[2]^2), 3,3) } par3dinterp <- function(times=NULL, userMatrix, scale, zoom, FOV, method=c("spline", "linear"), extrapolate = c("oscillate","cycle","constant", "natural"), dev = cur3d(), subscene = par3d("listeners", dev = dev)) { force(dev) force(subscene) if (is.list(times)) { for (n in setdiff(names(times), "times")) assign(n, times[[n]]) if ("times" %in% names(times)) times <- times[["times"]] else times <- NULL } if (!missing(userMatrix) && is.list(userMatrix)) userMatrix <- do.call(cbind, userMatrix) if (!missing(scale) && is.list(scale)) scale <- do.call(rbind, scale) if (!missing(zoom) && is.list(zoom)) zoom <- unlist(zoom) if (!missing(FOV) && is.list(FOV)) FOV <- unlist(FOV) if (is.null(times)) { times <- if (!missing(userMatrix)) 0:(length(userMatrix)/16 - 1) else if (!missing(scale)) 0:(dim(scale)[1] - 1) else if (!missing(zoom)) 0:(length(zoom) - 1) else if (!missing(FOV)) 0:(length(FOV) - 1) } data <- matrix(0, length(times), 0) if (!missing(userMatrix)) { stopifnot( length(userMatrix) == 16*length(times) ) userMatrix <- array(userMatrix, c(4,4,length(times))) xlat <- ncol(data) + 1:4 data <- cbind(data, t(userMatrix[,4,, drop = TRUE])) persp <- ncol(data) + 1:3 data <- cbind(data, t(userMatrix[4,1:3,, drop = TRUE])) rot <- ncol(data) + 1:4 quat <- toQuaternions(userMatrix[1:3, 1:3, , drop = FALSE]) # Since q and -q are the same rotation, we want to interpolate # to the nearer one. for (i in seq_len(nrow(quat))[-1]) { if (sum((quat[i - 1, ] - quat[i, ])^2) > sum((quat[i - 1, ] + quat[i, ])^2)) quat[i, ] <- -quat[i, ] } data <- cbind(data, quat) } else { xlat <- NULL } if (!missing(scale)) { stopifnot( dim(scale)[1] == length(times) ) sc <- ncol(data) + 1:3 data <- cbind(data, log(scale)) } else sc <- NULL if (!missing(zoom)) { stopifnot( length(zoom) == length(times) ) zm <- ncol(data) + 1 data <- cbind(data, log(zoom)) } else zm <- NULL if (!missing(FOV)) { stopifnot( length(FOV) == length(times) ) fov <- ncol(data) + 1 data <- cbind(data, FOV) } else fov <- NULL method <- match.arg(method) extrapolate <- match.arg(extrapolate) if (extrapolate == "oscillate") { n <- length(times) times <- c(times[-n], -rev(times) + 2*times[length(times)]) data <- rbind(data[-n,,drop=FALSE], data[n:1,,drop=FALSE]) n <- 2*n - 1 extrapolate <- "cycle" } else if (extrapolate == "natural" && method != "spline") stop("'natural' extrapolation only supported for spline method") if (method == "spline") { fns <- apply(data, 2, function(col) splinefun(times, col, method = ifelse(extrapolate == "cycle", "periodic", "natural"))) } else { fns <- apply(data, 2, function(col) approxfun(times, col, rule=2)) } mintime <- min(times) maxtime <- max(times) function(time) { if (time < mintime || time > maxtime) { if (extrapolate == "constant" || mintime == maxtime) time <- ifelse(time < mintime, mintime, maxtime) else if (extrapolate == "cycle") time <- (time - mintime) %% (maxtime - mintime) + mintime } data <- sapply(fns, function(f) f(time)) result <- list(dev = dev, subscene = subscene) if (!is.null(xlat)) { userMatrix <- matrix(0, 4,4) userMatrix[,4] <- data[xlat] userMatrix[4,1:3] <- data[persp] userMatrix[1:3,1:3] <- toRotmatrix(data[rot]) result$userMatrix <- userMatrix } if (!is.null(sc)) result$scale <- exp(data[sc]) if (!is.null(zm)) result$zoom <- exp(data[zm]) if (!is.null(fov)) result$FOV <- data[fov] result } } spin3d <- function(axis = c(0, 0, 1), rpm = 5, dev = cur3d(), subscene = par3d("listeners", dev = dev)) { force(axis) force(rpm) force(dev) force(subscene) M <- par3d("userMatrix", dev = dev, subscene = subscene) function(time, base = M) list(userMatrix = rotate3d(base, time*rpm*pi/30, axis[1], axis[2], axis[3]), dev = dev, subscene = subscene) } play3d <- function(f, duration = Inf, dev = cur3d(), ..., startTime = 0) { # Don't want to start timing until args are known: they may be obtained # interactively force(f) force(duration) force(dev) start <- proc.time()[3] - startTime rgl.setselectstate("none") repeat { if(!missing(dev) && cur3d() != dev) set3d(dev) time <- proc.time()[3] - start if (time > duration || rgl.selectstate()$state == msABORT) return(invisible(NULL)) stopifnot(cur3d() != 0) args <- f(time, ...) subs <- args$subscene if (is.null(subs)) subs <- currentSubscene3d(dev) else args$subscene <- NULL for (s in subs) par3d(args, subscene = s) } } movie3d <- function(f, duration, dev = cur3d(), ..., fps=10, movie = "movie", frames = movie, dir = tempdir(), convert = NULL, clean = TRUE, verbose=TRUE, top = !rgl.useNULL(), type = "gif", startTime = 0, webshot = TRUE) { olddir <- setwd(dir) on.exit(setwd(olddir)) for (i in round(startTime*fps):(duration*fps)) { time <- i/fps if(cur3d() != dev) set3d(dev) stopifnot(cur3d() != 0) args <- f(time, ...) subs <- args$subscene if (is.null(subs)) subs <- currentSubscene3d(dev) else args$subscene <- NULL for (s in subs) par3d(args, subscene = s) filename <- sprintf("%s%03d.png",frames,i) if (verbose) { cat(gettextf("Writing '%s'\r", filename)) flush.console() } if (top) rgl.bringtotop() snapshot3d(filename = filename, webshot = webshot) } cat("\n") if (.Platform$OS.type == "windows") system <- shell # nolint if (is.null(convert) && requireNamespace("magick", quietly = TRUE)) { m <- NULL for (i in round(startTime*fps):(duration*fps)) { filename <- sprintf("%s%03d.png",frames,i) frame <- magick::image_read(filename) if (is.null(m)) m <- frame else m <- c(m, frame) if (clean) unlink(filename) } m <- magick::image_animate(m, fps = fps, loop = 1, dispose = "previous") magick::image_write(m, paste0(movie, ".", type)) return(invisible(m)) } else if (is.null(convert)) { warning("R package 'magick' is not installed; trying external package.") convert <- TRUE } if (is.logical(convert) && convert) { # Check for ImageMagick progname <- "magick" version <- try(system2(progname, "--version", stdout = TRUE, stderr = TRUE), silent = TRUE) if (inherits(version, "try-error") || !length(grep("ImageMagick", version))) { progname <- "convert" version <- try(system2(progname, "--version", stdout = TRUE, stderr = TRUE), silent = TRUE) } if (inherits(version, "try-error") || !length(grep("ImageMagick", version))) stop("'ImageMagick' not found") filename <- paste0(movie, ".", type) if (verbose) cat(gettextf("Will create: %s\n", file.path(dir, filename))) convert <- paste(progname, "-delay 1x%d %s*.png %s.%s") } if (is.character(convert)) { convert <- sprintf(convert, fps, frames, movie, type, duration, dir) if (verbose) { cat(gettextf("Executing: '%s'\n", convert)) flush.console() } system(convert) if (clean) { if (verbose) cat(gettext("Deleting frames\n")) for (i in 0:(duration*fps)) { filename <- sprintf("%s%03d.png",frames,i) unlink(filename) } } } invisible(convert) } rgl/R/identify3d.R0000644000176200001440000000437114100762640013431 0ustar liggesusersidentify3d <- function(x, y = NULL, z = NULL, labels = seq_along(x), n = length(x), plot = TRUE, adj = c(-0.1, 0.5), tolerance = 20, buttons = c("right", "middle")) { cat <- function(...) { base::cat(...) flush.console() } opar <- par3d("mouseMode") odisp <- cur3d() on.exit( { disp <- cur3d() if (odisp != disp) try(set3d(odisp), silent=TRUE) if (cur3d() == odisp) par3d(mouseMode = opar) try(set3d(disp), silent=TRUE) } ) xyz <- xyz.coords(x, y, z) x <- xyz$x y <- xyz$y z <- xyz$z if (length(x)==0) return(numeric()) force(labels) force(adj) buttons <- match.arg(buttons, c("left", "right", "middle"), several.ok = TRUE) if (length(buttons > 1)) cat(gettextf("Use the %s button to select, the %s button to quit\n", buttons[1], buttons[2])) else cat(gettextf("Use the %s button to select\n"), buttons[1]) buttons <- c(left=1, right=2, middle=3)[buttons] selected <- NULL select <- function(mousex, mousey) { disp <- cur3d() if (disp != odisp) { set3d(odisp) on.exit(set3d(disp)) } viewport <- par3d("viewport") winxyz <- rgl.user2window(xyz) winxyz[,1] <- winxyz[,1]*viewport[3] winxyz[,2] <- (1-winxyz[,2])*viewport[4] dist <- sqrt( (mousex-winxyz[,1])^2 + (mousey - winxyz[,2])^2 ) dist[winxyz[,3] < 0 | winxyz[,3] > 1] <- Inf sel <- which.min(dist) if (dist[sel] > tolerance) cat(gettext("Warning: no point within tolerance\n")) else if (sel %in% selected) cat(gettext("Warning: nearest point already identified\n")) else { selected <<- c(selected, sel) if (plot) text3d(x[sel], y[sel], z[sel], texts=labels[sel], adj=adj) } } doquit <- FALSE quit <- function(mousex, mousey) { doquit <<- TRUE } rgl.setMouseCallbacks(buttons[1], begin=select) if (length(buttons) > 1) rgl.setMouseCallbacks(buttons[2], begin=quit) while(!doquit && length(selected) < n) Sys.sleep(0.2) selected } rgl/R/obj.R0000644000176200001440000003612414145464133012147 0ustar liggesuserswriteOBJ <- function(con, pointRadius=0.005, pointShape = icosahedron3d(), lineRadius = pointRadius, lineSides = 20, pointsAsPoints = FALSE, linesAsLines = FALSE, withNormals = TRUE, withTextures = TRUE, separateObjects = TRUE, ids = tagged3d(tags), tags = NULL) { writeHeader <- function() { ident <- paste(filename, " produced by RGL") cat("#", ident, "\n", file=con) } Vertices <- 0 Normals <- 0 Texcoords <- 0 writeData <- function(id) { vbase <- Vertices tbase <- Texcoords nbase <- Normals vertices <- rgl.attrib(id, "vertices") cat(paste("v", vertices[,1], vertices[,2], vertices[,3]), sep="\n", file=con) n <- nrow(vertices) Vertices <<- Vertices + n if (withTextures) { textures <- rgl.attrib(id, "texcoords") if (nrow(textures)) cat(paste("vt", textures[,1], textures[,2]), sep="\n", file=con) Texcoords <<- Texcoords + nrow(textures) } if (withNormals) { normals <- rgl.attrib(id, "normals") if (nrow(normals)) cat(paste("vn", normals[,1], normals[,2], normals[,3]), sep="\n", file=con) Normals <<- Normals + nrow(normals) } list(n=n, ntexcoords=if (withTextures) nrow(textures) else 0, nnormals=if (withNormals) nrow(normals) else 0, vbase=vbase, tbase=tbase, nbase=nbase) } refnum <- function(n) sprintf("%d", n) writeTriangles <- function(id) { if (separateObjects) cat("o triangles", id, "\n", sep="", file=con) x <- writeData(id) indices <- refnum(x$vbase + seq_len(x$n)) if (x$ntexcoords) indices <- paste0(indices, "/", refnum(x$tbase + seq_len(x$n))) if (x$nnormals) indices <- paste0(indices, if (!x$ntexcoords) "/", "/", refnum(x$nbase + seq_len(x$n))) indices <- matrix(indices, ncol=3, byrow=TRUE) cat(paste("f", indices[,1], indices[,2], indices[,3]), sep="\n", file=con) } writeQuads <- function(id) { if (separateObjects) cat("o quads", id, "\n", sep="", file=con) x <- writeData(id) indices <- refnum(x$vbase + seq_len(x$n)) if (x$ntexcoords) indices <- paste0(indices, "/", refnum(x$tbase + seq_len(x$n))) if (x$nnormals) indices <- paste0(indices, if (!x$ntexcoords) "/", "/", refnum(x$nbase + seq_len(x$n))) indices <- matrix(indices, ncol=4, byrow=TRUE) cat(paste("f", indices[,1], indices[,2], indices[,3], indices[,4]), sep="\n", file=con) } writeSurface <- function(id) { if (separateObjects) cat("o surface", id, "\n", sep="", file=con) x <- writeData(id) dims <- rgl.attrib(id, "dim") nx <- dims[1] nz <- dims[2] rows <- seq_len(nx) vertices <- matrix(character(0), ncol=3) for (i in seq_len(nz)[-nz]) { indices <- (i-1)*nx + c(rows[-nx],rows[-nx], rows[-1]+nx,rows[-nx]+nx, rows[-1],rows[-1]+nx) cindices <- refnum(x$vbase + indices) if (x$ntexcoords) cindices <- paste0(cindices, "/", refnum(x$tbase + indices)) if (x$nnormals) cindices <- paste0(cindices, if (!x$ntexcoords) "/", "/", refnum(x$nbase + indices)) vertices <- rbind(vertices, matrix(cindices, ncol=3)) } cat(paste("f", vertices[,1], vertices[,2], vertices[,3]), sep="\n", file=con) } writeMesh <- function(mesh, scale=1, offset=c(0,0,0)) { vertices <- asEuclidean(t(mesh$vb))*scale n <- nrow(vertices) vertices <- vertices + rep(offset, each=n) vbase <- Vertices cat(paste("v", vertices[,1], vertices[,2], vertices[,3]), sep="\n", file=con) Vertices <<- Vertices + n if (withTextures && length(textures <- mesh$texcoords)) { tbase <- Texcoords textures <- asEuclidean(t(textures)) cat(paste("vt", textures[,1], textures[,2]), sep="\n", file=con) Texcoords <<- Texcoords + nrow(textures) } else withTextures <- FALSE if (withNormals && length(normals <- mesh$normals)) { nbase <- Normals normals <- asEuclidean(t(normals)) cat(paste("vn", normals[,1], normals[,2], normals[,3]), sep="\n", file=con) Normals <<- Normals + nrow(normals) } else withNormals <- FALSE nt <- length(mesh$it)/3 nq <- length(mesh$ib)/4 if (nt) { indices <- t(mesh$it) cindices <- refnum(vbase + indices) if (withTextures) cindices <- paste0(cindices, "/", refnum(tbase + indices)) if (withNormals) cindices <- paste0(cindices, if (!withTextures) "/", "/", refnum(nbase + indices)) cindices <- matrix(cindices, ncol=3) cat(paste("f", cindices[,1], cindices[,2], cindices[,3]), sep="\n", file=con) } if (nq) { indices <- t(mesh$ib) cindices <- refnum(vbase + indices) if (withTextures) cindices <- paste0(cindices, "/", refnum(tbase + indices)) if (withNormals) cindices <- paste0(cindices, if (!withTextures) "/", "/", refnum(nbase + indices)) cindices <- matrix(cindices, ncol=4) cat(paste("f", cindices[,1], cindices[,2], cindices[,3], cindices[,4]), sep="\n", file=con) } } writeSpheres <- function(id) { if (separateObjects) cat("o sphere", id, "\n", sep="", file=con) vertices <- rgl.attrib(id, "vertices") n <- nrow(vertices) radii <- rgl.attrib(id, "radii") radii <- rep(radii, length.out=n) x <- subdivision3d(icosahedron3d(),3) r <- sqrt(x$vb[1,]^2 + x$vb[2,]^2 + x$vb[3,]^2) x$vb[4,] <- r x$normals <- x$vb for (i in seq_len(n)) writeMesh(x, radii[i], vertices[i,]) } avgScale <- function() { bbox <- par3d("bbox") ranges <- c(bbox[2]-bbox[1], bbox[4]-bbox[3], bbox[6]-bbox[5]) if (prod(ranges) == 0) 1 else exp(mean(log(ranges))) } writePoints <- function(id) { if (separateObjects) cat("o points", id, "\n", sep="", file=con) if (pointsAsPoints) { x <- writeData(id) cat("p", refnum(x$vbase + seq_len(x$n)), "\n", file=con) } else { vertices <- rgl.attrib(id, "vertices") n <- nrow(vertices) radius <- pointRadius*avgScale() if (withNormals && is.null(pointShape$normals)) pointShape <- addNormals(pointShape) for (i in seq_len(n)) writeMesh(pointShape, radius, vertices[i,]) } } writeSegments <- function(id) { if (separateObjects) cat("o segments", id, "\n", sep="", file=con) if (linesAsLines) { x <- writeData(id) indices <- matrix(refnum(x$vbase + seq_len(x$n)), ncol=2, byrow=TRUE) cat(paste("l", indices[,1], indices[,2]), sep="\n", file=con) } else { vertices <- rgl.attrib(id, "vertices") n <- nrow(vertices) n <- n/2 radius <- lineRadius*avgScale() for (i in seq_len(n)) { cyl <- cylinder3d( vertices[(2*i-1):(2*i),1:3], radius = radius, sides = lineSides, closed = -2 ) if (withNormals) cyl <- addNormals(cyl) writeMesh(cyl) } } } writeLines <- function(id) { if (separateObjects) cat("o lines", id, "\n", sep="", file=con) if (linesAsLines) { x <- writeData(id) indices <- refnum(x$vbase + seq_len(x$n)) cat("l", indices, "\n", file=con) } else { vertices <- rgl.attrib(id, "vertices") n <- nrow(vertices) - 1 radius <- lineRadius*avgScale() for (i in seq_len(n)) { cyl <- cylinder3d( vertices[i:(i+1),], radius = radius, sides = lineSides, closed = -2 ) if (withNormals) cyl <- addNormals(cyl) writeMesh(cyl) } } } knowntypes <- c("triangles", "quads", #, "surface", "spheres", "points", "linestrip", "lines", "planes") # Execution starts here! if (is.character(con)) { con <- file(con, "w") on.exit(close(con)) } filename <- summary(con)$description if (NROW(bbox <- ids3d("bboxdeco")) && (is.null(ids) || bbox$id %in% ids)) { ids <- setdiff(ids, bbox$id) save <- par3d(skipRedraw = TRUE) bbox <- convertBBox(bbox$id) on.exit({ pop3d(id=bbox); par3d(save) }, add=TRUE) # nolint dobbox <- TRUE } else dobbox <- FALSE if (is.null(ids)) { ids <- ids3d() types <- as.character(ids$type) ids <- ids$id } else { if (dobbox) ids <- c(ids, bbox) allids <- ids3d() ind <- match(ids, allids$id) keep <- !is.na(ind) if (any(!keep)) warning(gettextf("Object(s) with id %s not found", paste(ids[!keep], collapse=" ")), domain = NA) ids <- ids[keep] types <- allids$type[ind[keep]] } unknowntypes <- setdiff(types, knowntypes) if (length(unknowntypes)) warning(gettextf("Object type(s) %s not handled", paste("'", unknowntypes, "'", sep="", collapse=", ")), domain = NA) keep <- types %in% knowntypes ids <- ids[keep] types <- types[keep] writeHeader() for (i in seq_along(ids)) switch(types[i], planes =, triangles = writeTriangles(ids[i]), quads = writeQuads(ids[i]), surface = writeSurface(ids[i]), spheres = writeSpheres(ids[i]), points = writePoints(ids[i]), lines = writeSegments(ids[i]), linestrip = writeLines(ids[i]) ) invisible(filename) } readOBJ <- function(con, ...) { lines <- readLines(con) instrs <- sub(" .*", "", lines) vertices <- read.table(textConnection(lines[instrs == "v"]), col.names = c("instr", "x", "y", "z"), colClasses = c(instr = "character", x="numeric", y="numeric", z="numeric")) vertices <- with(vertices, rbind(x, y, z)) # nolint subset <- lines[instrs == "vn"] if (length(subset)) { fields <- count.fields(textConnection(subset)) if (!all(fields == 4)) stop("Normals must have 4 fields") vn <- read.table(textConnection(subset), col.names = c("instr", "x", "y", "z"), colClasses = c(instr = "character", x="numeric", y="numeric", z="numeric")) vn <- rbind(t(vn[,2:4]), 1) } else vn <- matrix(numeric(), nrow = 4, ncol = 0) subset <- lines[instrs == "vt"] if (length(subset)) { fields <- count.fields(textConnection(subset)) if (length(unique(fields)) != 1) stop("Textures must have consistent field count") fields <- fields[1] colClasses <- c("character", rep("numeric", fields - 1)) vt <- read.table(textConnection(subset), colClasses = colClasses) if (fields == 2) vt <- cbind(vt, 0) vt <- t(vt[, 2:3]) } else vt <- matrix(numeric(), nrow = 2, ncol = 0) # Get rid of texture and normal info polys <- gsub("/[^ ]*", "", lines[instrs == "f"]) polys <- strsplit(polys, " ") polys <- lapply(polys, function(poly) as.numeric(poly[-1])) # Regexp suggested by Bill Dunlap -- thanks! normals <- gsub("(^| *)([^/ ]*/?){0,2}", "\\1", lines[instrs == "f"]) # nolint normals <- strsplit(normals, " ") normals <- lapply(normals, function(normal) as.numeric(normal[nchar(normal) > 0])) textures <- gsub("(^| *)([^/ ]*/?){0,1}", "\\1", lines[instrs == "f"]) # nolint textures <- gsub("/[^ ]*", "", textures) textures <- strsplit(textures, " ") textures <- lapply(textures, function(texture) as.numeric(texture[nchar(texture) > 0])) nverts <- sapply(polys, length) nnorms <- sapply(normals, length) ntexts <- sapply(textures, length) hasnormals <- nnorms == nverts hastextures <- ntexts == nverts if (any(hasnormals) || any(hastextures)) { # OBJ format allows different normals to be associated # with a single vertex in different polygons. rgl # doesn't, so may need to replicate some vertices. # This could be slow... vlinks <- vector("list", ncol(vertices)) for (i in seq_along(polys)) { nvec <- tvec <- NA if (hasnormals[i]) nvec <- as.numeric(normals[[i]]) if (hastextures[i]) tvec <- as.numeric(textures[[i]]) vvec <- as.numeric(polys[[i]]) for (j in seq_along(vvec)) vlinks[[vvec[j]]] <- rbind(vlinks[[vvec[j]]], c(nvec[j], tvec[j], i, j)) } total <- 0 for (i in seq_along(vlinks)) { # Sort by texture vlinks[[i]] <- vlinks[[i]][order(vlinks[[i]][,2]),,drop=FALSE] total <- total + max(1, length(unique(vlinks[[i]][,2]))) } last <- ncol(vertices) vertices <- cbind(vertices, matrix(NA_real_, 3, total - ncol(vertices))) vnormals <- matrix(0, 4, total) vtexcoords <- matrix(NA_real_, 2, total) for (i in seq_along(vlinks)) { links <- vlinks[[i]] if (nrow(links)) { # Average the normals at this vertex by # summing the homogeneous coordinates for (j in seq_len(nrow(links))) if (!is.na(links[j,1])) vnormals[,i] <- vnormals[,i] + vn[,links[1,1]] # A given vertex may have more than one texture # coordinate; rgl doesn't allow this, so we # duplicate vertices where that happened if (!is.na(links[1,2])) vtexcoords[,i] <- vt[,links[1,2]] same <- duplicated(links[,2]) duped <- FALSE for (j in seq_len(nrow(links))[-1]) { if (!same[j]) { last <- last + 1 vertices[,last] <- vertices[,i] vnormals[,last] <- vnormals[,i] duped <- TRUE } # Update the polygon and texture links to the new copy if (duped) { polys[[links[j, 3]]][links[j, 4]] <- last if (!is.na(links[j, 2])) vtexcoords[,last] <- vt[,links[j, 2]] } } } } } triangles <- do.call(cbind, polys[nverts == 3]) if (!length(triangles)) triangles <- matrix(numeric(), 3, 0) # We build quads transposed, because we're going to stick # it directly into the structure quads <- do.call(cbind, polys[nverts == 4]) others <- which(!(nverts %in% 3:4)) # FIXME: this will be really slow if there are a lot of others # Should pre-allocate extra space. for (i in seq_along(others)) { v <- polys[[others[i]]] tri <- triangulate(t(vertices[,v])) tri <- structure(v[tri], dim = dim(tri)) triangles <- cbind(triangles, tri) } ignored <- unique(instrs) ignored <- ignored[!(ignored %in% c("v", "vn", "vt", "f", "", "#"))] if (length(ignored)) warning(gettextf("Instructions %s ignored", paste0('"', ignored, '"', collapse = ", ")), domain = NA) result <- tmesh3d(vertices, triangles, homogeneous = FALSE, ...) if (length(quads)) result$ib <- quads if (any(hasnormals)) result$normals <- vnormals[1:3,]/rep(vnormals[4,], each=3) if (any(hastextures)) result$texcoords <- vtexcoords result } rgl/R/windows/0000755000176200001440000000000014100762640012731 5ustar liggesusersrgl/R/windows/noOpenGL.R0000644000176200001440000000006014100762640014531 0ustar liggesusers# Windows always uses OpenGL noOpenGL <- FALSE rgl/R/rglMouse.R0000644000176200001440000000421614100762640013162 0ustar liggesusersrglMouse <- function(sceneId, choices = c("trackball", "selecting", "xAxis", "yAxis", "zAxis", "polar", "zoom", "fov", "none"), labels = choices, button = 1, dev = cur3d(), subscene = currentSubscene3d(dev), default = par3d("mouseMode", dev = dev, subscene = subscene)[button], stayActive = FALSE, height = 40, ...) { stopifnot(length(choices) == length(labels)) stopifnot(length(button == 1) && button %in% 1:3) options <- mapply(function(x, y) tags$option(x, value = y), labels, choices, SIMPLIFY = FALSE) for (i in seq_along(choices)) options[[i]] <- tags$option(labels[i], value = choices[i]) default <- which(choices == default) options[[default]] <- tagAppendAttributes(options[[default]], selected = NA) changecode <- 'document.getElementById(this.attributes.rglSceneId.value).rglinstance. setMouseMode(this.value, button = parseInt(this.attributes.rglButton.value), subscene = parseInt(this.attributes.rglSubscene.value), stayActive = parseInt(this.attributes.rglStayActive.value))' result <- tags$select(tagList(options), onchange = HTML(changecode), rglButton = button, rglSubscene = subscene, rglStayActive = as.numeric(stayActive), ...) if (!missing(sceneId) && !is.null(sceneId)) { upstream <- processUpstream(sceneId) if (!is.null(upstream$prevRglWidget)) result <- tagAppendAttributes(result, rglSceneId = upstream$prevRglWidget) } else upstream <- list() if (is.list(upstream$objects)) { if (requireNamespace("manipulateWidget", quietly = TRUE)) return(do.call(manipulateWidget::combineWidgets, c(upstream$objects, list(result, rowsize = c(upstream$rowsizes, height), ncol = 1)))) else warning("Combining widgets requires the 'manipulateWidget' package.", call. = FALSE) } browsable(result) } rgl/R/aspect3d.R0000644000176200001440000000123714100762640013073 0ustar liggesusersaspect3d <- function(x, y = NULL, z = NULL) { if (is.character(x) && pmatch(x, "iso") == 1) { scale <- c(1,1,1) } else { if (is.null(y)) { x <- rep(x, len=3) z <- x[3] y <- x[2] x <- x[1] } for (i in 1:5) { # To handle spheres, repeat this bbox <- .getRanges() scale <- c(diff(bbox$xlim), diff(bbox$ylim), diff(bbox$zlim)) scale <- ifelse(scale <= 0, 1, scale) avgscale <- sqrt(sum(scale^2)/3) scale <- c(x,y,z)*avgscale/scale oldscale <- par3d(scale = scale)$scale if (isTRUE(all.equal(scale, oldscale))) break } } par3d(scale = scale) } rgl/R/bgplot3d.R0000644000176200001440000000706214145464133013112 0ustar liggesuserslegend3d <- function(...) { args <- list(...) bgargs <- setdiff(names(formals(bgplot3d)), c("expression", "...")) idx <- which(names(args) %in% c("sphere", "fogtype", bgargs)) if (length(idx)) { bgargs <- args[idx] args <- args[-idx] } else bgargs <- NULL do.call(bgplot3d, c(list(quote({ par(mar=c(0,0,0,0)) plot(0,0, type="n", xlim=0:1, ylim=0:1, xaxs="i", yaxs="i", axes=FALSE, bty="n") do.call(legend, args) })), bgargs)) } bgplot3d <- function(expression, bg.color = getr3dDefaults("bg", "color"), magnify = 1, ...) { viewport <- par3d("viewport") width <- magnify*viewport["width"] height <- magnify*viewport["height"] if (width > 0 && height > 0) { filename <- tempfile(fileext = ".png") png(filename = filename, width = width, height = height, bg = bg.color) grDevices::devAskNewPage(FALSE) value <- try(expression) dev.off() result <- bg3d(texture = filename, col = "white", lit = FALSE, ...) } else { value <- NULL result <- bg3d(col = bg.color, ...) } lowlevel(structure(result, value = value)) } show2d <- function(expression, face = "z-", line = 0, reverse = FALSE, rotate = 0, x = NULL, y = NULL, z = NULL, width = 480, height = 480, filename = NULL, ignoreExtent = TRUE, color = "white", specular = "black", lit = FALSE, texmipmap = TRUE, texminfilter = "linear.mipmap.linear", expand = 1.03, texcoords = matrix(c(0,1,1,0,0,0,1,1), ncol=2), ...) { save <- par3d(ignoreExtent = ignoreExtent) on.exit(par3d(save)) if (is.null(filename)) { stopifnot(width > 0, height > 0) filename <- tempfile(fileext = ".png") png(filename = filename, width=width, height=height) value <- try(expression) dev.off() } else value <- filename face <- c(strsplit(face, '')[[1]], '-')[1:2] coord <- tolower(face[1]) lower <- face[2] == '-' ranges <- .getRanges(expand = expand) switch(coord, x = { if (is.null(x)) x <- with(ranges, if (lower) x[1] - 0.075*line*diff(x) else x[2] + 0.075*line*diff(x)) if (is.null(y)) y <- with(ranges, c(y[1], y[2], y[2], y[1])) if (is.null(z)) z <- with(ranges, c(z[1], z[1], z[2], z[2])) }, y = { if (is.null(x)) x <- with(ranges, c(x[1], x[2], x[2], x[1])) if (is.null(y)) y <- with(ranges, if (lower) y[1] - 0.075*line*diff(y) else y[2] + 0.075*line*diff(y)) if (is.null(z)) z <- with(ranges, c(z[1], z[1], z[2], z[2])) }, z = { if (is.null(x)) x <- with(ranges, c(x[1], x[2], x[2], x[1])) if (is.null(y)) y <- with(ranges, c(y[1], y[1], y[2], y[2])) if (is.null(z)) z <- with(ranges, if (lower) z[1] - 0.075*line*diff(z) else z[2] + 0.075*line*diff(z)) }) x <- cbind(x, y, z) if (nrow(x) != 4) stop("Exactly 4 corners must be specified.") if (reverse) { temp <- x[2,] x[2,] <- x[4,] x[4,] <- temp } if (rotate) x <- x[(0:3 + rotate) %% 4 + 1, ] result <- quads3d(x, texture=filename, texcoords = texcoords, color = color, lit = lit, texmipmap = texmipmap, texminfilter = texminfilter, ...) lowlevel(structure(result, value = value, xyz = x, texcoords = texcoords, filename = filename)) } rgl/NEWS.md0000644000176200001440000020117214146472747012157 0ustar liggesusers# rgl 0.108.3 ## Major changes * Added `getBoundary3d()` function to extract the boundary edges of a mesh. * Added material property `tag`, a string associated with each object. The value is reported by `ids3d(tags = TRUE)` and may be used to select objects in most functions that use ids, but otherwise is largely ignored by `rgl`. The `tagged3d()` function returns information on tags. * Primitive types (points, lines, segments, triangles, quads) can now accept an `indices` parameter, similar to the indices in `mesh3d` objects. * Added `Buffer` object, based on glTF design, for holding binary data for `rglwidget()`. ## Minor changes * Allowed for a third coordinate in `text3d()`'s `adj` parameter. * Added support for `adj`, `pos` and `offset` to `sprites3d()`. * Added support for `pos` values of `0` (at specified location), `5` (in front of it), and `6` (behind it) in `text3d()`, `sprites3d()` and `plotmath3d()`. * `crosstalk` is now a Suggested package, rather than a required one. * The `Makevars.ucrt` file has been modified with contributions from Tomas Kalibera to work with his winutf8 build of R. * `bgplot3d()` no longer pauses for each page when running examples. * `deldir` version 1.0-2 is incompatible with `rgl`. Added the `checkDeldir()` function to avoid running it. * `shade3d()` treated texture coordinates like colors, and duplicated the first one for the whole face when `meshColor = "faces"` was chosen. Instead, they are now treated like vertex coordinates. (Reported by Michael Sumner in issue #145). * Corrected the documentation and made the implementations of `asHomogeneous()`, `asEuclidean()` etc. more consistent. * An `as.rglscene()` generic has been added, though no methods are defined in this package. * `downlit` 0.4.0 has been released with support for `rgl`, so instructions for installing the devel version have been removed. ## Bug fixes * Fixed rendering of text as sprites3d() objects. * Added `--static` flag to configure script for FreeType installation. (Suggestion of Simon Urbanek and Prof. Brian Ripley.) * `shade3d()`, `wire3d()` and `dots3d()` overrode `"front"` and `"back"` material settings in mesh objects. * rglwidget() handling of bounding box decorations had several bugs. * `rgl` could not find routines in the DLL on some Windows installs (Issue 148.) * Some cases where allocations were not protected have been fixed. # rgl 0.107.10 ## Major changes * Added `expect_known_scene()` function to work with `testthat`. * Added some `testthat` tests. * Prepend a 5th entry to `par3d("mouseMode")`, corresponding to actions to take when no button is pressed. * Allowed any of the mouse modes to be applied to the mouse wheel. * Added the `setUserCallbacks()` function to allow user-specified mouse callbacks in WebGL code. * Added Javascript code for support of movable axis labels in `bboxdeco` objects. * Most drawing functions can now draw in the margins using new material properties `margin` and `floating`, with objects that move as the bounding box changes. See `?mtext3d` for details. * The `mtext3d()` argument order has changed. * Added the `setAxisCallbacks()` function to allow user-specified axis drawing routines. * Exposed (and generalized) the `as.tmesh3d()` function. ## Minor changes * The `shiny` and `manipulateWidget` packages have been changed from imports that are always loaded to suggested packages that will only be loaded if needed. This will reduce the "footprint" of `rgl` for users who don't use them. * The NULL device can now specify `par3d("useFreeType")` and the result is saved. * Code to work with pre-1.33 versions of `knitr` has now been removed. * Added documentation of Javascript to web page. * The handling of the `RGL_DEBUGGING` environment variable has changed: now it must look like `TRUE` to trigger Javascript debugging mode. * Argument `webshot = TRUE` has been added to `movie3d` (issue #113). * The assert() macro is now always defined. * In Windows, the `WM_PAINT` handler should be more tolerant of code called while painting. * `as.mesh3d.default()` can create segments. (Contributed by Michael Sumner.) * `compare_proxy.mesh3d()` has been modified to be compatible with both current and upcoming versions of `waldo`. ## Bug fixes * The bug workaround in 0.105.22 for issue #27 triggered a bug in RStudio, resulting in two RStudio processes showing up when `rgl` was loaded. The workaround is now skipped when RStudio is detected. Use `options(startQuartz = TRUE)` in RStudio before loading `rgl` to run it, or `options(startQuartz = FALSE)` to suppress it. * In some cases, snapshots in `rmarkdown` documents were produced at the wrong size. * Controls failed to modify sphere colors (e.g. as in `example(playwidget)`, issue #102) # rgl 0.106.8 ## Bug fixes * Some of the changes related to avoiding `testthat` errors in other files accidentally introduced a new error in coloring meshes in `rgl`: now fixed. * `readOBJ()` was broken by the 0.106.x changes. * `merge.mesh3d()` failed for meshes containing points or segments. # rgl 0.106.6 ## Major changes * Changes for `pkgdown` compatibility have been added. See `vignette("pkgdown")`. * Added `drape3d()`, to "drape" objects across a mesh. (Contributed by George Helffrich.) * Added `shadow3d()` to project one mesh onto another. * Added `facing3d()` to subset a mesh to parts facing in a particular direction. * Meshes may now include points and line segments as well as triangles and quads. The arguments to `as.mesh3d.default()` have changed accordingly, and a new function `mesh3d()` has been added. * Reformatted the `inst/NEWS` file so it is visible here. * Added `asHomogeneous2()` and `asEuclidean2()` to work directly with `3 x n` and `4 x n` matrices. * Added `rglExtrafonts()` to load additional fonts for use with FreeType rendering. Requires the `extrafont` package. ## Minor changes * The help pages have been edited to continue to de-emphasize `rgl.*` functions. * Changes have been made for compatibility with the experimental Windows-UTF8 build of R. * Allowed infinite values for strip limits in `filledContour3d()`. * Setting material property `point_antialias = TRUE` now gives round points in `rglwidget()` displays. * The reuse argument in `rglwidget()` is no longer used. * Sphere initialization in WebGL displays is now done entirely in Javascript. * Set "window_group" in X11 so `rgl` windows are grouped, based on code by Ivan Krylov. * `filledContour3d()` now accepts levels in decreasing order. * `mergeVertices()` and `as.mesh3d.rglId()` have been improved. * `r3dDefaults$useFreeType` is now set to `FALSE` on Windows, so that system fonts will be used by default. * Text `family = "symbol"` has never really worked, and is no longer recommended. * Added `compare_proxy` method in case a recent `testthat` is being used. ## Bug fixes * The width and height of an `rglwidget()` once again adapt to the viewer window in RStudio (issue #74). # rgl 0.105.22 ## Minor changes * Add `Biarch` to `DESCRIPTION` so both architectures are built on Windows. ## Bug fixes * Fixed error in new args to `snapshot3d()` (reported by Tony Hirst: https://github.com/dmurdoch/rgl/issues/21 .) * Improved test for presence of WebGL (suggested by Git Demont, https://github.com/dmurdoch/rgl/issues/31 ). * On macOS an interaction between `rgl` and the `quartz()` device caused a segfault (see issue #27). Added workaround. (reported by Rich Heiberger, https://github.com/dmurdoch/rgl/issues/27). * Fixed a bug affecting fat (`lwd > 1`) line segments in `rglwidget()`. * A bug in the `Makevars` files caused builds using a parallel make to fail. * A bug in conversion of displays to WebGL prevented planes from displaying properly. * In `rglwidget()`, background images could cause other parts of the display to disappear. # rgl 0.105.13 ## Major changes * Inclusion in `knitr` documents will now be simplified in versions of `knitr` that incorporate its PR#1892. * Added `webshot` argument to `snapshot3d()`, to use the `webshot2` package (currently only available from Github; see `?snapshot3d` for details) to produce snapshots even on headless systems. * Moved development home from R-forge to Github. ## Minor changes * Windows builds now download Freetype from `rwinlib` during the build. (Contributed by Jeroen Ooms.) * `shinySetPar3d()` now accepts a list, as returned in `input$par3d` by `shinyGetPar3d()`, as input. (Suggestion of Yohann Demont.) * The default color scheme for `filledContour3d()` changed in R versions previous to 3.6.0, as `hcl.colors()` didn't exist in those versions. (Reported by Daniel Baston.) * Testing shows that with the above change, `rgl` will now work in R versions from 3.3.0 up. * `snapshot3d()` now defaults to writing to a temporary file instead of failing if no filename is given. * Both `snapshot3d()` and `rgl.snapshot()` now return the output filename invisibly. * `rglwidget()` no longer tries to include both a snapshot and a WebGL scene: it can only do one or the other. * Now builds the non-OpenGL DLL and puts it in `inst/useNULL`, so `options(rgl.useNULL=TRUE)` before loading `rgl` will cause it to not use X11 at all. * Made the startup code more resilient in case X11 isn't working. * Set up a `drat` repository to hold the unreleased `webshot2` package. ## Bug fixes * Some bugs in `thigmophobe3d()`, `mergeVertices()` and `as.mesh3d.default()` have been fixed. # rgl 0.104.16 ## Minor changes * Added `--disable-opengl` configure option to run entirely without OpenGL (to support Apple M1 machines without GLX, and others which don't have X11 or OpenGL devel files installed). * Added explicit typecasts to suppress compile warnings. * Restored some of the Windows configuration from pre-0.101.2 to allow use on older R versions. * Dropped use of `mathjaxr`, which caused issues on Debian. * Experimental support for handling mouse selection in Shiny added, along with `"shinyMouse"` demo. * The result of `open3d()` now has class `"rglOpen3d"`, and `knitr` will use this during auto-plotting. ## Bug fixes * Fixed bug in `rglwidget()` that caused it to fail to display text if too many strings were in the same object. (Reported by Yohann Demont.) * Fixed some small bugs, found by `lintr`. * Fixed bugs in Shiny support, and moved Shiny demo code into single files in demo directory. * Fixed bugs in `addNormals.mesh3d()` method, added `angleWeighted` argument, defaulting to `TRUE`. * Fixed bugs in `rglwidget()` displays of transparent spheres. # rgl 0.103.5 ## Major changes * Added `clipObj3d()`, `contourLines3d()` and `filledContour3d()` functions. * Modified `clipMesh3d()` function to make it more consistent with the above three functions. The main incompatibility with the version in 0.100.26 is that only vertex coordinates are now passed to the clipping function. ## Minor changes * Add `merge()` method for `"mesh3d"` objects, and use it in `filledContour3d()`. * More deprecation of older `writeWebGL()` style controls. * Add extra `knitr` hooks, so support for `rgl` should be very similar to support for standard graphics output. * Major rewrite of the WebGL code so that transparency is handled better in `rglwidget()`. It has also been split into multiple files which are joined with "minification" on installation. * Added utility function `makeDependency()` to support Javascript library in source. * WebGL code now supports fog in scenes. The default `r3dDefaults` now sets `material$fog` to `TRUE`, and `bg$fog` to `"none"`. (In `rgl`, fog must be set *both* in the background and in the object to display.) The formula used in WebGL is slightly different than in the internal R display.) * `getr3dDefaults()` now has two optional arguments to specify what to retrieve, e.g. `getr3dDefaults("material", "color")` to retrieve `r3dDefaults$material$color`, with NULL if either part is missing. * Added `fogScale` parameter to `bg3d()` and `rgl.bg()` to allow increased or decreased fog. * Added `fastTransparency` parameter to `spheres3d()` and `rgl.spheres()`, to allow them to be drawn more quickly when transparency is used. * `"mesh3d"` methods for `shade3d()`, `wire3d()`, and `dots3d()` have been rewritten to share code, allowing meshes to have different front and back material properties. * New functions `cur3d()`, `set3d()`, `close3d()` and `ids3d()` have been added. Generally, users should use these rather than `rgl.cur()`, `rgl.set()`, `rgl.close()` and `rgl.ids()`. * `snapshot3d()` now has optional width and height parameters for the saved snapshot. * the cursor now reflects the mouse mode in `rglwidget()` displays. * Texture coordinates in mesh objects now act the same as colors with respect to the `meshColor` variable. * Touch events are now supported in WebGL. * Added `"snapshot"` `knitr` option to use when autoprinting. * Added defaults to `snapshot3d(width = NULL, height = NULL)`. * Added `as.mesh3d.rglobject()` method. * Added `clip_to_density` argument to `plot3d.lm()` method. * The build files have been updated to work with Rtools40 on Windows. * `rglwidget()` now saves a copy of the original scene, so it can be reconstructed or modified later. ## Bug fixes * Fixed some memory leaks found by `valgrind`, and problems seen on systems with no functional Asymptote or Pandoc. * A bug in the initial color of a mesh object has been fixed. * A bug in translating mouse coordinates (reported on StackOverflow by Richard Morey) when an `rgl` widget is included in a `Gitbook` has been fixed. * Modified `writeASY()` for compatibility with Asymptote 2.65. (Reported by Pavel Stříž.) * `pop3d()` has been modified slightly so that it no longer opens a new window if none is already present * added `setGraphicsDelay()` function to work around bug in macOS Catalina XQuartz. * Made various improvements to reduce notes and warnings during install, including suppressing deprecated OpenGL warnings on macOS. * Some declarations in WebGL made assumptions that were not valid on mobile devices. * The `"depth_mask"` material property was being ignored in `rglwidget()`. * `rgl.snapshot()` and `rgl.postscript()` could crash if a zero length filename was passed to them. # rgl 0.100.54 ## Minor changes * Changed `rgl.attrib(id, "normals")` so the normals will be returned whether or not the object is lit. (Suggestion of Tyler Morgan-Wall) * The labels used in `rglwidget()` are now independent of `set.seed()`, using code borrowed from Shiny for our own private RNG. * `getr3dDefaults()` now gets values from `rgl::r3dDefaults` if they are not present in the user's `r3dDefaults` list. * `bgplot3d()` now uses the background colour from argument `bg.color` (defaulting to the background color from `getr3dDefaults()`) rather than always choosing white. * The maintainer email address has been changed to murdoch.duncan@gmail.com. ## Bug fixes * Fixed bug in `plot3d.rglscene()` that caused restored subscenes to ignore the mouse. * `next3d()` no longer messes up when a user changes active subscenes. * If a sufficient version of Pandoc is not found, the vignettes will still run, but won't execute any `rgl` code. # rgl 0.100.50 ## Minor changes * Added `?rgl.init` help topic to describe initialization issues. * Added sanity check to setting of `par3d("windowRect")`. ## Bug fixes * Rewrote the initialization code to deal with problems related to indirect GLX and `Xvfb`. # rgl 0.100.47 ## Minor changes * `demo(stereo)` now uses `plot.raster()` rather than `image()`. * Added a section on textures to the main vignette. * The configure script has been updated. * The functions in the `tkrgl` package have been moved into `rgl`. * Demo tests are suppressed when run with the `rgl` null device. * The `anaglyph()` function in the `"stereo"` demo now prints information about failed pixel reads. * Included textures have been compressed (and in some cases repaired). * The tests of the demos have been moved to `inst/slowTests` so that running them is optional (and the CRAN checks will go faster). ## Bug fixes * Fixed a bug in `readOBJ()` that affected reading texture coordinates. * `rgl.pixels()`, `rgl.snapshot()` and `snapshot3d()` now read from the back buffer, which should increase reliability. * Fixed bug when setting `windowRect`: `viewport` was not always updated. * Fixed bug in handling mouse wheel events: they were not directed to the correct subscene. * Fixed bug in configure script for systems with `pkg-config` but no freetype2. * Fixed bug that caused `bg3d()` and `bgplot3d()` to wipe out fog setting. * Fixed `writeASY()` to work with a more recent version of Asymptote. Use `ver244 = TRUE` for the older version. * `plot3d(..., type = "s", add = TRUE)` chose a bad default radius for the spheres -- possibly even zero. * `planes3d()` could fail to draw the plane if it intersected a vertex of the bounding box of the scene. * In Shiny, controllers like `rglMouse()` did not automatically link to an `rglwidget()`. # rgl 0.100.30 ## Minor changes * Added `meshColor` as an argument to `tmesh3d()`, `qmesh3d()` and `dot3d()`; changed default to no longer give warning if `meshColor` is not specified. * Added `all.equal()` method for `"mesh3d"` objects, so that changes caused by the above are ignored. * Added `tri_to_keep` argument to `as.mesh3d.ashape3d()` for compatibility with conflicting method from `nat` package version 1.8.11. * Removed deprecated C++ functions `std::bind2nd` and `std::ptr_fun` as requested by CRAN. Other changes to remove compile warnings also made. # rgl 0.100.26 ## Major changes * added `clipMesh3d()` to allow smooth clipping of mesh objects * Made `plot3d.lm()` method handle a larger variety of models, by allowing for curved surfaces. * Added `as.mesh3d.default()` method to convert triangles or quads to a `"mesh3d"` object. * Added `as.triangles3d()` generic with methods to convert `"mesh3d"` objects into matrices representing triangles. * Added `as.triangles3d.rglId()` and `as.mesh3d.rglId()` methods to convert displayed objects to usable data. ## Minor changes * `open3d()` now signals an error if unnamed parameters are used * `toggleWidget()` now makes it easier to initialize the scene with some objects hidden. ## Bug fixes * Fixed the startup code so that systems that don't provide `uname` still work. (Suggestion of Settra Khemri.) # rgl 0.100.24 ## Bug fixes * Fix `thigmophobe3d()` to try to keep up with changes in `plotrix::thigmophobe()`. * Stop `rgl.postscript()` from writing files to current directory # rgl 0.100.19 ## Bug fixes * Fix some bugs detected by `valgrind` # rgl 0.100.18 ## Major changes * Added `shinyGetPar3d()` and `shinySetPar3d()` functions for Shiny interaction. * Added `thigmophobe3d()` function to place labels away from other points using `plotrix::thigmophobe()`. * Added `arc3d()` function to draw spherical arcs. * Added `"polygon_offset"` material property, to allow lines to be drawn on surfaces. * Added `plot3d()`, `persp3d()` and `as.mesh3d()` methods for `"triSht"` and `"tri"` classes (produced by `interp` and `tripack` packages.) * `plot3d()` methods for objects of class `"formula"` and `"lm"` and a `persp3d()` method for objects of class `"formula"` have been added. (A bug in the implementation of `as.mesh3d.deldir()` was found and fixed during the latter addition.) * `as.mesh3d()`, `plot3d()` and `persp3d()` methods for `"ashape3d"` objects from the `alphashape3d` package have been added. * The mouse mode (trackball, zoom, etc.) can now be applied separately to each individual subscene in a scene. (By default the mode is inherited from the root subscene.) * Added `par3d("userProjection")`, to allow the user to supply a change to the projection after all other display calculations have been done. * Added `par3d("activeSubscene")`, to allow mouse callback functions to determine which subscene was clicked. ## Minor changes * Added check for `"highp"` support to fragment shader in `rglwidget()`. * Updated `text3d()` and related functions: dropped deprecated argument `justify`, added `pos` and `offset` like base graphics `text()`. * Improved support of `"mesh3d"` objects: added print methods, added `meshColor` argument to `wire3d()` and `shade3d()` to control how colors are interpreted, added `"rgl.meshColorWarning"` option to control warnings about these changes. * The `plot3d.mesh3d()` method now has the same default for `aspect` as the default method. * `pch3d()` now allows separate `color` and `bg` specifications for each point. In addition, the default for the `"lit"` material property is now `FALSE`, so by default filled symbols will match the requested colour regardless of lighting. * Minor fix ups to the vignettes. * Now uses the `manipulateWidget::combineWidgets` function when putting multiple objects into a pipe. * Now accepts fixed CSS units in width and height for `rglwidget()`. * `playwidget()` is no longer an S3 generic function. * The configure code to detect freetype has been updated to use `pkg-config` (code contributed by Dirk Eddelbuettel.) * If a `playwidget()` has been initialized but it can't find the `rglwidget()` that it is controlling (likely due to a typo somewhere), it now throws an alert message. ## Bug fixes * Fixed texture bug introduced in fix in 0.99.16. * The `persp3d.deldir()` method didn't display labels properly. * When the X11 initialization failed, `rgl` messed up the S3 methods system. (Reported by Gregory Jefferis.) * Probably due to a compiler change, `rgl.bbox()` was returning 0/1 instead of the id of the axes. * `pch3d()` was failing in `rglwidget()` for some shapes. (Reported by Luca Scrucca.) * `par3d(mouseMode = "none")` was not implemented properly, so appeared to be a no-op. * Selection functions did not work well with subscenes. * Deleting an object that has been added as a 3D sprite caused `rgl` to crash. * A number of memory bugs found by `rchk` have been fixed. * Textures specified in global material list (e.g. by being used in `rgl.*` functions) were not handled properly. (Reported by Ty Tuff.) # rgl 0.99.9 ## Major changes * Added support for communication with other widgets using the `crosstalk` package. See `?rglShared` and `vignette("WebGL")` for details. * Added the `rglMouse()` function to allow the mouse mode to be changed in a WebGL display. ## Minor changes * Christophe Geuzaine's GL2PS library (used by `rgl.postscript()`) updated to version 1.4.0. * The Pandoc system requirement has been updated to 1.14, as 1.13.1 is no longer sufficient. ## Bug fixes * Fixed a bug causing the `rglwidget()` to fail to work in a `flexdashboard()` display. * Fixed a bug in Shiny interaction * Changed WebGL text rendering to avoid overloading browser. * Sphere rendering within R sometimes showed strange artifacts. # rgl 0.98.22 ## Minor changes * Record context (`ioslides`, `shiny`, etc.) in scene when `rglwidget()` is called. * Allow more than 16 scenes in `html_document`, `ioslides_presentation` and `slidy_presentation`. * `useSubscene3d()` now returns the id of the previously active subscene, to make temporary changes more convenient. * `renderRglwidget()` and `renderPlaywidget()` now have an optional argument `outputArgs` for use in dynamic R Markdown documents. * `rglwidget()` now warns if an object has too many vertices. * added an approximation to "polar" mouse controls to WebGL display. * the `"centers"` attribute now refers to the individual facets of spheres, rather than the whole sphere. Use `"vertices"` for that. * Tried to give a more helpful startup error message on macOS. * Added documentation to `rglwidgetClass` in Javascript. * `vertexSetter()` can now set plane parameters. * Modified `platform.cpp` so it works with `__STRICT_ANSI__` defined. * As many browsers have dropped support for setting line width in WebGL scenes, this has been redone in `rglwidget()` code using a vertex shader. Line endings and joins are rounded, not squared as in OpenGL. * The 65535 vertex limit has been removed (at least in browsers that support big indices). * The requirement that colors being controlled by an `ageControl()` or `vertexControl()` be duplicated in the original has been removed. ## Bug fixes * The rendering order is changed: now all opaque objects are drawn first, then all transparent objects. Previously this ordering was only done within subscenes, leading to rendering errors when transparent objects in one subscene were drawn before opaque objects in another. * transparent spheres sometimes showed rendering artifacts because they were not drawn from back to front. (Reported by Atte Tenkanen; original fix improved so nested spheres should now work. WebGL display could still be improved.) * `par3dinterp()` did not always choose the best direction for interpolation of the `userMatrix`. * The `toggleWidget()` function didn't work properly in Shiny. * Fixed addition of attribute to NULL. * Fixed bug where textures or normals caused `readOBJ()` to fail; added support for reading normals and texture coordinates. * `axes3d("bbox")` didn't send parameters to `bbox3d()`. * Fixed examples for `snapshot3d()` and `writeASY()` so that they don't change the working directory. # rgl 0.98.1 ## Minor changes * Cleaned up configure script. * Cleaned up dynamic entry points. * Added `add = FALSE` argument to `persp3d.deldir()`. * `"shiny.tag"` objects are now supported as inputs to `playwidget()`, so that `rglwidget()` values can be wrapped in `htmltools::div()` to set their style. * Added `figWidth()` and `figHeight()` functions for sizing `rgl` plots in R Markdown documents. ## Bug fixes * `layout3d()` handled multi-row cells incorrectly. (Reported by Felix Carbonell.) * Fixed a bug in `subsetControl()`, and added `toggleWidget()` * Renamed the `texture` argument to `persp3d.function()` to `texcoords` for consistency with other functions, and to avoid a collision with the `"texture"` material property. * Fixed bug in scene initialization that sometimes caused it to ignore initial control values. # rgl 0.97.0 ## Major changes * Added `plotmath3d()` function, and set `text3d()` to use it when necessary. ## Minor changes * Added `fixedSize` argument to `rgl.sprites()` and related functions. * ` material3d()` now silently ignores attempts to set read-only properties. * Added `setUserShaders()` for user-specified shaders (currently for WebGL only). * Added support for two-sided surfaces in WebGL. * Added `demo("rglExamples")` to display all the examples in the `rgl` help in a collection of web pages. This showed up a number of small bugs, which have been fixed. * `movie3d()` now optionally tries the R `magick` package first, then the external ImageMagick v7 command `magick` before trying `convert`. (The external change suggested by Earl F. Glynn.) * `par3d()` reports on the version of OpenGL that it sees (as component `"glVersion"`). ## Bug fixes * Fixed bug in conversion of bounding box decorations used in `rglwidget()`. * `addNormals()` gave an error if the mesh it was working with had degenerate triangles or quads. (Reported by Rolf Turner and Graham Griffiths.) * Auto-clipping sometimes changed result vectors into lists. * The controllers did not recycle some values correctly. * Fixed bug in initialization of `playwidget()`s. * Fixed some bugs in `pch3d()` (reported by Gina Joue). # rgl 0.96.0 ## Major changes * Added `as.mesh3d()` and `plot3d.deldir()` and `persp3d.deldir()` methods to allow plotting of surfaces defined by irregular collections of points. * Added `rglToLattice()` and `rglToBase()` functions to compute Euler angles for the `lattice::wireframe()`, `lattice::cloud()`, and base graphics `persp()` functions. * Added `arrow3d()` (based on the function of the same name in the `heplots` package). * Added `pch3d()` to give an approximation to plotting symbols using `pch=` in base graphics. * Added support for control of multiple subscenes to `spin3d()`, `par3dinterp()`, `play3d()` and `movie3d()`. * Added experimental function `writeASY()` for output in Asymptote format, which will allow inclusion in PDF files. * Added `rgl.attrib.info()` to display information about object attributes. * Merged `rglwidget` code back into `rgl`. * Functions that modify the scene now return their value with class `"rglLowlevel"` or `"rglHighlevel"` (using the new `lowlevel()` or `highlevel()` functions) to indicate that a low- or high-level plotting function has been called. If the new option `"rgl.printRglwidget"` is `TRUE`, printing objects of either class will trigger automatic printing of the `rgl` scene using `rglwidget()`. ## Minor changes * Gave better error when XQuartz is not found, tried for better test. * Added more information on backgrounds to `scene3d()` to allow them to be used in `rglwidget()`. * Now uses forward slashes in `rgl.postscript(fmt = "tex")` generated code. (Thanks to Uwe Ligges for the problem report.) * `cylinder3d()` now defaults to a rotation minimizing local frame. * Added this NEWS file. * Added better support for backgrounds. * Added support for orthographic projections (`FOV = 0`). * Added simple Shiny demo using tabs. * Added version dependency for `jsonlite` so that the new faster matrix code will be used. * The worker functions used by `subdivision3d()` have been exported for use on their own. * The `rglwidget()` code now supports textures on spheres. It now uses the same mesh as the one used inside R. (The lack of support was pointed out by Justin McManus.) ## Bug fixes * Background clearing was not handled properly. (Thanks to Paul Morse for a bug report on this.) * Fixed bug in rendering unlit 3D sprites. * Web browsers only support a finite number of active WebGL sessions; `rglwidget()` code now works to make more careful use of this finite resource, so that large numbers of `rgl` scenes can be present on a single web page without exhausting it. # rgl 0.95.1441 ## Bug fixes * Changed `rgl.pixels()` to attempt to avoid segfault on OSX. (Thanks to Greg Jefferis for testing and workaround.) # rgl 0.95.1435 ## Major changes * The Mac OS X native windowing system (`aglrgl.so`) has been dropped; it appears not to work in Yosemite and El Capitan. * WebGL code has been moved to the `rglwidget` package (though the functions in `rgl` still work). ## Minor changes * If `rgl.init()` fails, continue with the `NULL` device (with warnings). * `scene3d()` now returns the normals and offsets of "planes" objects, as with "clipplanes" objects. It still returns the triangles from embedding the planes in the most recent subscene. ## Bug fixes * A memory leak when drawing semi-transparent objects has been fixed. (Reported by Felix Kuehnl.) * Bounding box objects sometimes had miscalculated vertices in `scene3d()`. # rgl 0.95.1367 ## Major changes * Added `show2d()` to allow a 2d plot on a quadrilateral in a scene. * Added `matrixSetter()` function to allow multiple controls to modify one matrix. * Added `vertexSetter()` function to allow easier access to vertex attributes. ## Minor changes * Made error and warning text more consistent. * Dropped chunk option `"rgl.keepopen"`; replaced it with `"rgl.newwindow"`. * Added `accumulate` argument to the subset WebGL controls. * The `nticks` argument to `bbox3d()` was never used and has been removed. Use `xlen`, `ylen` or `zlen`. * Dependencies and imports have been updated. * Used Jeroen Ooms' `js::jshints()` function to clean up the WebGL Javascript code. * Allowed `values = NULL` in `propertySetter()` and `vertexSetter()` to allow code to directly set values. * Shaders are now stored in Javascript strings, not separate script sections. * Shape centers are now stored by `scene3d()`. * Font family and numeric font number (style) are now returned by `rgl.attrib()` and are stored by `scene3d()`. ## Bug fixes * Fixed bug that sometimes prevented textures from displaying. * `rgl.bbox()` (and hence `bbox3d()`, `decorate3d()`, `plot3d()`, etc.) did not return the correct id for the bounding box decoration. * Modified configure script to work with OS X 10.11 (suggestion of Brian Ripley). * Setting `xlen` etc. to zero in `bbox3d()` or `rgl.bbox()` now (correctly) suppresses tick marks. (Reported by Philipp Angerer.) * Specifying `normals` or `texcoords` in both a `"mesh3d"` object and a call to `shade3d()` to display it caused an error; now the `shade3d()` specified value has priority if `override = TRUE` (the default). * When used with clipping on the bounds, `persp3d()` and `plot3d()` did not work properly with a shared mouse. (Reported by Marian Talbert.) * Fixed a bug (reported by Dominick Samperi) that caused vignettes using WebGL code in `knitr` to fail to initialize properly. This required adding the `setupKnitr()` function, which should be called at the start of each vignette. It is *not* called automatically. * Fixed a bug (reported by Kurt Hornik) that caused `rgl` to fail to compile when `libfreetype` 2.6 was linked. * Fixed a bug in `writePLY()` (reported by Kurt Hornik). # rgl 0.95.1247 ## Major changes * Added `subsetSlider()`, `subsetSetter()`, `clipplaneSlider()`, `propertySlider()`, `ageSetter()`, `propertySetter()`, `par3dinterpSetter()` and `toggleButton()` functions to output HTML/Javascript controls for WebGL. * Added `hook_rgl()` and `hook_webgl()` functions, based on the `knitr` functions. * Added clipping regions to `plot3d()` and `persp3d()`. * Export the `GramSchmidt()` function (request of Remko Duursma) * Added `readOBJ()`, with a very limited ability to read OBJ shapefiles. ## Minor changes * If a template file is used in `writeWebGL()`, the string `%prefix%` will be replaced in it by the prefix argument. * `writeWebGL()` now outputs a Javascript global variable named `"rgl"` of class `"rglClass"` that allows access to many of the scene internals. (Inspired by patch submitted by Jeff Allen.) * User mouse callbacks can now be retrieved within R using `rgl.getMouseCallbacks()` and `rgl.getWheelCallback()`, and may be included in WebGL output. * `writeWebGL()` now outputs information on object ids to allow them to be re-used in multiple figures on the same page. See the `reuse` parameter and attribute of the result. * Started a vignette describing user interaction in WebGL. * Set the class of the main `"canvas"` element in `writeWebGL()` output to `"rglWebGL"`. * `rgl.snapshot()` now evaluates the `top` argument after `filename` and `fmt`, so windows created when those are evaluated don't overlay the `rgl` window. (Suggestion of Keith Jewell.) * `writeWebGL()` now includes an argument `commonParts`, to allow omission of common code in multi-figure displays. * If `template` is `NULL` in `writeWebGL()`, no template file is used. * The `persp.function()` method is now smarter about setting default axis labels. * The package now contains a vignette giving an overview of the functions. * `triangulate()` now supports polygons expressed with 3 coordinates (though they are still assumed to be planar). * `par3d()` now includes `"listeners"`, a list of subscenes that respond to mouse actions in the current subscene. * The Windows configuration file has been modified to work in R-devel (to become R 3.2.0). ## Bug fixes * Fixed bug in `abclines3d()` that caused it to skip lines that passed through the corners of the bounding box. (Reported by Sven Laur.) * The `NULL` device did not handle changes to `par3d("windowRect")` properly. * Subscenes with `ignoreExtent = TRUE` were not plotted. * The bounding box calculations now take clipping planes into account. * `writeWebGL()` did not display the `bboxdeco` properly when working in a subscene. # rgl 0.95.1158 ## Minor changes * `rgl.snapshot()` now works with the `NULL` device (but produces a black snapshot). This allows testing with `RGL_USE_NULL`. # rgl 0.95.1157 ## Major changes * Allowed background of window to show bitmap; added `bgplot3d()` and `legend3d()` functions. ## Bug fixes * Reverted misguided changes to `par3d("modelMatrix")` from 0.94. This affects `rgl.projection()` as well. * Fixed bug (introduced in 0.94) causing loss of rectangle showing selection area. (Reported by John Fox and others.) * The `NULL` device now does not make any spurious OpenGL calls. # rgl 0.94.1143 ## Major changes * Added function methods for `persp3d()` and `plot3d()`, to allow surfaces to be plotted just by specifying the function. ## Bug fixes * Fixed a bug introduced in 0.94 that made user callbacks crash R. (Reported by Dave Hadka.) * Fixed a bug exposed in 0.94 (but really introduced in 0.93.952) that caused `writeWebGL()` to fail when a `NULL` device was active. * Fixed a bug introduced in 0.94 with writing 3D sprite objects. * Fixed a bug computing the bounding box of an embedded subscene. # rgl 0.94 ## Major changes * Added "subscenes", i.e. scenes of objects nested within the main window. This affects a lot of other functions as well, which now act either on a single subscene or on the overall scene. * Added configurable mouse wheel actions via `par3d()` or `rgl.setWheelCallback()`. ## Minor changes * Allowed the coordinates of the viewport to be set. * Changed the behaviour of `pop3d()` and `rgl.pop()`: the type is now ignored if `id` is non-zero. * `par3d("modelMatrix")` no longer includes the observer translation * The `par3d()`, `par3dinterp()`, and `spin3d()` functions now have arguments dev and subscene to specify where they apply. * Included a copy of the source to `CanvasMatrix.js` (used by `writeWebGL()`) at the request of the Debian administrators. * Some of the animations have been sped up at the request of CRAN. ## Bug fixes * The `NULL` device was not removed from the device list when it was closed. (Reported by Henrik Bengtsson.) # rgl 0.93.1098 ## Minor changes * `rgl.material()` (for textures), `rgl.postscript()` and `rgl.snapshot()` now call `normalizePath()` on filenames, so tilde expansion should be supported. * internals are updated to be consistent with macOS 10.9 requirements * Improved the approximation to the surface normal for degenerate grids in `surface3d()` and `persp3d()`. (Problem found by Graham Griffiths using polar coordinates; all `r=0` points were at the same location.) * The new surface normals are now saved in memory, so `rgl.attrib()` will return them even if they were calculated by `rgl`. * `scene3d()` now records light settings. ## Bug fixes * `par3d()` could generate an error if an unnamed list was passed in. * ` material3d()` lost settings for textures * fixed a bug in triangulation code: it failed on `locator()` input. * The Aqua support now works again, XQuartz is only needed for command line use in Mac OSX. * Bounding box calculations for surfaces with user normals were incorrect. * An array-overrun bug in `rgl.attrib()` showed up in `writeWebGL()`. (Reported by Brian Ripley.) # rgl 0.93.991 ## Major changes * Added `clipplanes3d()` function to implement clip planes. (Still only partially implemented.) ## Minor changes * Some cleanup of the declarations (submitted by Karl Millar). # rgl 0.93.986 ## Bug fixes * The FTGL functions were mistakenly added to the `rgl` namespace on some OSX compiles. * Changes have been made to satisfy the stringent requirements of the Solaris compiler. # rgl 0.93.984 ## Minor changes * most `rgl` C++ functions and classes are now in namespace "rgl". Others have prefix rgl_, with the exception of gl2ps functions, which all have that prefix, and FTGL functions, which generally have an FT prefix. * entry points to the `rgl` DLL are now registered within the DLL, and on systems that support it, all entry points other than the registration function are hidden. ## Bug fixes * `writeWebGL()` and the other write methods did not handle material information properly after 0.93.975. # rgl 0.93.975 ## Minor changes * the `scene3d()` function now records complete information about the bounding box and the background. * `rgl` declares most of its C++ objects in the global namespace. Recently this has caused clashes with the `igraph` package, which does the same, and which also has a Shape class. As a temporary workaround the `rgl` class has been renamed to `"rglShape"`. A full `rgl` namespace will eventually be added, with only the API functions left in the global namespace. ## Bug fixes * `rgl.texts()` without a window failed because it queried the window before opening it. # rgl 0.93.963 ## Minor changes * font selection assumed `rgl` was on the search path; now it may be imported but not attached. Similarly, `r3dDefaults` need not be on the search path. # rgl 0.93.960 ## Minor changes * `writeWebGL()` now forces the position attribute to location 0, a recommended optimization strategy. The color attribute is forced to location 1. * gl2ps has been updated to version 1.3.8 and support for point and line sizes has been added (bug 4792) * internal functions `.check3d()` and `rgl.select()` have been exported, as they were used by the car package. * `rgl` now prints a warning when a requested font is unavailable and the default font is substituted. ## Bug fixes * we now check for invalid characters when drawing text using bitmapped fonts (bug 4787) * `writePLY()` had errors writing points and lines. # rgl 0.93.952 ## Major changes * added `triangulate()`, `polygon3d()`, `extrude3d()` and `turn3d()` for display of shapes based on two-dimensional polygons or curves. * added support for "headless" operation: see help for new function `rgl.useNULL()`. ## Minor changes * added name of device to result returned from `rgl.cur()`; added function `rgl.dev.list()` to list all open devices. * examples and demos now check `rgl.useNULL()`, and don't run invisible animations. ## Bug fixes * fixed formatting of vertex reference numbers in `writeOBJ()` (issue 4732, reported by Alejandro Baranek). # rgl 0.93.944 ## Major changes * added `identify3d()` function ## Minor changes * write the `rgl` version into the WebGL file * cleaned up use of `CHECKGLERROR`, so that setting `USE_GLGETERROR` to 1 in `R.h` will enable detailed checking ## Bug fixes * fixed bbox bug in `writeOBJ()` (reported by Matthias Zeeman), `writePLY()` and `writeSTL()`. * `aspect3d()` (called by `plot3d()`) caused the scene to be redrawn, even if `par3d("skipRedraw")` was `TRUE`. * `addNormals.mesh3d()` failed on objects when the matrices of triangles or quadrilaterals had zero columns. * `rotate3d.mesh3d()` did not transform normals properly * the `writeWebGL()` function produced fragment shaders that would not work in some browsers (e.g. Firefox and Chrome with the ANGLE WebGL engine). # rgl 0.93.935 ## Bug fixes * in certain circumstances since 0.93.930, text would fail to appear. (Reported by Karline Soetaert.) # rgl 0.93.932 ## Bug fixes * calling `rgl.material()` before any rendering caused a crash on OSX. (Reported by Dan Tenenbaum.) # rgl 0.93.930 ## Minor changes * Now handles local (not just directional) lighting. Based on code contributed by Alexander Senger.) * `writeWebGL()` handles lighting properly. Based on code contributed by Alexander Senger. ## Bug fixes * `writeWebGL()` did not handle `snapshot=FALSE` properly. (Reported by Yihui Xie.) # rgl 0.93.928 ## Minor changes * Updated the configure file using autoconf 2.69 * Forced OSX installs to put `/usr/X11/bin` at the head of the path when looking for freetype-config # rgl 0.92.879 ## Major changes * Added `writeWebGL()` function, to allow scenes to be viewed in a web browser. ## Minor changes * Removed `rgl.save.texture()`: textures are not saveable! * Added "centers" to the attributes that can be queried, for depth sorted transparent rendering. # rgl 0.92.880 ## Minor changes * Rearranged declarations for compatibility with gcc 4.7. # rgl 0.92.881 ## Bug fixes * Fixed degenerate (e.g. straight line) cases in `cylinder3d()`. # rgl 0.92.883 ## Major changes * Added 3d "sprites" -- shapes that maintain their initial orientation. # rgl 0.92.887 ## Minor changes * Added "caps" to the end of `cylinder3d()` objects. # rgl 0.92.891 ## Minor changes * Added support for 3d sprites to `writeWebGL()`. # rgl 0.92.892 ## Minor changes * Added declaration needed by Solaris. # rgl 0.92.893 ## Bug fixes * `rgl.light()` and `light3d()` did not return the light ID value. # rgl 0.92.894 ## Bug fixes * remove debugging code from `configure.win` that was causing problems on the CRAN WinBuilder system # rgl 0.93 ## Major changes * Added `readSTL()` and `writeSTL()` functions * Added `writePLY()` and `writeOBJ()` functions * Added `scene3d()` function * Added `selectpoints3d()` function to select points from the scene. ## Minor changes * Added `expand` argument to `decorate3d()` and `axes3d()` * Added `base` argument to `spin3d()` result * Added section argument to `cylinder3d()` * Added `res_name="rgl"` and `res_class="R_x11"` to the `WM_CLASS` property of X11 windows. (Contributed by Philip Johnson.) * Added code to work with R 3.0.0 `setHook()` changes * The `rgl` window now handles `ESC` key presses. During selection and `play3d()` they abort the process; otherwise they are ignored. * Copied the `R_pretty0()` function from R sources to avoid warning. ## Bug fixes * `writeWebGL()` did not render semi-transparent surfaces properly. (Reported by Robert Esswein.) # rgl 0.92.861 ## Minor changes * Added `rgl.save.texture()` to get texture from an object. ## Bug fixes * Fixed segfault on startup on Windows in MDI mode. # rgl 0.92.858 ## Major changes * Added `Sweave()` support through the `rgl.Sweave()` driver and the `Sweave.snapshot()` function. * Added `rgl.abclines()`, `rgl.planes()`, `abclines3d()` and `planes3d()` to draw lines and planes intersecting with the bounding box. * Functions `rgl.attrib.count()` and `rgl.attrib()` (and internal function `rgl.getmaterial()`) added to allow objects in the scene to be examined. ## Minor changes * Added declarations for Solaris compatibility (from Brian Ripley) * Fixed `configure.win` for bi-arch compatibility. Windows installers can set `HAVE_PNG` to a non-empty value, and `rgl` will look for the libpng files in the default `LOCAL_SOFT` location when installing. * Added `"depth_mask"` and `"depth_test"` material properties, to allow control over how objects are obscured by each other. * Added iterative computation of the bounding box to handle objects like spheres, which need to maintain their apparent shape as the scaling changes. * Improved the bounding box decoration in two ways: it can now draw the front faces (to surround the whole graph), and can label edges with pretty labels. `plot3d()` was modified to use this instead of manually setting axis locations and using `box3d()` to draw a box, allowing resizable labelled axes. * Removed some unnecessary declarations from `rglmath.h` that were causing problems in an old version of gcc on Solaris. * `rgl.postscript()` now adjusts the size of text following the `cex` setting. The `font` and `family` settings are still ignored. * Transparency in material textures was not always rendered properly. * In OSX, the Carbon system has been replaced by a Cocoa system. (Code contributed by Adam Strzelecki). For compatibility with the Windows build system, the new files have been put into `src/osx`. * Hardware antialiasing is now used if the OpenGL driver supports it. Set `options(rgl.antialias=0)` to disable it. * Updated gl2ps to version 1.3.6 ## Bug fixes * Bug fix for `divide.mesh3d()` in handling normals. * `rgl.ids()` did not return all object ids as documented. # rgl 0.92 ## Minor changes * Added detection of 64 bit MacPorts compiler to configure script. (Bug #861) * Allowed texture coordinates to be specified in mesh objects. * Updated gl2ps to version 1.3.5 * Should now install using `--merge-multiarch` on Windows # rgl 0.91 ## Minor changes * Added `R_ARCH*` macros to `configure.win` for Win64 compatibility ## Bug fixes * Fixed bug in `rgl.texts()`: zero-length texts argument caused crash. (Reported by Michael Friendly.) * Fixed bad declaration in `rglmath.h` # rgl 0.90 ## Minor changes * Added `startTime` argument to `play3d()` and `movie3d()`. * Fixed `configure.ac` as suggested by Jens Elkner. * Updated declarations for libpng 1.4.0 compatibility. ## Bug fixes * An off-by-one error caused the `"alpha"` component of the material properties to be messed up. (Bug #809) # rgl 0.89 ## Bug fixes * Fixed rounding errors and `Xvfb` errors in `rgl.pixels()` examples and demo. # rgl 0.88 ## Minor changes * Add `keepVars` argument to `cylinder3d()`, for debugging or special effects. * Add `BugReports` field to `DESCRIPTION`. # rgl 0.87 ## Minor changes * Allowed `FOV` to be set to 0, for an orthogonal projection. * Changed `seq(along=...)` to `seq_along(...)`. ## Bug fixes * Fixed crash when zero-length color vector was used. * Fixed crash in X11 after closing a window * Fixed typo in `cylinder3d()`. * Cleaned up bad links in Rd files. # rgl 0.85 ## Major changes * Added `addNormals()` generic, to add normals for smooth surface rendering. * Added `cylinder3d()` function, to make cylindrical or "tube" plots. ## Minor changes * Added some namespace declarations to the C++, and renamed `math.h`, for compatibility with Sun compilers (contributed by Brian Ripley). * Fixed visibility of some `shade3d()`, `wire3d()` and `points3d()` methods. ## Bug fixes * Fixed `material3d("color")` bug introduced in 0.82. # rgl 0.84 ## Major changes * Added triangle meshes, shape lists, the Platonic solids and a cuboctahedron. * Added classes `"mesh3d"` and `"shapelist3d"`; `"qmesh3d"` is only kept for back compatibility. ## Bug fixes * Bug fix to stop crashes when material is set before the first window is opened. # rgl 0.83-3 ## Bug fixes * Quick fix for R 2.9.x compatibility, and to remove accidental change introduced in v0.83 which caused errors on plotting without `open3d()`. # rgl 0.83-1 ## Minor changes * Don't try to build Carbon driver in 64 bit Mac OS (contributed by Brian Ripley). * Did not assume OpenGL 1.2 was available in material properties. * Added numerous error checks. ## Bug fixes * Fixed `rgl.pixels()` example for weird displays. * Fixed `demo(stereo)` to add sync in X11: X windows seemed to grab images before they were redrawn. * Rearranged headers for Win64 compatibility (contributed by Alex Chen). # rgl 0.82 ## Major changes * added `rgl.pixels()` to read the generated image, and `demo("stereo")` to illustrate its use. ## Minor changes * rewrote internal rendering of transparent and anti-aliased shapes, so they will be rendered better when there are several in the same scene * added material properties `"point_antialias"`, which causes points to be drawn as smooth circles, and `"line_antialias"`, which causes lines to be antialiased. * added material parameter `"lwd"` for line width; `"size"` now applies only to points. * increased default point size to 3 pixels across. * `movie3d()` gains a "type" argument to set the output type, and the `convert` argument is more flexible. * `rgl.snapshot()` gives more informative error messages when libpng is not available. * `axis3d()` now uses `format()` rather than `as.character()` to give nicer looking labels. * use R `warning()` to report messages, rather than popups or `REprintf`. ## Bug fixes * fixed a bug in the bounding box decoration which caused axis labels to be plotted in the wrong place. * fixed a bug in the Windows driver which caused the standard system font to disappear when justified. * fixed bug in `open3d()`: "..." was being ignored. * fixed bug in `qmesh3d()`: `homogeneous=FALSE` coordinates were not handled properly. * the clipping volume calculation was incorrect when scaling was used. * corrected the `?rgl` example to display this file. # rgl 0.81 ## Minor changes * converted Freetype font error into warning ## Bug fixes * `rglFonts()` was being set at install time, but it should be set at load time. * fixed configuration problems in OS X * fixed executable marker on a number of files # rgl 0.80 ## Minor changes * worked around bug(?) in Mac OSX FTGL rendering * updated FTGL to 2.1.3rc5 # rgl 0.79 ## Minor changes * added `mouseCallbacks()` demo, to show R implementations of standard mouse handlers, multiple connected windows, stereo view, etc. * added "silent" argument to `rgl.set()`, to allow temporary changes to focus without changing window labels. * added natural spline extrapolation to `par3dinterp()`. ## Bug fixes * `rgl.pop()` could cause corruption when multiple windows were open. # rgl 0.76 ## Minor changes * rename ChangeLog file to NEWS, as per discussion on R-devel * add `"windowRect"` to `par3d()` parameters to allow window size to be controlled from R. ## Bug fixes * put our own `assert()` macro in place to avoid crashing R. # rgl 0.77 ## Bug fixes * `par3d("windowRect")` returned garbage if there was no window open. * `persp3d()` and `plot3d()` sometimes miscalculated ranges involving NAs. * `select3d()` and `rgl.select()` produced a very inefficient test function. # rgl 0.78 ## Minor changes * `rgl.texts()` and `text3d()` can now handle font and size specifications using the FreeType library on any platform, or GDI on Windows. * `adj` is supported both horizontally and vertically in drawing text. ## Bug fixes * fix miscalculation of `mouseMatrix` that caused disappearing views. * `rgl.pop()` was very slow when given a long list of ids. * a workaround for OSX 10.5 OpenGL problems has been incorporated (thanks to mkv22@cam.ac.uk). # rgl 0.75 ## Major changes * add `play3d()`, `movie3d()`, `par3dinterp()`, and `spin3d()` functions, with flag demo ## Bug fixes * rounding error could cause `par3d("userMatrix")` to generate NaNs and fail * workaround for `Xvfb` on macOS problems # rgl 0.74 ## Major changes * add `rgl.setMouseCallbacks()` to allow user actions ## Minor changes * clean up `#include`s * clean up some calls for SunStudio 12 compiler # rgl 0.73 ## Minor changes * partial changes to avoid crash on macOS with `Xvfb` * change to `rgl_init()` for R 2.6.0 compatibility # rgl 0.72 ## Minor changes * declaration changes for compatibility with R 2.6.0 (from Brian Ripley) # rgl 0.71 ## Major changes * allowed normals and texture coordinates to be specified in triangles, quads and surfaces ## Minor changes * changes to configure script from Laszlo Kajan and Brian Ripley: should now be much more portable * removed deprecated OSX font setting calls * texture properties are now returned by `material3d()` * normals may be specified in `qmesh` objects, but (at present) `subdivision3d()` removes them * ` material3d()` now preserves the values of unspecified parameters (as documented, but not previously functioning) * `clear3d()` can now reset material properties to the defaults, and `open3d()` does this. * minor fix for gcc 4.3 compatibility * minor fix for R 2.5+ compatibility * allowed more general surfaces to be plotted by `rgl.surface()`, `surface3d()` and `persp3d()`, by specifying matrices for x and y coordinates * added world map texture, used in `example(persp3d)`. # rgl 0.70 ## Minor changes * OSX now builds two libraries, one for AGL, one for X11 * resolve entry points at load time, not call time * updated gl2ps to version 1.3.2 * tweaked positioning of labels in bounding box decoration * moved this file (ChangeLog) to inst directory, so it will be installed, and added code to display it to the `rgl` help topic. ## Bug fixes * fixed bug in `rgl.postscript()` in Linux, added text support to it * `snapshot3d()` wasn't being exported, and snapshots were from the back buffer * fixed bug that could cause crash on shutdown # rgl 0.69 ## Minor changes * allow selection to use any button * allow NA in primitives, surfaces, texts, and sprites * report error in OSX if the wrong configure options were used. ## Bug fixes * `persp3d()` partially ignored `add=TRUE` * `plot3d.qmesh3d()` did not return result * display was not being updated properly in OSX # rgl 0.68 ## Major changes * added `grid3d()`, added `nticks` argument to `bbox3d()`, `axis3d()` and `axes3d()`. ## Minor changes * fixed sphere drawing so spheres are spheres regardless of `par3d("scale")` * added `type="s"` to `plot3d()` to draw spheres * fixed handling of "..." in axis related functions * added full MDI support * removed use of `List` and `ListIterator` internally * fixed handling of axes and boxes when a coordinate had zero extent * changed `rgl.viewpoint()` default to be compatible with `r3dDefaults` * added id return values to primitives and higher level functions, and to `rgl.pop()`; added `rgl.ids()` to report on them. * updated gl2ps to version 1.3.1, adding support for svg and pgf output formats. # rgl 0.67-2 * minor correction # rgl 0.67 * added support for png files with palettes, and grayscale pngs with 1, 2 or 4 bits per pixel * added `"ignoreExtent"` option to `par3d()`: objects plotted when this is true are ignored when calculating the bounding box * added `axis3d()`, `axes3d()`, `box3d()`, `mtext3d()`, `title3d()` functions from `djmrgl` for annotating plots. * added `plot3d()` high level plot function * added ` material3d()`, which can both set and query material properties; changed most `*3d` functions so they leave material invariant across calls. * changed `open3d()` to set background and material defaults * added `aspect3d()` to control the aspect ratio of the bounding box. * added `xAxis`, `yAxis` and `zAxis` mouse modes, set `zAxis` as `r3d` default. * added `persp3d()` function * changed error messages to go through `REprintf` in X11 and OSX * fixed segfault if `rgl_init()` failed * converted type of `viewport` argument in `user2window()` and `window2user()` calls * if the `rgl_init()` call fails, the package will still load with a warning (but most function calls will result in errors). * added `par3d("scale")` to handle `aspect3d()` operations internally. * added `ellipse3d()` generic and methods for drawing confidence ellipsoids * added `decorate3d()` to draw all the decorations, `plot3d.qmesh3d()` method. * changed zoom to use ratio scale over larger range * fixed bug causing jump after resize in Mac OSX (and maybe other platforms) * `rgl.primitive()` now does sanity checks on inputs # rgl 0.66 * added `"all"` and `"viewpoint"` to `rgl.clear()` and `clear3d()` * added static libpng build support and user customizable prefix (unix) * used `xyz.coords()` in all functions taking x, y, z coordinates, allowing matrix or dataframe arguments (among others) * added `par3d(skipRedraw=TRUE)` to allow drawing to be done without being rendered * fixed display list memory leak when drawing shapes (e.g. spheres) * Changes for compatibility with strict enforcement of file naming rules in R 2.3.0. # rgl 0.65 * simplified build system: uses 'R' build system * added generic visualization/rendering interface (R3D) * text justification from 0 to 1 * added primitive type: `linestrip` * fixed `rgl.bringtotop()`, added stay option (win32) * added 4x4 matrix functions from `djmrgl` * added `rgl.user2window()` and `rgl.window2user()` functions * added user-selectable mouse handlers * added selection mouse handler * added trackball mouse handler * added z-distance sorted rendering of alpha-blended faces * added gl2ps patch ( contributed by Albrecht Gebhard ) * added port: native Mac OS X Carbon * bugfix: `rgl.close()`, `rgl.quit()` crashed on X11 occasionally. * generalized `rgl.surface()` to allow surface over any coordinate plane. * added `r3dDefaults` variable to allow user to set defaults * added environment texture-mapping # rgl 0.64-13 * DESCRIPTION fix: moved R 1.41 -> R 1.4.1 dependency # rgl 0.64-12 * CRAN bugfix: permissions of cleanup fixed. # rgl 0.64-11 * removed several redundant semicolons, required by gcc 3.4 ansi-pedantic mode. * win32: uses R's `zlib` and `libpng` sources * win32: added virtual destructor in `Win32GUIFactory` (removes warning) # rgl 0.64-10 * updated `.C()` calls using `PACKAGE="rgl"` * updated `Maintainer.mk` using correct `zlib` version * improved dynamic unload using `library.dynam.unload()` * conditional macOS x Darwin code in `.First.lib()` # rgl 0.64-9 * macOS X 'Panther' G5 fix for OpenGL library loading in .first.lib * removed `lpng` and `zlib` from source tree * support for automatic downloading of `zlib` and `lpng` on win32 * added demo directory with several examples using `demo(rgl)` # rgl 0.64-8 * build bugfix : removed `rgl/src/Makefile` * updated configure to check and setup `LDFLAGS` for `OpenGLU` library # rgl 0.64-7 * added mouse capturing * `rgl.sprites()` 'radius' bug fixed * memory leak bugfix: texture objects are now `AutoDestroy` and used through `Ref`'s * resource management improvement: pixmaps get `free`'d when they become unused e.g. texture objects are created. * no limitations on pixmap sizes * mipmap support * support for different texture minification and magnification filters # rgl 0.64-6 * updated build system: added `setversion.sh` * with MinGW version 3.0.1 pixmap loading does work * `project.mk`, `win32.mk` and `x11.mk` in `src/build` changed now a single variable MODS will extend. * MinGW build system changed. `rgl.dll` now contains an R compliant Resource information generated by R `perl` script * bug fix: R 1.8.0/win32 does not detach packages when quit it is safe now to call `rgl_quit()` and `lib_quit()` multiple times `win32lib.cpp`: added `dllmain` that calls `rgl_quit()` on process exit * added core support for `devcpp` IDE # rgl 0.64-5 * macOS X/X11 port # rgl 0.64-4 * manual update * acquired valid CRAN package status, `R CMD check` runs through with 2 WARNINGS (according to `latex`, and `codoc`) * uploaded to cvs # rgl 0.64-3 * configure.ac: X11 library path broken, fixed * `x11gui`: `glXChooseVisual()` part fixed * code cleanup: `rglview.h` * added: `man/maintainer.Rd` maintainer information # rgl 0.64-2 * `rgl.quads()`: `enum` id was broken, fixed ("quads" -> "quadrangles") # rgl 0.64 * autoconf build system * moved textures to `inst/` directory * x11 port * `win32/vc`: fixed fpu control word precision to remain on 64 bit links with `fp10.obj` * changed texture mapping t coordinate for Surface node # rgl 0.63 * API: added `rgl_init()`, `rgl_quit()`: explicit client initialization * added `setup.bat`: build setup for windows * win32 setup: MinGW compiler * win32 setup: visual c++ compiler through `gui` environment # rgl 0.62 * modified sphere set * support R color strings * use `system.file( , package="rgl" )` in examples to retrieve texture files * rewrote R code : * clear `enum` types * vertex vector datatype (internal representation matrix) # rgl 0.61 * added: `rgl.sprites()` * added: fps counter * added: `autoUpdate`, modified win32 main loop, on hide, `autoUpdate` disabled, on show enabled * modified material: added alpha vector # rgl 0.60 * (mini-thesis release) rgl/MD50000644000176200001440000007213314146502162011355 0ustar liggesuserse73499cb89e0d6e97b8ba271c46739fd *COPYING 956ed470275aaa2f0c086a984a14199e *DESCRIPTION 57dd2eabecd0289e7d170f2647e4a073 *NAMESPACE da2141894f7e532d9ac7ef25aeeee586 *NEWS.md 664118a44d0cbf5e0754bf2b3fcce21b *R/Sweave.R 67e457f4a3ecfa12f8b911faf11e7ab6 *R/addNormals.mesh3d.R d62767b6f3a51c93f666e30e437e5556 *R/animate.R baf0c2fd640c730aad8f424f407e4d1d *R/arc3d.R e56b1d2ea8a0ab652d17a561a7415b40 *R/arrow3d.R fb9464e05ec743b3b9047c92e94a4638 *R/as.mesh3d.default.R c4611e746f8484dd73df7aa7f83f6d92 *R/as.triangles3d.R 21d8ad9dc97626936f671cc24413f700 *R/ashape3d.R 853ac34ab3568c44d0326e6f89ccd68d *R/aspect3d.R 29db2c9e83228ef7ccac4194e00acd5b *R/asy.R 7a41be0939c11c9c43185ee5120f6d59 *R/axes.R c18f99b589f2e3b990dbfadbeecdfc2b *R/bgplot3d.R cbfe818b3921f18ee6a77caef63e51ff *R/buffer.R 156e3b5cd685c4d2300c311ded8375cd *R/callbacks.R 88b590e9b4f712208514a72f35d7787d *R/clipMesh3d.R f84082194ec14e7ce9ecac1412ba38ba *R/contourLines3d.R 149f8a63713267831727369515a66e8c *R/conversions.R a15a4bff1225902941e6359bd5383063 *R/convertScene.R e02c0b99986d8439fc3cfebf2c7f0ac2 *R/cylinder3d.R ee008f2ca2afcec2ddc69cdb501a5622 *R/device.R d55ef045a0119182af274b982c383a6f *R/drape3d.R 3b7a562a2087834ac77c58be27e22574 *R/ellipse3d.R 466ba7d1b526f7190d2e45af42df9d06 *R/enum.R 6efe2721e61641d11e7bbb31db79388f *R/extrafont.R e6fb7cb7e95424fc81bf48f458fd5c4b *R/filledContour3d.R fe8d5f9a3ff97345b7fef7be46e808f7 *R/fonts.R 873e3b79ffe51a42bdaa958979586980 *R/getBoundary.R 29fe43978098c6e436fed1b37cc4243f *R/getscene.R 878f2258edc9e9958e09aad1939575d9 *R/grid3d.R d17dd5924c4f6e242a9fa216bbf33c82 *R/hooks.R 0db39cbfb3fe01c3cd5ac549cbb61d2d *R/identify3d.R fa4b2912b3506c1b4423d4843dc22376 *R/internal.R ae36bf0b8f41600d560844732ed10d78 *R/knitr.R fe7d6387c3042c18ce8d94ce9b66569a *R/material.R 0464f8ae4fd2db092c3cf26019c07e49 *R/matrices.R 35e04fe986c7a93ff3a737f490ceee93 *R/merge.mesh3d.R 30777a8790463f74c003b7da15ff634c *R/mesh3d.R 980619e2ce4868352c2eaf1ee4ce0ce2 *R/noOpenGL.R.in a16fe35036f5e54d8837c2effbe5f5dc *R/obj.R 28282cc2b8bdd1db2670457562c19649 *R/oh3d.R 11abec92cfab3c9ad157c89af94a0c05 *R/par3d.R 10033235c3fcbf78a7d9e17837213d95 *R/pch3d.R 37d6094ab32154c42c5c3062c7519473 *R/persp3d.R fdd04f8889702ca3ffd4e2a46e1be2c5 *R/pkgchecks.R 274048d6cbd798887e525bae5ecaf619 *R/pkgdown.R e85f03d5a969ab86e4fb820e2b00b4ad *R/playwidget.R 5d66a5a93dd74ce86e55f5f2c96b2ae0 *R/plot3d.R 78aa3e2b18da183168cb87704d6b582f *R/plotmath3d.R 6c65179fb5627597f264c331297dbe74 *R/plugin.R 7845d53f2012010684121e0352c40609 *R/ply.R 0b36534fbb8286cf344c5bfd8b993716 *R/r3d.rgl.R a82494d493925454323cd8102200995d *R/rgl.bringtotop.R d2b57a988bab44a4c3c498ddc84f49f1 *R/rglMouse.R f942d0b07abe206476c85cc5d8fce567 *R/rglcontroller.R 2957470c2052d5f6b4f4441f7cda4fbf *R/rglwidget.R 50efd82368dd3b4df9c217b8280cfda5 *R/saveURI.R ff5583fe2874cd642d347b0ca9f75a66 *R/scene.R 447e6c7fddf51487b69157230df311fa *R/selectpoints3d.R db3355036490d5d5ccfe7d5c14c024c6 *R/setUserCallbacks.R 6a171293c416352fdc5ab95e98a83d1d *R/setUserShaders.R 2d9929c837439714fb2ce7e13971d25e *R/shadow3d.R 0421ba6d1a6715ed302eceb6229b4723 *R/shapelist3d.R 4eda099954045dcdfae81a22986dbd3d *R/shiny.R a34d24e39b93cf35ae4723970aef7e89 *R/solids3d.R 1566d8acdb0203972a6004a85b915d27 *R/stl.R c0d16a399fc7561f2cfbe4e9457105a2 *R/subdivision.mesh3d.R 805c09db41119daadcd5b0fc456b0e33 *R/subscenes.R cafb08b2f8a5fc5ad72623e3b493b590 *R/testthat.R b3dd6af59f03c97611ad8f6632896fb5 *R/thigmophobe3d.R 2e72fce267427a1271402c20b0133fa6 *R/tkpar3dsave.R 045ea58eb2d624a009c89851a247fa80 *R/tkspin3d.R 5eb7756634ad2024f81bb2a5d7f7d1e2 *R/triangulate.R 3447eb732f99d8015c8575c9a4e5077e *R/turn3d.R 7d0644c5d745d7113dc1257bd601f9b9 *R/webGL.R 3f3ec6108c694f57c77e23dbf0063e9b *R/webGLcontrols.R bf49a233d31d1b3db72726d570ee0918 *R/windows/noOpenGL.R 8b4eb2be806d8b9409ac6796426be750 *R/zzz.R 7c2fb769af90cc28bb294176df5e2631 *README.md 70fb7cb1338b501b441f81a689d524f4 *build/vignette.rds 10e89b551cff8c2453ea69fde1b97493 *cleanup ee1550a64d84ea5b26e1b7641f11078c *configure d401e18053b62d5bddd3116c7693d35a *configure.ac 2f6709e644fc4cd3ddf547a595d379ce *configure.win 03561f8b3b96760a631e07f0a3c297fd *demo/00Index e3f778b562290afb28800fb26ae9a159 *demo/abundance.r df29edec997357e70d7ff28d64222ac5 *demo/bivar.r a2cc38c9285defbab0e69636f092fb58 *demo/envmap.r 698bffb08ebec66d82e23de3024502ec *demo/flag.R 9b894982d13832ee5b948efc3641b890 *demo/hist3d.r 9d873c9d6b293d07433aa77f93d2fe35 *demo/lollipop3d.R 87c9bf9b1f435ef875dcfd647e523d83 *demo/lsystem.r cf1167ce23f7226af0829d93822c9c1e *demo/mouseCallbacks.R 0200b90b901a881da41938228274f6ae *demo/regression.r 2eadb63ad0685d7eec44ae5d05135277 *demo/rgl.r 1568bc3704a1c9e8df03d71f03948c88 *demo/rglExamples.R 0d7d6348c2c857c99e221de3e57d3bf4 *demo/shapes3d.R a2730048c2872b4ba9a5aa482f7854d2 *demo/shinyDemo.R 325e4140d6e5e623f12a88be70cda7e6 *demo/shinyMouse.R ef13a1c10dfbc78464e5b704b65447c1 *demo/shinyTabs.R 87810f2925f4ff100edf5c11ad04ce16 *demo/shinyToggle.R 81c525c9ce033282da7309a7193e250a *demo/simpleShinyRgl.R 009f222b0a5cd9e48ebcc9e9ea227a99 *demo/stereo.R 680b2e3bdfd450f60f8ebdfa8d5bfc09 *demo/subdivision.r 7c3f4a4a10193e75ae7ca2bc357e461f *inst/WORDLIST 8c5d291e3f47c3395fff092f09f599b9 *inst/WebGL/template.html 5bac46c36b13eac1302260ee06b16c0f *inst/demodata/population.dat 5544dce93555cfaced50ee41283e9e58 *inst/demodata/region.dat 6972272ab9d51f9c3095525f0c17da15 *inst/doc/WebGL.R 94dc3fbf1243230dbf06a936366b5f82 *inst/doc/WebGL.Rmd 1e89146eeb1c903a810d0ae7a09eceb6 *inst/doc/WebGL.html a79d75b941aa253abda2edb27625cda2 *inst/doc/pkgdown.R ef5db6d0057d0cb6b79f7a79fb43a6b1 *inst/doc/pkgdown.Rmd c28c913f95745cd5de7c4ba5beabeb69 *inst/doc/pkgdown.html f99aac24de4ff50cdbf669f6c13844a6 *inst/doc/rgl.R 2ba4aa9981b92a1c1a1d651280738f9f *inst/doc/rgl.Rmd 633094e6526e19e6084ee0131946d8bd *inst/doc/rgl.html 9cc7fbabd59616c69724412ddf87d9e3 *inst/doc/transparency.R 002b07c7e555fada70d405ea390aacd2 *inst/doc/transparency.Rmd e56e6a80442fe11e7df56918af689dd2 *inst/doc/transparency.html b4ef592c88333c7c509dd74fcd1912d9 *inst/fonts/FreeMono.ttf 867469f13ff81dec9adf2ae2f6ea2899 *inst/fonts/FreeSans.ttf dc0004a804503e126bc99998c7a1c677 *inst/fonts/FreeSerif.ttf 8d30ca0173ed0199035a9856ad846c9b *inst/htmlwidgets/lib/CanvasMatrix/CanvasMatrix.min.js ec09b6201dbd3edeb21417d212d4564b *inst/htmlwidgets/lib/CanvasMatrix/CanvasMatrix.src.js ad3b153c62394e7c510ec7ce6315378d *inst/htmlwidgets/lib/rglClass/JSDoc.json cf594823f31b491c46382ebccd2aec01 *inst/htmlwidgets/lib/rglClass/axes.src.js 19ec2fcec5d81f31f2b6bfddb2f72cae *inst/htmlwidgets/lib/rglClass/buffer.src.js f72030baead47486978d589ae3f3c481 *inst/htmlwidgets/lib/rglClass/controls.src.js 5bc14ac7ba7a3f6555c68d9fe946c16a *inst/htmlwidgets/lib/rglClass/draw.src.js e7e415021bfb07db581227c6e431bb42 *inst/htmlwidgets/lib/rglClass/init.src.js a08852df1baf53653e9eec1d4b88dca4 *inst/htmlwidgets/lib/rglClass/mouse.src.js 0144a563d14d284cf6092d408397d569 *inst/htmlwidgets/lib/rglClass/pieces.src.js f4fe316e7edf6f15d154c6e6e9300471 *inst/htmlwidgets/lib/rglClass/pretty.src.js 84ead2f39fe70612d6b8558252d88789 *inst/htmlwidgets/lib/rglClass/projection.src.js affdd5bb24638f5909595f0e7d9c7713 *inst/htmlwidgets/lib/rglClass/rgl.css dbb5a537dec81b9a3b436cdd70d41ace *inst/htmlwidgets/lib/rglClass/rglClass.min.js 1bad1a7d7c62acaa8c1de102879360cf *inst/htmlwidgets/lib/rglClass/rglClass.src.js ee768f63c54007c8d6b3e688688c60fe *inst/htmlwidgets/lib/rglClass/rglTimer.src.js e79d4ff9bca20785c3fddfcca21d36e3 *inst/htmlwidgets/lib/rglClass/selection.src.js dc8025b38dd2f659c7d69088b0c829a6 *inst/htmlwidgets/lib/rglClass/shaders.src.js 277067affb05b6d5933bd32c2e31d81e *inst/htmlwidgets/lib/rglClass/subscenes.src.js 2850bff85c2ae50f0b19dd355f37ab6e *inst/htmlwidgets/lib/rglClass/textures.src.js 039bb9892653793fcbc0577c31a8f541 *inst/htmlwidgets/lib/rglClass/utils.src.js cc1cfad09e78db798014b3d123e7d292 *inst/htmlwidgets/rglPlayer.js 2b4422ab434ff5c106bf53f3c21f3894 *inst/htmlwidgets/rglWebGL.js a67c4e96ec7009ed4debc42989552877 *inst/pkgdown/templates/after-head.html 41278bf843dea9954d79e7c03c5280c9 *inst/slowTests/demos.R cbe2e33ebb5b25d551984106b4875304 *inst/textures/bump_dust.png e221746e4c3cab9350cbd533d3c3f53b *inst/textures/nightfire.png a68491872e00896979cf9e7247cd380b *inst/textures/particle.png 8b20dae04ada6cf245757b0d1aa28788 *inst/textures/refmap.png 7143472a404be347ecb78ea35e1efa84 *inst/textures/rgl2.png 6913e9b79b90af9ef162055d09c3ff44 *inst/textures/sunsleep.png 760f11bccf3dc39aad741060ca7008aa *inst/textures/world.png 055baa857f3e397b0dece1a75f9092d0 *inst/textures/worldsmall.png 9672cd33dafccf3f11f677a8cb19218b *inst/useNULL/README.txt cd8bda7ee7f077a9a90d22f289755899 *man/3dobjects.Rd 982013062d1d99bd0393baf875f69cab *man/Buffer.Rd 36193edd2bf704e55ceeddbee64fc1ac *man/GramSchmidt.Rd 58a03ba16afe9fa47122641845d0be3d *man/abclines.Rd c23994f7330db8b6797e70eda80ebf9a *man/addNormals.Rd f554f9a882759791e5ab893966477bf9 *man/ageControl.Rd 8b05bee5af8ca38ba74dd02cea8f0a2e *man/ageSetter.Rd 893c479568d0f099ff0fc5873a060471 *man/all.equal.mesh3d.Rd 5f0d493f98d98ad2b80df59f8b7cbbaf *man/arc3d.Rd 8f2612f62364c3c3b7561c8ee5a602bd *man/arrow3d.Rd eb46acc4761180b96c97cbc19fc273d4 *man/as.mesh3d.ashape3d.Rd b7af116e7e06fd5c6ae84f77e849c66d *man/as.mesh3d.default.Rd 943b8af3b25369af47ccdd51b2bfc207 *man/as.mesh3d.rglId.Rd 95b858f7e4ab842bfea126b0ada1d93f *man/as.rglscene.Rd cb9b21172656a08e4ee7a50eea3b7be0 *man/as.tmesh3d.Rd f69d3bee8aa2d46434aa489a0efa275f *man/as.triangles3d.Rd fba9e60f5ae7d71f3c7e2e0be3d50298 *man/asRow.Rd 91224edeba2f1c2b44988b76069571b4 *man/aspect3d.Rd d908ac708af0e144164ee0fcd2a3b9a5 *man/attributes.Rd 0edf2d28ff47b3007b23c5d24b3182e7 *man/axes3d.Rd 8a8a3c3008126f1923f1b554eb182b5c *man/bbox.Rd 3a0289d2969f7c86122e8b132f5c79b9 *man/bg.Rd ae65a25a2c9d749155a122369d7f89f0 *man/bgplot3d.Rd 4c828b6017d5f42338379dfbb8b14cba *man/callbacks.Rd ebd1ae6fe7d4cf849f6f0c9508ce0fdc *man/check3d.Rd ff8e375df7965841a55375b12465109c *man/checkDeldir.Rd 7fc29f7b160ad04dc61a24287294800b *man/clipMesh3d.Rd 55b632bdc433fbfb10c3de2e9e6c3628 *man/clipplaneControl.Rd 66992b6e002285ea6cb1f9454ca54576 *man/contourLines3d.Rd 1e5d9c1192b5f5f6df412a31e2862cfd *man/cube3d.Rd e7dca415e1272c3107b825ba41a1ba42 *man/cylinder3d.Rd d9928a7f4b1404ef973efb92d455f69f *man/decorate3d.Rd 8c02cc59120ce7cd3a8392bae11995fb *man/drape3d.Rd 170312b767dc30095c5bc2a962de2c6c *man/elementId2Prefix.Rd 2c60375e0432b1e1e7d1965335ce16aa *man/ellipse3d.Rd 3952c07a12a03dc3c21389baa5a67dd3 *man/expect_known_scene.Rd 9341bca00a9c0c0170964684b215dbe7 *man/extrude3d.Rd 34012fc0fe8d969c9b58fb0102ee4fd6 *man/facing3d.Rd 9631bfc372795aa01646eb14ed157c4d *man/figWidth.Rd ffcba5e55a8b80e022f8df3a334c8119 *man/figures/READMEpolyhedra-1-rgl.png 5a286cb282a3115a545eb1a654c3e312 *man/getBoundary3d.Rd b45b8c32e7731c5e6e886706da165451 *man/grid3d.Rd 847ccf53ea1fc17549486130d2aaabf3 *man/identify3d.Rd 7ab6d7d03af0fee5880b73351dbcd14f *man/import.Rd 0a6538e26f3b23ee6c5ded415416fdeb *man/in_pkgdown_example.Rd 0881756a1d4fa8cae301dcf9f7f65d97 *man/light.Rd ba24a794590f638b23674ee4035745c2 *man/makeDependency.Rd 20aebabe47cd93ad13237f3a122c5170 *man/material.Rd 78d40ae7b865fb06b3bd4bb2db39063f *man/matrices.Rd 8c2f51a8c132bb14f88e849e9279b2bf *man/merge.mesh3d.Rd 66d140bc7c4db830ce94e9fa5ec8a333 *man/mergeVertices.Rd a86c8e0eb2456a08283482bdec7269e7 *man/mesh3d.Rd 87852d0f6059558ed79815ce493d0a38 *man/mfrow3d.Rd bc399992457ed1eecf0805eef7497d16 *man/observer3d.Rd 4d3875db87d81add9c3fc2bd4000c075 *man/open3d.Rd 80fac573e13662ca6cb16a97407b6efd *man/par3d.Rd 02c1a1a30893dc0c96c57595b09d138a *man/par3dinterp.Rd 5949fa84bff53df7500d4738ce7840c7 *man/par3dinterpControl.Rd 66b43af0fe4341c8ac8aa2819114c4f7 *man/pch3d.Rd 1ea2b7623003e193b624c49a1aaf130e *man/persp3d.Rd bf233ab3e4da37a51dc9ae61f6c32bcc *man/persp3d.deldir.Rd b8b8fcaebb75c173e3ff66408bb578b7 *man/persp3d.function.Rd e3a9e1de5ee878122427d3ed53eb1eb8 *man/persp3d.tri.Rd 4be8a43704dc9471dd220fd034091e56 *man/planes.Rd 0361fcbdc2259d3e39bb5537667894aa *man/play3d.Rd 9f0851d2c289cb2054a6ca51ae162fef *man/playwidget.Rd 44f583d205c94fd9d29dcbb071f2b1b3 *man/plot3d.Rd 23eb50400a78cb07d3161403d39970fd *man/plot3d.formula.Rd 605be2232e72797ef484503612c5f5d9 *man/plot3d.lm.Rd 28a54f83d1d390fa2dd7d95add0b8396 *man/plotmath3d.Rd 3aacb608287b26fb430a62d699232ce1 *man/polygon3d.Rd 852def0d65c7a623ed7f3f4584ac4d16 *man/postscript.Rd e9de32d595afdddb98e8783e703d5e3d *man/primitive.Rd ec0713d1216f9a2ae185418e72e24401 *man/propertyControl.Rd 3bc29f5f614c75d89dfbc03849f56ea0 *man/propertySetter.Rd 28ceee8b15aadede362da9d0b8a036d4 *man/r3d.Rd 4571cd64d13d7ce0f5a63e5e093c5b04 *man/readSTL.Rd 43940993bcb81a636dcaaec4cd86ed20 *man/rgl-internal.Rd 545db2b074250ac823186506faa56b64 *man/rgl-package.Rd 2b5816560188e336594a47d3b0c55c51 *man/rgl.Sweave.Rd b5e10c72208b0f5ea350e16a41125d19 *man/rgl.attrib.info.Rd 377cbdac5434cadc5f5ef7c420b912a6 *man/rgl.bringtotop.Rd e0a2d48f42ddd2281ab773d0d6c25a6e *man/rgl.fns.Rd 092c268370800d54d950953057bfb073 *man/rgl.init.Rd e94fcea1cbe5406eb4915221de014098 *man/rgl.open.Rd 37ed09923795b7aaf6a603e0420f3d86 *man/rgl.pixels.Rd e9a81e73c9257899ccdbff3ef411774a *man/rgl.select.Rd 3726417039c685349e2d9d90ecda24dd *man/rgl.setAxisCallback.Rd dd272224188b7ac3516f1f40971b8726 *man/rgl.texts.Rd ebded4002efb7e0419e937a72a8a127f *man/rgl.useNULL.Rd 190b4bacdb65f6cd4c7db16e56450a4b *man/rgl.user2window.Rd e6d5c64583e9f07f55c3252ce6671b46 *man/rglExtrafonts.Rd 4e30243bdf05dd0c711e2ddcf6ba80f7 *man/rglIds.Rd 285ec1ba7b9a9e7954acd4f9db1e5ce8 *man/rglMouse.Rd 933b403d413b0444dbe287125a8a99cc *man/rglShared.Rd de4e070d8d76b0f5820c6b0f8c4ce7f3 *man/rglToLattice.Rd d56e619c2b097da100fcc9d091fbecd7 *man/rglwidget.Rd 8d381d73ae9e04cd1ba7c15ea58d935a *man/scene.Rd e01ccf46ebf633dd7ff0b723a39ecee9 *man/scene3d.Rd ef63bae9826deb1a816b27d241fd4e39 *man/sceneChange.Rd dbc72d032b8a93d77413bfb0fa679a5e *man/select3d.Rd e9e74de3d08db9a390f7314b55273b2a *man/selectpoints3d.Rd e1f94cb7d5a0986c70481f215c7a8d29 *man/setAxisCallbacks.Rd d25ef62df68ae6ed8640e48318775bd9 *man/setGraphicsDelay.Rd 9b9f12c432336c0e85e4fdcfde69a423 *man/setUserCallbacks.Rd 77cd7e134d4c939f46ff5b6ede4e6309 *man/setUserShaders.Rd db2d156260823c32779f42060accb9da *man/setupKnitr.Rd e72a17ee452e7edde6d4d7b7934bac65 *man/shade3d.Rd c8bb0842063bf6f0a04bc4276cc232aa *man/shadow3d.Rd d71689c55996c3f624c5005eef65f77f *man/shapelist3d.Rd b039f52720975a1becac6a75144d39df *man/shiny.Rd 9777e80aa056ae98f152afeb0019cf1d *man/shinyGetPar3d.Rd 023e190d601845b16cdb9b333f088056 *man/show2d.Rd 26354db733a4c1ce98feee796074ae91 *man/snapshot.Rd 9e8055a8252a944f9676601f73ce561e *man/spheres.Rd 5524b70beb795c5f2c9917b6f0d0ccd6 *man/spin3d.Rd f1717378e0eda48a47cfb903ecf8ed31 *man/sprites.Rd 6a39e3060ad7a97811414c5b315f9177 *man/subdivision3d.Rd a5037be599e4b071ec1a6cc67dc3ce21 *man/subscene3d.Rd c9cea35eb1256499e8a0dbc30704e790 *man/subsceneInfo.Rd e03b0d51b94109fdd339ff2ead9677fc *man/surface.Rd b8a319d5a7e4813febbc7e6e55698937 *man/surface3d.Rd a367a00a034e320081a942bdb29e6274 *man/tagged3d.Rd 7f2d8914b5f06165144467863f229624 *man/texts.Rd 7fa188f24c26bda5a6adf17dada6b55c *man/thigmophobe3d.Rd 15322637869e240caf45586e34e89229 *man/tkpar3dsave.Rd d24f2e28706faf0585435219c0e66190 *man/tkrgl.Rd eea2c935a9cef078649d2a3161d29622 *man/tkspin3d.Rd eddbd60c251d4272e87cd9d567edc332 *man/tkspinControl.Rd 63cd50cefd3d4c217b595f578ebbe225 *man/toggleWidget.Rd 7fd702d84dac0f4c475545859e226bf9 *man/triangulate.Rd 48140ff7d386202959c76071902a414a *man/turn3d.Rd 78ef81ca1aa727e426822d7bfecdb892 *man/vertexControl.Rd ddfd766c2131b58e6e3d9306bccfecd9 *man/viewpoint.Rd 5fb68a28db878afb97b6aa31a609af96 *man/webGLcontrols.Rd 912b0e305e7a4688f8c8c0bd31846085 *man/writeASY.Rd f4f6126b3e31b93a2c325f35a0102461 *man/writeOBJ.Rd d667b61d58a16c512185f49a02b04b0e *man/writePLY.Rd 65a25991ad9beef80ad2249aac55d9ff *man/writeWebGL.Rd 3fd46c90a42a13fc520d765dce32ed50 *src/ABCLineSet.cpp 4e93c61da331b4806ec9d481f17b47cb *src/ABCLineSet.h dfdc055aec294bbcc530a7943e001bc6 *src/BBoxDeco.cpp 2dc49888b8ae433013a4a17ad0abccd4 *src/BBoxDeco.h 4470447f24d2aaff1214810b9d28271e *src/Background.cpp fd4cce8910720cb01e2901515ff48ede *src/Background.h 6b1349ed40ea31cc7560a03acc029455 *src/COPYING.GL2PS 30ba12de1f2fd326a630017b4981b00d *src/ClipPlane.cpp 969b28736e44716031c26ab2bc9ff209 *src/ClipPlane.h 034a984053086626b44487e48bda4b7f *src/Color.cpp 3b231f79bf9228e58fd6fd658d2b4148 *src/Color.h 2601c35dfde84ba115bfa5f7b1ea28aa *src/Device.h ac476179be232a04344ebe2f0e8a8c85 *src/DeviceManager.h 2fdf0fa29216eb97fff8bdf8c382da98 *src/Disposable.cpp b128eb378abdd8e63ea8287e7f9f6254 *src/Disposable.h 6110854830f1e49b6eaee19e33885805 *src/Light.cpp b03e2ab2e386594cd527d3cbad2b9f3a *src/Light.h d09267b7768c63f6a3e4c4903d264d9b *src/LineSet.cpp c85f33e46d89cb725cb27461cad4fb71 *src/LineStripSet.cpp 4cc39a3e9d73489ff6ef2aab9ffca667 *src/Makevars.in 06783eb536f9ef8b6d43ba5bea4651ba *src/Makevars.ucrt ef228a6534671e41750e62671def621d *src/Makevars.win 5a925fc1f0f015687e6106e022ea499f *src/Material.cpp 86233ac78d796c740fcdc410b424574e *src/Material.h 76e515167804f8b0e389e6e13604aad0 *src/NULLgui.cpp 9085d9989be04f4dcfa9a907860dfafb *src/NULLgui.h 78aa07005bc72436eaecbd8bc6366644 *src/OpenGL/gl.h 944837b2d669d4ff50a4b75d055c366b *src/PlaneSet.cpp 1b510976127456879201e4e737a6fcb4 *src/PlaneSet.h dd9a3e551ba95f9ff84b3ad5594bea09 *src/PointSet.cpp f917cd5688037d445abfe3b1db28d466 *src/PrimitiveSet.cpp 29baf02b50802d6a1637be3def420643 *src/PrimitiveSet.h a690ee6caf929116ca61fd2a97cd328e *src/R.h 9dd4aa8ad74533c5cd129a03d93c81df *src/RenderContext.cpp 2397bb9b330dc081bc2a8db7e8a6abcb *src/RenderContext.h c4c298f3136de1cc01eba7a68df1f5b4 *src/SceneNode.h 32e93e3f315c6997fa9a6d031df8f12f *src/Shape.cpp aeac4ed569674e66dd8befa5f6e07dc1 *src/Shape.h 4cd675299152d76c7bc3192a0d1b9197 *src/SphereMesh.cpp 89d265b652286745456a86979b4aba9a *src/SphereMesh.h 66d290304db930ce279b300787ce7986 *src/SphereSet.cpp 2e56126a61bd390fe2f1ccaf2fe0aa97 *src/SphereSet.h 0e860669783b6b5a66d3c5a4554191ff *src/SpriteSet.cpp fb356f0c41d6f478933e8fab00201d4d *src/SpriteSet.h 24fba47f0cbd5d9fca68740230101c84 *src/String.cpp e9a31e14589146f498de32e1d7e1a706 *src/String.h 60f86223a8b9f392d863e101a7de9531 *src/Surface.cpp 230ecf15f274784204529487720e5451 *src/Surface.h 0bad8cbf7c2994e18a4fd9ef88f97f3a *src/TextSet.cpp 51a684c89783c8aa78f194d0fe5d26eb *src/TextSet.h fbfc8be14016b8ffc82b951a5f531c04 *src/Texture.cpp 57491612dd6fd9fd94519e1598a226b0 *src/Texture.h 2a62e7eef319c946d7616c36bdd0cd14 *src/Viewpoint.cpp 405ac9f8fd106d601fdadf356cfefc98 *src/Viewpoint.h e7fc78212cc87eed76f8316c95a3f9e6 *src/api.cpp 472a1f889385e876c4c9ea9984816580 *src/api.h bb5f3d08f63b9c2414e546a8b0afd335 *src/assert.cpp 1a30ef7cbbd3426ec7047805ab23c156 *src/assert.h 356c24016516e628131be1beb93112f6 *src/build/autoconf/config.guess ea7a5a3a84c7ccf3fd8e3451fe77d3b2 *src/build/autoconf/config.sub 6e5fe73723cd40a28adc5b7b5650c8d1 *src/build/autoconf/install-sh c93b20f9fda97ae796b05742cbfdec76 *src/callbacks.cpp eaf77259ad89bde780fe9b73fcd66d1b *src/config.h f40e9029ea940c760eb8780a2c001e56 *src/device.cpp cdcb77e66b08ada7fdbf689ba436dfe8 *src/devicemanager.cpp c83c1ea7f7c9b201cdcf087fa83d10ff *src/ext/GLsdk/GL/gl.h b3a541f71a25364db3f2128ecceb23cb *src/ext/GLsdk/GL/glext.h 1d9b87c0753867872bde78597c327011 *src/ext/GLsdk/GL/glprocs.c 2f815b593663fa05c0b4218da5e859f5 *src/ext/GLsdk/GL/glprocs.h 7b7a17cf681ec55443208331ff7d2fa7 *src/ext/GLsdk/GL/wglext.h 02bd9b0a9a5faf1589190ac51176a1c5 *src/ext/GLsdk/README 3cdf0854d833c6aa64021c260776f3f7 *src/ext/GLsdk/glxdemo/Makefile a88d7c70039d75d1b7165b03c701c90e *src/ext/GLsdk/glxdemo/demo.c 3919e1e751b49ca79d26a389ea6075c5 *src/ext/GLsdk/windemo/Makefile 1a76796ea607f53471cf26be65754c87 *src/ext/GLsdk/windemo/README 65fc121bbc52e6a33984ba1d2a28344c *src/ext/GLsdk/windemo/demogl.c c08368f55d809f294f0f5b8f65fff152 *src/ext/GLsdk/windemo/demogl.h a196c678e345d99dbfb3f321568da889 *src/ext/GLsdk/windemo/multithread/Makefile cc539fdc60be6768b85a7e21a949d15e *src/ext/GLsdk/windemo/multithread/demo.c 8c37622620a17bbfe0ce031563efdc10 *src/ext/GLsdk/windemo/multiwin/Makefile ecbc58476e6d099e32553dcd1d8d54ea *src/ext/GLsdk/windemo/multiwin/demo.c 66476d12bb3ea2a99ac8c86e93188e11 *src/ext/GLsdk/windemo/singlewin/Makefile eecd615847d389422cc5d70cdba4b0bc *src/ext/GLsdk/windemo/singlewin/demo.c dadfdb1523fa7cb2b605ca739d3dc7d8 *src/ext/ftgl/FTBuffer.cpp ab357afb70bd9d9b2249e2628af41eba *src/ext/ftgl/FTCharToGlyphIndexMap.h b253ec3869e48b3b716c54d900c2ea9e *src/ext/ftgl/FTCharmap.cpp fbb46155bc03c58b0954c9c87b8c5489 *src/ext/ftgl/FTCharmap.h 198a83b2cdc6c0c25dea814e9f87b287 *src/ext/ftgl/FTContour.cpp 0df22d6e2afed2fa2c74b56d170666e3 *src/ext/ftgl/FTContour.h 7c097787cfc3ec9d5334294ee5857f73 *src/ext/ftgl/FTFace.cpp bc923b13aab60fc0d8345ce265d5c4f7 *src/ext/ftgl/FTFace.h 6cee05988d95769959751a6bf982bcfa *src/ext/ftgl/FTFont/FTBitmapFont.cpp 46cd76f77454183b656f840846f7962a *src/ext/ftgl/FTFont/FTBitmapFontImpl.h 2a5ad552a3668fa622e598b74bcdf193 *src/ext/ftgl/FTFont/FTBufferFont.cpp e595560279739292d4040fc99ccb6f8d *src/ext/ftgl/FTFont/FTBufferFontImpl.h 11894243a0b819ff86e47a32849cdb45 *src/ext/ftgl/FTFont/FTExtrudeFont.cpp c763a223ea70cb3c58aa0e5148d36091 *src/ext/ftgl/FTFont/FTExtrudeFontImpl.h 9fe096169e2b693fb19392366db68da5 *src/ext/ftgl/FTFont/FTFont.cpp bda6bab0aef5e5df1db9aa5f96df4d3d *src/ext/ftgl/FTFont/FTFontGlue.cpp b8b501aceae7097953d3d3d07fb3f22d *src/ext/ftgl/FTFont/FTFontImpl.h 578c3ed55e2991b90210e1f297a06d6f *src/ext/ftgl/FTFont/FTOutlineFont.cpp b30eda21f61429fb0a4680465f516237 *src/ext/ftgl/FTFont/FTOutlineFontImpl.h 8ffaf4d3327d55283a9b7405e0a1c573 *src/ext/ftgl/FTFont/FTPixmapFont.cpp 26853060924597f8ca076ae7d8e95752 *src/ext/ftgl/FTFont/FTPixmapFontImpl.h 0f6d6e0fb2174d041b9f333a93ed1397 *src/ext/ftgl/FTFont/FTPolygonFont.cpp 8fafdbb2666a3cc723e85bd6d4a6794a *src/ext/ftgl/FTFont/FTPolygonFontImpl.h fc9401eb562bf9f32c8a8b3dbd0f795b *src/ext/ftgl/FTFont/FTTextureFont.cpp 516421d846a01598ea710a972aaae599 *src/ext/ftgl/FTFont/FTTextureFontImpl.h 230bab96d6d850f1d33f2f1ad784a412 *src/ext/ftgl/FTGL/FTBBox.h 9e4292443f1b1b93ca6b634bf6d987f0 *src/ext/ftgl/FTGL/FTBitmapGlyph.h f49bdff8007e603d0c82fdbda0c25d48 *src/ext/ftgl/FTGL/FTBuffer.h 8c0b36ace135d7a55a97fdb6b663247d *src/ext/ftgl/FTGL/FTBufferFont.h 9c8ee2aab0f0a76b4dccf143a046f965 *src/ext/ftgl/FTGL/FTBufferGlyph.h c6df401411611c571a953790afff6630 *src/ext/ftgl/FTGL/FTExtrdGlyph.h 692a9fd4365ff11955e38a2e8feb6879 *src/ext/ftgl/FTGL/FTFont.h b1bdead397ff26e465fff6589b5c9830 *src/ext/ftgl/FTGL/FTGLBitmapFont.h e8548d181850f96793834feacd1c2856 *src/ext/ftgl/FTGL/FTGLExtrdFont.h da4d60ccfe6af055f6c7f66d381c5899 *src/ext/ftgl/FTGL/FTGLOutlineFont.h c8df9ea475390e02159833be3bdacc99 *src/ext/ftgl/FTGL/FTGLPixmapFont.h 32ab997693e08eb0265e7195dfd439b8 *src/ext/ftgl/FTGL/FTGLPolygonFont.h 0a03a39be54e5ef204c401b82cb536b5 *src/ext/ftgl/FTGL/FTGLTextureFont.h ce03934d2e2cf4bb3b0762c8ca8d150a *src/ext/ftgl/FTGL/FTGlyph.h 0dafe4d5a2e125ab0a2edbc9bfd5936c *src/ext/ftgl/FTGL/FTLayout.h bc6155067c5c42eb06d1557df2e43cc2 *src/ext/ftgl/FTGL/FTOutlineGlyph.h ded998ac5c20d8811cfaa26eac09a650 *src/ext/ftgl/FTGL/FTPixmapGlyph.h 992eddbbab7dfbd8eb5c15d6b876f14b *src/ext/ftgl/FTGL/FTPoint.h 902a47c1182e16d9df04e047902d5ca1 *src/ext/ftgl/FTGL/FTPolyGlyph.h 45b3c3fc72525a97df8314986e4760ab *src/ext/ftgl/FTGL/FTSimpleLayout.h 4200c568f82b18dd5ea0c7b9ff30e9c6 *src/ext/ftgl/FTGL/FTTextureGlyph.h d8bdcc5af3624847c7309665736a3b8a *src/ext/ftgl/FTGL/ftgl.h c3c4abcfe56e325d430029e543fb4ce5 *src/ext/ftgl/FTGlyph/FTBitmapGlyph.cpp d2e52f923d89e7cfbe976b40037c088f *src/ext/ftgl/FTGlyph/FTBitmapGlyphImpl.h 6a084df93d23154b06ae794e4e8c5427 *src/ext/ftgl/FTGlyph/FTBufferGlyph.cpp 19af28d3ac6f2494166372082634f0a7 *src/ext/ftgl/FTGlyph/FTBufferGlyphImpl.h 71ac13971b76de3508eb17827cd89da5 *src/ext/ftgl/FTGlyph/FTExtrudeGlyph.cpp 21da928e25d0d370a2fac6af1b11e35d *src/ext/ftgl/FTGlyph/FTExtrudeGlyphImpl.h f017bd959547aaea736fc8a189eed2be *src/ext/ftgl/FTGlyph/FTGlyph.cpp 568762d22d490f4140723be8fcbb2a55 *src/ext/ftgl/FTGlyph/FTGlyphGlue.cpp 8a657973e2ce18aa4f4ab933acf9cb8c *src/ext/ftgl/FTGlyph/FTGlyphImpl.h 45cb930c3377addd0eb4b36d0030fb2f *src/ext/ftgl/FTGlyph/FTOutlineGlyph.cpp 653ea146597a007704711585ce3bb1cf *src/ext/ftgl/FTGlyph/FTOutlineGlyphImpl.h 05cab235511ef9770ca0baa336e9753c *src/ext/ftgl/FTGlyph/FTPixmapGlyph.cpp d03c8a2e4118633d05661a4e97e44c47 *src/ext/ftgl/FTGlyph/FTPixmapGlyphImpl.h 96a3b4a56383677889f9be218dccbf70 *src/ext/ftgl/FTGlyph/FTPolygonGlyph.cpp 64f85eb98e1341f73e2aa96a2bdffb41 *src/ext/ftgl/FTGlyph/FTPolygonGlyphImpl.h 2ae9cfe909e39faf9506958269f88b3b *src/ext/ftgl/FTGlyph/FTTextureGlyph.cpp eeedd5ced1be160b6ac16364d972c966 *src/ext/ftgl/FTGlyph/FTTextureGlyphImpl.h bde3d77f0b6fb23338977c08d94127dd *src/ext/ftgl/FTGlyphContainer.cpp 72518f956e4124f14a3e3c7e56598928 *src/ext/ftgl/FTGlyphContainer.h 8dbca5ba67e5194fa3c3dbf3b0f070cb *src/ext/ftgl/FTInternals.h e9bcef03564229b55c1f41e08b6deb29 *src/ext/ftgl/FTLayout/FTLayout.cpp 63e9ec812b2e00b1e30dd2edd9225e16 *src/ext/ftgl/FTLayout/FTLayoutGlue.cpp 923471cafec7828be0ac98e32654b0b7 *src/ext/ftgl/FTLayout/FTLayoutImpl.h bb750695c84dd48d2d7c9b1a55c2f78a *src/ext/ftgl/FTLayout/FTSimpleLayout.cpp 2162c22bf4ab0dcecfce8a01df52840a *src/ext/ftgl/FTLayout/FTSimpleLayoutImpl.h c78f3e6fc5d8f1101ab4dbf9c39c8b2e *src/ext/ftgl/FTLibrary.cpp c89dd7f824e02ccb8f1417d9c749d14a *src/ext/ftgl/FTLibrary.h 0bee532772a9a4e6731234ae4ad0e1dc *src/ext/ftgl/FTList.h 0ad28cf7cb22082364ed3f7a757dbeac *src/ext/ftgl/FTPoint.cpp b44e9272b2622955623953a4e4f1519a *src/ext/ftgl/FTSize.cpp df0140033dc56cd6e35b2eb604c9be88 *src/ext/ftgl/FTSize.h 6663897b4edc1847d5826632fe1ecf8d *src/ext/ftgl/FTUnicode.h 66f64edb27e9343a06defee757372711 *src/ext/ftgl/FTVector.h 022e12e6d95b7cecad4c1d869e2e9e7f *src/ext/ftgl/FTVectoriser.cpp f628642b6af28e07c8fff0a9464ba650 *src/ext/ftgl/FTVectoriser.h 669126c660cd42496af6d02fe6a62741 *src/ext/ftgl/config.h d594405527b214d06982883602f728a4 *src/fps.cpp 9f344e98996f3d67fbf091c76585ecfb *src/fps.h 1fdd71d5a6d05d33bf335c0c10283aba *src/ftgl.cpp 9dd32b80e913c360584b022485e50a06 *src/geom.cpp 801de6ffecb85d9ad80257b168cfce48 *src/geom.h 0caa00bb13ae0907a7ca6471fd11c735 *src/gl2ps.c f98a5fba15e844bd7696aff31d2cb65c *src/gl2ps.h 01922e999eff711b7d11e7bf67e01dbc *src/glErrors.cpp 99e31ea4d478b83998b628dc1d492d0e *src/glgui.cpp 1d04ab6833c14ba95e190ecdd7a9ed71 *src/glgui.h 250f1cc2cafe47ca5528170a8e5ff5bf *src/gui.cpp 2ca359dab037ad2aef6ee87226d34402 *src/gui.h 1923a61126b606ebeb4209768444739e *src/init.cpp 190208962b2847c69e26112f22078f92 *src/init.h fe7602c5e1f839e5a131e1e75e95a219 *src/lib.h c94cdb35c96c9e8ea373f7c0b86a6fbc *src/opengl.h a60c195039a6d5927db9c18cd92ff70e *src/par3d.cpp b727187c2b64d8fec33bded317db4c4c *src/pixmap.cpp 57331fd0ba6dedf10b0d98cf40dcc02b *src/pixmap.h be1698aa4576d9b3ab05099277881a58 *src/platform.cpp e3bf330106d33801829cdd55c21d008b *src/platform.h aca94f6c0ac70dc568684bb277098107 *src/pngpixmap.h 0f3cbcc107a805669552e140ede08ed7 *src/pragma.h 3e7dde6417aea22e2720ecf946cf164d *src/pretty.c 28ba9504069a992227eec0a430d4803e *src/pretty.h da0fc38773c5fbffba460405d927216b *src/render.cpp 52cefaccd594ffc070d0e58d615347e2 *src/render.h d140e13b2a81bf64aca893a3de84c40f *src/rgl-win.def 72b5b7aa52f5f0f38ac79570c55473e4 *src/rglmath.cpp 7cd9dea143128d6261eb4e2d87b5560f *src/rglmath.h 95124b7c2516fc838dd098aa20d48987 *src/rglview.cpp 9dfbaebf5b98cf696011bbf6fd192230 *src/rglview.h e09e5a9cbdc20aa7beca56756bc8d47e *src/scene.cpp fac235696a7454133d287870ac5a1237 *src/scene.h 5a7649daaf33cbe272304dd001515acb *src/select.cpp 4f05e840d60d3d37706ef41e59e1b28e *src/select.h 4659b24f467b9cb504c129c0f47b0bd8 *src/subscene.cpp d08c372fff6d621b651178bedd607e58 *src/subscene.h 85a2bf4ffefd0d62fb061e7fc5db0a0d *src/types.h b2be2ae826114fb41cfd9edbca9eb739 *src/useNULL/Makevars 6d0bcb7db30efa347d8e4a434ba284aa *src/useNULL/Makevars.in 5dad4b46bd394730ed904ced7eceaf33 *src/win32gui.cpp 305ea9cb6c67ba53cd2e719ceb614479 *src/win32gui.h 9bd9cbf263308cb6792ba619767c79b7 *src/win32lib.cpp c56e4712bb7e408be537a9cd43a73a35 *src/x11gui.cpp 989fa9b098bd3853853ad77f2a0d00d2 *src/x11gui.h bb033aaefa628fb5e2c2eb0628db269c *src/x11lib.cpp c1cfc4a2398fb865c5cb4da26b1c5c8c *tests/bbox3dtests.R c3199d2881d143df1931b2f6215953e3 *tests/boundary.R 68699a6840b0acd3393892caea36c6ff *tests/indices.R fb7f6c757fd4a23d396f70f359dea064 *tests/testthat.R 77ca68d0c01c76771a0888ffbde8cc73 *tests/testthat/conversions.R fe2142d2244d2305ae38290b9b4f2c8b *tests/testthat/test-as.mesh3d.R 418b964d172fde4d829f00608ccd8ad6 *tests/testthat/test-mesh3d.R ce9c4f177de5d879e83bc769277a8dc2 *tests/testthat/test-obj.R 10cbd789db3908bfffdd680c56c7ee4a *tests/testthat/test-r3d.R 1f34cdf076fbbf2b651432f36afae8d9 *tests/testthat/test-subscenes.R e41bb5900f103481f6236d02de235b02 *tests/testthat/test-tags.R 0c0d61b90301a4c222fd53c1521f4dc0 *tests/testthat/testdata/mergeVertices.rds 89a5f41652aaee72de0b858258074a38 *tests/testthat/testdata/obj.rds 68ecdc479cae94c755fe92e74206068b *tests/testthat/testdata/qmesh3d.rds a6c8d985c43d7012a0e132f413e76dc7 *tests/testthat/testdata/r3d.rds f894aea2982144551abdceb6321ad1d7 *tests/testthat/testdata/shade3detc.rds 684d23143aec6c4259aaa35629986621 *tests/testthat/testdata/subscenes.rds 9f8813b24bbddf0b16605f69fcfd6d42 *tests/testthat/testdata/tmesh3d.rds 1d1bf5f68fe219d77e98003a1cd13f4b *tests/testthat/testdata/transformations.rds a7fa1d2be854209389accfa66ff7febb *tools/winlibs.R 94dc3fbf1243230dbf06a936366b5f82 *vignettes/WebGL.Rmd ef5db6d0057d0cb6b79f7a79fb43a6b1 *vignettes/pkgdown.Rmd 2ba4aa9981b92a1c1a1d651280738f9f *vignettes/rgl.Rmd a0fe30c481c71c9a8787137d48c0b2b0 *vignettes/setup.R 002b07c7e555fada70d405ea390aacd2 *vignettes/transparency.Rmd rgl/inst/0000755000176200001440000000000014146473375012031 5ustar liggesusersrgl/inst/slowTests/0000755000176200001440000000000014100762640014022 5ustar liggesusersrgl/inst/slowTests/demos.R0000644000176200001440000000054714100762640015262 0ustar liggesuserslibrary(rgl) # regression : this failed for headless tests par3d(userMatrix = diag(4)) if (!rgl.useNULL()) for(demo in demo(package="rgl")$results[,"Item"]) if (!(demo %in% c("rgl", "lsystem", "rglExamples", "shinyDemo", "simpleShinyRgl", "shinyMouse"))) demo(demo, package="rgl", character.only=TRUE) rgl/inst/doc/0000755000176200001440000000000014146473374012575 5ustar liggesusersrgl/inst/doc/rgl.html0000644000176200001440000122553114146473374014260 0ustar liggesusers rgl Overview

rgl Overview

Duncan Murdoch

November 21, 2021

## Warning in setupKnitr(autoprint = TRUE): Already set autoprint = FALSE,
## rgl.newwindow = FALSE, rgl.closewindows = FALSE

NULL

Introduction

The rgl package is used to produce interactive 3-D plots. It contains high-level graphics commands modelled loosely after classic R graphics, but working in three dimensions. It also contains low level structure inspired by (but incompatible with) the grid package.

This document gives an overview. See the help pages for details.

For installation instructions, see the README file in the top level directory of the source tarball rgl_0.108.3.tar.gz (or a later version).

About this document

This document was written in R Markdown, using the knitr package for production. It corresponds to rgl version 0.108.3.

Most of the highlighted function names are HTML links. The internal links should work in any browser; the links to help topics should work if you view the vignette from within the R help system.

The document includes WebGL figures. To view these, you must have Javascript and WebGL enabled in your browser. Some older browsers may not support this – see https://get.webgl.org for tests and links to a discussion.

Basics and High Level Functions

The plot3d function plots points within an RGL window. It is similar to the classic plot function, but works in 3 dimensions.

For example

with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length, 
                  type="s", col=as.numeric(Species)))

can be used to plot three columns of the iris data. Allowed plot types include "p", "l", "h", "s", meaning points, lines, segments from z=0, and spheres. There’s a lot of flexibility in specifying the coordinates; the xyz.coords function from the grDevices package is used for this.

You can use your mouse to manipulate the plot. The default is that if you click and hold with the left mouse button, you can rotate the plot by dragging it. The right mouse button is used to resize it, and the middle button changes the perspective in the point of view.

If you call plot3d again, it will overwrite the current plot. To open a new graphics window, use open3d.

The other high level function is persp3d to draw surfaces. It is similar to the classic persp function, but with greater flexibility. First, any of x, y or z can be specified using matrices, not just z. This allows parametric surfaces to be plotted. An even simpler specification is possible: x may be a function, in which case persp3d will work out the grid itself. See ?persp3d.function for details. For example, the MASS package estimates Gamma parameters using maximum likelihood in a ?MASS::fitdistr example. Here we show the log likelihood surface.

library(MASS)
# from the fitdistr example
set.seed(123)
x <- rgamma(100, shape = 5, rate = 0.1)
fit <- fitdistr(x, dgamma, list(shape = 1, rate = 0.1), lower = 0.001)
loglik <- function(shape, rate) sum(dgamma(x, shape=shape, rate=rate, 
                                           log=TRUE))
loglik <- Vectorize(loglik)
xlim <- fit$estimate[1]+4*fit$sd[1]*c(-1,1)
ylim <- fit$estimate[2]+4*fit$sd[2]*c(-1,1)

mfrow3d(1, 2, sharedMouse = TRUE)
persp3d(loglik, 
        xlim = xlim, ylim = ylim,
        n = 30)
zlim <- fit$loglik + c(-qchisq(0.99, 2)/2, 0)
next3d()
persp3d(loglik, 
        xlim = xlim, ylim = ylim, zlim = zlim,
        n = 30)

On the left, the whole surface over a range of the parameters; on the right, only the parts of the surface with log likelihood values near the maximum.

Note: this example used the knitr hook functions (see setupKnitr) to insert the scene into this vignette; the previous example used the rglwidget function. We generally recommend the newer rglwidget approach.

Note that both plot3d and persp3d are generic functions, with the following methods defined:

methods(plot3d)
##  [1] plot3d.ashape3d*      plot3d.default*       plot3d.deldir*       
##  [4] plot3d.formula*       plot3d.function*      plot3d.lm*           
##  [7] plot3d.mesh3d*        plot3d.rglWebGL*      plot3d.rglbackground*
## [10] plot3d.rglbboxdeco*   plot3d.rglobject*     plot3d.rglscene*     
## [13] plot3d.rglsubscene*   plot3d.tri*           plot3d.triSht*       
## see '?methods' for accessing help and source code
methods(persp3d)
## [1] persp3d.ashape3d* persp3d.default*  persp3d.deldir*   persp3d.formula* 
## [5] persp3d.function* persp3d.tri*      persp3d.triSht*  
## see '?methods' for accessing help and source code

Adding Graphical Elements

Primitive shapes

Just as we have points and lines in classic graphics, there are a number of low level functions in rgl to add graphical elements to the currently active plot. The “primitive†shapes are those that are native to OpenGL:

Function Description
points3d: adds points
lines3d: adds lines
segments3d: adds line segments
triangles3d: adds triangles
quads3d: adds quadrilaterals

Each of the above functions takes arguments x, y and z, again using xyz.coords for flexibility. They group successive entries as necessary. For example, the triangles3d function takes each successive triple of points as the vertices of a triangle.

You can use these functions to annotate the current graph, or to construct a figure from scratch.

Constructed shapes

rgl also has a number of objects which it constructs from the primitives.

Function Description
text3d, texts3d: adds text
abclines3d: adds straight lines to plot (like abline)
arc3d: adds spherical arcs or spirals to plot
planes3d: adds planes to plot
clipplanes3d: add clipping planes to plot
sprites3d, particles3d: add sprites (fixed shapes or images) to plot
spheres3d: adds spheres
surface3d, terrain3d: a surface (as used in persp3d)
drape3d: drapes lines on a surface or object(s)
shadow3d: projects mesh onto a surface
arrow3d: add an arrow to a scene
pch3d: draw base-style plotting symbols
plotmath3d: used by text3d for math text

Axes and other “decorationsâ€

The following low-level functions control the look of the graph:

Function Description
axes3d, axis3d: add axes to plot
box3d, bbox3d: add box around plot
title3d: add title to plot
mtext3d: add marginal text to plot
decorate3d: add multiple “decorations†(scales, etc.) to plot
aspect3d: set the aspect ratios for the plot
bg3d, bgplot3d: set the background of the scene
show2d: show a 2D plot or image in a 3D scene
legend3d: set a legend for the scene
grid3d: add a reference grid to a graph
thigmophobe3d: choose label positions to avoid overlap
setAxisCallbacks: set user-defined axis annotations

For example, to plot three random triangles, one could use

triangles3d(cbind(x=rnorm(9), y=rnorm(9), z=rnorm(9)), col = "green")
decorate3d()
bg3d("lightgray")
aspect3d(1,1,1)

Besides the *3d functions mentioned above, there are even lower-level functions rgl.primitive, rgl.points, rgl.linestrips, rgl.lines, rgl.triangles, rgl.quads, rgl.texts, rgl.abclines, rgl.planes, rgl.bg, rgl.clipplanes, rgl.bbox, rgl.spheres, rgl.sprites, rgl.surface.
You should avoid using these functions, which do not work well with the higher level *3d functions. See the ?r3d help topic for details. The functions rgl.setAxisCallback, rgl.getAxisCallback provide low-level support for setAxisCallbacks.

Controlling the Look of the Scene

Lighting

In most scenes, objects are “litâ€, meaning that their appearance depends on their position and orientation relative to lights in the scene. The lights themselves don’t normally show up, but their effect on the objects does.

Use the light3d function to specify the position and characteristics of a light. Lights may be infinitely distant, or may be embedded within the scene. Their characteristics include ambient, diffuse, and specular components, all defaulting to white. The ambient component appears the same from any direction. The diffuse component depends on the angle between the surface and the light, while the specular component also takes the viewer’s position into account.

The rgl.light function is a lower-level function with different defaults; users should normally use light3d.

Materials

The mental model used in rgl is that the objects being shown in scenes are physical objects in space, with material properties that affect how light reflects from them (or is emitted by them). These are mainly controlled by the material3d function, or by arguments to other functions that are passed to it.

The material properties that can be set by calls to material3d are described in detail in the ?material3d help page. Here we give an overview.

Property Default Meaning
color white vector of surface colors to apply to successive vertices for diffuse light
alpha 1 transparency: 0 is invisible, 1 is opaque
lit TRUE whether lighting calculations should be done
ambient black color in ambient light
specular white color in specular light
emission black color emitted by the surface
shininess 50 controls the specular lighting: high values look shiny
smooth TRUE whether shading should be interpolated between vertices
texture NULL optional path to a “texture†bitmap to be displayed on the surface
front, back fill should polygons be filled, or outlined?
size 3 size of points in pixels
lwd 1 width of lines in pixels

Other properties include “texmipmapâ€, “texmagfilterâ€, “texminfilterâ€, “texenvmapâ€, “fogâ€, “point_antialiasâ€, “line_antialiasâ€, “depth_maskâ€, “depth_testâ€, “polygon_offsetâ€, “marginâ€, “floating†and “tagâ€; see the help page for details.

There is also an rgl.material function that works at a lower level; users should normally avoid it.

Textures

As described in the previous section, one of the material properties is texture, the name of a bitmap file (in .png format) containing an image to be displayed on the surface. This section gives more details about textures.

In OpenGL, each vertex in a polygon may be associated with a particular location in the bitmap. The interior of the polygon interpolates within the bitmap. There are two conventions in rgl functions for specifying these coordinates.

Functions which specify primitives (triangles3d, etc.) accept an optional matrix argument texcoords which gives s (horizontal) and t (vertical) locations within the bitmap in columns with one row per vertex. The coordinates are (0,0) for the lower left, and (1,1) for the upper right. If values outside this range are given, the image repeats, i.e. (1.1, 1.1) would specify the same point in the image as (0.1, 0.1).

Other functions such as surface3d that take matrices for each vertex coordinate accept texture coordinates as matrices as well, in arguments texture_s and texture_t.

For example, the following code displays four copies of a 2D plot on a quad, because the texture coordinates run from 0 to 2 in both s and t:

filename <- tempfile(fileext = ".png")
png(filename = filename)
plot(rnorm(1000), rnorm(1000))
dev.off()
## quartz_off_screen 
##                 2
open3d()
## null 
##   16
xyz <- cbind(c(0,1,1,0), 0, c(0,0,1,1))
quads3d(xyz, texture = filename, texcoords = xyz[,c(1, 3)]*2, col = "white", specular = "black")

Some other notes:

  • The color in the figure above was specified to be white. By default, the colors in the bitmap will modify the colour of the quad. If col is black (a common default), you won’t see anything.
  • On the other hand, you usually don’t want specular reflections (which show up as glare). Setting specular to black prevents those.
  • How the bitmap is handled is controlled by the material property "textype". The default is "rgb", which takes the red-green-blue colours from the bitmap and uses them to modify the corresponding colours in the polygon. Other possibilities for "textype" are described in the material3d help page.
  • The other "tex*" material properties control how the interpolation within the image is done.
  • Modern OpenGL supports 1- and 3-dimensional textures; these are not supported in rgl.

Fonts

rgl uses the same ideas as base graphics for drawing text: there are font families named "sans", "serif", and "mono" for drawing text of those types. In rgl, the "symbol" family is not supported.

New font families can be defined using the low-level function rglFonts, or more simply using the higher level function rglExtrafonts. The latter function requires the extrafont package to be installed.

par3d: Miscellaneous graphical parameters

The par3d function, modelled after the classic graphics par function, sets or reads a variety of different rgl internal parameters. Some parameters are completely read-only; others are fixed at the time the window is opened, and others may be changed at any time.

Name Changeable? Description
antialias fixed Amount of hardware antialiasing
cex Default size for text
family Device-independent font family name; see ?text3d
font Integer font number
useFreeType Should FreeType fonts be used if available?
fontname read-only System-dependent font name set by rglFonts
FOV Field of view, in degrees. Zero means isometric perspective
ignoreExtent Should rgl ignore the size of new objects when computing the bounding box?
skipRedraw Should rgl suppress updates to the display?
maxClipPlanes read-only How many clip planes can be defined?
modelMatrix read-only The OpenGL ModelView matrix; partly set by view3d or the obsolete rgl.viewpoint
projMatrix read-only The OpenGL Projection matrix
bbox read-only Current bounding-box of the scene
viewport Dimensions in pixels of the scene within the window
windowRect Dimensions in pixels of the window on the whole screen
listeners Which subscenes respond to mouse actions in the current one
mouseMode What the mouse buttons do. See “mouseModeâ€
observer read-only The position of the observer; set by observer3d
scale Rescaling for each coordinate; see aspect3d
zoom Magnification of the scene

Default settings

The r3dDefaults list and the getr3dDefaults function control defaults in new windows opened by open3d.
The function looks for the variable in the user’s global environment, and if not found there, finds the one in the rgl namespace. This allows the user to override the default settings for new windows.

Once found, the r3dDefaults list provides initial values for par3d parameters, as well as defaults for material3d and bg3d in components "material" and "bg" respectively.

Meshes: Constructing Shapes

rgl includes a number of functions to construct and display various solid shapes. These generate objects of class "shape3d", "mesh3d" or "shapelist3d". The details of the classes are described below. We start with functions to generate them.

Specific solids

These functions generate specific shapes. Optional arguments allow attributes such as colour or transformations to be specified.

Function Description
tetrahedron3d, cube3d, octahedron3d, dodecahedron3d, icosahedron3d: Platonic solids
cuboctahedron3d, oh3d: other solids
cols <- rainbow(7)
layout3d(matrix(1:16, 4,4), heights=c(1,3,1,3))
text3d(0,0,0,"tetrahedron3d"); next3d()
shade3d(tetrahedron3d(col=cols[1])); next3d()
text3d(0,0,0,"cube3d"); next3d()
shade3d(cube3d(col=cols[2])); next3d()
text3d(0,0,0,"octahedron3d"); next3d()
shade3d(octahedron3d(col=cols[3])); next3d()
text3d(0,0,0,"dodecahedron3d"); next3d()
shade3d(dodecahedron3d(col=cols[4])); next3d()
text3d(0,0,0,"icosahedron3d"); next3d()
shade3d(icosahedron3d(col=cols[5])); next3d()
text3d(0,0,0,"cuboctahedron3d"); next3d()
shade3d(cuboctahedron3d(col=cols[6])); next3d()
text3d(0,0,0,"oh3d"); next3d()
shade3d(oh3d(col=cols[7]))

A very large collection of polyhedra is contained in the Rpolyhedra package.

Generating new shapes

These functions generate new shapes:

Function Description
cylinder3d: generate a tube or cylinder
polygon3d: generate a flat polygon by triangulation
extrude3d: generate an “extrusion†of a polygon
turn3d: generate a solid of rotation
ellipse3d: generate an ellipsoid in various ways
mesh3d: generate a shape from indexed vertices
shapelist3d: generate a shape by combining other shapes
as.mesh3d: a generic function; see below

A related function is triangulate, which takes a two dimensional polygon and divides it up into triangles using the “ear-clipping†algorithm.

The generic function as.mesh3d is provided to allow data structures produced by other code to be converted to mesh structures. Currently the following classes are supported:

Class Package Description
deldir deldir Delaunay triangulations of irregular point clouds
triSht interp Also Delaunay triangulations
tri tripack Generalized Delaunay triangulations
ashape3d alphashape3d Alpha-shapes
rglId rgl rgl object identifiers

The checkDeldir function checks that a compatible version of the deldir package is installed.

The default as.mesh3d.default method is a simple way to construct a mesh from a matrix of vertices; it can use mergeVertices (which can also be used on its own) to merge repeated vertices within the matrix, allowing addNormals to be used to give a smooth appearance.

The as.tmesh3d generic is a variation that guarantees the resulting object will have no quad entries.

Functions tmesh3d, qmesh3d are now obsolete; use mesh3d instead.

The underlying class structure for shapes

"shape3d" is the basic abstract type. Objects of this class can be displayed by shade3d (which shades faces), wire3d (which draws edges), or dot3d (which draws points at each vertex.)

"mesh3d" is a descendant type. Objects of this type contain the following fields:

Field Meaning
vb A 4 by n matrix of vertices in homogeneous coordinates. Each column is a point.
ip (optional) A vector of vertex indices for points.
is (optional) A 2 by s matrix of vertex indices. Each column is a line segment.
it (optional) A 3 by t matrix of vertex indices. Each column is a triangle.
ib (optional) A 4 by q matrix of vertex indices. Each column is a quadrilateral.
material (optional) A list of material properties.
normals (optional) A matrix of the same shape as vb, containing normal vectors at each vertex.
texcoords (optional) A 2 by n matrix of texture coordinates corresponding to each vertex.
values (optional) A vector of length n holding values at each vertex
meshColor (optional) A text value indicating how colors and texture coordinates should be interpreted.

Contouring shapes

These functions compute and plot contours of functions on surfaces, or clip objects along a contour of a function.

Function Description
contourLines3d: draw contour lines on surface
filledContour3d: fill between contours on surface
clipMesh3d: clip mesh object using curved boundary
clipObj3d: clip general object using curved boundary

Manipulating shapes

These functions manipulate and modify mesh objects:

Function Description
addNormals: add normal vectors to make a shape look smooth
subdivision3d: add extra vertices to make it look even smoother
merge: merge mesh objects
facing3d: subset of mesh facing “upâ€
getBoundary3d: get the boundary of a mesh object

The individual steps in subdivision3d are also available: deform.mesh3d, divide.mesh3d, normalize.mesh3d. These are mainly intended for internal use.

Multi-figure Layouts

rgl has several functions to support displaying multiple different “subscenes†in the same window. The high level functions are

Function Description
mfrow3d: Multiple figures (like par(“mfrowâ€)
layout3d: Multiple figures (like layout)
next3d: Move to the next figure (like plot.new or frame)
subsceneList: List all the subscenes in the current layout
clearSubsceneList: Clear the current list and revert to the previous one

There are also lower level functions.

Function Description
newSubscene3d: Create a new subscene, with fine control over what is inherited from the parent
currentSubscene3d: Report on the active subscene
subsceneInfo: Get information on current subscene
useSubscene3d: Make a different subscene active
addToSubscene3d, delFromSubscene3d: Add objects to a subscene, or delete them
gc3d: Do “garbage collectionâ€: delete objects that are not displayed in any subscene

Documents with rgl Scenes

The rgl package can produce output that can be embedded in other documents. The recommended way to do this has changed several times over the years. We will start with the current recommendation, then list older methods.

Producing PDF output

While some PDF previewers support interactive 3D graphics, most don’t. To produce a screenshot of an rgl scene in an R Markdown document with PDF output, simply follow the directions given above. The auto-printing will detect PDF output and use snapshot3d to produce a PNG file to insert. (See below if you want to insert a different format of graphic.)

If you really need interactive output, see the writeASY function.

Manual insertion of plots

You may not want to use the setupKnitr(autoprint = TRUE) method described above. It is very new, and may still have bugs; you may have an older document and not want to edit it to work that way.

In this case, you can insert plots manually. Use setup code

```{r echo=FALSE, include=FALSE}
library(rgl)
setupKnitr()
```

and call rglwidget() at top level whenever you want to insert a plot.

There are a couple of other differences in default behaviour if you are not using autoprint:

  • By default, each code chunk continues the rgl scene from earlier chunks. You’ll need an explicit open3d call to get a clean window.

  • Also by default, the rgl window is not closed at the end of the chunk. This probably doesn’t matter, but you may find you run out of memory if your scenes are really big.

Older methods

The original way to insert an rgl scene in a document was to use the writeWebGL function to write HTML code to insert in a document. Later, Sweave and knitr hooks were added. These are no longer maintained, and it is recommended that you update old documents to use the newer methods. See the writeWebGL, rgl.Sweave and hook_rgl help topics for details on these if you must use them. If you are reading documents that suggest using those methods, let the author know they need updating!

Utility Functions

User interaction

By default, rgl detects and handles mouse clicks within your scene, and uses these to control its appearance. You can find out the current handlers using the following code:

par3d("mouseMode")
##        none        left       right      middle       wheel 
##      "none" "trackball"      "zoom"       "fov"      "pull"

The labels c("left", "right", "middle") refer to the buttons on a three button mouse, or simulations of them on other mice. "wheel" refers to the mouse wheel, and "none" refers to actions that take place when the mouse is moved without pressing any button.

The button actions generally correspond to click and drag operations. Possible values for “mouseMode†for the mouse pointer or wheel are as follows:

Mode Description
"none" No action
"trackball" The mouse acts as a virtual trackball. Clicking and dragging rotates the scene
"xAxis", "yAxis", "zAxis" Like "trackball", but restricted to rotation about one axis
"polar" The mouse affects rotations by controlling polar coordinates directly
"selecting" The mouse is being used by the select3d function
"zoom" The mouse zooms the display
"fov" The mouse affects perspective by changing the field of view
"pull" Rotating the mouse wheel towards the user “pulls the scene closerâ€
"push" The same rotation “pushes the scene awayâ€
"user" A user action set by setUserCallbacks, rgl.setMouseCallbacks, rgl.setWheelCallback. Use rgl.getMouseCallbacks and rgl.getWheelCallback to retrieve.

The following functions make use of the mouse for selection within a scene.

Function Description
identify3d: like the classic graphics identify function
select3d: returns a function that tests whether a coordinate was selected
selectpoints3d: selects from specific objects

selectionFunction3d produces the selection function from information about the projection and mouse selection region; it is used internally in the functions above.

The rgl.select3d function is an obsolete version of select3d, and rgl.select is a low-level support function.

Animations

rgl has several functions that can be used to construct animations. These are based on functions that update the scene according to the current real-world time, and repeated calls to those. The functions are:

Function Description
play3d: Repeatedly call the update function
spin3d: Update the display by rotating at a constant rate
par3dinterp: Compute new values of some par3d parameters by interpolation over time

See the movie3d function for a way to output an animation to a file on disk.
Animations are not currently supported in the HTML written by rglwidget, though the playwidget function provides equivalent functionality.

Integration with TCL/TK

There are three functions in rgl that support control of an rgl scene using the TCL/TK framework.

Function Description
tkspin3d: Set up buttons in a window to control a scene
tkspinControl: Embed the control buttons in a separate TCL/TK frame
tkpar3dsave: Create a dialog to interactively save mouse actions

These functions were formerly contained (without the tk prefixes on their names) in the tkrgl package. That package is now deprecated.

Exporting and importing scenes

rgl contains several functions to write scenes to disk for use by other software, or to read them in.

In order from highest fidelity to lowest, the functions are:

Function Description
scene3d: Save a scene to an R variable, which can be saved and reloaded
rglwidget: Prints as HTML and Javascript to display a scene in a web browser. (See also User Interaction in WebGL.)
writeWebGL: Deprecated.
writeASY: Write files for Asymptote
writePLY: Write PLY files (commonly used in 3D printing)
readOBJ, writeOBJ: Read or write OBJ files (commonly used in 3D graphics)
readSTL, writeSTL: Read or write STL files (also common in 3D printing)
as.rglscene: Generic function, no methods in rgl

The rgl2gltf package can read or write GLTF and GLB files. It includes an as.rglscene method to convert GLTF objects to rgl scenes. The code in rgl’s Buffer R6 class is based on the GLTF format. It is used by rglwidget to make output webpages somewhat smaller than they were previously.

There are also functions to save snapshots or other recordings of a scene, without any 3D information being saved:

Function Description
snapshot3d: Save a PNG file bitmap of the scene
rgl.postscript: Save a Postscript, LaTeX, PDF, SVG or PGF vector rendering of the scene
movie3d: Save a series of bitmaps to be assembled into a movie
rgl.pixels: Obtain pixel-level information about the scene in an R variable
rgl.Sweave: Driver function for inserting a snapshot into a Sweave document.
hook_rgl, hook_webgl: knitr hook functions for inserting images into a document.
setupKnitr: Function to set up knitr hooks

The rgl.snapshot function is a low level version of snapshot3d(); it requires that the rgl display be onscreen and copies from there. snapshot3d() tries to use the webshot2 package so it will work even with no display. The functions rgl.Sweave.off, Sweave.snapshot are involved in Sweave processing and not normally called by users.

Default display

There are two ways in which rgl scenes are normally displayed within R. The older one is in a dedicated window. In Unix-alikes this is an X11 window; it is a native window in Microsoft Windows. On macOS, the XQuartz system (see https://www.xquartz.org) needs to be installed to support this.

To suppress this display, set options(rgl.useNULL = TRUE) before opening a new rgl window. See the help page for the rgl.useNULL function for how to set this before starting R.

The newer way to display a scene is by using WebGL in a browser window or in the Viewer pane in RStudio. To select this, set options(rgl.printRglwidget = TRUE). Each operation that would change the scene will return a value which triggers a new WebGL display when printed.

Working with WebGL scenes

You should use the following scheme for exporting a scene to a web page. There’s also an older scheme, which is no longer supported.

The recommended approach works with the htmlwidgets framework (see http://www.htmlwidgets.org/). In an R Markdown document in knitr, use the rglwidget function. (You can also use chunk option webgl=TRUE; we recommend the explicit use of rglwidget.) This approach also allows display of rgl scenes in RStudio. Besides rgl scenes, various controls for them can be displayed, and there are a few utility functions that can be useful:

Function Description
propertyControl: set individual properties
clipplaneControl: control a clipping plane
subsetControl: control which objects are displayed
ageControl: “age†vertices of an object
vertexControl: control properties of vertices
par3dinterpControl: WebGL control like par3dinterp
playwidget: display and automate controls
toggleWidget: display a button to toggle some items
%>%: magrittr pipe
figHeight, figWidth: Dimensions of figures in R Markdown document
rglShared: share data using crosstalk package
rglMouse: change mouse mode in RGL scene
asRow: arrange multiple objects in an HTML display
getWidgetId: get the elementId from a widget

These functions work with the above scheme in Shiny apps:

Function Description
sceneChange: used in Shiny for large scene changes
shinyGetPar3d, shinySetPar3d: get or set par3d values from Shiny
shinyResetBrush: reset the mouse brush in Shiny

The selectionFunction3d function is also likely to be involved in mouse interactions when using Shiny.

Some functions are mainly for internal use: elementId2Prefix, playwidgetOutput, renderPlaywidget, rglwidgetOutput, renderRglwidget, registerSceneChange. More details are given in the vignette User Interaction in WebGL. The functions lowlevel, highlevel, rglId are also for internal use, marking function results for automatic printing. Finally, the experimental function setUserShaders allows you to use hand-written shaders in WebGL.

The older approach uses the writeWebGL function to export a scene to HTML and Javascript code.
These functions write HTML and Javascript for working with the exported scene: propertySlider, clipplaneSlider, subsetSlider, toggleButton, propertySetter, subsetSetter, ageSetter, par3dinterpSetter, vertexSetter, matrixSetter. Use the newer functions instead.

Working with the scene

rgl maintains internal structures for all the scenes it displays. The following functions allow users to find information about them and manipulate them. In cases where there are both *3d and rgl.* versions of functions, most users should use the *3d version: the rgl.* functions are more primitive and are mainly intended for internal use.

Function Description
open3d: open a new window
close3d, rgl.close: close the current window
cur3d, rgl.cur: id of the active device
set3d, rgl.set: set a particular device to be active
pop3d, rgl.pop: delete objects from the scene
clear3d, rgl.clear: delete all objects of certain classes
ids3d, rgl.ids: ids, types and tags of current objects
tagged3d: find tags or objects with tags

These functions are mainly intended for programming, and have no corresponding *3d counterparts:

Function Description
rgl.bringtotop: bring the current window to the top
rgl.dev.list: ids of all active devices
rgl.attrib, rgl.attrib.info, rgl.attrib.count: attributes of objects in the scene
rgl.projection: return information about the current projection
rgl.user2window, rgl.window2user: convert between coordinates in the current projection

The as.triangles3d generic function is intended to extract coordinates in a form suitable for passing to triangles3d. Currently a method is provided for rglId objects.

In addition to these, there are some other related functions which should rarely be called by users: rgl.init, rgl.open, rgl.quit.

Working with 3-D vectors

Most rgl functions work internally with “homogeneous†coordinates. In this system, 3-D points are represented with 4 coordinates, generally called (x, y, z, w). The corresponding Euclidean point is (x/w, y/w, z/w), if w is nonzero; zero values of w correspond to “points at infinityâ€. The advantage of this system is that affine transformations including translations and perspective shifts become linear transformations, with multiplication by a 4 by 4 matrix.

rgl has the following functions to work with homogeneous coordinates:

Function Description
asEuclidean, asHomogeneous: convert between homogeneous and Euclidean coordinates when x, y and z are columns
asEuclidean2, asHomogeneous2: convert when x, y and z are rows
rotate3d, scale3d, translate3d: apply a transformation
transform3d: apply a general transformation
rotationMatrix, scaleMatrix, translationMatrix: compute the transformation matrix
identityMatrix: return a 4 x 4 identity matrix
projectDown: a 3D to 2D projection down a vector

There is also a function GramSchmidt, mainly for internal use: it does a Gram-Schmidt orthogonalization of a 3x3 matrix, with some specializations for its use in cylinder3d.

Working with other packages

Sometimes it may be convenient to interactively rotate a scene to a particular view, then display it in lattice or base graphics. The rglToLattice and rglToBase functions support this.

For example, we first display the volcano data in rgl:

persp3d(volcano, col = "green")

This display is interactive, but we can reproduce the initial view using the lattice wireframe or base graphics persp functions:

lattice::wireframe(volcano, col = "green", 
           screen = rglToLattice())

angles <- rglToBase()
persp(volcano, col = "green", shade = TRUE,
      theta = angles$theta, phi = angles$phi)

Note that the orientlib package must be available for these functions to work.

Creating pkgdown websites

The “Using RGL in pkgdown web sites†vignette describes how to use rgl in a pkgdown web site. The utility function in_pkgdown_example can be used to detect that pkgdown is being used.

Working with testthat

The testthat package is widely used for unit tests in packages. Such tests are hard to write with rgl, because the output is visual and interactive rather than a simple value. The expect_known_scene, compare_proxy.mesh3d and all.equal.mesh3d functions help with this by removing system-dependent features of rgl output.

Working with Javascript

The WebGL displays created using rglwidget rely on a large body of Javascript code included in this package. To help in development of this code, the makeDependency function was written. It may be useful in other packages that include Javascript.

Other functions

This section is for miscellaneous functions that don’t fall in any of the other categories in this document.

The setGraphicsDelay function is designed to work around what appears to be a bug on macOS: if a standard plot window is opened too quickly after an rgl window, R can crash. This function inserts a one second delay when it appears to be needed.

Warning: Work in Progress!

This vignette is always a work in progress. Some aspects of the rgl package are not described, or do not have examples. There may even be functions that are missed completely, if the following list is not empty:

## character(0)

Index of Functions

The following functions and constants are described in this document:

%>%   divide.mesh3d   par3dinterpSetter   rgl.pixels   shade3d  
Buffer   dodecahedron3d   particles3d   rgl.planes   shadow3d  
GramSchmidt   dot3d   pch3d   rgl.points   shapelist3d  
Sweave.snapshot   drape3d   persp3d   rgl.pop   shinyGetPar3d  
abclines3d   elementId2Prefix   pipe   rgl.postscript   shinyResetBrush  
addNormals   ellipse3d   planes3d   rgl.primitive   shinySetPar3d  
addToSubscene3d   expect_known_scene   play3d   rgl.projection   show2d  
ageControl   extrude3d   playwidget   rgl.quads   snapshot3d  
ageSetter   facing3d   playwidgetOutput   rgl.quit   spheres3d  
all.equal.mesh3d   figHeight   plot3d   rgl.select   spin3d  
arc3d   figWidth   plotmath3d   rgl.select3d   sprites3d  
arrow3d   filledContour3d   points3d   rgl.set   subdivision3d  
as.mesh3d   gc3d   polygon3d   rgl.setAxisCallback   subsceneInfo  
as.mesh3d.default   getBoundary3d   pop3d   rgl.setMouseCallbacks   subsceneList  
as.rglscene   getWidgetId   projectDown   rgl.setWheelCallback   subsetControl  
as.tmesh3d   getr3dDefaults   propertyControl   rgl.snapshot   subsetSetter  
as.triangles3d   grid3d   propertySetter   rgl.spheres   subsetSlider  
asEuclidean   highlevel   propertySlider   rgl.sprites   surface3d  
asEuclidean2   hook_rgl   qmesh3d   rgl.surface   tagged3d  
asHomogeneous   hook_webgl   quads3d   rgl.texts   terrain3d  
asHomogeneous2   icosahedron3d   r3dDefaults   rgl.triangles   tetrahedron3d  
asRow   identify3d   readOBJ   rgl.useNULL   text3d  
ashape3d   identityMatrix   readSTL   rgl.user2window   texts3d  
aspect3d   ids3d   registerSceneChange   rgl.viewpoint   thigmophobe3d  
axes3d   in_pkgdown_example   renderPlaywidget   rgl.window2user   title3d  
axis3d   layout3d   renderRglwidget   rglExtrafonts   tkpar3dsave  
bbox3d   legend3d   rgl.Sweave   rglFonts   tkspin3d  
bg3d   light3d   rgl.Sweave.off   rglId   tkspinControl  
bgplot3d   lines3d   rgl.abclines   rglMouse   tmesh3d  
box3d   lowlevel   rgl.attrib   rglShared   toggleButton  
checkDeldir   makeDependency   rgl.attrib.count   rglToBase   toggleWidget  
clear3d   material3d   rgl.attrib.info   rglToLattice   transform3d  
clearSubsceneList   matrixSetter   rgl.bbox   rglwidget   translate3d  
clipMesh3d   merge.mesh3d   rgl.bg   rglwidgetOutput   translationMatrix  
clipObj3d   mergeVertices   rgl.bringtotop   rotate3d   tri  
clipplaneControl   mesh3d   rgl.clear   rotationMatrix   triSht  
clipplaneSlider   mfrow3d   rgl.clipplanes   scale3d   triangles3d  
clipplanes3d   mouseMode   rgl.close   scaleMatrix   triangulate  
close3d   movie3d   rgl.cur   scene3d   turn3d  
compare_proxy.mesh3d   mtext3d   rgl.dev.list   sceneChange   useSubscene3d  
contourLines3d   newSubscene3d   rgl.getAxisCallback   segments3d   vertexControl  
cube3d   next3d   rgl.getMouseCallbacks   select3d   vertexSetter  
cuboctahedron3d   normalize.mesh3d   rgl.getWheelCallback   selectionFunction3d   view3d  
cur3d   observer3d   rgl.ids   selectpoints3d   wire3d  
currentSubscene3d   octahedron3d   rgl.init   set3d   writeASY  
cylinder3d   oh3d   rgl.light   setAxisCallbacks   writeOBJ  
decorate3d   open3d   rgl.lines   setGraphicsDelay   writePLY  
deform.mesh3d   par3d   rgl.linestrips   setUserCallbacks   writeSTL  
delFromSubscene3d   par3dinterp   rgl.material   setUserShaders   writeWebGL  
deldir   par3dinterpControl   rgl.open   setupKnitr  
rgl/inst/doc/transparency.R0000644000176200001440000000546514146473374015443 0ustar liggesusers## ----setup, include=FALSE----------------------------------------------------- if (!requireNamespace("rmarkdown", quietly = TRUE) || !rmarkdown::pandoc_available("1.14")) { warning(call. = FALSE, "These vignettes assume rmarkdown and pandoc version 1.14. These were not found. Older versions will not work.") knitr::knit_exit() } knitr::opts_chunk$set(echo = TRUE) library(rgl) options(rgl.useNULL = TRUE) setupKnitr(autoprint = TRUE) M <- structure(c(0.997410774230957, 0.0707177817821503, -0.0130676832050085, 0, -0.0703366547822952, 0.99714070558548, 0.02762770652771, 0, 0.0149840852245688, -0.0266370177268982, 0.999532878398895, 0, 0, 0, 0, 1), .Dim = c(4L, 4L)) ## ----------------------------------------------------------------------------- theta <- 2*pi*c(0:2, 4:6, 8:10)/12 x <- cos(theta) y <- sin(theta) z <- rep(c(0,0,1), 3) xyz <- cbind(x, y, z) xyz <- xyz[c(1,2,6, 4,5,9, 7,8,3),] open3d() par3d(userMatrix = M) triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3)) ## ----fig.width=8-------------------------------------------------------------- open3d() par3d(userMatrix = M) layout3d(matrix(1:9, ncol = 3, byrow=TRUE), widths = c(1,2,2), heights = c(1, 3,3), sharedMouse = TRUE) text3d(0,0,0, " ") next3d() text3d(0,0,0, "depth_mask = TRUE") next3d() text3d(0,0,0, "depth_mask = FALSE") next3d() text3d(0,0,0, "alpha = 0.7") next3d() triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3), alpha = 0.7, depth_mask = TRUE) next3d() triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3), alpha = 0.7, depth_mask = FALSE) next3d() text3d(0,0,0, "alpha = 0.3") next3d() triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3), alpha = 0.3, depth_mask = TRUE) next3d() triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3), alpha = 0.3, depth_mask = FALSE) ## ----------------------------------------------------------------------------- open3d() par3d(userMatrix = M) triangles3d(xyz[1:3,], col = "red", alpha = 0.3, depth_mask = FALSE) triangles3d(xyz[4:6,], col = "green", alpha = 0.7, depth_mask = TRUE) triangles3d(xyz[7:9,], col = "blue", depth_mask = TRUE) ## ----fig.width=8-------------------------------------------------------------- open3d() par3d(userMatrix = M) layout3d(matrix(1:9, ncol = 3, byrow=TRUE), widths = c(1,2,2), heights = c(1, 3,3), sharedMouse = TRUE) text3d(0,0,0, " ") next3d() text3d(0,0,0, "depth_mask = TRUE") next3d() text3d(0,0,0, "depth_mask = FALSE") next3d() text3d(0,0,0, "alpha = 0.7") next3d() triangles3d(xyz, col = "red", alpha = 0.7, depth_mask = TRUE) next3d() triangles3d(xyz, col = "red", alpha = 0.7, depth_mask = FALSE) next3d() text3d(0,0,0, "alpha = 0.3") next3d() triangles3d(xyz, col = "red", alpha = 0.3, depth_mask = TRUE) next3d() triangles3d(xyz, col = "red", alpha = 0.3, depth_mask = FALSE) rgl/inst/doc/WebGL.html0000644000176200001440000236042614146473370014434 0ustar liggesusers User Interaction in WebGL (updated)

User Interaction in WebGL (updated)

Duncan Murdoch

November 21, 2021

Introduction

This document describes how to embed rgl scenes in HTML documents and use embedded Javascript to control a WebGL display in an HTML document. For more general information about rgl, see rgl Overview.

We assume that the HTML document is produced from R markdown source using knitr or rmarkdown. This format mixes text with Markdown markup with chunks of R code. There is a limited amount of discussion of other methods.

There are two ways to embed an rgl scene in the document. The newest one is recommended: call setupKnitr with argument autoprint = TRUE early in the document. This will set things up to be quite similar to the way standard 2D graphics are included by knitr, i.e. it will detect the fact that you’ve drawn something, and just include it automatically.

If autoprint = FALSE is used or no call is made to setupKnitr(), an explicit call to rglwidget will produce a “widget†which can be embedded into your document by printing it. This document uses that method.

Older methods (e.g. writeWebGL or various hooks) that were used before rgl version 0.102.0 are no longer supported.

Browser support

Most browsers now support WebGL, but in some browsers it may be disabled by default. See https://get.webgl.org for help on a number of different browsers.

Examples

We start with a simple plot of the iris data. We insert a code chunk and call the rglwidget function with optional argument elementId. This allows later Javascript code to refer to the image. We also save the object ids from the plot, so that they can be manipulated later. (The first example in Controls uses tags instead of saving the ids.)

library(rgl)
plotids <- with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length, 
                  type="s", col=as.numeric(Species)))
rglwidget(elementId = "plot3drgl")

Next we insert a button to toggle the display of the data.

toggleWidget(sceneId = "plot3drgl", ids = plotids["data"], label = "Data")

The sceneId is the same as the elementId we used in rglwidget(), the ids are the object ids of the objects that we’d like to toggle, and the label is the label shown on the button. To find the names in the plotids variable, apply names() or unclass():

names(plotids)
## [1] "data" "axes" "xlab" "ylab" "zlab"
unclass(plotids)
## data axes xlab ylab zlab 
##   13   14   15   16   17

Using magrittr or base pipes

It can be error-prone to set the elementId in the rglwidget() to match the sceneId in the toggleWidget() (or playwidget(), described below). In the usual case where both are intended to appear together, magrittr-style pipes can be used quite flexibly: the first argument of the control widget accepts the result of rglwidget() (or other control widgets), and the controllers argument of rglwidget() accepts control widgets. In R 4.1.0, the new base pipe operator |> should be usable in the same way.

For example,

rglwidget() %>%
toggleWidget(ids = plotids["data"], label = "Data")

If you have R 4.1.0 or greater, this should do the same:

rglwidget() |>
toggleWidget(ids = plotids["data"], label = "Data")

You can swap the order of button and scene; use the magrittr dot (or the => syntax in base pipes) to pass the toggleWidget to rglwidget in the controllers argument:

toggleWidget(NA, ids = plotids["data"], label = "Data") %>%
rglwidget(controllers = .) 

or using R 4.1.0 or later,

toggleWidget(NA, ids = plotids["data"], label = "Data") |> 
  w => rglwidget(controllers = w) 

Controls

We have seen how to change the contents of the plot using toggleWidget. We can do more elaborate displays. For example, we can redo the previous plot, but with the three species as separate “spheres†objects and buttons to toggle them:

clear3d() # Remove the earlier display

with(subset(iris, Species == "setosa"), 
     spheres3d(Sepal.Length, Sepal.Width, Petal.Length, 
                  col=as.numeric(Species),
                  radius = 0.211,
                  tag = "setosa"))
with(subset(iris, Species == "versicolor"), 
     spheres3d(Sepal.Length, Sepal.Width, Petal.Length, 
               col=as.numeric(Species),
               radius = 0.211, 
               tag = "versicolor"))
with(subset(iris, Species == "virginica"), 
     spheres3d(Sepal.Length, Sepal.Width, Petal.Length, 
               col=as.numeric(Species),
               radius = 0.211,
               tag = "virginica"))
aspect3d(1,1,1)
decorate3d(tag = "axes")
rglwidget() %>%
toggleWidget(tags = "setosa") %>%
toggleWidget(tags = "versicolor") %>%
toggleWidget(tags = "virginica") %>%
toggleWidget(tags = "axes") %>% 
asRow(last = 4)

Since we skipped the label argument, the buttons are labelled with the values of the tags. The asRow function is discussed below.

toggleWidget() is actually a convenient wrapper for two functions: playwidget and subsetControl. playwidget() adds the button to the web page (and can also add sliders, do animations, etc.), while subsetControl() chooses a subset of objects to display.

subsetControl

For a more general example, we could use a slider to select several subsets of the data in the iris display. For example,

rglwidget() %>%
playwidget(start = 0, stop = 3, interval = 1,
       subsetControl(1, subsets = list(
                 Setosa = tagged3d("setosa"),
                 Versicolor = tagged3d("versicolor"),
                 Virginica = tagged3d("virginica"),
                 All = tagged3d(c("setosa", "versicolor", "virginica"))
                 )))

There are several other “control†functions.

par3dinterpControl

par3dinterpControl approximates the result of par3dinterp.

For example, the following code (similar to the play3d example) rotates the scene in a complex way.

M <- r3dDefaults$userMatrix
fn <- par3dinterp(time = (0:2)*0.75, userMatrix = list(M,
                                      rotate3d(M, pi/2, 1, 0, 0),
                                      rotate3d(M, pi/2, 0, 1, 0)) )
rglwidget() %>%
playwidget(par3dinterpControl(fn, 0, 3, steps=15),
       step = 0.01, loop = TRUE, rate = 0.5)

Some things to note: The generated Javascript slider has 300 increments, so that motion appears smooth. However, storing 300 userMatrix values would take up a lot of space, so we use interpolation in the Javascript code. However, the Javascript code can only do linear interpolation, not the more complex spline-based SO(3) interpolation done by par3dinterp. Because of this, we need to output 15 steps from par3dinterpControl so that the distortions of linear interpolation are not visible.

propertyControl

propertyControl is a more general function to set the value of properties of the scene. Currently most properties are supported, but use does require knowledge of the internal implementation.

clipplaneControl

clipplaneControl allows the user to control the location of a clipping plane by moving a slider.

vertexControl

Less general than propertyControl is vertexControl. This function sets attributes of individual vertices in a scene. For example, to set the x-coordinate of the closest point in the setosa group, and modify its colour from black to white,

setosavals <- subset(iris, Species == "setosa")
which <- which.min(setosavals$Sepal.Width)
init <- setosavals$Sepal.Length[which]
rglwidget() %>%
playwidget(
  vertexControl(values = matrix(c(init,   0,   0,   0, 
                                     8,   1,   1,   1), 
                                nrow = 2, byrow = TRUE),
                attributes = c("x", "red", "green", "blue"),
                vertices = which, tag = "setosa"),
    step = 0.01)

ageControl

A related function is ageControl, though it uses a very different specification of the attributes. It is used when the slider controls the “age†of the scene, and attributes of vertices change with their age.

To illustrate we will show a point moving along a curve. We give two ageControl calls in a list; the first one controls the colour of the trail, the second controls the position of the point:

time <- 0:500
xyz <- cbind(cos(time/20), sin(time/10), time)
lineid <- plot3d(xyz, type="l", col = "black")["data"]
sphereid <- spheres3d(xyz[1, , drop=FALSE], radius = 8, col = "red")
rglwidget() %>%
playwidget(list(
  ageControl(births = time, ages = c(0, 0, 50),
        colors = c("gray", "red", "gray"), objids = lineid),
  ageControl(births = 0, ages = time,
        vertices = xyz, objids = sphereid)),
  start = 0, stop = max(time) + 20, rate = 50,
  components = c("Reverse", "Play", "Slower", "Faster",
                 "Reset", "Slider", "Label"),
  loop = TRUE)

rglMouse

While not exactly a control in the sense of the other functions in this section, the rglMouse function is used to add an HTML control to a display to allow the user to select the mouse mode.

For example, the display below initially allows selection of particular points, but the mouse mode may be changed to let the user rotate the display for a another view of the scene.

# This example requires the crosstalk package
# We skip it if crosstalk is not available. 

ids <- with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length, 
                  type="s", col=as.numeric(Species)))
par3d(mouseMode = "selecting")
rglwidget(shared = rglShared(ids["data"])) %>% 
rglMouse()

The rglShared() call used here is described below.

Layout of the display

Many rgl displays will contain several elements: one or more rgl scenes and controls. Internally rgl uses the combineWidgets function from the manipulateWidget package.

The rgl package provides 3 convenience functions for arranging displays. We have already met the first: the magrittr pipe, %>%. When the display is constructed as a single object using pipes, the objects in the pipeline will be arranged in a single column.

The second convenience function is asRow. This takes as input a list of objects or a combineWidgets object (perhaps the result of a pipe), and rearranges (some of) them into a horizontal row. As in the toggleWidget example, the last argument can be used to limit the actions of asRow to the specified number of components. (If last = 0, all objects are stacked: this can be useful if some of them are not from the rgl package, so piping doesn’t work for them.)

Finally, getWidgetId can be used to extract the HTML element ID from an HTML widget. This is useful when combining widgets that are not all elements of the same pipe, as in the crosstalk example below.

If these convenience functions are not sufficient, you can call manipulateWidget::combineWidgets or other functions from manipulateWidget for more flexibility in the display arrangements.

Integration with crosstalk

The crosstalk package allows widgets to communicate with each other. Currently it supports selection and filtering of observations.

rgl can send, receive and display these messages. An rgl display may have several subscenes, each displaying different datasets. Each object in the scene is potentially a shared dataset in the crosstalk sense.

The linking depends on the rglShared function. Calling rglShared(id), where id is the rgl id value for an object in the current scene, creates a shared data object containing the coordinates of the vertices of the rgl object. This object is passed to rglwidget in the shared argument. It can also be passed to other widgets that accept shared data, linking the two displays.

If a shared data object has been created in some other way, it can be linked to a particular rgl id value by copying its key and group properties as shown in the example below.

# This example requires the crosstalk package.  
# We skip it if crosstalk is not available. 

library(crosstalk)
sd <- SharedData$new(mtcars)
ids <- plot3d(sd$origData(), col = mtcars$cyl, type = "s")
# Copy the key and group from existing shared data
rglsd <- rglShared(ids["data"], key = sd$key(), group = sd$groupName())
rglwidget(shared = rglsd) %>%
asRow("Mouse mode: ", rglMouse(getWidgetId(.)), 
      "Subset: ", filter_checkbox("cylinderselector", 
                        "Cylinders", sd, ~ cyl, inline = TRUE),
      last = 4, colsize = c(1,2,1,2), height = 60)

If multiple objects in the rgl scene need to be considered as shared data, you can pass the results of several rglShared() calls in a list, i.e. rglwidget(shared = <list>). The key values will be assumed to be shared across datasets; if this is not wanted, use a prefix or some other means to make sure they differ between objects.

If the same rgl id is used in more than one rglShared() object, it will respond to messages from all of them. This may lead to undesirable behaviour as one message cancels the previous one.

Low level controls

We repeat the initial plot from this document:

plotids <- with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length, 
                  type="s", col=as.numeric(Species)))
subid <- currentSubscene3d()
rglwidget(elementId="plot3drgl2")

We might like a button on the web page to cause a change to the display, e.g. a rotation of the plot. First we add buttons, with the “onclick†event set to a function described below:

<button type="button" onclick="rotate(10)">Forward</button>
<button type="button" onclick="rotate(-10)">Backward</button>

which produces these buttons:

We stored the subscene number that is currently active in subid in the code chunk above, and use it as `r subid` in the script below. knitr substitutes the value when it processes the document.

The rotate() function uses the Javascript function document.getElementById to retrieve the <div> component of the web page containing the scene. It will have a component named rglinstance which contains information about the scene that we can modify:

<script type="text/javascript">
var rotate = function(angle) {
  var rgl = document.getElementById("plot3drgl2").rglinstance;
  rgl.getObj(`r subid`).par3d.userMatrix.rotate(angle, 0,1,0);
  rgl.drawScene();
};
</script>

If we had used webGL=TRUE in the chunk header, the knitr WebGL support would create a global object with a name of the form <chunkname>rgl. For example, if the code chunk was named plot3d2, the object would be called plot3d2rgl, and this code would work:

<script type="text/javascript">
var rotate = function(angle) {
  plot3d2rgl.getObj(`r subid`).par3d.userMatrix.rotate(angle, 0,1,0);
  plot3d2rgl.drawScene();
};
</script>

Index

The following functions are described in this document:

ageControl   getWidgetId   propertyControl   subsetControl  
asRow   par3dinterpControl   rglMouse   toggleWidget  
clipplaneControl   playwidget   rglShared   vertexControl  
rgl/inst/doc/pkgdown.html0000644000176200001440000004523614146473370015142 0ustar liggesusers Using RGL in pkgdown web sites

Using RGL in pkgdown web sites

Duncan Murdoch

What is the problem?

pkgdown is an R package that makes it easy to build a web site for your package. However, the current version 1.6.1 on CRAN doesn’t work so well for packages whose examples use RGL or other packages like leaflet that use htmlwidgets. This document describes current progress in supporting both of these.

The main problem for pkgdown support is that RGL and other htmlwidgets users require multiple Javascript libraries to be linked to each web page. pkgdown 1.6.1 can’t do this, but the current development version on Github adds support for additional dependent libraries. This also require downlit version 0.4.0 or higher.

Installing the changes

Installing the changes is fairly easy. Make sure you have the remotes package installed, then run

remotes::install_github(c("rstudio/webshot2",
                          "rstudio/chromote",
                          "r-lib/pkgdown"))

With these development version packages installed, you should see RGL or leaflet output appear automatically in examples. The RGL output is set up to mimic what would happen in a knitr document that uses

setupKnitr(autoprint = TRUE)

i.e. the output RGL commands will automatically be included in the display. Low-level changes will be collected into a single display:

# Show regression plane with z as dependent variable
library(rgl)
open3d()
## null 
##   15
x <- rnorm(100)
y <- rnorm(100)
z <- 0.2*x - 0.3*y + rnorm(100, sd = 0.3)
fit <- lm(z ~ x + y)

plot3d(x, y, z, type = "s", col = "red", size = 1)

# No plot here, because of the planes3d() call below

coefs <- coef(fit)
a <- coefs["x"]
b <- coefs["y"]
c <- -1
d <- coefs["(Intercept)"]
planes3d(a, b, c, d, alpha = 0.5)

Specifying the size of figures

By default, pkgdown generates standard plots which are wider than they are high (according to the golden ratio). Often RGL plots look better with equal width and height, since the contents may be rotated by the user.

To specify the size of plots in pkgdown, you use the figures entry in _pkgdown.yml. The defaults are similar to

figures:
  dev: ragg::agg_png
  dpi: 96
  dev.args: []
  fig.ext: png
  fig.width: 7
  fig.height: ~
  fig.retina: 2
  fig.asp: 1.618
  bg: NA
  other.parameters: []

By default RGL uses these parameters as well, but allows you to override any of fig.width, fig.height and fig.asp by specifying an rgl entry in other.parameters. For example:

figures:
  fig.width: 5
  other.parameters:
    rgl:
      fig.asp: 1

This will make all plots have a width of 5 inches and will make RGL plots square.

Is this safe to use?

These are development versions of the packages, so they may contain bugs, either in my changes or in other unreleased changes. I don’t recommend you use them in regular production code. To re-install released versions of the packages, run

install.packages(c("pkgdown", "rgl"))

If you do use them and notice any bugs, please report them!

rgl/inst/doc/pkgdown.R0000644000176200001440000000255514146473370014374 0ustar liggesusers## ----setup, include=FALSE----------------------------------------------------- if (!requireNamespace("rmarkdown", quietly = TRUE) || !rmarkdown::pandoc_available("1.14")) { warning(call. = FALSE, "These vignettes assume rmarkdown and pandoc version 1.14. These were not found. Older versions will not work.") knitr::knit_exit() } knitr::opts_chunk$set(echo = TRUE) library(rgl) options(rgl.useNULL = TRUE) setupKnitr(autoprint = TRUE) ## ----eval=FALSE--------------------------------------------------------------- # remotes::install_github(c("rstudio/webshot2", # "rstudio/chromote", # "r-lib/pkgdown")) ## ----eval=FALSE--------------------------------------------------------------- # setupKnitr(autoprint = TRUE) ## ----------------------------------------------------------------------------- # Show regression plane with z as dependent variable library(rgl) open3d() x <- rnorm(100) y <- rnorm(100) z <- 0.2*x - 0.3*y + rnorm(100, sd = 0.3) fit <- lm(z ~ x + y) plot3d(x, y, z, type = "s", col = "red", size = 1) # No plot here, because of the planes3d() call below coefs <- coef(fit) a <- coefs["x"] b <- coefs["y"] c <- -1 d <- coefs["(Intercept)"] planes3d(a, b, c, d, alpha = 0.5) ## ----eval=FALSE--------------------------------------------------------------- # install.packages(c("pkgdown", "rgl")) rgl/inst/doc/transparency.html0000644000176200001440000007437214146473374016211 0ustar liggesusers A Note on Transparency

A Note on Transparency

Duncan Murdoch

24/10/2020

Introduction

When drawing transparent surfaces, rgl tries to sort objects from back to front to get better rendering of transparency. However, it doesn’t sort each pixel separately, so some pixels end up drawn in the incorrect order. This note describes the consequences of that error, and suggests remedies.

Correct Drawing

We’ll assume that the standard glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) blending is used. That is, when drawing with transparency \(\alpha\), the new colour is mixed at proportion \(\alpha\) with the colour previously drawn (which gets weight \(1-\alpha\).)

This note is concerned with what happens when two transparent objects are drawn at the same location. We suppose the further one has transparency \(\alpha_1\), and the closer one has transparency \(\alpha_2\). If they are drawn in the correct order (further first), the three colours (background, further object, closer object) should end up mixed in proportions \(C = [(1-\alpha_1)(1-\alpha_2), \alpha_1(1-\alpha_2), \alpha_2]\) respectively.

Incorrect sorting

If the objects are drawn in the wrong order, the actual proportions of each colour will be \(N = [(1-\alpha_1)(1-\alpha_2), \alpha_1, \alpha_2(1-\alpha_1)]\) if no masking occurs.

rgl currently defaults to depth masking using glDepthMask(GL_TRUE). This means that depths are saved when the objects are drawn, and if an attempt is made to draw the further object after the closer one (i.e. as here), the further object will be culled, and the proportions will be \(M = [(1-\alpha_2), 0, \alpha_2]\).

Mask or Not?

The question is: which is better, glDepthMask(GL_TRUE) or glDepthMask(GL_FALSE)? One way to measure this is to measure the distance between \(C\) and the incorrect proportions. (This is unlikely to match perceptual distance, which will depend on the colours as well, but we need something. Some qualitative comments below.)

So we have

\[|C-N|^2 = 2\alpha_1^2\alpha_2^2\],

and

\[|C-M|^2 = 2\alpha_1^2(1-\alpha_2)^2\].

Thus the error is larger with \(N\) when \(\alpha_2 > 1/2\), and larger with \(M\) when \(\alpha_2 < 1/2\). The value of \(\alpha_1\) doesn’t affect the preference, though small values of \(\alpha_1\) will be associated with smaller errors.

Depending on the colours of the background and the two objects, this recommendation could be modified. For example, if the two objects are the same colour (or very close), it doesn’t really matter how the 2nd and 3rd proportions are divided up, and \(N\) will be best because it gets the background proportion exactly right.

Recommendation

Typically in rgl we don’t know which object will be closer and which one will be further, so we can’t base our choice on a single \(\alpha_i\). The recommendation would be to use all small levels of alpha and disable masking, or use all large values of alpha and retain masking.

Example

The classic example of an impossible to sort scene involves three triangles arranged cyclicly so each one is behind one and in front of one of the others (based on https://paroj.github.io/gltut/Positioning/Tut05%20Overlap%20and%20Depth%20Buffering.html).

theta <- 2*pi*c(0:2, 4:6, 8:10)/12
x <- cos(theta)
y <- sin(theta)
z <- rep(c(0,0,1), 3)
xyz <- cbind(x, y, z)
xyz <- xyz[c(1,2,6, 4,5,9, 7,8,3),]
open3d()
## null 
##   17
par3d(userMatrix = M)
triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3))

To see the effect of the calculations above, consider the following four displays.

open3d()
## null 
##   18
par3d(userMatrix = M)
layout3d(matrix(1:9, ncol = 3, byrow=TRUE),
         widths = c(1,2,2), heights = c(1, 3,3), 
         sharedMouse = TRUE)
text3d(0,0,0, " ")
next3d()
text3d(0,0,0, "depth_mask = TRUE")
next3d()
text3d(0,0,0, "depth_mask = FALSE")
next3d()
text3d(0,0,0, "alpha = 0.7")
next3d()
triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3), alpha = 0.7, depth_mask = TRUE)
next3d()
triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3), alpha = 0.7, depth_mask = FALSE)
next3d()
text3d(0,0,0, "alpha = 0.3")
next3d()
triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3), alpha = 0.3, depth_mask = TRUE)
next3d()
triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3), alpha = 0.3, depth_mask = FALSE)

As you rotate the figures, you can see imperfections in rendering. On the right, the last drawn appears to be on top, while on the left, the first drawn appears more opaque than it should.

In the figure below, the three triangles each have different transparency, and each use the recommended setting:

open3d()
## null 
##   19
par3d(userMatrix = M)
triangles3d(xyz[1:3,], col = "red", alpha = 0.3, depth_mask = FALSE)
triangles3d(xyz[4:6,], col = "green", alpha = 0.7, depth_mask = TRUE)
triangles3d(xyz[7:9,], col = "blue", depth_mask = TRUE)

In this figure, all three triangles are the same colour, only lighting affects the display:

open3d()
## null 
##   20
par3d(userMatrix = M)
layout3d(matrix(1:9, ncol = 3, byrow=TRUE),
         widths = c(1,2,2), heights = c(1, 3,3), 
         sharedMouse = TRUE)
text3d(0,0,0, " ")
next3d()
text3d(0,0,0, "depth_mask = TRUE")
next3d()
text3d(0,0,0, "depth_mask = FALSE")
next3d()
text3d(0,0,0, "alpha = 0.7")
next3d()
triangles3d(xyz, col = "red", alpha = 0.7, depth_mask = TRUE)
next3d()
triangles3d(xyz, col = "red", alpha = 0.7, depth_mask = FALSE)
next3d()
text3d(0,0,0, "alpha = 0.3")
next3d()
triangles3d(xyz, col = "red", alpha = 0.3, depth_mask = TRUE)
next3d()
triangles3d(xyz, col = "red", alpha = 0.3, depth_mask = FALSE)

Here depth_mask = FALSE seems to be the right choice in both cases.

rgl/inst/doc/rgl.Rmd0000644000176200001440000013130314146471171014017 0ustar liggesusers--- title: "rgl Overview" author: "Duncan Murdoch" date: "`r format(Sys.time(), '%B %d, %Y')`" output: rmarkdown::html_vignette: fig_height: 5 fig_width: 5 toc: yes html_document: df_print: paged toc: yes pdf_document: fig_height: 5 fig_width: 5 toc: yes vignette: > %\VignetteIndexEntry{rgl Overview} %\VignetteEngine{knitr::rmarkdown} --- ```{r setup, echo=FALSE, results="asis"} source("setup.R") setupKnitr(autoprint = TRUE) set.seed(123) ``` ## Introduction The `rgl` package is used to produce interactive 3-D plots. It contains high-level graphics commands modelled loosely after classic R graphics, but working in three dimensions. It also contains low level structure inspired by (but incompatible with) the `grid` package. This document gives an overview. See the help pages for details. For installation instructions, see the `README` file in the top level directory of the source tarball `r paste0("rgl_", packageVersion("rgl"), ".tar.gz")` (or a later version). ### About this document This document was written in R Markdown, using the `knitr` package for production. It corresponds to `rgl` version `r packageVersion("rgl")`. Most of the highlighted function names are HTML links. The internal links should work in any browser; the links to help topics should work if you view the vignette from within the R help system. The document includes WebGL figures. To view these, you must have Javascript and WebGL enabled in your browser. Some older browsers may not support this -- see https://get.webgl.org for tests and links to a discussion. ## Basics and High Level Functions The `r indexfns("plot3d")` function plots points within an RGL window. It is similar to the classic `r linkfn("plot", pkg="graphics")` function, but works in 3 dimensions. For example ```{r} with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length, type="s", col=as.numeric(Species))) ``` \noindent can be used to plot three columns of the `iris` data. Allowed plot types include `"p", "l", "h", "s"`, meaning points, lines, segments from z=0, and spheres. There's a lot of flexibility in specifying the coordinates; the `r linkfn("xyz.coords", pkg = "grDevices")` function from the `grDevices` package is used for this. You can use your mouse to manipulate the plot. The default is that if you click and hold with the left mouse button, you can rotate the plot by dragging it. The right mouse button is used to resize it, and the middle button changes the perspective in the point of view. If you call `r linkfn("plot3d")` again, it will overwrite the current plot. To open a new graphics window, use `r linkfn("open3d")`. The other high level function is `r indexfns("persp3d")` to draw surfaces. It is similar to the classic `r linkfn("persp", pkg = "graphics")` function, but with greater flexibility. First, any of `x`, `y` or `z` can be specified using matrices, not just `z`. This allows parametric surfaces to be plotted. An even simpler specification is possible: `x` may be a function, in which case `persp3d` will work out the grid itself. See `r linkfn("persp3d.function", text="?persp3d.function", pkg="rgl")` for details. For example, the `MASS` package estimates Gamma parameters using maximum likelihood in a `r linkfn("fitdistr", text="?MASS::fitdistr", pkg="MASS")` example. Here we show the log likelihood surface. ```{r persp3d, fig.height=3, fig.width=6, fig.keep="last"} library(MASS) # from the fitdistr example set.seed(123) x <- rgamma(100, shape = 5, rate = 0.1) fit <- fitdistr(x, dgamma, list(shape = 1, rate = 0.1), lower = 0.001) loglik <- function(shape, rate) sum(dgamma(x, shape=shape, rate=rate, log=TRUE)) loglik <- Vectorize(loglik) xlim <- fit$estimate[1]+4*fit$sd[1]*c(-1,1) ylim <- fit$estimate[2]+4*fit$sd[2]*c(-1,1) mfrow3d(1, 2, sharedMouse = TRUE) persp3d(loglik, xlim = xlim, ylim = ylim, n = 30) zlim <- fit$loglik + c(-qchisq(0.99, 2)/2, 0) next3d() persp3d(loglik, xlim = xlim, ylim = ylim, zlim = zlim, n = 30) ``` On the left, the whole surface over a range of the parameters; on the right, only the parts of the surface with log likelihood values near the maximum. Note: this example used the `knitr` hook functions (see `r linkfn("setupKnitr")`) to insert the scene into this vignette; the previous example used the `rglwidget` function. We generally recommend the newer `r linkfn("rglwidget")` approach. Note that both `plot3d` and `persp3d` are generic functions, with the following methods defined: ```{r} methods(plot3d) methods(persp3d) ``` ## Adding Graphical Elements ### Primitive shapes Just as we have `r linkfn("points", pkg="graphics")` and `r linkfn("lines", pkg="graphics")` in classic graphics, there are a number of low level functions in `rgl` to add graphical elements to the currently active plot. The "primitive" shapes are those that are native to OpenGL: Function | Description ----------------------------- | ----------- `r indexfns("points3d")`: | adds points `r indexfns("lines3d")`: | adds lines `r indexfns("segments3d")`: | adds line segments `r indexfns("triangles3d")`: | adds triangles `r indexfns("quads3d")`: | adds quadrilaterals Each of the above functions takes arguments `x`, `y` and `z`, again using `r linkfn("xyz.coords", pkg="grDevices")` for flexibility. They group successive entries as necessary. For example, the `r linkfn("triangles3d")` function takes each successive triple of points as the vertices of a triangle. You can use these functions to annotate the current graph, or to construct a figure from scratch. ### Constructed shapes `rgl` also has a number of objects which it constructs from the primitives. Function | Description ----------------------------- | ----------- `r indexfns(c("text3d", "texts3d"))`: | adds text `r indexfns("abclines3d")`: | adds straight lines to plot (like `abline`) `r indexfns("arc3d")`: | adds spherical arcs or spirals to plot `r indexfns("planes3d")`: | adds planes to plot `r indexfns("clipplanes3d")`: | add clipping planes to plot `r indexfns(c("sprites3d", "particles3d"))`: | add sprites (fixed shapes or images) to plot `r indexfns("spheres3d")`: | adds spheres `r indexfns(c("surface3d", "terrain3d"))`: | a surface (as used in `r linkfn("persp3d")`) `r indexfns("drape3d")`: | drapes lines on a surface or object(s) `r indexfns("shadow3d")`: | projects mesh onto a surface `r indexfns("arrow3d")`: | add an arrow to a scene `r indexfns("pch3d")`: | draw base-style plotting symbols `r indexfns("plotmath3d")`: | used by `r linkfn("text3d")` for math text ### Axes and other "decorations" The following low-level functions control the look of the graph: Function | Description ------------------------------------ | ----------- `r indexfns(c("axes3d", "axis3d"))`: | add axes to plot `r indexfns(c("box3d", "bbox3d"))`: | add box around plot `r indexfns("title3d")`: | add title to plot `r indexfns("mtext3d")`: | add marginal text to plot `r indexfns("decorate3d")`: | add multiple "decorations" (scales, etc.) to plot `r indexfns("aspect3d")`: | set the aspect ratios for the plot `r indexfns(c("bg3d", "bgplot3d"))`: | set the background of the scene `r indexfns("show2d")`: | show a 2D plot or image in a 3D scene `r indexfns("legend3d")`: | set a legend for the scene `r indexfns("grid3d")`: | add a reference grid to a graph `r indexfns("thigmophobe3d")`: | choose label positions to avoid overlap `r indexfns("setAxisCallbacks")`: | set user-defined axis annotations For example, to plot three random triangles, one could use ```{r fig.width=3, fig.height=3} triangles3d(cbind(x=rnorm(9), y=rnorm(9), z=rnorm(9)), col = "green") decorate3d() bg3d("lightgray") aspect3d(1,1,1) ``` Besides the `*3d` functions mentioned above, there are even lower-level functions `r indexfns(c("rgl.primitive", "rgl.points", "rgl.linestrips", "rgl.lines", "rgl.triangles", "rgl.quads", "rgl.texts", "rgl.abclines", "rgl.planes", "rgl.bg", "rgl.clipplanes", "rgl.bbox", "rgl.spheres", "rgl.sprites", "rgl.surface"))`. You should avoid using these functions, which do not work well with the higher level `*3d` functions. See the `r linkfn("r3d", text="?r3d", pkg="rgl")` help topic for details. The functions `r indexfns(c("rgl.setAxisCallback", "rgl.getAxisCallback"))` provide low-level support for `r linkfn("setAxisCallbacks")`. ## Controlling the Look of the Scene ### Lighting In most scenes, objects are "lit", meaning that their appearance depends on their position and orientation relative to lights in the scene. The lights themselves don't normally show up, but their effect on the objects does. Use the `r indexfns("light3d")` function to specify the position and characteristics of a light. Lights may be infinitely distant, or may be embedded within the scene. Their characteristics include `ambient`, `diffuse`, and `specular` components, all defaulting to white. The `ambient` component appears the same from any direction. The `diffuse` component depends on the angle between the surface and the light, while the `specular` component also takes the viewer's position into account. The `r indexfns("rgl.light")` function is a lower-level function with different defaults; users should normally use `r linkfn("light3d")`. ### Materials The mental model used in `rgl` is that the objects being shown in scenes are physical objects in space, with material properties that affect how light reflects from them (or is emitted by them). These are mainly controlled by the `r indexfns("material3d")` function, or by arguments to other functions that are passed to it. The material properties that can be set by calls to `material3d` are described in detail in the `r linkfn("material3d", text="?material3d", pkg="rgl")` help page. Here we give an overview. Property | Default | Meaning --------- | ------- | ------------------ color | white | vector of surface colors to apply to successive vertices for diffuse light alpha | 1 | transparency: 0 is invisible, 1 is opaque lit | TRUE | whether lighting calculations should be done ambient | black | color in ambient light specular | white | color in specular light emission | black | color emitted by the surface shininess | 50 | controls the specular lighting: high values look shiny smooth | TRUE | whether shading should be interpolated between vertices texture | NULL | optional path to a "texture" bitmap to be displayed on the surface front, back | fill | should polygons be filled, or outlined? size | 3 | size of points in pixels lwd | 1 | width of lines in pixels Other properties include "texmipmap", "texmagfilter", "texminfilter", "texenvmap", "fog", "point\_antialias", "line\_antialias", "depth\_mask", "depth\_test", "polygon_offset", "margin", "floating" and "tag"; see `r linkfn("material3d", "the help page", pkg = "rgl")` for details. There is also an `r indexfns("rgl.material")` function that works at a lower level; users should normally avoid it. ### Textures As described in the previous section, one of the material properties is `texture`, the name of a bitmap file (in `.png` format) containing an image to be displayed on the surface. This section gives more details about textures. In `OpenGL`, each vertex in a polygon may be associated with a particular location in the bitmap. The interior of the polygon interpolates within the bitmap. There are two conventions in `rgl` functions for specifying these coordinates. Functions which specify primitives (`r linkfn("triangles3d")`, etc.) accept an optional matrix argument `texcoords` which gives `s` (horizontal) and `t` (vertical) locations within the bitmap in columns with one row per vertex. The coordinates are `(0,0)` for the lower left, and `(1,1)` for the upper right. If values outside this range are given, the image repeats, i.e. `(1.1, 1.1)` would specify the same point in the image as `(0.1, 0.1)`. Other functions such as `r linkfn("surface3d")` that take matrices for each vertex coordinate accept texture coordinates as matrices as well, in arguments `texture_s` and `texture_t`. For example, the following code displays four copies of a 2D plot on a quad, because the texture coordinates run from 0 to 2 in both `s` and `t`: ```{r} filename <- tempfile(fileext = ".png") png(filename = filename) plot(rnorm(1000), rnorm(1000)) dev.off() open3d() xyz <- cbind(c(0,1,1,0), 0, c(0,0,1,1)) quads3d(xyz, texture = filename, texcoords = xyz[,c(1, 3)]*2, col = "white", specular = "black") ``` Some other notes: - The color in the figure above was specified to be white. By default, the colors in the bitmap will modify the colour of the quad. If `col` is black (a common default), you won't see anything. - On the other hand, you usually don't want specular reflections (which show up as glare). Setting `specular` to black prevents those. - How the bitmap is handled is controlled by the material property `"textype"`. The default is `"rgb"`, which takes the red-green-blue colours from the bitmap and uses them to modify the corresponding colours in the polygon. Other possibilities for `"textype"` are described in `r linkfn("material3d", "the material3d help page", pkg = "rgl")`. - The other `"tex*"` material properties control how the interpolation within the image is done. - Modern `OpenGL` supports 1- and 3-dimensional textures; these are not supported in `rgl`. ### Fonts `rgl` uses the same ideas as base graphics for drawing text: there are font families named `"sans"`, `"serif"`, and `"mono"` for drawing text of those types. In `rgl`, the `"symbol"` family is not supported. New font families can be defined using the low-level function `r indexfns("rglFonts")`, or more simply using the higher level function `r indexfns("rglExtrafonts")`. The latter function requires the `extrafont` package to be installed. ### par3d: Miscellaneous graphical parameters The `r indexfns("par3d")` function, modelled after the classic graphics `r linkfn("par", pkg="graphics")` function, sets or reads a variety of different `rgl` internal parameters. Some parameters are completely read-only; others are fixed at the time the window is opened, and others may be changed at any time. Name | Changeable? | Description ----------- | ----- | ----------- antialias | fixed | Amount of hardware antialiasing cex | | Default size for text family | | Device-independent font family name; see `r linkfn("text3d", text="?text3d", pkg="rgl")` font | | Integer font number useFreeType | | Should FreeType fonts be used if available? fontname | read-only | System-dependent font name set by `r linkfn("rglFonts")` FOV | | Field of view, in degrees. Zero means isometric perspective ignoreExtent | | Should `rgl` ignore the size of new objects when computing the bounding box? skipRedraw | | Should `rgl` suppress updates to the display? maxClipPlanes | read-only | How many clip planes can be defined? modelMatrix | read-only | The OpenGL ModelView matrix; partly set by `r indexfns("view3d")` or the obsolete `r indexfns("rgl.viewpoint")` projMatrix | read-only | The OpenGL Projection matrix bbox | read-only | Current bounding-box of the scene viewport | | Dimensions in pixels of the scene within the window windowRect | | Dimensions in pixels of the window on the whole screen listeners | | Which subscenes respond to mouse actions in the current one mouseMode | | What the mouse buttons do. See `r linkfn("mouseMode", '"mouseMode"')` observer | read-only | The position of the observer; set by `r indexfns("observer3d")` scale | | Rescaling for each coordinate; see `r linkfn("aspect3d")` zoom | | Magnification of the scene ### Default settings The `r indexfns("r3dDefaults")` list and the `r indexfns("getr3dDefaults")` function control defaults in new windows opened by `r linkfn("open3d")`. The function looks for the variable in the user's global environment, and if not found there, finds the one in the `rgl` namespace. This allows the user to override the default settings for new windows. Once found, the `r3dDefaults` list provides initial values for `r linkfn("par3d")` parameters, as well as defaults for `r linkfn("material3d")` and `r linkfn("bg3d")` in components `"material"` and `"bg"` respectively. ## Meshes: Constructing Shapes `rgl` includes a number of functions to construct and display various solid shapes. These generate objects of class `"shape3d"`, `"mesh3d"` or `"shapelist3d"`. The details of the classes are described below. We start with functions to generate them. ### Specific solids These functions generate specific shapes. Optional arguments allow attributes such as colour or transformations to be specified. Function | Description ------------------------------------ | ----------- `r indexfns(c("tetrahedron3d", "cube3d", "octahedron3d", "dodecahedron3d", "icosahedron3d"))`: | Platonic solids `r indexfns(c("cuboctahedron3d", "oh3d"))`: | other solids ```{r} cols <- rainbow(7) layout3d(matrix(1:16, 4,4), heights=c(1,3,1,3)) text3d(0,0,0,"tetrahedron3d"); next3d() shade3d(tetrahedron3d(col=cols[1])); next3d() text3d(0,0,0,"cube3d"); next3d() shade3d(cube3d(col=cols[2])); next3d() text3d(0,0,0,"octahedron3d"); next3d() shade3d(octahedron3d(col=cols[3])); next3d() text3d(0,0,0,"dodecahedron3d"); next3d() shade3d(dodecahedron3d(col=cols[4])); next3d() text3d(0,0,0,"icosahedron3d"); next3d() shade3d(icosahedron3d(col=cols[5])); next3d() text3d(0,0,0,"cuboctahedron3d"); next3d() shade3d(cuboctahedron3d(col=cols[6])); next3d() text3d(0,0,0,"oh3d"); next3d() shade3d(oh3d(col=cols[7])) ``` A very large collection of polyhedra is contained in the `r linkfn("Rpolyhedra-package", text = "Rpolyhedra", pkg = "Rpolyhedra")` package. ### Generating new shapes These functions generate new shapes: Function | Description ------------------------------------ | ----------- `r indexfns("cylinder3d")`: | generate a tube or cylinder `r indexfns("polygon3d")`: | generate a flat polygon by triangulation `r indexfns("extrude3d")`: | generate an "extrusion" of a polygon `r indexfns("turn3d")`: | generate a solid of rotation `r indexfns("ellipse3d")`: | generate an ellipsoid in various ways `r indexfns("mesh3d")`: | generate a shape from indexed vertices `r indexfns("shapelist3d")`: | generate a shape by combining other shapes `as.mesh3d`: | a generic function; see below A related function is `r indexfns("triangulate")`, which takes a two dimensional polygon and divides it up into triangles using the "ear-clipping" algorithm. The generic function `r indexfns("as.mesh3d")` is provided to allow data structures produced by other code to be converted to mesh structures. Currently the following classes are supported: Class | Package | Description ----- | ------- | ----------- `r indexfns("deldir", pkg = "deldir")` | `deldir` | Delaunay triangulations of irregular point clouds `r indexfns("triSht", pkg = "interp")` | `interp` | Also Delaunay triangulations `r indexfns("tri", pkg = "tripack")` | `tripack` | Generalized Delaunay triangulations `r indexfns("ashape3d", pkg = "alphashape3d")` | `alphashape3d` | Alpha-shapes `r linkfn("rglId")` | `rgl` | `rgl` object identifiers The `r indexfns("checkDeldir")` function checks that a compatible version of the `deldir` package is installed. The default `r indexfns("as.mesh3d.default")` method is a simple way to construct a mesh from a matrix of vertices; it can use `r indexfns("mergeVertices")` (which can also be used on its own) to merge repeated vertices within the matrix, allowing `r linkfn("addNormals")` to be used to give a smooth appearance. The `r indexfns("as.tmesh3d")` generic is a variation that guarantees the resulting object will have no quad entries. Functions `r indexfns(c("tmesh3d","qmesh3d"))` are now obsolete; use `r linkfn("mesh3d")` instead. ### The underlying class structure for shapes `"shape3d"` is the basic abstract type. Objects of this class can be displayed by `r indexfns("shade3d")` (which shades faces), `r indexfns("wire3d")` (which draws edges), or `r indexfns("dot3d")` (which draws points at each vertex.) `"mesh3d"` is a descendant type. Objects of this type contain the following fields: Field | Meaning ------------ | --------------- vb | A 4 by n matrix of vertices in homogeneous coordinates. Each column is a point. ip | (optional) A vector of vertex indices for points. is | (optional) A 2 by s matrix of vertex indices. Each column is a line segment. it | (optional) A 3 by t matrix of vertex indices. Each column is a triangle. ib | (optional) A 4 by q matrix of vertex indices. Each column is a quadrilateral. material | (optional) A list of material properties. normals | (optional) A matrix of the same shape as vb, containing normal vectors at each vertex. texcoords | (optional) A 2 by n matrix of texture coordinates corresponding to each vertex. values | (optional) A vector of length n holding values at each vertex meshColor | (optional) A text value indicating how colors and texture coordinates should be interpreted. ### Contouring shapes These functions compute and plot contours of functions on surfaces, or clip objects along a contour of a function. Function | Description -------------------------------- | ----------- `r indexfns("contourLines3d")`: | draw contour lines on surface `r indexfns("filledContour3d")`: | fill between contours on surface `r indexfns("clipMesh3d")`: | clip mesh object using curved boundary `r indexfns("clipObj3d")`: | clip general object using curved boundary ### Manipulating shapes These functions manipulate and modify mesh objects: Function | Description ------------------------------------ | ----------- `r indexfns("addNormals")`: | add normal vectors to make a shape look smooth `r indexfns("subdivision3d")`: | add extra vertices to make it look even smoother `r indexfns("merge.mesh3d", backticked("merge"))`: | merge mesh objects `r indexfns("facing3d")`: | subset of mesh facing "up" `r indexfns("getBoundary3d")`: | get the boundary of a mesh object The individual steps in `r linkfn("subdivision3d")` are also available: `r indexfns(c("deform.mesh3d", "divide.mesh3d", "normalize.mesh3d"))`. These are mainly intended for internal use. ## Multi-figure Layouts `rgl` has several functions to support displaying multiple different "subscenes" in the same window. The high level functions are Function | Description ------------------------- | ----------- `r indexfns("mfrow3d")`: | Multiple figures (like `r linkfn("par", text = 'par("mfrow")', pkg="graphics")` `r indexfns("layout3d")`: | Multiple figures (like `r linkfn("layout", pkg="graphics")`) `r indexfns("next3d")`: | Move to the next figure (like `r linkfn("plot.new", pkg="graphics")` or `r linkfn("frame", pkg="graphics")`) `r indexfns("subsceneList")`: | List all the subscenes in the current layout `r indexfns("clearSubsceneList")`: | Clear the current list and revert to the previous one There are also lower level functions. Function | Description ---------------------------------- | ----------- `r indexfns("newSubscene3d")`: | Create a new subscene, with fine control over what is inherited from the parent `r indexfns("currentSubscene3d")`: | Report on the active subscene `r indexfns("subsceneInfo")`: | Get information on current subscene `r indexfns("useSubscene3d")`: | Make a different subscene active `r indexfns(c("addToSubscene3d", "delFromSubscene3d"))`: | Add objects to a subscene, or delete them `r indexfns("gc3d")`: | Do "garbage collection": delete objects that are not displayed in any subscene ## Documents with `rgl` Scenes The `rgl` package can produce output that can be embedded in other documents. The recommended way to do this has changed several times over the years. We will start with the current recommendation, then list older methods. ### The recommended method Currently the best way to embed an `rgl` scene in a document is to produce the document in HTML using R Markdown. Early in the document, you should have code like this in one of the setup code chunks: ````markdown `r ''````{r echo=FALSE, include=FALSE} library(rgl) setupKnitr(autoprint = TRUE) ``` ```` The call to `setupKnitr()` will install a number of hooks and set options in `knitr` so that `rgl` code is handled properly. The `autoprint = TRUE` argument makes `rgl` act in the document almost the same way it would act in the console, or the way base graphics are handled by `knitr`: If you print the value of high level `rgl` functions, a plot will be inserted into the output, but maybe only after low level modifications to it are complete. For example, this code block prints both triangles and spheres in a single plot at the end: ```{r} xyz <- matrix(rnorm(27), ncol = 3) triangles3d(xyz, col = rainbow(9)) spheres3d(xyz, col = rainbow(9), radius = 0.1) ``` There are a few differences if you have a complicated situation: - The mechanism depends on the result of the `rgl` function calls being automatically printed. If the calls are in a loop or other code block where automatic printing doesn't happen, you'll need some trickery to get things to print. For example, this will print three plots: ```{r eval = FALSE} plots <- NULL for (i in 1:3) { plot3d(rnorm(10), rnorm(10), rnorm(10)) plots <- htmltools::tagList(plots, rglwidget()) close3d() } plots ``` - It also depends on the fact that `rgl` functions return results using `lowlevel()` or `highlevel()` to mark which kind of plot they are. If you are using a function from another package to produce the plot, you may need to insert an explicit call to one of those to get it to print. Use `lowlevel()` if the function just modifies an existing plot, `highlevel()` if it starts a new one. For example, ```{r eval = FALSE} foreignHigh() # Produces a high level plot, but doesn't return # an appropriate value highlevel() foreignLow() # Modifies the previous plot lowlevel() ``` This should display the output at the end of the code chunk, when modifications are assumed complete. ### Producing PDF output While some PDF previewers support interactive 3D graphics, most don't. To produce a screenshot of an `rgl` scene in an R Markdown document with PDF output, simply follow the directions given above. The auto-printing will detect PDF output and use `snapshot3d` to produce a PNG file to insert. (See below if you want to insert a different format of graphic.) If you really need interactive output, see the `r linkfn("writeASY")` function. ### Manual insertion of plots You may not want to use the `setupKnitr(autoprint = TRUE)` method described above. It is very new, and may still have bugs; you may have an older document and not want to edit it to work that way. In this case, you can insert plots manually. Use setup code ````markdown `r ''````{r echo=FALSE, include=FALSE} library(rgl) setupKnitr() ``` ```` and call `rglwidget()` at top level whenever you want to insert a plot. There are a couple of other differences in default behaviour if you are not using `autoprint`: - By default, each code chunk continues the `rgl` scene from earlier chunks. You'll need an explicit `r linkfn("open3d")` call to get a clean window. - Also by default, the `rgl` window is not closed at the end of the chunk. This probably doesn't matter, but you may find you run out of memory if your scenes are really big. ### Older methods The original way to insert an `rgl` scene in a document was to use the `r indexfns("writeWebGL")` function to write HTML code to insert in a document. Later, `Sweave` and `knitr` hooks were added. These are no longer maintained, and it is recommended that you update old documents to use the newer methods. See the `r linkfn("writeWebGL")`, `r linkfn("rgl.Sweave")` and `r linkfn("hook_rgl")` help topics for details on these if you must use them. If you are reading documents that suggest using those methods, let the author know they need updating! ## Utility Functions ### User interaction By default, `rgl` detects and handles mouse clicks within your scene, and uses these to control its appearance. You can find out the current handlers using the following code: ```{r} par3d("mouseMode") ``` The labels `c("left", "right", "middle")` refer to the buttons on a three button mouse, or simulations of them on other mice. `"wheel"` refers to the mouse wheel, and `"none"` refers to actions that take place when the mouse is moved without pressing any button. The button actions generally correspond to click and drag operations. Possible values for `r indexfns("mouseMode", '"mouseMode"')` for the mouse pointer or wheel are as follows: Mode | Description -------------- | --------- `"none"` | No action `"trackball"` | The mouse acts as a virtual trackball. Clicking and dragging rotates the scene `"xAxis"`, `"yAxis"`, `"zAxis"` | Like `"trackball"`, but restricted to rotation about one axis `"polar"` | The mouse affects rotations by controlling polar coordinates directly `"selecting"` | The mouse is being used by the `r linkfn("select3d")` function `"zoom"` | The mouse zooms the display `"fov"` | The mouse affects perspective by changing the field of view `"pull"` | Rotating the mouse wheel towards the user "pulls the scene closer" `"push"` | The same rotation "pushes the scene away" `"user"` | A user action set by `r indexfns(c("setUserCallbacks", "rgl.setMouseCallbacks", "rgl.setWheelCallback"))`. Use `r indexfns("rgl.getMouseCallbacks")` and `r indexfns("rgl.getWheelCallback")` to retrieve. The following functions make use of the mouse for selection within a scene. Function | Description ---------------------------- | ----------- `r indexfns("identify3d")`: | like the classic graphics `r linkfn("identify", pkg="graphics")` function `r indexfns("select3d")`: | returns a function that tests whether a coordinate was selected `r indexfns("selectpoints3d")`: | selects from specific objects `r indexfns("selectionFunction3d")` produces the selection function from information about the projection and mouse selection region; it is used internally in the functions above. The `r indexfns("rgl.select3d")` function is an obsolete version of `select3d`, and `r indexfns("rgl.select")` is a low-level support function. ### Animations `rgl` has several functions that can be used to construct animations. These are based on functions that update the scene according to the current real-world time, and repeated calls to those. The functions are: Function | Description ---------------------- | ------------- `r indexfns("play3d")`: | Repeatedly call the update function `r indexfns("spin3d")`: | Update the display by rotating at a constant rate `r indexfns("par3dinterp")`: | Compute new values of some `r linkfn("par3d")` parameters by interpolation over time See the `r linkfn("movie3d")` function for a way to output an animation to a file on disk. Animations are not currently supported in the HTML written by `r linkfn("rglwidget")`, though the `playwidget` function provides equivalent functionality. ### Integration with TCL/TK There are three functions in `rgl` that support control of an `rgl` scene using the TCL/TK framework. Function | Description ---------------------- | ------------- `r indexfns("tkspin3d")`: | Set up buttons in a window to control a scene `r indexfns("tkspinControl")`: | Embed the control buttons in a separate TCL/TK frame `r indexfns("tkpar3dsave")`: | Create a dialog to interactively save mouse actions These functions were formerly contained (without the `tk` prefixes on their names) in the `tkrgl` package. That package is now deprecated. ### Exporting and importing scenes `rgl` contains several functions to write scenes to disk for use by other software, or to read them in. In order from highest fidelity to lowest, the functions are: Function | Description ----------- | ------------- `r indexfns("scene3d")`: | Save a scene to an R variable, which can be saved and reloaded `r indexfns("rglwidget")`: | Prints as HTML and Javascript to display a scene in a web browser. (See also [User Interaction in WebGL](WebGL.html).) `r linkfn("writeWebGL")`: | Deprecated. `r indexfns("writeASY")`: | Write files for Asymptote `r indexfns("writePLY")`: | Write PLY files (commonly used in 3D printing) `r indexfns(c("readOBJ", "writeOBJ"))`: | Read or write OBJ files (commonly used in 3D graphics) `r indexfns(c("readSTL", "writeSTL"))`: | Read or write STL files (also common in 3D printing) `r indexfns("as.rglscene")`: | Generic function, no methods in `rgl` The [`rgl2gltf`](https://dmurdoch.github.io/rgl2gltf/dev/) package can read or write GLTF and GLB files. It includes an `as.rglscene` method to convert GLTF objects to `rgl` scenes. The code in `rgl`'s `r indexfns("Buffer")` R6 class is based on the GLTF format. It is used by `r linkfn("rglwidget")` to make output webpages somewhat smaller than they were previously. There are also functions to save snapshots or other recordings of a scene, without any 3D information being saved: Function | Description ------------ | ------------- `r indexfns("snapshot3d")`: | Save a PNG file bitmap of the scene `r indexfns("rgl.postscript")`: | Save a Postscript, LaTeX, PDF, SVG or PGF vector rendering of the scene `r indexfns("movie3d")`: | Save a series of bitmaps to be assembled into a movie `r indexfns("rgl.pixels")`: | Obtain pixel-level information about the scene in an R variable `r indexfns("rgl.Sweave")`: | Driver function for inserting a snapshot into a Sweave document. `r indexfns(c("hook_rgl", "hook_webgl"))`: | `knitr` hook functions for inserting images into a document. `r indexfns("setupKnitr")`: | Function to set up `knitr` hooks The `r indexfns("rgl.snapshot")` function is a low level version of `snapshot3d()`; it requires that the `rgl` display be onscreen and copies from there. `snapshot3d()` tries to use the `webshot2` package so it will work even with no display. The functions `r indexfns(c("rgl.Sweave.off", "Sweave.snapshot"))` are involved in Sweave processing and not normally called by users. ### Default display There are two ways in which `rgl` scenes are normally displayed within R. The older one is in a dedicated window. In Unix-alikes this is an X11 window; it is a native window in Microsoft Windows. On macOS, the XQuartz system (see https://www.xquartz.org) needs to be installed to support this. To suppress this display, set `options(rgl.useNULL = TRUE)` before opening a new `rgl` window. See the help page for the `r indexfns("rgl.useNULL")` function for how to set this before starting R. The newer way to display a scene is by using WebGL in a browser window or in the Viewer pane in RStudio. To select this, set `options(rgl.printRglwidget = TRUE)`. Each operation that would change the scene will return a value which triggers a new WebGL display when printed. ### Working with WebGL scenes You should use the following scheme for exporting a scene to a web page. There's also an older scheme, which is no longer supported. The recommended approach works with the `htmlwidgets` framework (see http://www.htmlwidgets.org/). In an R Markdown document in `knitr`, use the `r linkfn("rglwidget")` function. (You can also use chunk option `webgl=TRUE`; we recommend the explicit use of `rglwidget`.) This approach also allows display of `rgl` scenes in [RStudio](https://www.rstudio.com/). Besides `rgl` scenes, various controls for them can be displayed, and there are a few utility functions that can be useful: Function | Description ------------------------------------ | ------------- `r indexfns("propertyControl")`: | set individual properties `r indexfns("clipplaneControl")`: | control a clipping plane `r indexfns("subsetControl")`: | control which objects are displayed `r indexfns("ageControl")`: | "age" vertices of an object `r indexfns("vertexControl")`: | control properties of vertices `r indexfns("par3dinterpControl")`: | WebGL control like `r linkfn("par3dinterp")` `r indexfns("playwidget")`: | display and automate controls `r indexfns("toggleWidget")`: | display a button to toggle some items `r documentedfns <- c(documentedfns, "%>%");indexfns("pipe", text="%>%")`: | `magrittr` pipe `r indexfns(c("figHeight", "figWidth"))`: | Dimensions of figures in R Markdown document `r indexfns("rglShared")`: | share data using `crosstalk` package `r indexfns("rglMouse")`: | change mouse mode in RGL scene `r indexfns("asRow")`: | arrange multiple objects in an HTML display `r indexfns("getWidgetId")`: | get the `elementId` from a widget These functions work with the above scheme in Shiny apps: Function | Description ------------------------------------ | ------------- `r indexfns("sceneChange")`: | used in `Shiny` for large scene changes `r indexfns(c("shinyGetPar3d", "shinySetPar3d"))`: | get or set `r linkfn("par3d")` values from Shiny `r indexfns("shinyResetBrush")`: | reset the mouse brush in Shiny The `r linkfn("selectionFunction3d")` function is also likely to be involved in mouse interactions when using Shiny. Some functions are mainly for internal use: `r indexfns(c("elementId2Prefix", "playwidgetOutput", "renderPlaywidget", "rglwidgetOutput", "renderRglwidget", "registerSceneChange"))`. More details are given in the vignette [User Interaction in WebGL](WebGL.html). The functions `r indexfns(c("lowlevel", "highlevel", "rglId"))` are also for internal use, marking function results for automatic printing. Finally, the experimental function `r indexfns("setUserShaders")` allows you to use hand-written shaders in WebGL. The older approach uses the `r linkfn("writeWebGL")` function to export a scene to HTML and Javascript code. These functions write HTML and Javascript for working with the exported scene: `r indexfns("propertySlider")`, `r indexfns("clipplaneSlider")`, `r indexfns("subsetSlider")`, `r indexfns("toggleButton")`, `r indexfns("propertySetter")`, `r indexfns("subsetSetter")`, `r indexfns("ageSetter")`, `r indexfns("par3dinterpSetter")`, `r indexfns("vertexSetter")`, `r indexfns("matrixSetter")`. Use the newer functions instead. ### Working with the scene `rgl` maintains internal structures for all the scenes it displays. The following functions allow users to find information about them and manipulate them. In cases where there are both `*3d` and `rgl.*` versions of functions, most users should use the `*3d` version: the `rgl.*` functions are more primitive and are mainly intended for internal use. Function | Description ------------------------------------ | ----------- `r indexfns("open3d")`: | open a new window `r indexfns(c("close3d", "rgl.close"))`: | close the current window `r indexfns(c("cur3d", "rgl.cur"))`: | id of the active device `r indexfns(c("set3d", "rgl.set"))`: | set a particular device to be active `r indexfns(c("pop3d", "rgl.pop"))`: | delete objects from the scene `r indexfns(c("clear3d", "rgl.clear"))`: | delete all objects of certain classes `r indexfns(c("ids3d", "rgl.ids"))`: | ids, types and tags of current objects `r indexfns("tagged3d")`: | find tags or objects with tags These functions are mainly intended for programming, and have no corresponding `*3d` counterparts: Function | Description ------------- | ----------- `r indexfns("rgl.bringtotop")`: | bring the current window to the top `r indexfns("rgl.dev.list")`: | ids of all active devices `r indexfns(c("rgl.attrib", "rgl.attrib.info", "rgl.attrib.count"))`: | attributes of objects in the scene `r indexfns("rgl.projection")`: | return information about the current projection `r indexfns(c("rgl.user2window", "rgl.window2user"))`: | convert between coordinates in the current projection The `r indexfns("as.triangles3d")` generic function is intended to extract coordinates in a form suitable for passing to `r linkfn("triangles3d")`. Currently a method is provided for `r linkfn("rglId")` objects. In addition to these, there are some other related functions which should rarely be called by users: `r indexfns(c("rgl.init", "rgl.open", "rgl.quit"))`. ### Working with 3-D vectors Most `rgl` functions work internally with "homogeneous" coordinates. In this system, 3-D points are represented with 4 coordinates, generally called (x, y, z, w). The corresponding Euclidean point is (x/w, y/w, z/w), if w is nonzero; zero values of w correspond to "points at infinity". The advantage of this system is that affine transformations including translations and perspective shifts become linear transformations, with multiplication by a 4 by 4 matrix. `rgl` has the following functions to work with homogeneous coordinates: Function | Description ------------------------------------ | ----------- `r indexfns(c("asEuclidean", "asHomogeneous"))`: | convert between homogeneous and Euclidean coordinates when x, y and z are columns `r indexfns(c("asEuclidean2", "asHomogeneous2"))`: | convert when x, y and z are rows `r indexfns(c("rotate3d", "scale3d", "translate3d"))`: | apply a transformation `r indexfns("transform3d")`: | apply a general transformation `r indexfns(c("rotationMatrix", "scaleMatrix", "translationMatrix"))`: | compute the transformation matrix `r indexfns("identityMatrix")`: | return a 4 x 4 identity matrix `r indexfns("projectDown")`: | a 3D to 2D projection down a vector There is also a function `r indexfns("GramSchmidt")`, mainly for internal use: it does a Gram-Schmidt orthogonalization of a 3x3 matrix, with some specializations for its use in `r linkfn("cylinder3d")`. ### Working with other packages Sometimes it may be convenient to interactively rotate a scene to a particular view, then display it in `lattice` or base graphics. The `r indexfns("rglToLattice")` and `r indexfns("rglToBase")` functions support this. For example, we first display the volcano data in `rgl`: ```{r echo = 2:3} close3d() persp3d(volcano, col = "green") ``` This display is interactive, but we can reproduce the initial view using the `lattice` `r linkfn("wireframe", pkg = "lattice")` or base graphics `r linkfn("persp", pkg = "graphics")` functions: ```{r} lattice::wireframe(volcano, col = "green", screen = rglToLattice()) angles <- rglToBase() persp(volcano, col = "green", shade = TRUE, theta = angles$theta, phi = angles$phi) ``` Note that the `orientlib` package must be available for these functions to work. ### Creating `pkgdown` websites The ["Using RGL in pkgdown web sites"](pkgdown.html) vignette describes how to use `rgl` in a `pkgdown` web site. The utility function `r indexfns("in_pkgdown_example")` can be used to detect that `pkgdown` is being used. ### Working with `testthat` The `testthat` package is widely used for unit tests in packages. Such tests are hard to write with `rgl`, because the output is visual and interactive rather than a simple value. The `r indexfns("expect_known_scene")`, `r indexfns("compare_proxy.mesh3d")` and `r indexfns("all.equal.mesh3d")` functions help with this by removing system-dependent features of `rgl` output. ### Working with Javascript The WebGL displays created using `r linkfn("rglwidget")` rely on a large body of Javascript code included in this package. To help in development of this code, the `r indexfns("makeDependency")` function was written. It may be useful in other packages that include Javascript. ### Other functions This section is for miscellaneous functions that don't fall in any of the other categories in this document. The `r indexfns("setGraphicsDelay")` function is designed to work around what appears to be a bug on macOS: if a standard plot window is opened too quickly after an `rgl` window, R can crash. This function inserts a one second delay when it appears to be needed. ## Warning: Work in Progress! This vignette is always a work in progress. Some aspects of the `rgl` package are not described, or do not have examples. There may even be functions that are missed completely, if the following list is not empty: ```{r echo=FALSE} setdiff(ls("package:rgl"), documentedfns) ``` ## Index of Functions The following functions and constants are described in this document:
```{r echo=FALSE, results="asis"} writeIndex(cols = if (knitr::is_html_output()) 5 else 4) ``` rgl/inst/doc/pkgdown.Rmd0000644000176200001440000000772014145464133014710 0ustar liggesusers--- title: "Using RGL in pkgdown web sites" author: "Duncan Murdoch" output: rmarkdown::html_vignette: fig_height: 5 fig_width: 5 toc: yes pdf_document: fig_height: 5 fig_width: 5 toc: yes html_document: default vignette: > %\VignetteIndexEntry{Using RGL in pkgdown web sites} %\VignetteEngine{knitr::rmarkdown} --- ```{r setup, include=FALSE} if (!requireNamespace("rmarkdown", quietly = TRUE) || !rmarkdown::pandoc_available("1.14")) { warning(call. = FALSE, "These vignettes assume rmarkdown and pandoc version 1.14. These were not found. Older versions will not work.") knitr::knit_exit() } knitr::opts_chunk$set(echo = TRUE) library(rgl) options(rgl.useNULL = TRUE) setupKnitr(autoprint = TRUE) ``` ## What is the problem? [pkgdown](https://pkgdown.r-lib.org/) is an R package that makes it easy to build a web site for your package. However, the current version 1.6.1 on CRAN doesn't work so well for packages whose examples use RGL or other packages like [leaflet](http://rstudio.github.io/leaflet/) that use [htmlwidgets](http://www.htmlwidgets.org). This document describes current progress in supporting both of these. The main problem for [pkgdown](https://pkgdown.r-lib.org/) support is that RGL and other [htmlwidgets](http://www.htmlwidgets.org) users require multiple Javascript libraries to be linked to each web page. `pkgdown` 1.6.1 can't do this, but the current development version on Github adds support for additional dependent libraries. This also require [downlit](https://downlit.r-lib.org/) version 0.4.0 or higher. ## Installing the changes Installing the changes is fairly easy. Make sure you have the [remotes](https://remotes.r-lib.org/) package installed, then run ```{r eval=FALSE} remotes::install_github(c("rstudio/webshot2", "rstudio/chromote", "r-lib/pkgdown")) ``` With these development version packages installed, you should see RGL or `leaflet` output appear automatically in examples. The RGL output is set up to mimic what would happen in a `knitr` document that uses ```{r eval=FALSE} setupKnitr(autoprint = TRUE) ``` i.e. the output RGL commands will automatically be included in the display. Low-level changes will be collected into a single display: ```{r} # Show regression plane with z as dependent variable library(rgl) open3d() x <- rnorm(100) y <- rnorm(100) z <- 0.2*x - 0.3*y + rnorm(100, sd = 0.3) fit <- lm(z ~ x + y) plot3d(x, y, z, type = "s", col = "red", size = 1) # No plot here, because of the planes3d() call below coefs <- coef(fit) a <- coefs["x"] b <- coefs["y"] c <- -1 d <- coefs["(Intercept)"] planes3d(a, b, c, d, alpha = 0.5) ``` ## Specifying the size of figures By default, pkgdown generates standard plots which are wider than they are high (according to the golden ratio). Often RGL plots look better with equal width and height, since the contents may be rotated by the user. To specify the size of plots in pkgdown, you use the `figures` entry in `_pkgdown.yml`. The defaults are similar to ``` figures: dev: ragg::agg_png dpi: 96 dev.args: [] fig.ext: png fig.width: 7 fig.height: ~ fig.retina: 2 fig.asp: 1.618 bg: NA other.parameters: [] ``` By default RGL uses these parameters as well, but allows you to override any of `fig.width`, `fig.height` and `fig.asp` by specifying an `rgl` entry in `other.parameters`. For example: ``` figures: fig.width: 5 other.parameters: rgl: fig.asp: 1 ``` This will make all plots have a width of 5 inches and will make RGL plots square. ## Is this safe to use? These are development versions of the packages, so they may contain bugs, either in my changes or in other unreleased changes. I don't recommend you use them in regular production code. To re-install released versions of the packages, run ```{r eval=FALSE} install.packages(c("pkgdown", "rgl")) ``` If you do use them and notice any bugs, please [report them](https://github.com/dmurdoch/rgl/issues)! rgl/inst/doc/rgl.R0000644000176200001440000000747014146473373013513 0ustar liggesusers## ----setup, echo=FALSE, results="asis"---------------------------------------- source("setup.R") setupKnitr(autoprint = TRUE) set.seed(123) ## ----------------------------------------------------------------------------- with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length, type="s", col=as.numeric(Species))) ## ----persp3d, fig.height=3, fig.width=6, fig.keep="last"---------------------- library(MASS) # from the fitdistr example set.seed(123) x <- rgamma(100, shape = 5, rate = 0.1) fit <- fitdistr(x, dgamma, list(shape = 1, rate = 0.1), lower = 0.001) loglik <- function(shape, rate) sum(dgamma(x, shape=shape, rate=rate, log=TRUE)) loglik <- Vectorize(loglik) xlim <- fit$estimate[1]+4*fit$sd[1]*c(-1,1) ylim <- fit$estimate[2]+4*fit$sd[2]*c(-1,1) mfrow3d(1, 2, sharedMouse = TRUE) persp3d(loglik, xlim = xlim, ylim = ylim, n = 30) zlim <- fit$loglik + c(-qchisq(0.99, 2)/2, 0) next3d() persp3d(loglik, xlim = xlim, ylim = ylim, zlim = zlim, n = 30) ## ----------------------------------------------------------------------------- methods(plot3d) methods(persp3d) ## ----fig.width=3, fig.height=3------------------------------------------------ triangles3d(cbind(x=rnorm(9), y=rnorm(9), z=rnorm(9)), col = "green") decorate3d() bg3d("lightgray") aspect3d(1,1,1) ## ----------------------------------------------------------------------------- filename <- tempfile(fileext = ".png") png(filename = filename) plot(rnorm(1000), rnorm(1000)) dev.off() open3d() xyz <- cbind(c(0,1,1,0), 0, c(0,0,1,1)) quads3d(xyz, texture = filename, texcoords = xyz[,c(1, 3)]*2, col = "white", specular = "black") ## ----------------------------------------------------------------------------- cols <- rainbow(7) layout3d(matrix(1:16, 4,4), heights=c(1,3,1,3)) text3d(0,0,0,"tetrahedron3d"); next3d() shade3d(tetrahedron3d(col=cols[1])); next3d() text3d(0,0,0,"cube3d"); next3d() shade3d(cube3d(col=cols[2])); next3d() text3d(0,0,0,"octahedron3d"); next3d() shade3d(octahedron3d(col=cols[3])); next3d() text3d(0,0,0,"dodecahedron3d"); next3d() shade3d(dodecahedron3d(col=cols[4])); next3d() text3d(0,0,0,"icosahedron3d"); next3d() shade3d(icosahedron3d(col=cols[5])); next3d() text3d(0,0,0,"cuboctahedron3d"); next3d() shade3d(cuboctahedron3d(col=cols[6])); next3d() text3d(0,0,0,"oh3d"); next3d() shade3d(oh3d(col=cols[7])) ## ----------------------------------------------------------------------------- xyz <- matrix(rnorm(27), ncol = 3) triangles3d(xyz, col = rainbow(9)) spheres3d(xyz, col = rainbow(9), radius = 0.1) ## ----eval = FALSE------------------------------------------------------------- # plots <- NULL # for (i in 1:3) { # plot3d(rnorm(10), rnorm(10), rnorm(10)) # plots <- htmltools::tagList(plots, rglwidget()) # close3d() # } # plots ## ----eval = FALSE------------------------------------------------------------- # foreignHigh() # Produces a high level plot, but doesn't return # # an appropriate value # highlevel() # foreignLow() # Modifies the previous plot # lowlevel() ## ----------------------------------------------------------------------------- par3d("mouseMode") ## ----echo = 2:3--------------------------------------------------------------- close3d() persp3d(volcano, col = "green") ## ----------------------------------------------------------------------------- lattice::wireframe(volcano, col = "green", screen = rglToLattice()) angles <- rglToBase() persp(volcano, col = "green", shade = TRUE, theta = angles$theta, phi = angles$phi) ## ----echo=FALSE--------------------------------------------------------------- setdiff(ls("package:rgl"), documentedfns) ## ----echo=FALSE, results="asis"----------------------------------------------- writeIndex(cols = if (knitr::is_html_output()) 5 else 4) rgl/inst/doc/transparency.Rmd0000644000176200001440000001474314100762641015747 0ustar liggesusers--- title: "A Note on Transparency" author: "Duncan Murdoch" date: "24/10/2020" output: rmarkdown::html_vignette: fig_height: 5 fig_width: 5 toc: yes pdf_document: fig_height: 5 fig_width: 5 toc: yes html_document: default vignette: > %\VignetteIndexEntry{A Note on Transparency} %\VignetteEngine{knitr::rmarkdown} --- ```{r setup, include=FALSE} if (!requireNamespace("rmarkdown", quietly = TRUE) || !rmarkdown::pandoc_available("1.14")) { warning(call. = FALSE, "These vignettes assume rmarkdown and pandoc version 1.14. These were not found. Older versions will not work.") knitr::knit_exit() } knitr::opts_chunk$set(echo = TRUE) library(rgl) options(rgl.useNULL = TRUE) setupKnitr(autoprint = TRUE) M <- structure(c(0.997410774230957, 0.0707177817821503, -0.0130676832050085, 0, -0.0703366547822952, 0.99714070558548, 0.02762770652771, 0, 0.0149840852245688, -0.0266370177268982, 0.999532878398895, 0, 0, 0, 0, 1), .Dim = c(4L, 4L)) ``` ## Introduction When drawing transparent surfaces, `rgl` tries to sort objects from back to front to get better rendering of transparency. However, it doesn't sort each pixel separately, so some pixels end up drawn in the incorrect order. This note describes the consequences of that error, and suggests remedies. ## Correct Drawing We'll assume that the standard `glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)` blending is used. That is, when drawing with transparency $\alpha$, the new colour is mixed at proportion $\alpha$ with the colour previously drawn (which gets weight $1-\alpha$.) This note is concerned with what happens when two transparent objects are drawn at the same location. We suppose the further one has transparency $\alpha_1$, and the closer one has transparency $\alpha_2$. If they are drawn in the correct order (further first), the three colours (background, further object, closer object) should end up mixed in proportions $C = [(1-\alpha_1)(1-\alpha_2), \alpha_1(1-\alpha_2), \alpha_2]$ respectively. ## Incorrect sorting If the objects are drawn in the wrong order, the actual proportions of each colour will be $N = [(1-\alpha_1)(1-\alpha_2), \alpha_1, \alpha_2(1-\alpha_1)]$ if no masking occurs. `rgl` currently defaults to depth masking using `glDepthMask(GL_TRUE)`. This means that depths are saved when the objects are drawn, and if an attempt is made to draw the further object after the closer one (i.e. as here), the further object will be culled, and the proportions will be $M = [(1-\alpha_2), 0, \alpha_2]$. ## Mask or Not? The question is: which is better, `glDepthMask(GL_TRUE)` or `glDepthMask(GL_FALSE)`? One way to measure this is to measure the distance between $C$ and the incorrect proportions. (This is unlikely to match perceptual distance, which will depend on the colours as well, but we need something. Some qualitative comments below.) So we have \[|C-N|^2 = 2\alpha_1^2\alpha_2^2\], and \[|C-M|^2 = 2\alpha_1^2(1-\alpha_2)^2\]. Thus the error is larger with $N$ when $\alpha_2 > 1/2$, and larger with $M$ when $\alpha_2 < 1/2$. The value of $\alpha_1$ doesn't affect the preference, though small values of $\alpha_1$ will be associated with smaller errors. Depending on the colours of the background and the two objects, this recommendation could be modified. For example, if the two objects are the same colour (or very close), it doesn't really matter how the 2nd and 3rd proportions are divided up, and $N$ will be best because it gets the background proportion exactly right. ## Recommendation Typically in `rgl` we don't know which object will be closer and which one will be further, so we can't base our choice on a single $\alpha_i$. The recommendation would be to use all small levels of `alpha` and disable masking, or use all large values of `alpha` and retain masking. ## Example The classic example of an impossible to sort scene involves three triangles arranged cyclicly so each one is behind one and in front of one of the others (based on https://paroj.github.io/gltut/Positioning/Tut05%20Overlap%20and%20Depth%20Buffering.html). ```{r} theta <- 2*pi*c(0:2, 4:6, 8:10)/12 x <- cos(theta) y <- sin(theta) z <- rep(c(0,0,1), 3) xyz <- cbind(x, y, z) xyz <- xyz[c(1,2,6, 4,5,9, 7,8,3),] open3d() par3d(userMatrix = M) triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3)) ``` To see the effect of the calculations above, consider the following four displays. ```{r fig.width=8} open3d() par3d(userMatrix = M) layout3d(matrix(1:9, ncol = 3, byrow=TRUE), widths = c(1,2,2), heights = c(1, 3,3), sharedMouse = TRUE) text3d(0,0,0, " ") next3d() text3d(0,0,0, "depth_mask = TRUE") next3d() text3d(0,0,0, "depth_mask = FALSE") next3d() text3d(0,0,0, "alpha = 0.7") next3d() triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3), alpha = 0.7, depth_mask = TRUE) next3d() triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3), alpha = 0.7, depth_mask = FALSE) next3d() text3d(0,0,0, "alpha = 0.3") next3d() triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3), alpha = 0.3, depth_mask = TRUE) next3d() triangles3d(xyz, col = rep(c("red", "green", "blue"), each = 3), alpha = 0.3, depth_mask = FALSE) ``` As you rotate the figures, you can see imperfections in rendering. On the right, the last drawn appears to be on top, while on the left, the first drawn appears more opaque than it should. In the figure below, the three triangles each have different transparency, and each use the recommended setting: ```{r} open3d() par3d(userMatrix = M) triangles3d(xyz[1:3,], col = "red", alpha = 0.3, depth_mask = FALSE) triangles3d(xyz[4:6,], col = "green", alpha = 0.7, depth_mask = TRUE) triangles3d(xyz[7:9,], col = "blue", depth_mask = TRUE) ``` In this figure, all three triangles are the same colour, only lighting affects the display: ```{r fig.width=8} open3d() par3d(userMatrix = M) layout3d(matrix(1:9, ncol = 3, byrow=TRUE), widths = c(1,2,2), heights = c(1, 3,3), sharedMouse = TRUE) text3d(0,0,0, " ") next3d() text3d(0,0,0, "depth_mask = TRUE") next3d() text3d(0,0,0, "depth_mask = FALSE") next3d() text3d(0,0,0, "alpha = 0.7") next3d() triangles3d(xyz, col = "red", alpha = 0.7, depth_mask = TRUE) next3d() triangles3d(xyz, col = "red", alpha = 0.7, depth_mask = FALSE) next3d() text3d(0,0,0, "alpha = 0.3") next3d() triangles3d(xyz, col = "red", alpha = 0.3, depth_mask = TRUE) next3d() triangles3d(xyz, col = "red", alpha = 0.3, depth_mask = FALSE) ``` Here `depth_mask = FALSE` seems to be the right choice in both cases.rgl/inst/doc/WebGL.R0000644000176200001440000001303714146473367013666 0ustar liggesusers## ----setup, echo=FALSE, results="asis"---------------------------------------- source("setup.R") setupKnitr(autoprint = FALSE) set.seed(123) ## ----------------------------------------------------------------------------- library(rgl) plotids <- with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length, type="s", col=as.numeric(Species))) rglwidget(elementId = "plot3drgl") ## ----------------------------------------------------------------------------- toggleWidget(sceneId = "plot3drgl", ids = plotids["data"], label = "Data") ## ----------------------------------------------------------------------------- names(plotids) unclass(plotids) ## ----------------------------------------------------------------------------- rglwidget() %>% toggleWidget(ids = plotids["data"], label = "Data") ## ----eval=FALSE--------------------------------------------------------------- # rglwidget() |> # toggleWidget(ids = plotids["data"], label = "Data") ## ----------------------------------------------------------------------------- toggleWidget(NA, ids = plotids["data"], label = "Data") %>% rglwidget(controllers = .) ## ----eval=FALSE--------------------------------------------------------------- # toggleWidget(NA, ids = plotids["data"], label = "Data") |> # w => rglwidget(controllers = w) ## ----------------------------------------------------------------------------- clear3d() # Remove the earlier display with(subset(iris, Species == "setosa"), spheres3d(Sepal.Length, Sepal.Width, Petal.Length, col=as.numeric(Species), radius = 0.211, tag = "setosa")) with(subset(iris, Species == "versicolor"), spheres3d(Sepal.Length, Sepal.Width, Petal.Length, col=as.numeric(Species), radius = 0.211, tag = "versicolor")) with(subset(iris, Species == "virginica"), spheres3d(Sepal.Length, Sepal.Width, Petal.Length, col=as.numeric(Species), radius = 0.211, tag = "virginica")) aspect3d(1,1,1) decorate3d(tag = "axes") rglwidget() %>% toggleWidget(tags = "setosa") %>% toggleWidget(tags = "versicolor") %>% toggleWidget(tags = "virginica") %>% toggleWidget(tags = "axes") %>% asRow(last = 4) ## ----------------------------------------------------------------------------- rglwidget() %>% playwidget(start = 0, stop = 3, interval = 1, subsetControl(1, subsets = list( Setosa = tagged3d("setosa"), Versicolor = tagged3d("versicolor"), Virginica = tagged3d("virginica"), All = tagged3d(c("setosa", "versicolor", "virginica")) ))) ## ----------------------------------------------------------------------------- M <- r3dDefaults$userMatrix fn <- par3dinterp(time = (0:2)*0.75, userMatrix = list(M, rotate3d(M, pi/2, 1, 0, 0), rotate3d(M, pi/2, 0, 1, 0)) ) rglwidget() %>% playwidget(par3dinterpControl(fn, 0, 3, steps=15), step = 0.01, loop = TRUE, rate = 0.5) ## ----------------------------------------------------------------------------- setosavals <- subset(iris, Species == "setosa") which <- which.min(setosavals$Sepal.Width) init <- setosavals$Sepal.Length[which] rglwidget() %>% playwidget( vertexControl(values = matrix(c(init, 0, 0, 0, 8, 1, 1, 1), nrow = 2, byrow = TRUE), attributes = c("x", "red", "green", "blue"), vertices = which, tag = "setosa"), step = 0.01) ## ----------------------------------------------------------------------------- time <- 0:500 xyz <- cbind(cos(time/20), sin(time/10), time) lineid <- plot3d(xyz, type="l", col = "black")["data"] sphereid <- spheres3d(xyz[1, , drop=FALSE], radius = 8, col = "red") rglwidget() %>% playwidget(list( ageControl(births = time, ages = c(0, 0, 50), colors = c("gray", "red", "gray"), objids = lineid), ageControl(births = 0, ages = time, vertices = xyz, objids = sphereid)), start = 0, stop = max(time) + 20, rate = 50, components = c("Reverse", "Play", "Slower", "Faster", "Reset", "Slider", "Label"), loop = TRUE) ## ----eval = requireNamespace("crosstalk")------------------------------------- # This example requires the crosstalk package # We skip it if crosstalk is not available. ids <- with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length, type="s", col=as.numeric(Species))) par3d(mouseMode = "selecting") rglwidget(shared = rglShared(ids["data"])) %>% rglMouse() ## ----eval=requireNamespace("crosstalk")--------------------------------------- # This example requires the crosstalk package. # We skip it if crosstalk is not available. library(crosstalk) sd <- SharedData$new(mtcars) ids <- plot3d(sd$origData(), col = mtcars$cyl, type = "s") # Copy the key and group from existing shared data rglsd <- rglShared(ids["data"], key = sd$key(), group = sd$groupName()) rglwidget(shared = rglsd) %>% asRow("Mouse mode: ", rglMouse(getWidgetId(.)), "Subset: ", filter_checkbox("cylinderselector", "Cylinders", sd, ~ cyl, inline = TRUE), last = 4, colsize = c(1,2,1,2), height = 60) ## ----plot3d2------------------------------------------------------------------ plotids <- with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length, type="s", col=as.numeric(Species))) subid <- currentSubscene3d() rglwidget(elementId="plot3drgl2") ## ----echo=FALSE, results="asis"----------------------------------------------- writeIndex(cols = 5) rgl/inst/doc/WebGL.Rmd0000644000176200001440000004006514145464133014176 0ustar liggesusers--- title: "User Interaction in WebGL (updated)" author: "Duncan Murdoch" date: "`r format(Sys.time(), '%B %d, %Y')`" output: rmarkdown::html_vignette: toc: yes fig_width: 5 fig_height: 5 vignette: > %\VignetteIndexEntry{User Interaction in WebGL (updated)} %\VignetteEngine{knitr::rmarkdown} --- ```{r setup, echo=FALSE, results="asis"} source("setup.R") setupKnitr(autoprint = FALSE) set.seed(123) ``` ## Introduction This document describes how to embed `rgl` scenes in HTML documents and use embedded Javascript to control a WebGL display in an HTML document. For more general information about `rgl`, see [rgl Overview](rgl.html). We assume that the HTML document is produced from R markdown source using `knitr` or `rmarkdown`. This format mixes text with Markdown markup with chunks of R code. There is a limited amount of discussion of other methods. There are two ways to embed an `rgl` scene in the document. The newest one is recommended: call `r linkfn("setupKnitr")` with argument `autoprint = TRUE` early in the document. This will set things up to be quite similar to the way standard 2D graphics are included by `knitr`, i.e. it will detect the fact that you've drawn something, and just include it automatically. If `autoprint = FALSE` is used or no call is made to `setupKnitr()`, an explicit call to `r linkfn("rglwidget")` will produce a "widget" which can be embedded into your document by printing it. This document uses that method. Older methods (e.g. `writeWebGL` or various hooks) that were used before `rgl` version 0.102.0 are no longer supported. ## Browser support Most browsers now support WebGL, but in some browsers it may be disabled by default. See https://get.webgl.org for help on a number of different browsers. ## Examples We start with a simple plot of the iris data. We insert a code chunk and call the `r linkfn("rglwidget")` function with optional argument `elementId`. This allows later Javascript code to refer to the image. We also save the object ids from the plot, so that they can be manipulated later. (The first example in [Controls](#controls) uses tags instead of saving the ids.) ```{r} library(rgl) plotids <- with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length, type="s", col=as.numeric(Species))) rglwidget(elementId = "plot3drgl") ``` Next we insert a button to toggle the display of the data. ```{r} toggleWidget(sceneId = "plot3drgl", ids = plotids["data"], label = "Data") ``` The `sceneId` is the same as the `elementId` we used in `rglwidget()`, the `ids` are the object ids of the objects that we'd like to toggle, and the `label` is the label shown on the button. To find the names in the `plotids` variable, apply `names()` or `unclass()`: ```{r} names(plotids) unclass(plotids) ``` ## Using `magrittr` or base pipes It can be error-prone to set the `elementId` in the `rglwidget()` to match the `sceneId` in the `toggleWidget()` (or `playwidget()`, described below). In the usual case where both are intended to appear together, [`magrittr`](https://CRAN.R-project.org/package=magrittr)-style pipes can be used quite flexibly: the first argument of the control widget accepts the result of `rglwidget()` (or other control widgets), and the `controllers` argument of `rglwidget()` accepts control widgets. In R 4.1.0, the new base pipe operator `|>` should be usable in the same way. For example, ```{r} rglwidget() %>% toggleWidget(ids = plotids["data"], label = "Data") ``` If you have R 4.1.0 or greater, this should do the same: ```{r eval=FALSE} rglwidget() |> toggleWidget(ids = plotids["data"], label = "Data") ``` You can swap the order of button and scene; use the `magrittr` dot (or the `=>` syntax in base pipes) to pass the `toggleWidget` to `rglwidget` in the `controllers` argument: ```{r} toggleWidget(NA, ids = plotids["data"], label = "Data") %>% rglwidget(controllers = .) ``` or using R 4.1.0 or later, ```{r eval=FALSE} toggleWidget(NA, ids = plotids["data"], label = "Data") |> w => rglwidget(controllers = w) ``` ## Controls We have seen how to change the contents of the plot using `r indexfns("toggleWidget")`. We can do more elaborate displays. For example, we can redo the previous plot, but with the three species as separate "spheres" objects and buttons to toggle them: ```{r} clear3d() # Remove the earlier display with(subset(iris, Species == "setosa"), spheres3d(Sepal.Length, Sepal.Width, Petal.Length, col=as.numeric(Species), radius = 0.211, tag = "setosa")) with(subset(iris, Species == "versicolor"), spheres3d(Sepal.Length, Sepal.Width, Petal.Length, col=as.numeric(Species), radius = 0.211, tag = "versicolor")) with(subset(iris, Species == "virginica"), spheres3d(Sepal.Length, Sepal.Width, Petal.Length, col=as.numeric(Species), radius = 0.211, tag = "virginica")) aspect3d(1,1,1) decorate3d(tag = "axes") rglwidget() %>% toggleWidget(tags = "setosa") %>% toggleWidget(tags = "versicolor") %>% toggleWidget(tags = "virginica") %>% toggleWidget(tags = "axes") %>% asRow(last = 4) ``` Since we skipped the `label` argument, the buttons are labelled with the values of the tags. The `asRow` function is discussed `r linkfn("asRow", "below")`. `toggleWidget()` is actually a convenient wrapper for two functions: `r indexfns("playwidget")` and `r indexfns("subsetControl")`. `playwidget()` adds the button to the web page (and can also add sliders, do animations, etc.), while `subsetControl()` chooses a subset of objects to display. ### `subsetControl` For a more general example, we could use a slider to select several subsets of the data in the iris display. For example, ```{r} rglwidget() %>% playwidget(start = 0, stop = 3, interval = 1, subsetControl(1, subsets = list( Setosa = tagged3d("setosa"), Versicolor = tagged3d("versicolor"), Virginica = tagged3d("virginica"), All = tagged3d(c("setosa", "versicolor", "virginica")) ))) ``` There are several other "control" functions. ### `par3dinterpControl` `r indexfns("par3dinterpControl")` approximates the result of `r linkfn("par3dinterp")`. For example, the following code (similar to the `r linkfn("play3d")` example) rotates the scene in a complex way. ```{r} M <- r3dDefaults$userMatrix fn <- par3dinterp(time = (0:2)*0.75, userMatrix = list(M, rotate3d(M, pi/2, 1, 0, 0), rotate3d(M, pi/2, 0, 1, 0)) ) rglwidget() %>% playwidget(par3dinterpControl(fn, 0, 3, steps=15), step = 0.01, loop = TRUE, rate = 0.5) ``` Some things to note: The generated Javascript slider has 300 increments, so that motion appears smooth. However, storing 300 `userMatrix` values would take up a lot of space, so we use interpolation in the Javascript code. However, the Javascript code can only do linear interpolation, not the more complex spline-based SO(3) interpolation done by `r linkfn("par3dinterp")`. Because of this, we need to output 15 steps from `r linkfn("par3dinterpControl")` so that the distortions of linear interpolation are not visible. ### `propertyControl` `r indexfns("propertyControl")` is a more general function to set the value of properties of the scene. Currently most properties are supported, but use does require knowledge of the internal implementation. ### `clipplaneControl` `r indexfns("clipplaneControl")` allows the user to control the location of a clipping plane by moving a slider. ### `vertexControl` Less general than `r linkfn("propertyControl")` is `r indexfns("vertexControl")`. This function sets attributes of individual vertices in a scene. For example, to set the x-coordinate of the closest point in the setosa group, and modify its colour from black to white, ```{r} setosavals <- subset(iris, Species == "setosa") which <- which.min(setosavals$Sepal.Width) init <- setosavals$Sepal.Length[which] rglwidget() %>% playwidget( vertexControl(values = matrix(c(init, 0, 0, 0, 8, 1, 1, 1), nrow = 2, byrow = TRUE), attributes = c("x", "red", "green", "blue"), vertices = which, tag = "setosa"), step = 0.01) ``` ### `ageControl` A related function is `r indexfns("ageControl")`, though it uses a very different specification of the attributes. It is used when the slider controls the "age" of the scene, and attributes of vertices change with their age. To illustrate we will show a point moving along a curve. We give two `ageControl` calls in a list; the first one controls the colour of the trail, the second controls the position of the point: ```{r} time <- 0:500 xyz <- cbind(cos(time/20), sin(time/10), time) lineid <- plot3d(xyz, type="l", col = "black")["data"] sphereid <- spheres3d(xyz[1, , drop=FALSE], radius = 8, col = "red") rglwidget() %>% playwidget(list( ageControl(births = time, ages = c(0, 0, 50), colors = c("gray", "red", "gray"), objids = lineid), ageControl(births = 0, ages = time, vertices = xyz, objids = sphereid)), start = 0, stop = max(time) + 20, rate = 50, components = c("Reverse", "Play", "Slower", "Faster", "Reset", "Slider", "Label"), loop = TRUE) ``` ### `rglMouse` While not exactly a control in the sense of the other functions in this section, the `r indexfns("rglMouse")` function is used to add an HTML control to a display to allow the user to select the mouse mode. For example, the display below initially allows selection of particular points, but the mouse mode may be changed to let the user rotate the display for a another view of the scene. ```{r eval = requireNamespace("crosstalk")} # This example requires the crosstalk package # We skip it if crosstalk is not available. ids <- with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length, type="s", col=as.numeric(Species))) par3d(mouseMode = "selecting") rglwidget(shared = rglShared(ids["data"])) %>% rglMouse() ``` The `rglShared()` call used here is described `r linkfn("rglShared", "below")`. ## Layout of the display Many `rgl` displays will contain several elements: one or more `rgl` scenes and controls. Internally `rgl` uses the `combineWidgets` function from the [`manipulateWidget`](https://github.com/rte-antares-rpackage/manipulateWidget) package. The `rgl` package provides 3 convenience functions for arranging displays. We have already met the first: the `magrittr` pipe, `%>%`. When the display is constructed as a single object using pipes, the objects in the pipeline will be arranged in a single column. The second convenience function is `r indexfns("asRow")`. This takes as input a list of objects or a `combineWidgets` object (perhaps the result of a pipe), and rearranges (some of) them into a horizontal row. As in the `r linkfn("toggleWidget", "toggleWidget example")`, the `last` argument can be used to limit the actions of `asRow` to the specified number of components. (If `last = 0`, all objects are stacked: this can be useful if some of them are not from the `rgl` package, so piping doesn't work for them.) Finally, `r indexfns("getWidgetId")` can be used to extract the HTML element ID from an HTML widget. This is useful when combining widgets that are not all elements of the same pipe, as in the `crosstalk` example below. If these convenience functions are not sufficient, you can call `r linkfn("combineWidgets", text = "manipulateWidget::combineWidgets", pkg = "manipulateWidget")` or other functions from `manipulateWidget` for more flexibility in the display arrangements. ## Integration with `crosstalk` The [`crosstalk`](https://rstudio.github.io/crosstalk/) package allows widgets to communicate with each other. Currently it supports selection and filtering of observations. `rgl` can send, receive and display these messages. An `rgl` display may have several subscenes, each displaying different datasets. Each object in the scene is potentially a shared dataset in the `crosstalk` sense. The linking depends on the `r indexfns("rglShared")` function. Calling `rglShared(id)`, where `id` is the `rgl` id value for an object in the current scene, creates a shared data object containing the coordinates of the vertices of the `rgl` object. This object is passed to `r linkfn("rglwidget")` in the `shared` argument. It can also be passed to other widgets that accept shared data, linking the two displays. If a shared data object has been created in some other way, it can be linked to a particular `rgl` `id` value by copying its `key` and `group` properties as shown in the example below. ```{r eval=requireNamespace("crosstalk")} # This example requires the crosstalk package. # We skip it if crosstalk is not available. library(crosstalk) sd <- SharedData$new(mtcars) ids <- plot3d(sd$origData(), col = mtcars$cyl, type = "s") # Copy the key and group from existing shared data rglsd <- rglShared(ids["data"], key = sd$key(), group = sd$groupName()) rglwidget(shared = rglsd) %>% asRow("Mouse mode: ", rglMouse(getWidgetId(.)), "Subset: ", filter_checkbox("cylinderselector", "Cylinders", sd, ~ cyl, inline = TRUE), last = 4, colsize = c(1,2,1,2), height = 60) ``` If multiple objects in the `rgl` scene need to be considered as shared data, you can pass the results of several `rglShared()` calls in a list, i.e. `rglwidget(shared = )`. The key values will be assumed to be shared across datasets; if this is not wanted, use a prefix or some other means to make sure they differ between objects. If the same `rgl` id is used in more than one `rglShared()` object, it will respond to messages from all of them. This may lead to undesirable behaviour as one message cancels the previous one. ## Low level controls We repeat the initial plot from this document: ```{r plot3d2} plotids <- with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length, type="s", col=as.numeric(Species))) subid <- currentSubscene3d() rglwidget(elementId="plot3drgl2") ``` We might like a button on the web page to cause a change to the display, e.g. a rotation of the plot. First we add buttons, with the "onclick" event set to a function described below: which produces these buttons: We stored the subscene number that is currently active in `subid` in the code chunk above, and use it as `r rinline("subid")` in the script below. `knitr` substitutes the value when it processes the document. The `rotate()` function uses the Javascript function `document.getElementById` to retrieve the `
` component of the web page containing the scene. It will have a component named `rglinstance` which contains information about the scene that we can modify: If we had used `webGL=TRUE` in the chunk header, the `knitr` WebGL support would create a global object with a name of the form `rgl`. For example, if the code chunk was named `plot3d2`, the object would be called `plot3d2rgl`, and this code would work: ## Index The following functions are described in this document:
```{r echo=FALSE, results="asis"} writeIndex(cols = 5) ``` rgl/inst/demodata/0000755000176200001440000000000014100762640013571 5ustar liggesusersrgl/inst/demodata/region.dat0000644000176200001440000052544414100762640015564 0ustar liggesusersstructure(c(3.71114253706474, 4.01779675877195, 4.28656904179763, 4.50076660092056, 4.64619071647352, 4.71349254349867, 4.70016541088465, 4.6115552355105, 4.46032928164021, 4.26421093830594, 4.04246933185776, 3.81237141855995, 3.58704556714176, 3.3755855810663, 3.18495554003389, 3.02218397671240, 2.89530357041327, 2.81254466310459, 2.78056540241673, 2.80300294351220, 2.88011139818937, 3.00931780934633, 3.18596283700096, 0, 0, 0, 0, 4.4710591748498, 4.70948819878899, 4.89872181207017, 5.02051921157744, 5.06013125543746, 5.00806359728137, 4.86128360217772, 4.62371056612909, 4.3059981576005, 3.92478071983061, 3.50164515839338, 3.06203621718930, 2.63406742028284, 2.24685725266602, 1.92776393521573, 1.69808969649104, 1.56769252810029, 1.53026304325852, 1.56198954045970, 1.62591227445305, 1.68203461740870, 1.70009636765875, 1.66977099576159, 1.60362803966042, 1.53152411467252, 1.48923433055194, 1.50658148407650, 1.59976708640559, 1.76980341966483, 2.00588212663519, 2.29087619783296, 2.60634981646881, 2.93570324219523, 3.26537586715308, 3.58475345647643, 3.88553154486786, 4.16105219094723, 4.40584254917525, 4.61538792773383, 4.78608624645687, 4.9153144358217, 5.00154838089022, 5.04449334533078, 5.04519407167202, 5.00610295131046, 4.93109270334441, 4.82540890084237, 4.69556887426935, 4.54922639597066, 4.39503116727252, 4.24250812929838, 4.10195127908395, 3.98426397117676, 3.90059628895129, 3.86157237320898, 3.875930868916, 3.94857501129059, 4.07834266816769, 4.25616177675292, 4.46446713258873, 4.67862714035609, 4.87058793953534, 5.01412481357765, 5.09033389715201, 5.09168693783603, 5.02332625411098, 4.90119624927908, 4.74770066164599, 4.58635961145821, 4.43710111451504, 4.3133594571693, 4.22135156130706, 4.16114656990489, 3.89700585253865, 4.22886109942203, 4.51989598517139, 4.75159744128911, 4.90823191543841, 4.97952661958404, 4.96293748642882, 4.86476859750004, 4.6994670657364, 4.48686171586016, 4.24795638915308, 4.00078219162283, 3.75810141673599, 3.52794979776719, 3.31638022180937, 3.13041853986297, 2.97924097477999, 2.87297940538678, 2.82023105721542, 2.82600130300695, 2.89112371800521, 3.01296791072630, 3.18648583748062, 0, 0, 0, 0, 4.50221868296492, 4.7516899946142, 4.9516531839248, 5.082955652852, 5.1300650773303, 5.08292656463883, 4.93823727132185, 4.69997410774362, 4.37919223567675, 3.99328528742998, 3.56498907339343, 3.1213377615046, 2.69250181926538, 2.31002585322016, 2.00370441153561, 1.79658133865914, 1.69859792364187, 1.70098738444312, 1.77466075574443, 1.87532702065300, 1.95543750057437, 1.97928918103662, 1.93507581107475, 1.83836096274211, 1.72538731886278, 1.63955718677841, 1.61732045387912, 1.67905006815417, 1.82715792126502, 2.05006946864233, 2.32873107131955, 2.64253414898331, 2.97302597060795, 3.30531446627761, 3.62793280033241, 3.93205639715069, 4.21068787819006, 4.4580836524531, 4.66946367582298, 4.84094343206792, 4.96960661004997, 5.05364903135097, 5.09254206573137, 5.08717842625571, 5.03997454196596, 4.95491342105982, 4.83752207099119, 4.69478986941448, 4.53504840526328, 4.36784376135249, 4.20382689937575, 4.05465166788792, 3.93279588797054, 3.85112544719211, 3.82195505112571, 3.85539873784604, 3.95701349573957, 4.12511594726059, 4.34857545942243, 4.60613454167730, 4.86814875657774, 5.10098478490398, 5.27333376568751, 5.36279239738902, 5.36069847492058, 5.27363958658383, 5.1211611847113, 4.93051219370601, 4.73020510080281, 4.54435513247573, 4.38920343104757, 4.27226439017113, 4.19362928795208, 4.07491302868166, 4.43137640497536, 4.74406166052454, 4.9926297010233, 5.15982359856952, 5.23448867730731, 5.21412680149075, 5.10612385396442, 4.92684837773999, 4.69834717863986, 4.44338253639325, 4.18064029313238, 3.92227731972436, 3.67496540712135, 3.44357440615526, 3.23497684833404, 3.05949095243323, 2.92925673262058, 2.85494715648567, 2.84303490375728, 2.89496815677644, 3.00804511559018, 3.17680092865961, 0, 0, 0, 0, 4.51256600745384, 4.77118198839211, 4.98039115601543, 5.12027121224973, 5.17461961486849, 5.1328918519855, 4.99153538658068, 4.75455222836937, 4.43331664565167, 4.04585702517308, 3.61590167934052, 3.17189678677550, 2.74588183039085, 2.37164001810793, 2.08122868154864, 1.89929185486929, 1.83576647020625, 1.87941363534475, 1.99593213579537, 2.13383002199728, 2.23816559651834, 2.26793236038767, 2.20992248050721, 2.08269328009899, 1.92880792169203, 1.79920002605776, 1.73685986555595, 1.76628213628716, 1.89127491418130, 2.09953411782598, 2.37014302001071, 2.68039813788614, 3.01007734098488, 3.34304116504317, 3.66705045981566, 3.97283202531075, 4.25310580572896, 4.50189387402052, 4.71416321029967, 4.88573462611568, 5.01336445036647, 5.09491781913378, 5.12957205259379, 5.11800578767904, 5.06254334590535, 4.96723546090745, 4.83786880428998, 4.68190988310029, 4.50840402964777, 4.32786160512497, 4.15215729250468, 3.99442669625632, 3.86885892017108, 3.79017369120736, 3.77249647693588, 3.82739440219987, 3.96108511064196, 4.17127365178147, 4.4445675267108, 4.75570559773734, 5.06964350463872, 5.34676455354722, 5.55032940147435, 5.65421722586217, 5.64858771723579, 5.54160930140493, 5.35670754719982, 5.12633272245133, 4.88434721757477, 4.65934894211133, 4.47058257016638, 4.32695132260256, 4.2285720486294, 4.24122540292336, 4.62116113538191, 4.95438657223701, 5.21876415677214, 5.39555008410446, 5.47275846063356, 5.44800604047671, 5.32984611012871, 5.13665838969873, 4.89277650468045, 4.62273732336765, 4.34582023497493, 4.07343636722213, 3.810702008461, 3.56110913684306, 3.33122436372728, 3.13241919836277, 2.97880859607307, 2.88313687697481, 2.85334285313893, 2.89148043165617, 2.99476492550612, 3.15731440882888, 0, 0, 0, 0, 4.50171657383887, 4.76725753659364, 4.98391420212611, 5.13116282900903, 5.1922661357174, 5.15627751914707, 5.01942414072968, 4.78570024311716, 4.46670539018071, 4.08095251099637, 3.65296076842997, 3.21233916861373, 2.79270466101750, 2.42975911543662, 2.15750800485746, 2.00194697805369, 1.97290760545717, 2.05680079909251, 2.21448505094414, 2.38783204204583, 2.51511906195553, 2.55050705299750, 2.47956187763093, 2.32366368567253, 2.13125434717041, 1.96024829618887, 1.85969010927111, 1.85789019005685, 1.95995656723782, 2.15292894462235, 2.41419938144864, 2.71917457572363, 3.04605980854715, 3.37763903739759, 3.70104207993791, 4.0066596719188, 4.28701275012887, 4.53594203423922, 4.74818224238988, 4.91924859716058, 5.0455312332008, 5.1245042206177, 5.15497690116675, 5.13733511295875, 5.07373669524447, 4.96823945877397, 4.82685190757809, 4.65751022716956, 4.47000078714063, 4.27586004803647, 4.08827750731205, 3.92198115254226, 3.79298841716358, 3.71798094621164, 3.7129773306653, 3.79103740160411, 3.95902096501416, 4.21393440130147, 4.53996622440893, 4.90763596210863, 5.2762508723412, 5.59996715677052, 5.83641800129229, 5.95565099187045, 5.94663664988127, 5.81921394310418, 5.60085503437514, 5.32941642729954, 5.04431237182853, 4.77878912630848, 4.55520577161284, 4.38390793508276, 4.26504410647743, 4.39225106037538, 4.79396804520538, 5.14611996984028, 5.42483326807406, 5.60993793463673, 5.68867132093289, 5.65880980205548, 5.53010717831344, 5.32297639746498, 5.06405217388541, 4.77965665147626, 4.48967031795952, 4.2047542989952, 3.92843467196028, 3.66273953019106, 3.41378301857579, 3.19379583799207, 3.01865975830088, 2.90300820605021, 2.85611884970752, 2.88058823266243, 2.9735423438331, 0, 0, 0, 0, 0, 4.46990199737718, 4.73987574167139, 4.96190456482528, 5.11505470389628, 5.18220991309226, 5.1521245533833, 5.02084405362733, 4.79232338272826, 4.47828509589732, 4.09755449206992, 3.67519853986911, 3.24167134108731, 2.83177400292007, 2.48267477890587, 2.22987001970025, 2.10034909124184, 2.10372263900162, 2.22431142235542, 2.41881776360557, 2.62348424628304, 2.77088172818290, 2.81114872275059, 2.72890006867141, 2.54799419315954, 2.32192590149148, 2.11457523794484, 1.98014614227148, 1.95019548051183, 2.03093866001168, 2.20886850617957, 2.45996734876978, 2.75808668983349, 3.08017203900379, 3.40819131657945, 3.72884861202347, 4.0323551632616, 4.31114613407575, 4.55895262928926, 4.77030771005267, 4.94041222908187, 5.06524654553613, 5.14182247384686, 5.1684913753007, 5.14524718176656, 5.07398365091871, 4.95868121045947, 4.80551075245565, 4.62285369501289, 4.42125318798466, 4.21332585330744, 4.01365902931349, 3.83866990671195, 3.70629693370025, 3.63525496763948, 3.64349213032120, 3.74555519446323, 3.94889875892279, 4.2497504163714, 4.62978257035287, 5.05520033820381, 5.47958685929801, 5.85082565729932, 6.12090902055605, 6.2560655785137, 6.24410445923309, 6.0965665384933, 5.84499696590647, 5.53267619305043, 5.20458022402375, 4.89860926258534, 4.64024189155383, 4.4412730926733, 4.30189217947355, 4.52437843842459, 4.94563928171095, 5.31461493278886, 5.60579355197354, 5.79766253426646, 5.87673715030005, 5.84096762741382, 5.70128032214276, 5.48006656370948, 5.20621525860416, 4.90783916928748, 4.60550604955838, 4.30927790978361, 4.02123569485505, 3.74198478298928, 3.47705295448595, 3.23922363790154, 3.04574632229705, 2.91276616126612, 2.8506343693205, 2.86236864768995, 2.94500619894028, 0, 0, 0, 0, 4.12222479140656, 4.41797158524696, 4.68967588389628, 4.91477578678273, 5.07213798082884, 5.14444018331966, 5.1202545958934, 4.99549272909628, 4.77404215624414, 4.46764166314082, 4.09524084058210, 3.68217814680073, 3.25937678434531, 2.86233933325241, 2.52912956051951, 2.29614783229777, 2.19091846344185, 2.22269982825905, 2.37410529101064, 2.59864656642528, 2.82834566045499, 2.99156227602585, 3.03553236305217, 2.94428795541026, 2.74366537143984, 2.49103886233603, 2.25481679152423, 2.09309511383225, 2.03986703294317, 2.10217310107382, 2.26609933197402, 2.50659806475214, 2.79641767544558, 3.11166318452061, 3.43383089199968, 3.74946598763345, 4.04880064228538, 4.32432820259532, 4.56976229176694, 4.77947640978951, 4.94835162817009, 5.0719107669163, 5.14662085877274, 5.17026705559572, 5.14232768936262, 5.06430542447896, 4.93998767039331, 4.77561956268827, 4.57998103510349, 4.36437362187791, 4.14254024951007, 3.93054203452818, 3.74656882028543, 3.61054702563459, 3.54325576201809, 3.56455833759209, 3.69043278348098, 3.9288500657618, 4.27518835558542, 4.70857618845026, 5.19094717819963, 5.67028165339388, 6.08837049564086, 6.39176004025996, 6.54301567131396, 6.52885584921441, 6.3624875003779, 6.07939557972459, 5.72808957229962, 5.35889914276413, 5.01420232528685, 4.7224820692474, 4.4969364326753, 4.33780790914313, 4.63421938830739, 5.07227150071444, 5.45551299468007, 5.7569257384984, 5.95375956164311, 6.03186111487858, 5.98933751524211, 5.83819900578265, 5.60268443709929, 5.31382887495504, 5.00153336867663, 4.68721254691924, 4.3806286030896, 4.08273662556706, 3.79288595030719, 3.51590031888879, 3.2647051722316, 3.05733804039149, 2.91089328509889, 2.83639988339644, 2.83712101701803, 2.91001356693944, 0, 0, 0, 0, 4.0543607583253, 4.34736224864797, 4.61795771556188, 4.8436641730507, 5.00337316297953, 5.07974246107731, 5.06129049907384, 4.94385172790372, 4.73122381735371, 4.43505553174343, 4.07422493220536, 3.67404450441306, 3.26548937511235, 2.88421419523044, 2.56851599557929, 2.35501014538399, 2.27121533388073, 2.32588941918418, 2.50041178801474, 2.74628426000971, 2.99302708185691, 3.16661181858213, 3.21273515564775, 3.11529049044952, 2.901474139069, 2.63109859583607, 2.37533608091850, 2.19461689755169, 2.12437094604672, 2.17210895143643, 2.32367111983467, 2.55343394154111, 2.83358575614840, 3.13989495230659, 3.45379970060349, 3.76200642296972, 4.05500907683318, 4.32553334507004, 4.56738891660688, 4.7748450398943, 4.94246285798426, 5.06525723075913, 5.13905691870026, 5.16095262730448, 5.12975404584442, 5.04640853204392, 4.91435404130698, 4.73978391717514, 4.53180134197104, 4.30245183870978, 4.06664520380553, 3.8419899662917, 3.64852363251879, 3.50820520953431, 3.44387022921621, 3.47723195202623, 3.625593168207, 3.89733066737768, 4.28691161216511, 4.77096401128823, 5.30733666655624, 5.83873597184363, 6.30127921832531, 6.63648269389814, 6.80355558332298, 6.78824153148795, 6.60530669563235, 6.29387482578498, 5.90726611599113, 5.50072664962259, 5.12074485150309, 4.79856590173797, 4.54868793977738, 4.37142159085302, 4.7187537334399, 5.17038151825482, 5.56492718242987, 5.87402972368622, 6.07382604157255, 6.14954753947655, 6.09941609168555, 5.93638765885159, 5.68635505133456, 5.38233892247458, 5.05601431996438, 4.72985390975367, 4.41373154731433, 4.10793127797224, 3.81081313222161, 3.52639439536079, 3.26725180149393, 3.05149037241562, 2.89644672123608, 2.81333110434166, 2.80543617425376, 2.86965475010813, 0, 0, 0, 0, 3.97276990451914, 4.26003827386985, 4.52662843436359, 4.75038429011679, 4.91045465809386, 4.98967195069152, 4.97663788054682, 4.86717522795664, 4.66497712374533, 4.38150211772178, 4.03536286842535, 3.65154249683142, 3.26063219669426, 2.89785357656792, 2.60102157708710, 2.40621480555622, 2.34035190548911, 2.41152425671554, 2.60039579848306, 2.85775890850993, 3.11252956113543, 3.29030690300051, 3.33675835840157, 3.23613351553983, 3.01630841857296, 2.737940830149, 2.47301318314949, 2.28256188320369, 2.20233976406911, 2.2399254990554, 2.38108202905808, 2.60010443649768, 2.86921683847191, 3.16440717976567, 3.46751559778716, 3.76576988490860, 4.05020054491997, 4.3139677763999, 4.5511127295829, 4.75587093369906, 4.92249161473922, 5.0454315521492, 5.1197785152016, 5.14177936138252, 5.10938726619937, 5.02278285546114, 4.88484459005568, 4.70153796336422, 4.48217798052837, 4.23952307863794, 3.98969096073363, 3.75191916753923, 3.54817065938062, 3.40246917042756, 3.33966775355409, 3.38321937126527, 3.55159762097857, 3.85344158868433, 4.28224854432901, 4.81225009743090, 5.39753065171361, 5.97605304705234, 6.47891727676002, 6.84324649908228, 7.02535203845866, 7.01016403787899, 6.81383246277487, 6.4786560782124, 6.06213079339533, 5.62375927405432, 5.21358637646652, 4.86525276239859, 4.5943970849878, 4.40141421275043, 4.77546662845339, 5.23706235859208, 5.6396119297589, 5.95360135952351, 6.15419628043112, 6.2260694989708, 6.16750298426093, 5.99223302771255, 5.7275764863723, 5.40834472437697, 5.06795586800001, 4.73016670230584, 4.40542273210376, 4.09385713114715, 3.79315858297812, 3.50644401879233, 3.24540859071695, 3.02742952271926, 2.86930348489247, 2.78187582184568, 2.76823579037145, 2.82523519053189, 0, 0, 0, 0, 3.87978717178604, 4.15840456595246, 4.41811953779152, 4.63735115314415, 4.79573949470505, 4.87648947745451, 4.86842849995224, 4.76744071693814, 4.57711001969853, 4.30861626343306, 3.98012512985339, 3.61599788647548, 3.24601284159768, 2.90437370106838, 2.62768987153482, 2.45073550259769, 2.39921458462532, 2.48036807259369, 2.67465472685892, 2.93346486607224, 3.18703015316856, 3.36262512130317, 3.40742927317881, 3.3065633091387, 3.08790545990051, 2.81135161723768, 2.54771570179163, 2.35688407219232, 2.27379476309823, 2.30567581129097, 2.43837355966422, 2.64659616284687, 2.90320645446021, 3.18498162837201, 3.474642893516, 3.76032259671493, 4.03388750059585, 4.28915894929571, 4.52056679695071, 4.72240115387749, 4.888619823768, 5.0130766434524, 5.09001008090792, 5.11465230098389, 5.08387080641865, 4.99680776886555, 4.8555012931597, 4.6654467300428, 4.43601388338495, 4.18062732793338, 3.91666534239503, 3.6651017464766, 3.4499250982844, 3.2972618002663, 3.23392854340511, 3.28497616207010, 3.46985570012423, 3.79728930839534, 4.25973082572584, 4.82915138004083, 5.45629424288163, 6.07508712789851, 6.61249218490676, 7.00208872258732, 7.19789390827433, 7.18423025782933, 6.97839584318949, 6.62525644206309, 6.18565703788797, 5.72249974146896, 5.28866546469499, 4.91971103171681, 4.63220334211714, 4.42663627985062, 4.80247001974546, 5.27011984986897, 5.67710917415651, 5.99297990875967, 6.1920811930721, 6.25859178170409, 6.19080433947539, 6.0030744433197, 5.72391457799209, 5.38972528172021, 5.03561747695123, 4.68682724142573, 4.35479710821947, 4.04000121045724, 3.73975859791, 3.45618724819807, 3.19957112216633, 2.98577352569701, 2.83028377649005, 2.74305417182548, 2.72675266739475, 2.77821840223208, 0, 0, 0, 0, 3.77799821273446, 4.0451988389428, 4.29527887839908, 4.50747407829273, 4.66214473016431, 4.74306393537978, 4.73942888709712, 4.64726453978517, 4.47005239376277, 4.21862203745574, 3.91053285711592, 3.5692593131588, 3.22337051905335, 2.90550429476842, 2.65037921316086, 2.49072978166204, 2.45044578003383, 2.53571639760076, 2.72724328731843, 2.97821386434215, 3.22195787365123, 3.38934015348133, 3.43050612202610, 3.33195066185616, 3.12094566484782, 2.85514474475821, 2.60235786695393, 2.41968393932387, 2.34017744180246, 2.37031303278676, 2.49615784678524, 2.69328648233986, 2.93576354761783, 3.20169818691637, 3.47516141836105, 3.74557766914899, 4.00596416322597, 4.25104989168577, 4.47583230700778, 4.67476556528333, 4.84155526598606, 4.96942026972381, 5.05164194277751, 5.08224630517719, 5.05673694463811, 4.97286837074075, 4.83146355008879, 4.63721748976397, 4.39934022568186, 4.13186305316887, 3.85350688050387, 3.58714199106592, 3.35893523856651, 3.19718841270064, 3.13063968044945, 3.18578743988191, 3.38284051465872, 3.73038101535741, 4.21969441824634, 4.82060119165937, 5.48097166753056, 6.13154589915124, 6.69623301907905, 7.10612256961282, 7.31368087262304, 7.30287233450894, 7.09185969716232, 6.72735312017427, 6.2725696847365, 5.79279915422354, 5.3429061428228, 4.95979278259604, 4.66069645025358, 4.44621974538603, 4.79860028523471, 5.26818118744296, 5.67586205647178, 5.99045848687793, 6.18566518356959, 6.24524371809209, 6.16747362750522, 5.9672101989973, 5.67398017565461, 5.32560026115805, 4.95880616361247, 4.60043058473645, 4.26321394554523, 3.94833086278696, 3.65293865547108, 3.37803332202554, 3.13200584711355, 2.92851767527852, 2.78109765660189, 2.69837299276269, 2.68242570116859, 2.73011443197831, 0, 0, 0, 0, 3.67012243594377, 3.92336961540529, 4.16124489744943, 4.36402907112446, 4.51302016005368, 4.59274747878707, 4.59291996744294, 4.50978748110112, 4.34674844919528, 4.11423170043855, 3.82906175490214, 3.51360340906885, 3.19487578232719, 2.9034725414926, 2.67161600734074, 2.52934242352246, 2.49817540779703, 2.58303543420119, 2.76520599139444, 3.0006606739691, 3.22732978128740, 3.38130321466654, 3.41695207805157, 3.32260734787202, 3.12445336790189, 2.87667284560786, 2.6425295108776, 2.47494704538026, 2.40417987802154, 2.43559163585020, 2.55557107065122, 2.74093494065728, 2.96743054869448, 3.21497767734516, 3.4694279090718, 3.72187123433537, 3.96679308934991, 4.20009137352893, 4.41753157285494, 4.61386708248057, 4.78261784834966, 4.91635929340923, 5.00731746407215, 5.04810232990364, 5.03251676161986, 4.95647863238416, 4.8190966484354, 4.62381882883875, 4.37940811596318, 4.10043587619462, 3.80710271694531, 3.52442723654263, 3.28100292878479, 3.10745670064492, 3.03445813751898, 3.08983017901495, 3.29431218824815, 3.65606030142776, 4.16494679171776, 4.78862365602126, 5.47250834207583, 6.14509006302842, 6.7285090651162, 7.15263446380243, 7.36926941872251, 7.36231427498401, 7.15047829911452, 6.78151390553348, 6.3199354818303, 5.83230999794829, 5.37454732821478, 4.9842607055508, 4.6790643453964, 4.45966912577065, 4.7634856335994, 5.23076900575989, 5.63529075412713, 5.94535452443002, 6.13416198359387, 6.18514947255902, 6.09660462278803, 5.88384180215846, 5.57731514373678, 5.21615202759857, 4.83863476552199, 4.47319293099221, 4.13395930843905, 3.82293806528228, 3.53716203774516, 3.27633243203328, 3.04654801236977, 2.85875886266293, 2.7240914258893, 2.6495936061982, 2.63669325733159, 2.68230312557212, 0, 0, 0, 0, 3.55889181126306, 3.79594771068907, 4.01931107143418, 4.21051792131906, 4.35200445658842, 4.42923138352605, 4.43255526596698, 4.35853750062431, 4.21052526831992, 3.99851988778449, 3.73851929427134, 3.45160874590754, 3.16298948564507, 2.90082773675253, 2.69435640992194, 2.5703659877223, 2.54753586126203, 2.62928854357335, 2.79768573910094, 3.01219107666590, 3.21645166373023, 3.35302627013252, 3.38149648473676, 3.29242683457909, 3.11060265631865, 2.88585172770531, 2.67575439064467, 2.52801921172838, 2.46939931592673, 2.50385738417156, 2.61815868255717, 2.79063294160187, 2.99907671408684, 3.22560597861603, 3.45822286881537, 3.69002612717348, 3.91728021029953, 4.13732273336216, 4.34690939191277, 4.54125968138225, 4.71381302806997, 4.85653078244177, 4.96050740798815, 5.01671212005329, 5.01684043272585, 4.95439695021873, 4.82611405788608, 4.63359335579182, 4.38477145477466, 4.09469359599033, 3.78526629606398, 3.48405142062912, 3.22247076890368, 3.03376104727827, 2.95064289135499, 3.00222025713222, 3.20955346363039, 3.57998755983265, 4.10150103756086, 4.73926847566972, 5.43648881936621, 6.12037394678793, 6.71280568240996, 7.14396878714872, 7.36606453278633, 7.36327269215247, 7.15450409877892, 6.78770415429329, 6.32756779313453, 5.8407931148302, 5.38336348402251, 4.99293816218283, 4.68718950595144, 4.46691971061376, 4.69757891029593, 5.15833718320386, 5.55582856579325, 5.85804226439464, 6.03783803563582, 6.07843403802448, 5.9782073782275, 5.75300153549868, 5.4342476440385, 5.0623829469143, 4.67716123492882, 4.30846801165701, 3.97165680185852, 3.66938359593077, 3.39835858017991, 3.1567365882599, 2.94802503287358, 2.78019128707897, 2.66181278484295, 2.59836226726451, 2.59068853468894, 2.63579375395151, 0, 0, 0, 0, 3.44693260499254, 3.66591909353684, 3.87278899234073, 4.05052278041977, 4.18287369302662, 4.25639153578144, 4.2622064772513, 4.19727810136438, 4.06494567962549, 3.87478083678907, 3.64190313848658, 3.38600753643480, 3.1302926568833, 2.90022415967459, 2.72168450510276, 2.61780382286102, 2.60403081730423, 2.68205361867667, 2.83475031096862, 3.02545346316872, 3.20419874371826, 3.32080452789023, 3.34072612333029, 3.25707944082382, 3.09313046323638, 2.89386250328332, 2.71050184252012, 2.58490456492980, 2.53987223674973, 2.57775810509896, 2.68570866826787, 2.84371768025971, 3.03186441761490, 3.2347352122373, 3.44277607762599, 3.65139453604868, 3.85892854314071, 4.06443074725669, 4.26589154423311, 4.45920230865071, 4.63787942450616, 4.79335499867336, 4.91555325333559, 4.99356849345013, 5.01649976832395, 4.97470124064199, 4.86165776558416, 4.67632840308658, 4.42532897311606, 4.12412219381925, 3.79667769381832, 3.47370220716348, 3.1900731270557, 2.98213144353705, 2.88495564266196, 2.92903863614969, 3.13560230704533, 3.51063656133243, 4.03933253218333, 4.68354556016222, 5.38411550899288, 6.06794065661645, 6.65846353627748, 7.0881032627675, 7.31076184568369, 7.31130239155569, 7.10846201214203, 6.74950276616621, 6.2981912279164, 5.82023721715296, 5.37074647706468, 4.98676170346079, 4.68568020452808, 4.46835448130839, 4.60215383659388, 5.05226742776673, 5.43891969104848, 5.72995327304418, 5.89801692942429, 5.92622972127119, 5.81320742197126, 5.57552300620124, 5.24579898853505, 4.86591441281175, 4.47703875130912, 4.11022672391526, 3.78158811108863, 3.49390500928120, 3.24308915916836, 3.02538968250961, 2.84152048657846, 2.69646476542108, 2.59646435043476, 2.54575487559735, 2.54487406447010, 2.59094677305295, 0, 0, 0, 0, 3.33665719647678, 3.53610669512673, 3.72487822429742, 3.88756488980770, 4.00939130688132, 4.07813280841131, 4.08580568729736, 4.02985149668746, 3.91365442663768, 3.74637764030111, 3.54225028317313, 3.31952628563305, 3.09930249040823, 2.90418533796918, 2.75648424196924, 2.67539528529486, 2.67285012869733, 2.74856602238639, 2.88612093755650, 3.05276886421297, 3.20515479320831, 3.30068473203858, 3.31101972959487, 3.23205880337121, 3.08561788191272, 2.91174422699507, 2.75511253171016, 2.65149904924011, 2.61956085029432, 2.65991867187630, 2.76005604427085, 2.90166058375622, 3.06719064523968, 3.2438592740398, 3.42476481264968, 3.6078714589543, 3.79386080942959, 3.98377555355549, 4.17710831013604, 4.3706750550028, 4.55829441326756, 4.7310296683252, 4.87765208755995, 4.9851447288948, 5.03942606726333, 5.0267668491283, 4.93627330280364, 4.76322009932108, 4.51226584406615, 4.19925375346751, 3.85075130384167, 3.50149033381804, 3.1907404033999, 2.95874060952439, 2.84351757830052, 2.87730400737198, 3.08141353219187, 3.45969318691837, 3.99299890232162, 4.6381704789745, 5.33293446850391, 6.00479717775991, 6.58103895596515, 6.99880610184325, 7.215358359247, 7.21672436277878, 7.02104281064125, 6.67398971985216, 6.23733798050489, 5.77477054362346, 5.33963458646905, 4.9677268484968, 4.67583093682652, 4.46477635134101, 4.47926509606809, 4.91482817825166, 5.28698242329011, 5.56355255431041, 5.71707883282257, 5.73070678084673, 5.6035057911057, 5.35311112710058, 5.01372233718404, 4.62893586750874, 4.24131480388836, 3.88266603637585, 3.56911035028463, 3.30268521238054, 3.07773961839196, 2.88812668375766, 2.73163941325851, 2.61054677043347, 2.52936888944549, 2.49184180398565, 2.49870155329940, 0, 0, 0, 0, 0, 3.23017308556017, 3.40906799032475, 3.57855020799175, 3.72497534993697, 3.83516794636285, 3.89824116634359, 3.90719331057992, 3.86002572242012, 3.7602268320787, 3.61659294495419, 3.44248712307173, 3.25472765361836, 3.07229114563930, 2.91487484108862, 2.8011248718597, 2.74616591476099, 2.75822653530803, 2.83482562398059, 2.95999120091270, 3.10465835665471, 3.23189208047814, 3.30658960326434, 3.30664250881027, 3.230879776214, 3.0999036661104, 2.94909257748605, 2.81680175405271, 2.73287461221186, 2.71186749418326, 2.75262609604792, 2.84288421813823, 2.96594285597348, 3.10660817077224, 3.25476307583297, 3.40628074223116, 3.56187250678000, 3.72480266294644, 3.89837378190258, 4.08387148675017, 4.27934362658137, 4.47921957278528, 4.67445046343636, 4.85274751112202, 4.9987535163439, 5.09451770022406, 5.12106641091667, 5.0616877091622, 4.90663578065608, 4.65780570637303, 4.33141124723265, 3.95737499831703, 3.57568492909152, 3.23133501077393, 2.96965110914430, 2.83258760726373, 2.85481264661715, 3.05779381541624, 3.44210288909926, 3.98177775273799, 4.62572292632957, 5.3069194193525, 5.95434525584665, 6.50205366900407, 6.89523167870392, 7.09665432697269, 7.09409918614135, 6.90460025584298, 6.57130051258724, 6.15297636131757, 5.71036744799306, 5.29429220278684, 4.93873052332892, 4.65951484307744, 4.45733782852156, 4.33167479118716, 4.74909910063414, 5.10334209735486, 5.36229619107485, 5.49846336248573, 5.49514087676297, 5.35211964347078, 5.08854273463045, 4.74072171474158, 4.35437588265863, 3.97347988957932, 3.63007770987852, 3.33932666269526, 3.10135509648407, 2.90792391225931, 2.74986011270857, 2.62194916591391, 2.52426041983072, 2.4606168066579, 2.43543542182541, 2.45043950744652, 0, 0, 0, 0, 2.97344218018593, 3.12921608661597, 3.28701407566672, 3.43645213099226, 3.56578448860047, 3.66353842806582, 3.72025128160923, 3.72997992123203, 3.69135414653498, 3.60802865711773, 3.48849020909223, 3.3452904882166, 3.19386559091311, 3.05112343314247, 2.93389702996387, 2.85719566616386, 2.8320574429166, 2.86291610088224, 2.94488459695206, 3.06209302955571, 3.18868524901235, 3.29362421082383, 3.3488525175471, 3.33825944936905, 3.26367282051659, 3.144845635162, 3.01304121369429, 2.90087499419422, 2.83270996951723, 2.81924091573587, 2.85756488811465, 2.93554698813950, 3.03793126398214, 3.15173279579461, 3.26944748333081, 3.38976442452100, 3.51627269359202, 3.65502131737835, 3.81183198170264, 3.99009599803087, 4.18946013319694, 4.40536874700664, 4.62903177529908, 4.84728759143595, 5.04222914967591, 5.19124105222819, 5.26869587263126, 5.25028022328335, 5.11955915865457, 4.87466338821773, 4.532196732451, 4.12644981139801, 3.70430667601366, 3.31828736850245, 3.02047149832711, 2.8582030784654, 2.86971551759795, 3.07686048023836, 3.47536510633018, 4.02877907539078, 4.67359920474169, 5.33531818784261, 5.9451845723945, 6.44780557744068, 6.80077245255206, 6.97517023185617, 6.96123207716454, 6.77426781787476, 6.45387392807673, 6.05489912357131, 5.63437453429027, 5.23996024422837, 4.90332532684795, 4.6390188912505, 4.4474352959063, 4.16274941799028, 4.5588652692192, 4.89213696675141, 5.13057148024099, 5.24667313206902, 5.22400969537815, 5.06339116608385, 4.78598361581786, 4.43084091263388, 4.04629681549938, 3.67778778827195, 3.35702517790374, 3.09708589854954, 2.89482980120673, 2.73821417840603, 2.61428656725282, 2.51474547462886, 2.43816872232292, 2.38908506680046, 2.37421532265966, 2.39734769007181, 0, 0, 0, 0, 2.89906013805462, 3.03511400935256, 3.1717544869414, 3.30083496397157, 3.41263464558465, 3.49746135667763, 3.54733586830952, 3.55742872391485, 3.52705455336936, 3.4600947411168, 3.36479364371859, 3.2529686886872, 3.13876446201234, 3.03712710631874, 2.96214658363033, 2.92531688215127, 2.93367673474855, 2.98785817960997, 3.08039281875047, 3.19511050554772, 3.30873662905555, 3.39537648745556, 3.43331946153897, 3.41202661423296, 3.33632538510119, 3.22556274347878, 3.10763523632784, 3.01024030310296, 2.95292957427452, 2.94291719943478, 2.97563134333662, 3.03893004687893, 3.11876653402510, 3.20414471831733, 3.29003502221851, 3.37791023170032, 3.47430721859514, 3.58821901818592, 3.72822827945377, 3.90016215909498, 4.10569332493038, 4.34178683219985, 4.60040757521324, 4.86781711600791, 5.12338335705618, 5.3389354454232, 5.48053766940134, 5.51414148822056, 5.41460771601759, 5.1750937798981, 4.81263613422296, 4.36716562102616, 3.89453348147839, 3.45709893535271, 3.11588615819973, 2.92561491280031, 2.92968434741858, 3.15074107459817, 3.57762081538562, 4.15842101728362, 4.81106543872888, 5.44960003977639, 6.00826012272442, 6.4468939322818, 6.74098990483432, 6.8734235267304, 6.83772395108897, 6.6467401631873, 6.33544635349738, 5.95392167572155, 5.55489864212975, 5.18241046913411, 4.86541006287187, 4.61683879663252, 4.43657905487276, 3.97633259201855, 4.34848512451084, 4.65819775208086, 4.87361353771054, 4.96726076030818, 4.92308577938877, 4.74321299247322, 4.45135170375098, 4.08993872162705, 3.71042586201945, 3.3597686858072, 3.06876935823662, 2.84727868731623, 2.68747467674014, 2.57222191178495, 2.48396558326460, 2.41122662993522, 2.35192102756040, 2.31297262152434, 2.30539076496224, 2.33634987114765, 0, 0, 0, 0, 2.83153026896765, 2.94878488244903, 3.06466998087394, 3.17350788351283, 3.26771921308467, 3.33944499779784, 3.38222103841321, 3.39236358276451, 3.36991325690597, 3.31903238764742, 3.24779338526998, 3.16736990205453, 3.09073063373577, 3.03100590072448, 2.99971929373339, 3.00504262922821, 3.05018334841783, 3.13203943916300, 3.24043080331649, 3.35847691968396, 3.46478465934995, 3.53771783049348, 3.56106401030619, 3.52930556952157, 3.4502126350067, 3.34319565997406, 3.23362916200651, 3.14524437108951, 3.09357270341429, 3.08281321835009, 3.10684158178854, 3.15336458952563, 3.20927529066909, 3.2652936140982, 3.31866473920329, 3.37354897164441, 3.43944047556447, 3.52838664756657, 3.65194664902691, 3.81872193526978, 4.03289005429385, 4.29353837760983, 4.59400687818541, 4.92039148599671, 5.24921202705784, 5.54578683653053, 5.76601271095609, 5.86366217923944, 5.8025601719825, 5.56948755595432, 5.18196008025102, 4.68701325790465, 4.15191648255108, 3.65170100020195, 3.25904020663015, 3.03847890775467, 3.0405808209992, 3.28934656549153, 3.76426258224486, 4.39190420179898, 5.06400119187248, 5.67812054147124, 6.17206159783088, 6.52628725261033, 6.74056390123656, 6.8135830525179, 6.74312919372171, 6.538795727515, 6.22986822826848, 5.86095679581458, 5.48011106056629, 5.12744539060914, 4.82888674493855, 4.59545438141169, 4.42625258002827, 3.77659940928052, 4.12273595443875, 4.40689908580827, 4.5973858157634, 4.66676902570298, 4.5994699087366, 4.3991830661453, 4.09260605457652, 3.72610103033774, 3.35465454598279, 3.02676345251464, 2.77178315881945, 2.59529297988016, 2.48349371245741, 2.41295368647685, 2.36072226387708, 2.31205086645285, 2.26505559285676, 2.23085989105553, 2.22691575509856, 2.26522236485806, 0, 0, 0, 0, 2.77096329340621, 2.87076905384715, 2.96671280368765, 3.05581916732458, 3.1327487301397, 3.19150094160704, 3.22712991738684, 3.23710548292177, 3.22221769137659, 3.18695348610930, 3.13928043610568, 3.08982300732643, 3.05050216558398, 3.03280126763361, 3.04588978114086, 3.09485981998592, 3.17931655856058, 3.29255697105795, 3.42161669023175, 3.54853086542541, 3.65309173939183, 3.71700770541613, 3.72866123079236, 3.68694405722511, 3.60246319274612, 3.49513881623100, 3.38867281422055, 3.30380730404465, 3.25287863497306, 3.23756772058768, 3.25033528110471, 3.27859957309134, 3.30991488733271, 3.33641828128333, 3.35738773057208, 3.37951989929339, 3.41521494618795, 3.47962907801373, 3.58747556079393, 3.75046152131317, 3.97578150974308, 4.26532167502292, 4.61452265342356, 5.0098351342609, 5.42488000707292, 5.81750101564328, 6.13145390118676, 6.30568538487825, 6.29043926040268, 6.06460491662167, 5.6461932569541, 5.09073589868851, 4.47954053853865, 3.90372457763539, 3.45080963091094, 3.19784911138688, 3.20471708495402, 3.49737243496062, 4.04330357228846, 4.74099960258526, 5.44769800618729, 6.03887265613734, 6.45620580197203, 6.706205424001, 6.81947284160728, 6.81466776571767, 6.69485543088777, 6.46567350305626, 6.14983739322152, 5.78604328356676, 5.41752870346985, 5.08038918193803, 4.79731631512887, 4.57710713573164, 4.41777495437382, 3.56789876672984, 3.88664062177226, 4.14398003768039, 4.30840904718231, 4.35258781294774, 4.26149868888499, 4.04058486472658, 3.71981627568066, 3.34980626466824, 2.98929498807042, 2.68825444087012, 2.47413356152744, 2.3474250529762, 2.28736050506937, 2.26328331975812, 2.24622513712234, 2.21811870423259, 2.17807247564713, 2.14307410392058, 2.13902119491254, 2.18407511680987, 0, 0, 0, 0, 2.71730993084346, 2.80128737521429, 2.87843071720471, 2.94866151700838, 3.00894289854844, 3.05512512882298, 3.08375472724777, 3.09343821893772, 3.08571881116011, 3.06543719139277, 3.04051362361533, 3.02111340581506, 3.01823908125481, 3.0419044316063, 3.09915538899459, 3.19227752459288, 3.31754749791225, 3.46485282263715, 3.61844149110566, 3.75896375335697, 3.86676902657477, 3.92604734095404, 3.92889620479501, 3.87799457556051, 3.78663799794285, 3.67563754095677, 3.56780013384325, 3.48179446817262, 3.42754818228495, 3.40470853466195, 3.40446729683216, 3.4138343020348, 3.42075892617112, 3.41849242211591, 3.40807720839415, 3.39854743891005, 3.40509635223444, 3.44597969383978, 3.53918995543674, 3.69984195666981, 3.93866109348705, 4.26104422598751, 4.66532438829371, 5.13891499620287, 5.65257992397829, 6.1557998494768, 6.57825048650009, 6.8413953398006, 6.87936295823035, 6.66177773471189, 6.20707552070228, 5.57980045616913, 4.87751834342646, 4.2118569150382, 3.68906500555838, 3.40114539303782, 3.41905462172027, 3.7711600857035, 4.41049646717339, 5.20147620586737, 5.95922889999484, 6.5318081425021, 6.86465366467221, 6.99473666945029, 6.98901049209942, 6.88966361922856, 6.7060372843336, 6.43945842049027, 6.10566065906394, 5.73741203369638, 5.3733344602206, 5.04561444356019, 4.77360406758822, 4.56360041958991, 4.41217936291879, 3.35459043807896, 3.64528018227744, 3.87533272162249, 4.01352653174248, 4.03269736232261, 3.91846917867983, 3.67810178899181, 3.3448831692826, 2.97367821866426, 2.62689753658539, 2.35577975751455, 2.18551410500624, 2.11103579562234, 2.10409253235635, 2.12634363401394, 2.14252027658199, 2.1313027644062, 2.09340902136285, 2.05289978831835, 2.04555121784742, 2.09663254047198, 0, 0, 0, 0, 2.67048956741527, 2.7403101211381, 2.80000791770546, 2.85249790205626, 2.897045736795, 2.93130408863033, 2.95325570572498, 2.96260215469286, 2.96162257507743, 2.95552279786498, 2.95221844823384, 2.96149366688900, 2.99355346330721, 3.05711630368322, 3.15734007875519, 3.29399366065968, 3.4603319535582, 3.64307859473147, 3.82376878676735, 3.98146838364582, 4.09657047290969, 4.15499346058377, 4.1517496628285, 4.09270922164694, 3.99366908179732, 3.87661632903924, 3.76411314559936, 3.67354609522914, 3.61312891117978, 3.58091542042977, 3.56697352847246, 3.55780953480374, 3.5415295746332, 3.51220786974913, 3.47236791686811, 3.43313995978013, 3.41233447772712, 3.43122560623353, 3.51114100479252, 3.67084734284009, 3.92507291045114, 4.28341510257027, 4.7478964843256, 5.30754978786203, 5.93043527381376, 6.55696650273776, 7.10104395721, 7.46427310426379, 7.56255284606779, 7.35557738013864, 6.86196038307621, 6.15304848396789, 5.34327441137094, 4.57152433930050, 3.96810557914353, 3.64138288183969, 3.67392464937056, 4.09648924847856, 4.84588750848624, 5.74842726648532, 6.57196816801213, 7.13324412294515, 7.38066468123711, 7.38371069389517, 7.248609170289, 7.04312311469008, 6.78370353949187, 6.46766489515861, 6.10416658622602, 5.72067473273998, 5.35179661123596, 5.02614602315886, 4.75974206394064, 4.55613964643839, 4.41011822849517, 3.14088432885009, 3.40359917705138, 3.60676320845211, 3.71960444213394, 3.71528688548001, 3.58015524186393, 3.32322138250247, 2.98084383715788, 2.61173596445998, 2.28151755556621, 2.04230118498996, 1.91678609161437, 1.89430358438933, 1.93921235769805, 2.00566091536894, 2.05229383899859, 2.05480224872650, 2.01586296148607, 1.96704779427740, 1.95444225699088, 2.01067486525502, 0, 0, 0, 0, 2.63046977257235, 2.68761707105262, 2.73131412714189, 2.76740277983112, 2.7973598705751, 2.82054288285505, 2.83628371181846, 2.84531322049920, 2.85060794524701, 2.85773040371859, 2.87461539336677, 2.91072618821718, 2.97557550025195, 3.07674910182225, 3.21774786156653, 3.39612110497025, 3.60243417321788, 3.82054361311801, 4.02943047659954, 4.20649467786359, 4.33180243812622, 4.39239221904954, 4.38550405034041, 4.3196508557569, 4.21290698684653, 4.08860583105834, 3.96955400571817, 3.87248498440708, 3.80447002321572, 3.76234600704290, 3.73519490467666, 3.70895278079344, 3.67168053857061, 3.61800484306997, 3.55163866472917, 3.48552765015361, 3.43985953795976, 3.43876635667718, 3.50688042295492, 3.66677424239622, 3.93755705020269, 4.33362279088033, 4.86140760298578, 5.51221376158566, 6.25167628668956, 7.0107485466791, 7.68636582716565, 8.15857467932695, 8.32392641277419, 8.13303033492234, 7.60407266339695, 6.80754237417285, 5.87203188539307, 4.97482452146988, 4.27840895676929, 3.90697327036445, 3.95290597301953, 4.44847755811869, 5.31366579762761, 6.33599514655835, 7.23512075028946, 7.79514546332882, 7.96582382924355, 7.8475177025166, 7.58454513129263, 7.26987077385593, 6.92758545030435, 6.5522189626106, 6.14789388996675, 5.73821695174993, 5.35484165202111, 5.02337714302335, 4.75663052458874, 4.55522559502561, 4.41180256215167, 2.93069002877573, 3.16621342559867, 3.34373683134264, 3.43318235805533, 3.40826793780982, 3.25614003066633, 2.98735867467201, 2.64079346962257, 2.27817174168776, 1.96745478985646, 1.76103502094789, 1.67901820699985, 1.70554033378606, 1.79833547838306, 1.90493548549391, 1.97870949522303, 1.99288123623077, 1.95210968295862, 1.89492051108615, 1.87682083260713, 1.93713255340154, 0, 0, 0, 0, 2.59725770492085, 2.64283211169289, 2.67195370394137, 2.69311324055598, 2.70979527898147, 2.7229103368618, 2.73302225583074, 2.74180300920132, 2.75286732365775, 2.77210521750345, 2.80747323165808, 2.86815266091363, 2.96304881818309, 3.09876039539758, 3.27735207895690, 3.49445256099218, 3.73829065635408, 3.99020139693295, 4.22685534517716, 4.4240289292659, 4.56124482128938, 4.62621212607346, 4.61783819639964, 4.54678699385445, 4.43315084203131, 4.30165808334177, 4.17567513369992, 4.07173431754297, 3.99619950990590, 3.94499474860153, 3.90634288389397, 3.86557113813202, 3.81053130875373, 3.73615530029516, 3.64704836127708, 3.55765348101761, 3.49023127474187, 3.47152649555714, 3.52934390076991, 3.69009392396166, 3.9774965673251, 4.41116734591979, 5.00251940851281, 5.74570237870044, 6.60433425266361, 7.49995654330209, 8.3121489408904, 8.89881773227751, 9.13752183331333, 8.97237491897058, 8.41976971319293, 7.53518171888935, 6.454696568358, 5.40988158394625, 4.60666567155930, 4.18227345899916, 4.23424138050449, 4.79430784416509, 5.76646354257127, 6.9030624058498, 7.88006861955056, 8.45106418152925, 8.56465289259888, 8.3459930578016, 7.97126675834142, 7.5552694545348, 7.1298401338749, 6.68900870762301, 6.23466480775634, 5.7888669128835, 5.38182586208392, 5.03692528806415, 4.76399385430463, 4.56060925389635, 4.41697980425133, 2.7274852158865, 2.93723317171141, 3.09112835111875, 3.16010727726025, 3.11873537454509, 2.95504413748439, 2.68080988036966, 2.33656658682861, 1.98582366888244, 1.69764167467021, 1.52391323912367, 1.48216566262718, 1.55217416248747, 1.68644742194713, 1.82749402365235, 1.92481678573146, 1.94996454042724, 1.90927102081138, 1.84661977158542, 1.82466243205682, 1.88777976283807, 0, 0, 0, 0, 2.57079596354694, 2.60542685674782, 2.62130990575043, 2.62908531742244, 2.63392769034692, 2.6380966866048, 2.64324402593544, 2.65187496842788, 2.66816427320271, 2.69828003694764, 2.75018124605378, 2.8327831760547, 2.95444614757391, 3.12090783078064, 3.3330046128452, 3.58474228595963, 3.86238389659017, 4.14513395455165, 4.40767755069159, 4.62433020106473, 4.77400441484487, 4.84478630137484, 4.83681507476603, 4.76247083719335, 4.64357134456754, 4.50617095284446, 4.37434210545033, 4.26469479606899, 4.18318634587034, 4.12505917859546, 4.0777899217226, 4.02608222955441, 3.95744882348718, 3.86690012877755, 3.7596302502574, 3.65122542430324, 3.56565198718497, 3.53193606886032, 3.58081098936982, 3.74241011524621, 4.04509898673008, 4.51389868426603, 5.16551898675086, 5.99739382448138, 6.97165568619586, 8.00103986376478, 8.94847456448094, 9.65067976917799, 9.96796533248832, 9.84062154842272, 9.2803304190552, 8.31181349570841, 7.07101984454836, 5.85893378113683, 4.93595881691178, 4.44879194102041, 4.49363473115277, 5.09852130023022, 6.15372499197171, 7.38442652038774, 8.43301714227922, 9.02827613119029, 9.11448023249484, 8.83120347999217, 8.37531980897472, 7.87710817838605, 7.37578403470041, 6.86809642489001, 6.35761803332862, 5.86789173145916, 5.42953762962525, 5.06464548146878, 4.78039980384675, 4.57131161987348, 4.42495114215577, 2.53421118462931, 2.72011615943038, 2.85300341923453, 2.90519804947298, 2.8524547816582, 2.68377248987657, 2.41171291156281, 2.07740899897806, 1.74461953702026, 1.48198082103023, 1.33997150105553, 1.33365527620950, 1.43961853732567, 1.60704419943099, 1.77556464509530, 1.89270276793779, 1.92934165105760, 1.89291040921661, 1.83020216873038, 1.80759494298872, 0, 0, 0, 0, 2.48918136174444, 2.55079919421979, 2.57470342535592, 2.57858429936695, 2.57455206695902, 2.56906215395669, 2.56547874957470, 2.56637675969028, 2.57497128364860, 2.59590277891122, 2.63554962511253, 2.70183323108199, 2.80339648661491, 2.94809482168631, 3.14091118526168, 3.3816478618729, 3.66298268315183, 3.96959827886201, 4.2789995449002, 4.56428374981886, 4.79857591982774, 4.96024688746697, 5.03760665174635, 5.03170389169992, 4.95625205328373, 4.83447318828757, 4.69357418024436, 4.55832856531413, 4.44554736441134, 4.36096044652253, 4.29929176407554, 4.24736788616121, 4.18927021115577, 4.11206710204873, 4.01063409281969, 3.89044146387618, 3.76782996428519, 3.66804596066751, 3.6219832629581, 3.66294698093175, 3.82451931745257, 4.13952255864519, 4.63827836505577, 5.34280626769745, 6.25406131366127, 7.33332550333899, 8.48576890707182, 9.55971539433808, 10.3735166357038, 10.7727078610951, 10.6930690611438, 10.1359405665549, 9.08837608148785, 7.68402161160696, 6.29697388798957, 5.24619361042816, 4.68669985211064, 4.70767134447054, 5.32949185407167, 6.43197890030913, 7.72458186520583, 8.8306989938654, 9.46301834708647, 9.55807082573969, 9.25644248629193, 8.76092011991896, 8.20868547774631, 7.64550075596836, 7.07458069482475, 6.50572447270615, 5.9673439641739, 5.49244409481865, 5.10280631156478, 4.80338220757185, 4.58570674242587, 4.43462614717222, 2.35320236345218, 2.51756446465764, 2.63245862005482, 2.67199107681924, 2.6134641760817, 2.44691916067040, 2.18521635023211, 1.86890700388932, 1.56031273704002, 1.32598412550823, 1.21401696490579, 1.23720035374202, 1.37030516615607, 1.56137197042896, 1.74960621534692, 1.88268618061421, 1.93193945491839, 1.90515253793803, 1.84912172238643, 1.82993107971309, 0, 0, 0, 0, 2.48511060022732, 2.53660229848625, 2.54977908093329, 2.54283544688290, 2.52858142972784, 2.51429791687079, 2.50418805830229, 2.50157348631018, 2.51024509075478, 2.53520221405369, 2.58295047358448, 2.66131575046851, 2.77864240189102, 2.94230097594528, 3.15660784748144, 3.42051220827332, 3.72565471631403, 4.05553328572906, 4.38641567853637, 4.69026813550976, 4.93938466365049, 5.11177545164295, 5.19593925838841, 5.1936078157627, 5.11949095930829, 4.99787278873228, 4.85685464321291, 4.72178203206265, 4.6096612140301, 4.52607066440634, 4.46531820701356, 4.4136560485275, 4.35454962492979, 4.27452919571564, 4.16812485273032, 4.04075638948042, 3.90909746152691, 3.79919734737178, 3.74333162683068, 3.77691784557464, 3.93656105113424, 4.25912804204893, 4.77983570282564, 5.52569400911278, 6.50117789215991, 7.66742310927255, 8.92392172117137, 10.1079147264498, 11.0243124716946, 11.5067932349023, 11.4805228065412, 10.9270898506646, 9.8026615257441, 8.24438222099197, 6.69454395836211, 5.51505869528966, 4.87617964673346, 4.8567904808988, 5.46503337889872, 6.57373944723597, 7.88970766312196, 9.03413483060018, 9.71401195893566, 9.85508545376471, 9.58471511334539, 9.095581327482, 8.52230175444343, 7.91599694728247, 7.28999439373371, 6.66475011300998, 6.07674461112536, 5.56317218323831, 5.14641925580262, 4.82965873133224, 4.60166105903879, 4.44460963105653, 2.18615401155911, 2.33147512138044, 2.43154169420566, 2.46260933011599, 2.40386425436048, 2.24644935215608, 2.00303107914507, 1.71240547069632, 1.43379099086349, 1.23002367769882, 1.14588922189432, 1.19213653011999, 1.34313498009064, 1.54798979332901, 1.7479225041859, 1.89286390467722, 1.95564749913148, 1.94366212853676, 1.90084817663536, 1.88906900726808, 0, 0, 0, 0, 2.48784666611036, 2.52709547937699, 2.52959749029701, 2.5130221393433, 2.49013269286312, 2.46859140817617, 2.45317798024781, 2.44778267523289, 2.45663309830342, 2.48497255862730, 2.53933978121376, 2.62739344549079, 2.75713763181817, 2.93546176168889, 3.16608852341744, 3.44728292377754, 3.76993327084702, 4.11675286557328, 4.46325507310223, 4.78077355799657, 5.04119650418263, 5.22244018213885, 5.31324921244186, 5.31588952319771, 5.24577094087536, 5.12788693888328, 4.99091535134283, 4.86055247755703, 4.75389549975115, 4.67636572861515, 4.62190407330455, 4.57623836045583, 4.52221561879092, 4.44572973846253, 4.34074487938065, 4.21228372201708, 4.07690037292331, 3.96092807781107, 3.8974825291285, 3.9235550622725, 4.07822609015741, 4.40180742155019, 4.93374146089095, 5.70540039138742, 6.72453365070441, 7.95285430415555, 9.28661820836957, 10.5568841213412, 11.5622193707845, 12.1287247044626, 12.1620530366758, 11.6107725539074, 10.4051631085523, 8.68345432942746, 7.02347246399391, 5.71910527234693, 4.99828576767851, 4.92698237870272, 5.49535618688456, 6.57205202076107, 7.87377466771425, 9.03575846498451, 9.76971586172651, 9.98861363845765, 9.79407144274035, 9.35420404553007, 8.79232330782743, 8.16350998948944, 7.49405676064897, 6.81857485423036, 6.1840483350735, 5.63318717116485, 5.18969520104399, 4.85542545838042, 4.61671685907145, 4.4533129466213, 2.03412859237132, 2.16294815403227, 2.25126199369108, 2.27777633894250, 2.22383731952961, 2.08172463790495, 1.86346259351669, 1.60504663477616, 1.3611192420883, 1.18937478351013, 1.13049903436992, 1.19345322961877, 1.35350309745098, 1.56279533783913, 1.76670514269714, 1.91919806484991, 1.99548194827741, 2.00190943286615, 1.97723168393029, 1.97591662420701, 0, 0, 0, 0, 2.4951692111281, 2.52078918319345, 2.51298060946788, 2.48805384989154, 2.4581103363518, 2.43081474911840, 2.41128659175990, 2.40381458353105, 2.41292446225033, 2.44398520997621, 2.50346834119990, 2.59878518700403, 2.73754761734534, 2.92615644164646, 3.16780200575315, 3.46022317599021, 3.79383220271446, 4.15095459311913, 4.50683847266356, 4.83270470944862, 5.10050075183307, 5.28837297808136, 5.3854353022629, 5.39439940106919, 5.33111632098913, 5.22093931807658, 5.09277219945559, 4.9723828477099, 4.87678807554634, 4.81118552065404, 4.76915189863359, 4.73590799516898, 4.69365554232599, 4.62753128801385, 4.53068864516324, 4.40737955411096, 4.27355705274528, 4.15528862515246, 4.08595428320877, 4.10353683033133, 4.24897731368991, 4.56532043656676, 5.09538785409189, 5.87405558847084, 6.91188969707187, 8.17185752617379, 9.54974948636217, 10.8762681763014, 11.952408152049, 12.6034921614212, 12.7095963821235, 12.1709315848717, 10.8994407405519, 9.0529224721195, 7.25905811148125, 5.83390609751141, 5.03549854409491, 4.910162793399, 5.42276893061381, 6.4394150709056, 7.6968941820341, 8.85767141569128, 9.64708352957119, 9.9648884403333, 9.87839682169243, 9.52071714981243, 8.99726862434646, 8.36564109858221, 7.66657675861329, 6.9507327013967, 6.27679803310619, 5.6936048765709, 5.22658544932844, 4.87670088373727, 4.62830297322504, 4.45907971083568, 1.89759724653608, 2.01234788772209, 2.09168647630904, 2.1169698760942, 2.07188901234193, 1.94986508460679, 1.76191744456867, 1.54042360994558, 1.33431244279957, 1.19505003456062, 1.15864831803422, 1.23252920949391, 1.39391012833550, 1.59952608185143, 1.80051068839159, 1.95613042611781, 2.04454263877208, 2.07063442719238, 2.06648430457382, 2.07718441480537, 0, 0, 0, 0, 2.50427129385027, 2.51599757566291, 2.49871661128628, 2.46684615136025, 2.43141344257659, 2.39980775719830, 2.37729289934151, 2.36840100778523, 2.37782274467254, 2.41093582902773, 2.47404331798631, 2.57422643791626, 2.71864887251054, 2.9132097939168, 3.16062113666318, 3.45824396799634, 3.79627896411591, 4.15704839362882, 4.51601528462398, 4.84480709970159, 5.11590911136409, 5.30805138857643, 5.41088291447177, 5.42751865397792, 5.37402953698831, 5.27579753473932, 5.16159731615537, 5.05696452285448, 4.9786273648358, 4.93145180898637, 4.90861148197413, 4.8947964189187, 4.87149484878442, 4.82292418801489, 4.7411427656167, 4.62922325384856, 4.50200793757161, 4.38472891306743, 4.3104448794834, 4.31754895489206, 4.44823537740554, 4.74756632186432, 5.26085547990002, 6.02552527065688, 7.05435734275163, 8.31212574174283, 9.69689217458477, 11.0448780986016, 12.1684832062527, 12.9008728510732, 13.0965274769561, 12.5938710758196, 11.2815905491785, 9.35431859210125, 7.37201844220321, 5.83387479738699, 4.97294605927871, 4.80407978508779, 5.25901936966817, 6.20213152039266, 7.39712114048219, 8.54227831408041, 9.38293115161734, 9.80698897256262, 9.8441012175374, 9.58739812309495, 9.12083798221783, 8.5031409344399, 7.78931966290077, 7.04601078133739, 6.34334502642348, 5.73605107402748, 5.25135079591565, 4.88968450624849, 4.63395222526803, 4.46031439738531, 1.77650917173984, 1.87940622365401, 1.95210248770907, 1.97868398474010, 1.9452620837687, 1.84637084165127, 1.69177444875207, 1.50970681080349, 1.34267041193203, 1.23524378036628, 1.21845484513846, 1.29841503575975, 1.45502888006276, 1.65062233126866, 1.84304345324694, 1.99752284218379, 2.09541473278899, 2.13995483008131, 2.15601676271013, 2.17866130479253, 0, 0, 0, 0, 2.51230805597391, 2.51108016294049, 2.48566250854132, 2.44837440418327, 2.40897833276683, 2.37442197046277, 2.34996485106885, 2.34024662480189, 2.34999889640925, 2.38449695752686, 2.44977846208635, 2.55251516446994, 2.69936890734359, 2.89572455721868, 3.14386634819420, 3.4409171826444, 3.77711515175976, 4.13514205947947, 4.49113115491975, 4.81761398595632, 5.08808044272563, 5.28220198302789, 5.39034991925628, 5.41603481382573, 5.37536570352238, 5.29345684077655, 5.19862084004685, 5.11586346778194, 5.06140605659799, 5.03964985944301, 5.04328784731348, 5.0564051824568, 5.05965000662126, 5.03609814005259, 4.976374031422, 4.88191947395619, 4.76592778054468, 4.6522150609483, 4.57294664463384, 4.56639448258106, 4.67549288587896, 4.94673647535492, 5.42717392763591, 6.15588864796632, 7.14723478051295, 8.3681433705429, 9.72120493476256, 11.0529201745332, 12.1940138300532, 12.9928987730693, 13.2830122579865, 12.8349631100172, 11.48647895911, 9.44698520435983, 7.32275055170774, 5.69512775242125, 4.80167390963627, 4.61296075849017, 5.02209237398498, 5.89283992961107, 7.0193265999462, 8.13934318241592, 9.02172831443447, 9.54553941684167, 9.7046600652096, 9.56098050078914, 9.15220994888641, 8.56131597664301, 7.84767438489529, 7.09193258388646, 6.3739938793188, 5.75346890696851, 5.25909473767731, 4.89109147719361, 4.6315036494888, 4.4556017803458, 1.67037933889657, 1.76335171712258, 1.83121894670606, 1.86074999079595, 1.84044031119523, 1.76587639243934, 1.64543967509192, 1.50300672075006, 1.37439262076982, 1.29708057588848, 1.29707878527945, 1.37938898312202, 1.52699589373580, 1.70825513084903, 1.88803890907202, 2.0376320344437, 2.14153615651960, 2.20137147136424, 2.23511398950068, 2.26829523651567, 0, 0, 0, 0, 2.5169054403656, 2.504661847782, 2.47283370903927, 2.43171755865972, 2.38981224674195, 2.35355585813413, 2.32809840592153, 2.31807106528536, 2.32813432302842, 2.36335948402351, 2.42943097788537, 2.53254077121636, 2.67880359336745, 2.87308331135043, 3.11728789859888, 3.40843385445842, 3.73702651369883, 4.08643905923348, 4.43389059565212, 4.75327260604256, 5.01951209907872, 5.21356177769464, 5.32670686181397, 5.36287238125814, 5.33806678391916, 5.27689013265322, 5.20690621227528, 5.15232618555997, 5.12865890796121, 5.13969603481176, 5.17753483094664, 5.22552141953563, 5.26326277410553, 5.27239389772408, 5.24169920645492, 5.17048801685093, 5.06973677566776, 4.96125947892874, 4.87578781582479, 4.8510352275608, 4.93034528706804, 5.16133280976874, 5.59234181901631, 6.26349468222401, 7.19015459990983, 8.3415023781885, 9.62602893758016, 10.9030887851826, 12.0244562609207, 12.856603110322, 13.2178525330765, 12.8174074428160, 11.4372897007839, 9.2975347896573, 7.0724873994259, 5.40441527285881, 4.52439853836277, 4.34941711383963, 4.73401929730131, 5.5441480960504, 6.60529831695207, 7.69427598658427, 8.60442861133145, 9.2100947240149, 9.4756677771742, 11.0070105074411, 9.0863562861471, 8.531079385428, 7.83197710039442, 7.07995549421753, 6.36193219115038, 5.74077617616276, 5.24619822643, 4.87842616133017, 4.6192686790549, 4.44380610638197, 1.57838429201714, 1.66304686434006, 1.72737466217328, 1.76066170032533, 1.75365120256807, 1.70289559915564, 1.61538229498841, 1.51070727893428, 1.41815532578149, 1.36832181038292, 1.38240821927248, 1.46447594315356, 1.60066726045558, 1.76530397761755, 1.93004421022512, 2.07186175603605, 2.17813668369441, 2.24907205732595, 2.29664088583873, 2.33814399763739, 0, 0, 0, 0, 2.51647733084520, 2.49576878804313, 2.45945900534221, 2.41608610775369, 2.37301684845839, 2.33618110069259, 2.31054767871754, 2.30064172969243, 2.31095412142299, 2.34626329032706, 2.41182583708335, 2.51329757626183, 2.65621452178116, 2.84492373204992, 3.08101253096381, 3.36151561361129, 3.67741302027234, 4.01306232081835, 4.34713174188077, 4.65527031222434, 4.91422177476704, 5.10652439135911, 5.22455982376708, 5.27270720664495, 5.26678253831666, 5.23068827755951, 5.19101842242827, 5.17097920478782, 5.18519195265323, 5.2366918022505, 5.31682747475204, 5.40800261141339, 5.48849348490946, 5.53810509157051, 5.54330048223133, 5.50070259940333, 5.4184736963565, 5.31583532546797, 5.22158545177214, 5.17256700636295, 5.21245897178684, 5.3900884301228, 5.75515205323046, 6.34863961568705, 7.1865670699185, 8.2401899649041, 9.42416182084014, 10.6105759207556, 11.6699498219255, 12.4837340515773, 12.8608484137322, 12.4696535813820, 11.0571372616460, 8.85943104739656, 6.60606167202327, 4.97223906717111, 4.16182448696471, 4.03658677007398, 4.41994529255244, 5.18496561967392, 6.18782536680549, 7.24105247248146, 8.16169149683667, 8.82391262182217, 9.17060437912843, 9.79474366912428, 8.92270736532926, 8.40963317250536, 7.73835843434309, 7.00623724458038, 6.30382848665447, 5.69529138908518, 5.21060478320733, 4.85016458847983, 4.5961447130041, 4.42414122563700, 1.49945678734891, 1.57711804384436, 1.63872653839866, 1.67585748650205, 1.68128907447904, 1.65243613979010, 1.59497792160065, 1.52454297795299, 1.46437982506593, 1.43873498963183, 1.4644103412092, 1.54466405066029, 1.66861862290093, 1.81611233409004, 1.96495790604231, 2.09715888788684, 2.20258176331726, 2.28030159375940, 2.33747517157711, 2.3848496722315, 0, 0, 0, 0, 2.51029596657563, 2.48385775494629, 2.44499383857533, 2.40083270476060, 2.35780176757706, 2.32136052123693, 2.29624680082857, 2.28679806365053, 2.29725142244545, 2.33201844985901, 2.39586964009487, 2.49388603828370, 2.63101113778332, 2.81109411142833, 3.03546413208480, 3.30129213799474, 3.60021558509235, 3.91782465058201, 4.23453804551324, 4.52808929764088, 4.77735180050369, 4.96670510263903, 5.08979104988904, 5.15149914153371, 5.16741071782829, 5.16061982677224, 5.15660978206894, 5.17744139734991, 5.23671655737288, 5.33657118992896, 5.4674131324302, 5.61042236348722, 5.74215586709215, 5.84010316003595, 5.88785151598753, 5.87873948436238, 5.81749459396392, 5.72014943851274, 5.61310253981775, 5.53214760483436, 5.52152777135892, 5.63187815819184, 5.91494836058505, 6.41303116586691, 7.14276172598473, 8.07707261126662, 9.13598034426014, 10.2018577139994, 11.1577113811886, 11.8926176312343, 12.2118249254316, 11.7739993739031, 10.3295921089896, 8.139582042131, 5.95619572057033, 4.44267829180161, 3.75534050456659, 3.70815152318242, 4.10727852212514, 4.83925528109783, 5.78917659094294, 6.80059597089343, 7.71242226625984, 8.40287439532384, 8.80217113155368, 8.8860650242433, 8.66768650706328, 8.2006960587575, 7.56900450703507, 6.87187353861381, 6.20002465857028, 5.61687894288707, 5.15192516505756, 4.80582795158565, 4.56166629048139, 4.39620651601538, 1.43237228746685, 1.50406714194092, 1.56339949615569, 1.60392888646832, 1.62020928745191, 1.61040816286244, 1.57905290487032, 1.53828082260547, 1.50602619452782, 1.50094527864752, 1.53596934680369, 1.61365765620337, 1.72575844791200, 1.85692899576568, 1.99028246989441, 2.11206116292724, 2.21419403668266, 2.29494547643291, 2.35787986817062, 0, 0, 0, 0, 0, 2.4983583645165, 2.46875753031928, 2.42909910731742, 2.38544837088782, 2.34348968987344, 2.30825879815419, 2.28422458712786, 2.27546851686572, 2.28590437705771, 2.3195190756803, 2.38055702438073, 2.47350608663771, 2.60272391919892, 2.77159798891926, 2.98127052179582, 3.22916070650597, 3.50772003197963, 3.80397117013846, 4.10031699510367, 4.37682420628588, 4.61473345151534, 4.80046437964433, 4.92905744897372, 5.00598212426463, 5.04659339539922, 5.07314368131692, 5.10995272546462, 5.17787407257413, 5.2894083193513, 5.44565616776305, 5.63584922602454, 5.83957699482984, 6.03118323053453, 6.18526422475194, 6.28192307165544, 6.31059952492682, 6.27196244591415, 6.17825010898878, 6.05300647185257, 5.93090549080871, 5.85728683592661, 5.88573889448707, 6.07149429633454, 6.45929274337035, 7.06676292486413, 7.8679818870619, 8.78675350972279, 9.711981706078, 10.5315463908670, 11.1340851389619, 11.3275108041878, 10.7943680316534, 9.32967282898245, 7.2240996664462, 5.21022145325165, 3.89116674798176, 3.36195431154378, 3.40402025868286, 3.82333245673302, 4.52573028499586, 5.42248851594828, 6.38316700839612, 7.26632336240472, 7.95751136448811, 8.38198559939036, 8.50488664458807, 8.33272288758558, 7.91415882224313, 7.3317748635362, 6.68257812343122, 6.0543074146674, 5.50780472562043, 5.07135677498206, 4.74594458488367, 4.51599249457905, 4.35998777388975, 1.37582314148465, 1.44235951176019, 1.49959095977461, 1.54274578942494, 1.56787965105252, 1.57380769075585, 1.56410354311551, 1.54797433053553, 1.53887400582627, 1.55072761017196, 1.59316965081921, 1.66812988874313, 1.76952804602821, 1.88602882597932, 2.0051223290515, 2.11650113132646, 2.21377140551706, 2.29469136189550, 2.36032433055767, 0, 0, 0, 0, 2.49859643589447, 2.48114729666650, 2.45056413467425, 2.41160097827543, 2.36954969740515, 2.32951523024998, 2.2961473924465, 2.27361335353661, 2.26568169136098, 2.27588764120952, 2.30775226786186, 2.36497301027632, 2.45144735654128, 2.5709754131927, 2.72653742885273, 2.91916939736611, 3.14664509556696, 3.40236033472388, 3.67492085418472, 3.9488778639063, 4.20679894767227, 4.43245087521633, 4.61443142793509, 4.74928898343998, 4.84315279725952, 4.91120848993955, 4.97491096218256, 5.05745267877949, 5.17849851856086, 5.34941698254553, 5.57014225216724, 5.82844510732893, 6.10186384317467, 6.36192825266677, 6.57968992847393, 6.73115046602325, 6.80127922754853, 6.7861026225879, 6.69345147517189, 6.54352654186786, 6.36985342326598, 6.21964714982411, 6.15111637802044, 6.22514012934982, 6.49078024918842, 6.96747933955074, 7.62989283514535, 8.40364352013914, 9.18037379998823, 9.8466744135374, 10.2855391435888, 10.3143949476916, 9.6664009030031, 8.20967378558434, 6.26018608041607, 4.49037510358825, 3.40668317787488, 3.04075612553028, 3.16159226030582, 3.5909276173844, 4.25718501274439, 5.09403058715656, 5.99232890791816, 6.82807859725506, 7.4962056864029, 7.92255880908457, 8.06796574818454, 7.9340145580762, 7.56509909590137, 7.03920511911996, 6.44785715134165, 5.87330536157647, 5.37233597506213, 4.97143968716634, 4.67191339561957, 4.45983767361976, 4.3158265813969, 1.32847894222033, 1.39048803496155, 1.44563259035269, 1.49050633393587, 1.52240587355204, 1.54070393209805, 1.54823429323292, 1.55184898664591, 1.56136199381108, 1.58681801106845, 1.63510224338895, 1.70754522931699, 1.7997493324903, 1.90357132606927, 2.0100042090987, 2.11149919284358, 2.20303886458939, 2.28214974862465, 2.34827536096727, 0, 0, 0, 0, 2.47772947694326, 2.45938712743726, 2.42953236309223, 2.39244736370943, 2.35286249881562, 2.31541985095754, 2.28440516832705, 2.26365329027946, 2.25657324257794, 2.26628024131742, 2.29580457169627, 2.34829453516536, 2.42708085338430, 2.53545549488122, 2.67606383001568, 2.84992558371957, 3.05526994847046, 3.28654179727896, 3.53403264657306, 3.78453864861364, 4.02321699607095, 4.23644206636322, 4.41506709485808, 4.55722688830908, 4.66979703721869, 4.76789446423048, 4.87229223448571, 5.00517528264662, 5.18511366227674, 5.42235877829222, 5.71554468771339, 6.0506371784326, 6.4025586053153, 6.7393207887896, 7.02774258394759, 7.23917817084513, 7.35370077484042, 7.36222891192322, 7.26757535542422, 7.08601100363595, 6.84981490642998, 6.60897852613645, 6.42840251502251, 6.37740753868595, 6.51191051733564, 6.85441508931346, 7.3796439948058, 8.01300317201422, 8.64589264030354, 9.1605840078726, 9.433882504481, 9.29926255494085, 8.55423382026633, 7.1477690928431, 5.40678197834047, 3.91428501754484, 3.06418631125657, 2.8354573679138, 3.00551652486643, 3.42326100555404, 4.03931676532813, 4.80502987441205, 5.6284689535018, 6.40103545275006, 7.0278073037093, 7.43854000572773, 7.59354967041763, 7.49153373762878, 7.17220769081254, 6.70702076771977, 6.1798050577098, 5.66561204515428, 5.21615488446086, 4.85569325464417, 4.58579452480237, 4.39435952263885, 4.26436522310411, 1.28903354024552, 1.3470165869893, 1.40001838442632, 1.44573110124208, 1.48246723269283, 1.51008979067056, 1.53090224729185, 1.54993512484811, 1.57412613455558, 1.61039603365406, 1.66334409265717, 1.73368655148299, 1.81823154321226, 1.91128706121808, 2.00660349393934, 2.09885118695899, 2.18419709251151, 2.26018243064254, 2.32529584589393, 0, 0, 0, 0, 2.45134425318502, 2.43385932185581, 2.40599123998748, 2.37167144121148, 2.33520574762311, 2.3008446279568, 2.27251603231286, 2.25369369122068, 2.24738995329613, 2.25627146321668, 2.28286796220143, 2.32979379976205, 2.39985562556477, 2.49590585299694, 2.62034327882711, 2.77426925425175, 2.95646356772239, 3.16250091893084, 3.38441696217958, 3.6112870033271, 3.83087353738269, 4.03216804285098, 4.2082991009094, 4.35903551598269, 4.49208820962468, 4.62264155726228, 4.77096296437984, 4.9584207711161, 5.20264735977708, 5.51282651811249, 5.88614381601368, 6.30634112303107, 6.7450432804349, 7.1659454347636, 7.53096745720493, 7.80646286291578, 7.96748325037485, 7.99961175217142, 7.90005944464966, 7.68040185187624, 7.37135072483379, 7.0265064044373, 6.71972388819803, 6.53197184899673, 6.52903048490644, 6.73805998522611, 7.13346618617274, 7.63853618090317, 8.14245770509429, 8.52321985625904, 8.65492275691076, 8.39214884305961, 7.59671039143536, 6.28664635544501, 4.77954066854441, 3.55520669943093, 2.90032685420737, 2.76097901635789, 2.94061183024626, 3.32057330461252, 3.87002543860800, 4.5528798731979, 5.29098056738028, 5.98927304035438, 6.5627404891082, 6.94645536258757, 7.10223285197093, 7.02706258934952, 6.75581501032446, 6.35237107099348, 5.89170157513582, 5.44076935257165, 5.04567725145219, 4.72819060528927, 4.49006071813468, 4.32102276863074, 4.20647640443917, 1.25624030360506, 1.31060775691633, 1.36141056070413, 1.40722473778967, 1.44720408162005, 1.48166286768850, 1.51256619909665, 1.54357829427647, 1.57939199426391, 1.62440750670214, 1.68127694174955, 1.75003464276783, 1.82825638122995, 1.91208077489821, 1.99744130408185, 2.08086455219464, 2.15962762594591, 2.23151802404519, 2.29455355700041, 0, 0, 0, 0, 2.42073372771172, 2.40529758182597, 2.38029222323388, 2.34936590433156, 2.31647754649424, 2.28552204454185, 2.26006465369887, 2.24319211234791, 2.23749209767720, 2.24516595771293, 2.26824669306665, 2.30884504486796, 2.36930256899639, 2.45211665790091, 2.55954065869373, 2.69286108369783, 2.85149733861128, 3.03221282029364, 3.22880637185471, 3.43261190252393, 3.63394888374743, 3.82437185143262, 3.99925283763219, 4.16001209004611, 4.31528210933897, 4.48047517213112, 4.67557390783204, 4.92137418223268, 5.23477339858561, 5.62395510151678, 6.08447633757187, 6.59734256535088, 7.13006868330411, 7.64115444326442, 8.08705489029211, 8.42912050499299, 8.63775560273426, 8.69337461058996, 8.58707021348233, 8.3246915401444, 7.93466230797674, 7.47471378265132, 7.0298044543094, 6.6958273182291, 6.55161694907472, 6.63080340841573, 6.90729218174897, 7.3006110364242, 7.69648913570317, 7.97036705789654, 7.99881326199578, 7.66012948834808, 6.87041571020083, 5.69367369168079, 4.41847378519406, 3.42237820331211, 2.90465984299650, 2.80072908219947, 2.95157304312457, 3.27069835831637, 3.74034924914542, 4.3322448455849, 4.97921371159353, 5.59800629854559, 6.11258249573004, 6.46343666439151, 6.61462478405522, 6.56203368477586, 6.33580039479886, 5.99203231790645, 5.59660702481531, 5.2082541080984, 4.8673720245234, 4.59313094505726, 4.3873443940084, 4.241457568315, 4.14318753565034, 1.22893752346215, 1.28003950319424, 1.32863344628759, 1.37402502528539, 1.41609264980611, 1.45559383478089, 1.49432297712145, 1.53493603152758, 1.58035135876304, 1.63286807787271, 1.69338266751314, 1.76112086956132, 1.83403646950529, 1.90961625493292, 1.98558754652073, 2.06014982511333, 2.131733641375, 2.19860680168126, 2.25866989477328, 0, 0, 0, 0, 2.38696514967807, 2.37434974724438, 2.3527852161458, 2.32566669228692, 2.29664331452775, 2.26926745734447, 2.24673103621401, 2.23171223106684, 2.22635480760866, 2.23238867388055, 2.25136550175786, 2.28493515352429, 2.33504574540716, 2.40393594169488, 2.49382343249508, 2.60628594035165, 2.74146441246969, 2.89735018604688, 3.06949097858768, 3.25141319218737, 3.43589192565623, 3.61693763521817, 3.79208924728295, 3.96440707120976, 4.14352259350775, 4.34524717222693, 4.58952479568825, 4.89685375544058, 5.28362265198176, 5.75708032898116, 6.31092564941276, 6.92280465550127, 7.55517039857036, 8.16039270915537, 8.68908874512601, 9.0981289340105, 9.3543589434394, 9.43375234944676, 9.3208832533337, 9.01450450360187, 8.53946500541417, 7.95758407672075, 7.36659702754773, 6.88022841194575, 6.59335524097765, 6.54793781702217, 6.71749519509717, 7.01657626809259, 7.32657188195435, 7.52218282825858, 7.48675694897398, 7.12206598466895, 6.38414806537986, 5.3585102382366, 4.2913022242345, 3.46941113999732, 3.02982512733957, 2.91562247074262, 3.00970677890596, 3.25365441502007, 3.63731721118023, 4.1364808410929, 4.69271842014371, 5.23289777597018, 5.68867528106453, 6.00536056710982, 6.1492544315125, 6.11543283433204, 5.92968687297854, 5.64081808195374, 5.30613408532858, 4.97659413101387, 4.68716579359682, 4.45446210394022, 4.28021107405351, 4.15732945633887, 4.07560828637782, 1.20606565288663, 1.25421421282435, 1.30066231864060, 1.34535251309758, 1.38882993234567, 1.43231836345282, 1.47758328423813, 1.52652944811658, 1.58060424229874, 1.64023439342099, 1.70459891933358, 1.77192509955108, 1.8402014178506, 1.90791570764917, 1.97437800581131, 2.03944576924146, 2.10285736712601, 2.16361281530643, 2.21976679180033, 0, 0, 0, 0, 2.35089953806267, 2.34158013771217, 2.32381174154831, 2.30074283653064, 2.27572561380628, 2.25197053668352, 2.23228443464743, 2.21892085022508, 2.21356871104365, 2.21748961046812, 2.23177878097753, 2.25767722249045, 2.29681983761623, 2.35128978590875, 2.42338271637842, 2.51507236637938, 2.62729468303392, 2.75929072256875, 2.90831563086255, 3.06998649255612, 3.23939155869329, 3.41284833973909, 3.58994922458977, 3.77535578958465, 3.97976033218111, 4.21954013050206, 4.51485020612870, 4.88617199026598, 5.34961100892964, 5.91152601072113, 6.56346617897762, 7.27898070336888, 8.01437975586553, 8.71495390934437, 9.32539546847843, 9.79929235162343, 10.1019024448376, 10.2061711103796, 10.0899111547744, 9.74303765319415, 9.18487488359958, 8.48052053919352, 7.74132397195514, 7.10089653754508, 6.67250267780056, 6.50814278068918, 6.58147626452975, 6.80152477879146, 7.04474217052064, 7.18600354384817, 7.11736935015841, 6.76125805258769, 6.09966551369841, 5.22085069484382, 4.32396685645033, 3.62237259265737, 3.21377150759756, 3.05982791041228, 3.08341420779945, 3.24833467153915, 3.54780709997840, 3.95925910220801, 4.43120625347217, 4.8989601736221, 5.30048362169184, 5.58501598367906, 5.72075471200924, 5.70211842826168, 5.55117512325328, 5.31037936020038, 5.02952733685511, 4.75270509050335, 4.50999262598091, 4.31559099792489, 4.17098131264011, 4.070233138594, 4.00486791374166, 1.18667765607189, 1.23216214884194, 1.27661051373452, 1.32056633404268, 1.36523790816362, 1.41236683981667, 1.46380718883518, 1.52087558405586, 1.58369648671110, 1.65087449337239, 1.71976439227842, 1.78734262843177, 1.85132701122618, 1.91097857589350, 1.96713623572600, 2.02144815241893, 2.07521429963710, 2.12844640652063, 2.17957951246521, 0, 0, 0, 0, 2.31324207856646, 2.30748785729263, 2.29370531132109, 2.27478919657539, 2.25379495815632, 2.23358680751080, 2.21657687292294, 2.20458418104395, 2.19883969949914, 2.20014781391917, 2.20917954954549, 2.22682516430250, 2.25449085839079, 2.29420933499682, 2.34846644565757, 2.41973135880834, 2.50979826870736, 2.61916409970780, 2.74672883058054, 2.89007241399503, 3.04642446235736, 3.21423027364242, 3.39499314771191, 3.59491104751698, 3.82577636917009, 4.10467933250215, 4.45221694772085, 4.88911504609991, 5.43139867398959, 6.08454690739054, 6.8376091837589, 7.65921130548991, 8.4983595747814, 9.29237007209738, 9.980286477217, 10.5143519806139, 10.8611227963603, 10.9926120596909, 10.8797848056906, 10.5016430286641, 9.86942035294467, 9.04985689949563, 8.16764927243616, 7.37705601593919, 6.8110000934521, 6.53287417714597, 6.51750501069021, 6.6688107450653, 6.85824294007336, 6.96084437223142, 6.87685238678253, 6.54477455362544, 5.96143099255248, 5.20718335766344, 4.43752018517431, 3.81064072823252, 3.40213644491087, 3.19561964416985, 3.14770871759873, 3.23846103773240, 3.46189523958871, 3.79587514915668, 4.19438933636943, 4.59955122424253, 4.9542911073487, 5.21085818354018, 5.33878909373255, 5.33187390739138, 5.20930159003085, 5.00850376081484, 4.77312172833259, 4.54149607019016, 4.33952063165366, 4.17920162293066, 4.06161281762631, 3.98161683761619, 3.93206613057439, 1.16994340640654, 1.21304013272826, 1.25571536077983, 1.29912620821700, 1.34518620837775, 1.39622976605656, 1.45429568531838, 1.52019536440507, 1.59274634247182, 1.66862973792080, 1.74314548434927, 1.811711737981, 1.87149903335033, 1.92241015845596, 1.96688650142564, 2.00861885406513, 2.05080416285709, 2.09477459438702, 2.13955077449285, 0, 0, 0, 0, 2.27459154764584, 2.27252541347698, 2.2627926206159, 2.24802002505989, 2.23096117859329, 2.21412933714842, 2.19953633101943, 2.18856328709272, 2.18198736214093, 2.18017363960115, 2.18340651110356, 2.19228666322309, 2.20807621331569, 2.23285924845593, 2.26941750540511, 2.32080536720233, 2.38972630858839, 2.47792502121998, 2.58586789007695, 2.7129527809588, 2.85836047380605, 3.02246490576831, 3.2085158258222, 3.4241578106264, 3.68229350588584, 4.00083864226083, 4.40102351501945, 4.90403705169121, 5.52598522397428, 6.27144185821721, 7.12657695257184, 8.05424874053263, 8.99502746225112, 9.8775227192836, 10.6358138279517, 11.2234006648209, 11.6117439932324, 11.7744851501521, 11.6757203242273, 11.2812578305583, 10.5913226927977, 9.67201520802684, 8.65993623766617, 7.72828900961081, 7.03014321645144, 6.64436846750306, 6.54345830329711, 6.62980824988952, 6.77074556319454, 6.84118151339995, 6.74745013141078, 6.43892775702012, 5.91943722367799, 5.25763088590064, 4.57347346232937, 3.98663528137074, 3.56152535364551, 3.30166001895060, 3.18933100471787, 3.21571242674804, 3.37453703849588, 3.64378395842255, 3.98171835729106, 4.33574981220292, 4.65269825076043, 4.88701365862487, 5.00845290003945, 5.00969548552707, 4.90842240523296, 4.73896653520659, 4.54019380417687, 4.34574966799579, 4.17805859407902, 4.04718276214137, 3.95364436507638, 3.89273848881779, 3.858238621134, 1.15514894949594, 1.19612582682779, 1.23732228394382, 1.28055809539945, 1.32852773954161, 1.38424932980366, 1.4500241190378, 1.52617845412254, 1.61013812545242, 1.69644543108620, 1.77802324030755, 1.8483847386571, 1.90389952474165, 1.94505210152343, 1.97605169190590, 2.00296720518222, 2.03128406534258, 2.06398501069747, 2.10087184818367, 0, 0, 0, 0, 2.23547517908129, 2.23711097794002, 2.23139286236143, 2.22066250721248, 2.20736518225758, 2.19366057296698, 2.18115953579781, 2.17080841064772, 2.16294144945914, 2.15750810562381, 2.15444727959763, 2.15413155233648, 2.15775987052441, 2.16756169666548, 2.18670893977409, 2.2189173091196, 2.26783630113496, 2.33643693155641, 2.42666213474849, 2.5395731596979, 2.67610278593241, 2.83834371878788, 3.03111212238366, 3.26338566918785, 3.54915266909298, 3.90721994028471, 4.35958490337302, 4.92805705479792, 5.62893287717366, 6.46583278631527, 7.42169860200956, 8.4528859194901, 9.49060498789824, 10.4543464289842, 11.2743219962568, 11.9083018112911, 12.3364970385716, 12.5366995420882, 12.4659534111347, 12.0746015911347, 11.3491105561784, 10.3524984363824, 9.2308463936093, 8.12890161367402, 7.25108809323415, 6.86230806980814, 6.6745294834076, 6.69281459774883, 6.78263801853232, 6.81895414276739, 6.7117918733413, 6.41648541847007, 5.93873711041304, 5.33572921501037, 4.70138952716579, 4.13016316849818, 3.68127226730480, 3.37345522824251, 3.20677370682689, 3.17962250709848, 3.28536704668414, 3.50230842383782, 3.79208352025031, 4.1063092731464, 4.39550439562052, 4.61587298756253, 4.73391844634879, 4.73856003960357, 4.64946365420038, 4.50198552076855, 4.331177846978, 4.16624879148418, 4.02662348856374, 3.92065362711973, 3.84819504680122, 3.80465076849706, 3.78433618785478, 1.14169155629438, 1.18080815893123, 1.22086669278678, 1.26442139705819, 1.31504246459453, 1.37652876568757, 1.45150518815679, 1.53978949179532, 1.63726609395243, 1.73605475974759, 1.8263295841792, 1.89933788387611, 1.95041761514602, 1.98062230399381, 1.99614662999498, 2.00581406620747, 2.01781214628319, 2.03710818862552, 0, 0, 0, 0, 2.18261118504317, 2.19636750074306, 2.20163353684381, 2.19981486049210, 2.19295019676112, 2.18317110148287, 2.17228430392275, 2.16150422597762, 2.1513518588606, 2.14173573875310, 2.13221825915690, 2.12243604623615, 2.11259299274029, 2.10389881586543, 2.09881051426766, 2.10096889423559, 2.11480990748984, 2.14494960346525, 2.19555106635462, 2.26993589189022, 2.37067062203381, 2.50023949031142, 2.66224085196883, 2.86286699940368, 3.11229271936026, 3.42552869144426, 3.82228208721348, 4.32538073648985, 4.95733844825089, 5.73469799153308, 6.66008382285581, 7.71298024585169, 8.84278798375668, 9.9708802197353, 11.0077301376417, 11.8811586252550, 12.5562249200948, 13.0252371694272, 13.2718501220904, 13.2453324038565, 12.8785602037281, 12.1423912900149, 11.0949293671124, 9.88883882995543, 8.5467218774983, 7.38690239704012, 7.20028586517441, 6.92043014430779, 6.86143897644225, 6.89059907129659, 6.88405298591553, 6.75375272735434, 6.45704940593019, 5.99827023740558, 5.42489406846863, 4.81312363509525, 4.24164599830188, 3.76717516319476, 3.41849141084796, 3.20687868985864, 3.13531160799788, 3.19726936232059, 3.37187355001604, 3.62363677543904, 3.90835991174716, 4.18271251920784, 4.40525039755585, 4.52804728137545, 4.52660271870405, 4.43310912163146, 4.29534519965863, 4.14419234461087, 4.00209980777877, 3.88513476360589, 3.80006647929475, 3.74600714192558, 3.71820914728559, 3.71121514895179, 1.12907174741704, 1.16657503920103, 1.20585455515754, 1.25027802286868, 1.30438875168590, 1.37285790802295, 1.45867934271824, 1.56111418076886, 1.67432970685413, 1.78772224047499, 1.88834590715381, 1.96484058717613, 2.01131146996977, 2.02939422600685, 2.02749713054915, 2.017566957081, 2.01088694359659, 2.01472049875274, 0, 0, 0, 0, 2.14106436937397, 2.15769709688887, 2.16645279746909, 2.16835275671587, 2.16511658361561, 2.15855887975471, 2.15013770888115, 2.14068077509741, 2.13029921693778, 2.11849889035789, 2.10448787534990, 2.08764460278591, 2.06805976147979, 2.04701820758887, 2.02727166803889, 2.01298976888780, 2.00936771450538, 2.02199095204544, 2.05616791944931, 2.11649542949621, 2.20688808432580, 2.33118528688089, 2.49428034835324, 2.70354544055190, 2.97019564338028, 3.31016017147592, 3.74399425930201, 4.29534153748999, 4.98742454365918, 5.83703986372478, 6.84581573225755, 7.9897683612796, 9.21136267386093, 10.4223586065191, 11.5250256568069, 12.4465668740278, 13.1619399067332, 13.6774765121676, 13.9827265434522, 14.0174649685661, 13.6956202838429, 12.972263545503, 11.9002302195401, 10.6362347126091, 9.34161440054387, 8.2488564383788, 7.66401998970449, 7.28287742927576, 7.13308039718399, 7.08700701496978, 7.0241709780143, 6.85774670783103, 6.54442480070732, 6.0851708912103, 5.5195858110821, 4.91214095201913, 4.33161677927973, 3.83278821984338, 3.44986296786115, 3.20049046074421, 3.09064101768301, 3.11467707821387, 3.25325229041775, 3.47387581742023, 3.73870854457766, 4.01901163307043, 4.27864379610441, 4.42603391976134, 4.39727270511581, 4.26429950241995, 4.11597565992685, 3.97577724902600, 3.85118814414364, 3.75269361262722, 3.68536079333201, 3.64751843520065, 3.63409589415079, 3.63963599884458, 1.11688373731934, 1.15300022096017, 1.19184407594847, 1.23766659626951, 1.29606689322007, 1.37266166545810, 1.47084267985751, 1.58926037216047, 1.72020225812903, 1.85007694348328, 1.96250284019761, 2.04322996587519, 2.08497157275856, 2.0899661002218, 2.06903191016032, 2.03754764277234, 2.01021774039954, 1.99685779115398, 0, 0, 0, 0, 2.10052554036014, 2.11984620894457, 2.13189612790536, 2.13728110665595, 2.13738903470545, 2.13371732847486, 2.12738347627678, 2.11884315624598, 2.10781888823772, 2.09344232101834, 2.07460353686438, 2.05046674091682, 2.02105950660020, 1.98779468185492, 1.95376872129204, 1.92371904727234, 1.90361759239201, 1.90000364560147, 1.91927230689419, 1.96718838753431, 2.04886113090591, 2.16929682817279, 2.33447938215127, 2.55276197050079, 2.83622444353239, 3.20157080027028, 3.67008977667765, 4.26614716749673, 5.013600320537, 5.92946873971242, 7.01446010012979, 8.2414125807649, 9.54649567372274, 10.8329766324908, 11.9965841671648, 12.9613224645721, 13.7274244183203, 14.3015555286402, 14.6811613493057, 14.7935647529786, 14.5329897428001, 13.8407001792527, 12.7659258918045, 11.4677283177979, 10.1621040379609, 9.0483827073821, 8.24549741800722, 7.75411718136203, 7.49807943177817, 7.35969717590859, 7.22477095174145, 7.00803658123804, 6.66409980910448, 6.18955101284335, 5.61755260720478, 5.00451339516068, 4.41217241250260, 3.89250573714906, 3.48126355315427, 3.19903741029168, 3.05398784809124, 3.04231150818417, 3.14714937391073, 3.33993058860954, 3.59453190784398, 3.91419386929792, 4.27455190741087, 4.48400173261203, 4.3886753952194, 4.15270259423548, 3.96081669218834, 3.82163577293503, 3.71069325406455, 3.62790352015387, 3.57614276736261, 3.55294955067899, 3.55285289535755, 3.57026733138316, 1.10480588951478, 1.13973162005644, 1.17843198443470, 1.2260872133063, 1.28940317363614, 1.37498417524279, 1.48663118671564, 1.62234087119777, 1.77240892207476, 1.92008131109204, 2.04533581806943, 2.13085143587836, 2.16784817585825, 2.1591805155286, 2.11820167367268, 2.06391821677194, 2.01466346755079, 1.98297010969913, 0, 0, 0, 0, 2.06135881741654, 2.08314695574494, 2.09825417536246, 2.10684992459736, 2.10998321025265, 2.10883765811510, 2.10420204500342, 2.09617942249999, 2.08413034146384, 2.06684578792876, 2.04293721230291, 2.01139763444192, 1.9722350149735, 1.92703007919652, 1.87925540372025, 1.83423323987825, 1.79870787627895, 1.78013891287312, 1.78593848109967, 1.82292987154011, 1.89726915130456, 2.01495126868194, 2.18285495801099, 2.41011538483469, 2.70948566853317, 3.09826405257952, 3.59829975373812, 4.23451290313271, 5.03124981506028, 6.00569320793327, 7.15779911939937, 8.45785116316068, 9.83703725607356, 11.1922022626508, 12.4150425494835, 13.429023634366, 14.2584506108118, 14.9094824933427, 15.382049538181, 15.5868770037456, 15.3986609694871, 14.7487072048178, 13.6857805326760, 12.3708418675633, 11.0208794507340, 9.83358911217194, 8.9267386569962, 8.3168854357185, 7.93984863736648, 7.69228884269417, 7.4694352068031, 7.18864091443858, 6.80205916532897, 6.30176804201687, 5.71571489134189, 5.09419634748297, 4.49255684214331, 3.95800974971464, 3.52438396348523, 3.21271543602515, 3.03306250979564, 2.98458543785135, 3.05416906913482, 3.21877790913008, 3.47143818277871, 3.87017025185080, 4.4110412396696, 4.73015199042386, 4.51870743560812, 4.10015754496742, 3.82506291242926, 3.67709851184234, 3.57758799314518, 3.50919055327683, 3.47186580712054, 3.46239311652179, 3.47491689112451, 3.50369239351861, 1.09259269147293, 1.12648339577914, 1.16524806343820, 1.21500253681346, 1.28356356219863, 1.37852245442349, 1.50408149356672, 1.65756594079698, 1.82725089434319, 1.99318083806216, 2.13164880624121, 2.22222201355131, 2.25460013174145, 2.23224829147454, 2.17107291958425, 2.09374520194346, 2.02227160734264, 1.97194195927519, 0, 0, 0, 0, 2.02385469450301, 2.04787621287714, 2.06577585061504, 2.07727974459240, 2.08309786312332, 2.08410746087856, 2.08078412841083, 2.07290215729709, 2.05949197482675, 2.03904228088324, 2.00992787943252, 1.97101190133932, 1.92231837591571, 1.86562144672995, 1.80478164335074, 1.74570116043695, 1.69587162858016, 1.66362349825449, 1.65730755902768, 1.68469548948433, 1.75284901504695, 1.86858419878932, 2.03948826027335, 2.2752808678303, 2.58918415954514, 2.99887867182532, 3.52655048868287, 4.1974420706442, 5.03618119754002, 6.06003094517858, 7.26844923641765, 8.63008352683753, 10.0730401286278, 11.490609498157, 12.7735953381492, 13.859570732391, 14.7582444727795, 15.5082139254609, 16.0933365680617, 16.403500205769, 16.2953983287967, 15.6944155728285, 14.6507378870934, 13.3276769786089, 11.9417718903158, 10.6869744463448, 9.68007697911116, 8.94571807706118, 8.43589070391587, 8.06494045040962, 7.74038200218037, 7.38356170095187, 6.94461424064093, 6.4118111914697, 5.8092350770206, 5.18202740304209, 4.57827642745096, 4.03754234763704, 3.5883017366014, 3.24998128814764, 3.03455908826655, 2.94550183256647, 2.97501293051948, 3.10727837905074, 3.35925100133783, 3.85699179802917, 4.62207194042947, 5.07742364844644, 4.72240672794806, 4.07745934275981, 3.69818066439022, 3.5372794716143, 3.44906817798646, 3.39508750413308, 3.37199116091975, 3.37589375486047, 3.4006519255279, 3.44041619577327, 1.08006941171753, 1.11303351990491, 1.15196055072232, 1.20385925895660, 1.27760313584406, 1.38171852944129, 1.52078082950781, 1.6914625903671, 1.88009741953985, 2.06366082483967, 2.21491584050317, 2.31044780039043, 2.33849642650003, 2.30310586541981, 2.22262209449609, 2.12322295416734, 2.03043406280274, 1.96219133030469, 0, 0, 0, 0, 1.98822513480713, 2.01424941184788, 2.03466233903327, 2.04875622803230, 2.05690969807065, 2.05970509849795, 2.05732383739838, 2.04923971406282, 2.03419017985666, 2.01040495418473, 1.97606651803535, 1.92994662703966, 1.87211138967514, 1.80453746605977, 1.73146436715107, 1.65934812215865, 1.59638497251012, 1.55171516746302, 1.53454527461601, 1.55348748741996, 1.61637556392836, 1.73068938353014, 1.90454718696872, 2.14805801548179, 2.47469950028785, 2.90229819262905, 3.45311387834772, 4.15242914554776, 5.02489680007215, 6.08775452521722, 7.34026435846657, 8.75054013360485, 10.2458641616154, 11.7192773124281, 13.0640222316845, 14.2248586067824, 15.2200764777282, 16.0902680999717, 16.8052834716266, 17.2329313614732, 17.2157969596821, 16.6738148072042, 15.652824301889, 14.3189478582656, 12.8957048652500, 11.5756912917554, 10.4705437171529, 9.60911487249641, 8.9593041871031, 8.45516520067462, 8.01872120775808, 7.5767285976454, 7.07833864314502, 6.50949506182001, 5.89209572424734, 5.26660327920551, 4.67201804160830, 4.13660293493871, 3.67985213986765, 3.31766935872385, 3.06417573767813, 2.92873110016263, 2.91071774297832, 3.00249836411837, 3.24126650706821, 3.8065945528039, 4.73998983425282, 5.29924711404113, 4.83471715932010, 4.01829740614448, 3.56322341568362, 3.39745293558043, 3.32289991287684, 3.28445457161840, 3.27611273462255, 3.29351067730285, 3.3303752413731, 3.38087173527404, 1.06713002335740, 1.09922749153532, 1.13829306041276, 1.19213039961673, 1.27055123700846, 1.38290919050791, 1.53410399776426, 1.72021668235851, 1.92583964625228, 2.12520203281832, 2.28791045343511, 2.38788469246961, 2.41205938506642, 2.36499607544323, 2.26722168779241, 2.14805012207708, 2.03615596930510, 1.95184537704106, 0, 0, 0, 0, 1.95459748064579, 1.98241176742155, 2.00505871223768, 2.0214232339632, 2.03156768928051, 2.03579441987043, 2.03401290541399, 2.02542949632247, 2.00853196825542, 1.98134013289368, 1.94189083024759, 1.88889856749748, 1.82248446930261, 1.74481620732901, 1.6604797095875, 1.57643821492466, 1.50153701323129, 1.44566114759945, 1.41879317146479, 1.43028514825263, 1.48861824734302, 1.60178789861258, 1.77827291839082, 2.02837869529967, 2.36561880680999, 2.80771321005069, 3.37670570693602, 4.09760315226874, 4.9947922372049, 6.08535313334075, 7.36864872697784, 8.81338684659615, 10.3483193389227, 11.8694830388866, 13.2755167451802, 14.5188886570903, 15.6240161744333, 16.6279181930830, 17.4839414521584, 18.0430092103202, 18.1420802389593, 17.6863773225027, 16.6925310275615, 15.3295980154114, 13.8512616554676, 12.4605649283117, 11.2589700457949, 10.2719300141831, 9.48031532413198, 8.83838744821754, 8.28418213055386, 7.75129254868271, 7.189454422257, 6.5843832704453, 5.95771108233163, 5.3453706760025, 4.77480329209743, 4.258811065195, 3.8040825604423, 3.42113261463858, 3.12661209595853, 2.93761053594246, 2.86279814919386, 2.90280003875365, 3.10247055966783, 3.65148959664572, 4.59463912741762, 5.16456011917996, 4.68797264296615, 3.85669885566685, 3.40469996560978, 3.25417010726751, 3.19768589086478, 3.17661919791165, 3.18403606951675, 3.21535790931586, 3.26437442727869, 3.32542452905029, 1.05373826206938, 1.08498750668122, 1.12405115101024, 1.17937436795693, 1.26152462447726, 1.38052009457523, 1.54151654111819, 1.74010774056429, 1.95946602784159, 2.17158529555505, 2.34350552182260, 2.44698094094939, 2.46788870926009, 2.41121638280840, 2.29927054024881, 2.16392142663445, 2.03640976401455, 1.93897380325536, 0, 0, 0, 0, 1.92300341189822, 1.95242368059682, 1.97704055614641, 1.99537258319747, 2.00718593941892, 2.01251970427202, 2.01103672537121, 2.00171498124666, 1.98284430746182, 1.95229170163348, 1.90799800852569, 1.84864756140624, 1.77440997945218, 1.68760354421847, 1.59309813272143, 1.49829673939532, 1.41263250243384, 1.34667873815119, 1.31113017384015, 1.31599419230321, 1.37028674365481, 1.48237787144252, 1.66094017154617, 1.91628269879467, 2.26173177423158, 2.71463974300915, 3.29653188143405, 4.03180738357422, 4.94427625174843, 6.05069938841322, 7.35077555435101, 8.81479446015053, 10.3749771964701, 11.933047648378, 13.3950862941261, 14.7208014855859, 15.9372886349607, 17.0746191726552, 18.0728327922758, 18.7819689109905, 19.0498215546726, 18.7413749319490, 17.7851491559766, 16.3529971717198, 14.7784924757846, 13.3011177454035, 12.0045899517902, 10.8975281102768, 9.96758708178804, 9.18823880386408, 8.51451087277347, 7.88851115379281, 7.26274118402454, 6.62517372760472, 5.99894341616321, 5.41508807658444, 4.88653615271766, 4.40625227493652, 3.96431661130635, 3.56410940312005, 3.22536472505094, 2.974961224473, 2.83320110592435, 2.80905957708161, 2.94110106049522, 3.38107326319098, 4.1585850375097, 4.63589378141589, 4.25474719101611, 3.58154148214524, 3.21965569624523, 3.10653197426286, 3.07300734355814, 3.07142764969769, 3.09580823819109, 3.14162071114107, 3.20291526187436, 3.2743752788748, 1.03993096743807, 1.07032506278931, 1.10915422040637, 1.16530236003887, 1.24985351040254, 1.37327921592104, 1.54090578269681, 1.74798197608328, 1.97668728999166, 2.19745668079912, 2.37554255859186, 2.4811943005693, 2.49956039740852, 2.43593723946017, 2.3138853166153, 2.16706883744929, 2.02852574841233, 1.92184611431169, 0, 0, 0, 0, 1.89335692834254, 1.92423545781155, 1.95059195453422, 1.97062812081397, 1.98383390417540, 1.99000074286832, 1.98857312252786, 1.97834856081856, 1.95748385704106, 1.92376298043183, 1.87508502212178, 1.81011977154413, 1.72904799651139, 1.63425395678879, 1.53078650933030, 1.42639734853349, 1.33105062474711, 1.25597923457848, 1.21256311962543, 1.211411446722, 1.26197998777612, 1.37287780156612, 1.55280284612479, 1.81187155803477, 2.16299676879371, 2.6229005437734, 3.21228713952599, 3.95461727220578, 4.87281016789061, 5.98311729788887, 7.2857057106199, 8.7531697265089, 10.3226590640286, 11.9033762536789, 13.4096698359776, 14.8068372803984, 16.1210409587582, 17.3744911103895, 18.5038525980048, 19.3847990086172, 19.9041130512343, 19.8464802537508, 18.9532559612267, 17.3896685486017, 15.6493351107782, 14.0569217638778, 12.6670247632186, 11.4495894290264, 10.3894065779757, 9.4770002289530, 8.6852423654237, 7.96709030326162, 7.28076695178615, 6.61908452410128, 6.00774301348632, 5.47163844031236, 5.00582514077527, 4.57919786790578, 4.16177142964374, 3.74830792210543, 3.36234228104793, 3.04275693243495, 2.82403385935268, 2.72463338607132, 2.77043376386471, 3.05127103059847, 3.57237838895841, 3.90393146915024, 3.67272405948706, 3.24593091793093, 3.01946034615338, 2.95629916357576, 2.94937582021758, 2.96921223283823, 3.01170241753335, 3.07255030832972, 3.14624127435675, 3.22796105396074, 1.02582227735342, 1.05535398010028, 1.09366666455625, 1.14984267233729, 1.23520043808051, 1.36041691508426, 1.53089004583244, 1.74169333963475, 1.97451871926256, 2.19904037891091, 2.3796420139239, 2.48584769501000, 2.50246639841505, 2.43496755809966, 2.30754814471535, 2.15476873636519, 2.01055731316446, 0, 0, 0, 0, 0, 1.86541400026264, 1.89764559278251, 1.92557064266269, 1.94712147246933, 1.96152283961485, 1.96832814962070, 1.96679499632654, 1.95560239003385, 1.93286068677209, 1.89636171443199, 1.84402491466019, 1.77450279970846, 1.68790028616861, 1.58651274585118, 1.47539821025578, 1.36253540125810, 1.25838046817508, 1.17485391772142, 1.12406298478324, 1.11721975882330, 1.16415227772011, 1.27357620378512, 1.45403703985966, 1.71525169820105, 2.06948817308672, 2.53257843880859, 3.12411413435815, 3.86630317586712, 4.7808723243819, 5.88335331639968, 7.17439714024284, 8.6293046100876, 10.1909711212168, 11.7768733985851, 13.3092807134415, 14.7565594420184, 16.1405702081968, 17.4768492530923, 18.7118810468321, 19.7776776555536, 20.6336883419751, 20.9567254733387, 20.1905312905105, 18.4368799194418, 16.4358974300351, 14.6880865090464, 13.2078603818306, 11.8937715287394, 10.7151077223166, 9.67680551964508, 8.7707404423834, 7.96405347528263, 7.22451050750371, 6.55214557735801, 5.97508532814266, 5.50966420860472, 5.12941704385461, 4.77545403140032, 4.39492809181753, 3.97286574558289, 3.53742652035223, 3.14175059845003, 2.83714487530986, 2.65388962117223, 2.60835772508618, 2.73527565521623, 3.0181145572862, 3.21518880476227, 3.12034977198468, 2.91958396012209, 2.81995730616512, 2.80662444296583, 2.82800835642973, 2.87069122287679, 2.93216716840114, 3.00844211571620, 3.09456735506986, 3.1863558190438, 1.01160692005338, 1.04030039310963, 1.07782166782766, 1.13318975351891, 1.21765094975431, 1.34181858340324, 1.51105468975107, 1.72044037845002, 1.95172517475660, 2.17468391714116, 2.35382349043897, 2.4587847402046, 2.47445847719687, 2.40634217928974, 2.2786037271608, 2.12573034201601, 1.98155804488291, 0, 0, 0, 0, 1.80571245523669, 1.83870729719839, 1.87223773454329, 1.90165705271267, 1.92465775213268, 1.94018807590714, 1.94755953591264, 1.94587816313595, 1.93378904125657, 1.90947818779140, 1.87087092489650, 1.81598263814625, 1.74341723463298, 1.65303825066996, 1.54678659087214, 1.42945912233753, 1.3090961678708, 1.19664226746488, 1.10483148670934, 1.04665642590097, 1.03402305912932, 1.07710666674731, 1.18459803298698, 1.36469201085675, 1.62647743890647, 1.98133527911457, 2.44395176251166, 3.03253294660888, 3.76774852598455, 4.66985828454912, 5.75345862370587, 7.01959745320356, 8.44638212353566, 9.9826787329912, 11.5541925777933, 13.089971779318, 14.5586816027459, 15.9751365178099, 17.3501886522649, 18.6507911295221, 19.8825028983498, 21.1011581492899, 21.9076135585424, 21.3991627093274, 19.4573344121182, 17.1016779487026, 15.1550901622987, 13.5923416173947, 12.1995553630542, 10.9170582732069, 9.76201466768818, 8.74701461383123, 7.85772770074768, 7.0759989785008, 6.41101138509752, 5.89178733369965, 5.52255782341881, 5.25170513338048, 4.98970874147798, 4.65891959304474, 4.23385970992346, 3.74809644009125, 3.27115150847581, 2.87371813795380, 2.60068769548145, 2.46676036581926, 2.47372129758928, 2.59176441179691, 2.69808088644139, 2.69127447932974, 2.64064813640115, 2.63139328360380, 2.66067468964316, 2.71053522530999, 2.77682909505654, 2.85775480882934, 2.94960469240545, 3.0480705784283, 3.14967137491526, 0.997560833168382, 1.02550650870025, 1.06203178454735, 1.11582761818357, 1.19775845870028, 1.31810176223002, 1.48207287757926, 1.68494000934542, 1.90905194218795, 2.12514213213168, 2.29882976606676, 2.40071305212298, 2.41618607260544, 2.35063044824133, 2.22752001009542, 2.08029734653683, 1.94172058476645, 0, 0, 0, 0, 1.77844961285460, 1.81245387349484, 1.84729560355688, 1.87828754911457, 1.9028723207533, 1.91966875185731, 1.92771836301546, 1.92601592787383, 1.91329259713944, 1.88798811774479, 1.84834189971688, 1.79256304977836, 1.71913294370706, 1.62738893422765, 1.51848345492207, 1.39652960430952, 1.2693994152888, 1.14857967646170, 1.04789722601920, 0.981568187364813, 0.962421739139982, 1.00101935893633, 1.10589406182318, 1.28465681062745, 1.54550250291555, 1.8986620078655, 2.35742179991282, 2.93835197471374, 3.66033604349328, 4.54193169491662, 5.59659737110635, 6.82562257656828, 8.20979359859746, 9.70373901076467, 11.2408219115957, 12.7554843511631, 14.2143872003541, 15.6234904712394, 16.990295021882, 18.3046725687164, 19.6358834173618, 21.1306534213728, 22.4193711475810, 22.3317915446646, 20.3087811164344, 17.5741399424383, 15.4169231902559, 13.7915701342804, 12.3424419361091, 10.9732112904132, 9.71257058497935, 8.5959430797656, 7.63238090969573, 6.8225536703692, 6.18608786672666, 5.75024942052392, 5.50305044944623, 5.36462829290447, 5.21315129344, 4.94511203633521, 4.52394758664736, 3.98914260286382, 3.42837028305348, 2.93396977353382, 2.56785806383231, 2.34997571673175, 2.26918428036199, 2.29002893094672, 2.34526432339046, 2.3814311638208, 2.41038952347654, 2.4569403207109, 2.52113916551417, 2.59873921282632, 2.68868722828663, 2.78904477181651, 2.89632728488181, 3.00688157151414, 3.11795975784644, 0.984037617612806, 1.01142577913925, 1.04688246331256, 1.09852127422955, 1.17653306272647, 1.29060180722814, 1.44568764038464, 1.63740576875896, 1.84919936749818, 2.05354893195050, 2.21809699771135, 2.31517460981324, 2.33106855504908, 2.27091151955522, 2.15686636572407, 2.02042677837346, 1.89235158995455, 0, 0, 0, 0, 1.75046567422901, 1.78544347752892, 1.82170404672001, 1.85457966148879, 1.88118542316903, 1.89969050580836, 1.90879934625308, 1.90744212002496, 1.89460870245747, 1.8692541895626, 1.83019492870750, 1.77596590734405, 1.70479202840582, 1.61502809557940, 1.50636097477801, 1.38157747456271, 1.24805851934897, 1.11797049930290, 1.00673427444189, 0.930388249777948, 0.903113906686615, 0.935989418225768, 1.03725336190731, 1.21364634387706, 1.4721459822684, 1.82153491212993, 2.27344110884513, 2.84257092452241, 3.54581550106296, 4.39984306342527, 5.41680175869754, 6.59804067283221, 7.92676641837584, 9.36292478732141, 10.8467825920663, 12.317049538971, 13.7370919754603, 15.1033319566973, 16.4199189104114, 17.6933213203939, 19.0237410563955, 20.6095439135118, 22.2188626310053, 22.6063942969818, 20.6879126499616, 17.7190356512176, 15.4310682503249, 13.7853663323208, 12.3063087472732, 10.8697740238746, 9.51748017916185, 8.30960819619003, 7.2829633190412, 6.46116886212965, 5.87487364340106, 5.54652397299636, 5.4442169056116, 5.45799949366485, 5.43344230965492, 5.24090197752489, 4.8320995086088, 4.25239832010788, 3.60876548925047, 3.01689490316301, 2.55734624787037, 2.25913678351461, 2.10939421956693, 2.07127145460335, 2.09703828474162, 2.14898225717742, 2.21566338306058, 2.29684069169086, 2.39036364004672, 2.49435124963134, 2.60729066599064, 2.72657623840116, 2.84885288638491, 2.97107923724482, 3.09121785707345, 0.971459825966679, 0.998608387801888, 1.03310739535480, 1.08227516275883, 1.15537359751239, 1.26126590969737, 1.40455577620029, 1.58133197252920, 1.77654366860293, 1.96508015610592, 2.11737513845789, 2.20814765403943, 2.22490652083426, 2.17242098419243, 2.07101385167732, 1.94944995496044, 1.83568867163124, 0, 0, 0, 0, 1.72013756557919, 1.75593099331962, 1.79385886230853, 1.82926913088081, 1.85877049157812, 1.87986245279258, 1.89078723474865, 1.89046453866286, 1.8783891512508, 1.85441023343660, 1.81829942659656, 1.76909963657125, 1.70456629821716, 1.62138418292203, 1.51676866200750, 1.39123951801067, 1.25123677804825, 1.10985515997004, 0.984909542681677, 0.895210507253769, 0.856990131620135, 0.882096804517931, 0.978332001473723, 1.15120605394432, 1.40607555683809, 1.74992462178705, 2.19244991741391, 2.74628547671905, 3.42616592921611, 4.24673419917158, 5.21869864711565, 6.34329575596431, 7.60585055526862, 8.97111210415583, 10.3855659085724, 11.7916028342807, 13.1492077446017, 14.4457194156585, 15.6810222003548, 16.8677818483120, 18.1010066263597, 19.5734998698562, 21.2063283183735, 21.8932605275869, 20.2567827517088, 17.3918329834376, 15.1670487856400, 13.5658197212973, 12.0854091878812, 10.6032646693369, 9.17723319793398, 7.89306432177594, 6.81798063906048, 6.00112326851375, 5.48402595584097, 5.28177355884121, 5.34043238069579, 5.52007898796947, 5.63495465499833, 5.52966047127258, 5.14333444614876, 4.52639616282374, 3.80530853151601, 3.11996347561404, 2.57024913967037, 2.19554051486398, 1.98546433293506, 1.90347862236651, 1.90702297218895, 1.96153189552628, 2.04660978120843, 2.15167149821511, 2.27045950715575, 2.39889469376168, 2.53352868353043, 2.67080017165063, 2.80736152759876, 2.94069055277642, 3.06939451619883, 0.960304672553514, 0.987677299121674, 1.02154740039932, 1.06826304251503, 1.13595183804885, 1.23247101413344, 1.36197799310928, 1.52111886785725, 1.69665042694228, 1.86636462022055, 2.00406363665093, 2.08734910026752, 2.10520025245428, 2.0619317077013, 1.97561219993721, 1.87166102921054, 1.77459698802378, 0, 0, 0, 0, 1.68527264287413, 1.72157695304012, 1.76162662482731, 1.80069387835730, 1.83456306635897, 1.85970677738001, 1.87369910893414, 1.87551085349473, 1.86548337196194, 1.84489140260310, 1.81499122388366, 1.77558308756392, 1.72364403229993, 1.65321331791367, 1.55761724599420, 1.43379341370010, 1.28663014722083, 1.13053587657899, 0.986890539118945, 0.878663861761312, 0.82517221100699, 0.839441049516308, 0.928684413003913, 1.09673007501431, 1.34680764216297, 1.68368345913019, 2.11482577465671, 2.65060143279348, 3.30346349199873, 4.08594462150438, 5.00723262382784, 6.06831290531273, 7.25634340697171, 8.54039808108924, 9.87267756652758, 11.1992210893923, 12.4775644811400, 13.6873659481387, 14.8233752228127, 15.8956791010380, 16.9716607077361, 18.1909248319357, 19.5496972662868, 20.2207474975313, 18.9591158259112, 16.572309222692, 14.6320193187002, 13.1402849439639, 11.6854023349000, 10.1813034950558, 8.70423833413912, 7.36432636824328, 6.25912159862487, 5.46350230607213, 5.0290873101669, 4.96239808572317, 5.18786565697386, 5.53818949960021, 5.79921302317837, 5.79082766217718, 5.43850076788906, 4.79598841851855, 4.00818186708345, 3.23874264422896, 2.60650405166979, 2.1609912627801, 1.89527366584608, 1.77378330784233, 1.75537409197107, 1.80557447497989, 1.90006431843874, 2.02283956497768, 2.16320722078109, 2.31358228336464, 2.46809783519404, 2.62205527429776, 2.77196559636319, 2.91569578505082, 3.05239980169906, 0.95108431862122, 0.979296291134575, 1.01309687174522, 1.05773805474051, 1.12006525818608, 1.20679335420813, 1.32155811949481, 1.46159975713152, 1.6156611535216, 1.7647417172567, 1.88637429982743, 1.96135587235192, 1.98029209092176, 1.94697638701850, 1.87693656735675, 1.79180994307366, 1.71220806897508, 0, 0, 0, 0, 1.64313780895901, 1.67950006823137, 1.72241378354199, 1.76687450374331, 1.80734742429013, 1.83874514594204, 1.85766267787651, 1.86318868704515, 1.85696672644755, 1.84241223274065, 1.82297720053463, 1.79955286195461, 1.7679242287051, 1.71818378613949, 1.63788293426548, 1.51863469676055, 1.36297933160555, 1.18717661192765, 1.01776123889828, 0.883743431564935, 0.808937460543945, 0.808126858991371, 0.887779735982757, 1.04948459952473, 1.29372161134567, 1.62253971874503, 2.04084954081546, 2.55656402380479, 3.17976387245663, 3.92083331079112, 4.78740695862813, 5.78012414830259, 6.88773443428403, 8.08323190163563, 9.32420037641722, 10.5606676796553, 11.7492516880401, 12.8639236355331, 13.8941630674096, 14.8431696557821, 15.7459705448660, 16.6729213615750, 17.6154514033032, 18.0500693150149, 17.1520604402034, 15.4217580767356, 13.8783653683135, 12.5310254397431, 11.1230212238664, 9.62188792597147, 8.12109991371683, 6.75148798548525, 5.63761875990788, 4.87763738861606, 4.53185936986394, 4.59877947886043, 4.98445002216841, 5.49937412237967, 5.90565188495454, 6.00040288398029, 5.69441361842045, 5.04222512395637, 4.20451983294783, 3.36656361762337, 2.66443738885096, 2.15674249219377, 1.83994160584543, 1.68008881535013, 1.63756973029919, 1.67839321125631, 1.77638327608945, 1.91185591043523, 2.06991836427751, 2.23927423955255, 2.41148672357498, 2.58056674055624, 2.74271608348126, 2.89603813126163, 3.04011558962406, 0.944321349231223, 0.97413216462925, 1.00864314347021, 1.05193401519828, 1.10947861334332, 1.18676344310755, 1.28684332786640, 1.40754381463176, 1.53964993106133, 1.66748411922763, 1.77245602370390, 1.83868758872101, 1.85847301947430, 1.83504086330994, 1.78121552444379, 1.71459162057188, 1.65157546381819, 0, 0, 0, 0, 1.59066540136799, 1.6265162393636, 1.67341322380626, 1.72574728140143, 1.77596143762750, 1.81666697296651, 1.84304217216708, 1.85436023334117, 1.85414512378412, 1.84886751201615, 1.84508388963736, 1.84520621633481, 1.84331604339017, 1.82393503158163, 1.7664861778473, 1.65508736015079, 1.48894656788663, 1.28686141641603, 1.08252593839058, 0.91336341077317, 0.809477951249996, 0.788166530985535, 0.854986314439343, 1.00862756370898, 1.24608383898218, 1.56610736518297, 1.97068886507764, 2.46510587815061, 3.05700531631018, 3.75462542712121, 4.56405793658297, 5.4855433235809, 6.50922894777293, 7.61169038632372, 8.75565883442602, 9.89561594094782, 10.9889300900854, 12.0060563680472, 12.9318772742126, 13.7624067607966, 14.5073926251239, 15.1830224441504, 15.7536867068034, 15.9347596638694, 15.3176922803559, 14.1616865657102, 12.9769006224760, 11.7707795854786, 10.4244574754927, 8.95139450492716, 7.45736349516749, 6.08803266404915, 4.9886916550443, 4.27580596401902, 4.01648451833252, 4.20330973257952, 4.72969740190946, 5.39136964768243, 5.93305041105437, 6.13233062231567, 5.88492361990525, 5.24301829243355, 4.37868390070267, 3.49447306420965, 2.74043206381528, 2.18251099439081, 1.82047048549797, 1.62307473198842, 1.55371786424714, 1.58038465460896, 1.67651266359201, 1.81974534784172, 1.99138408158093, 2.17649225264571, 2.36399380578766, 2.54646223877838, 2.71961641540144, 2.88163580103803, 3.03240626237118, 0.940520392826103, 0.972813640618701, 1.00900436813902, 1.05196900200722, 1.10577428392406, 1.17463950837842, 1.26099578674977, 1.36320596725615, 1.47404390910284, 1.58110007216261, 1.66961137203939, 1.72698791228199, 1.74718853113531, 1.73285216638162, 1.69404702753879, 1.64421882698868, 1.59541751656278, 0, 0, 0, 0, 1.52490024895367, 1.55962774542444, 1.61208515856043, 1.67559440691135, 1.73964973418194, 1.79359552085616, 1.83061657529745, 1.85022844834583, 1.85852800423004, 1.86614411384209, 1.88383365622318, 1.91605687159231, 1.95461277726707, 1.97657209774334, 1.95049907378614, 1.85049900161375, 1.67130934836900, 1.43506886513072, 1.18496673358818, 0.96960564997879, 0.827476146612508, 0.779286287713264, 0.829515407999217, 0.973218459144729, 1.20307745135217, 1.51390885409132, 1.90439867220483, 2.37701508957244, 2.93693583458744, 3.59028980438135, 4.34167150068762, 5.190904694509, 6.12937868503407, 7.13695184995947, 8.1812797710307, 9.22168143450828, 10.2177330283435, 11.1383812060573, 11.9650592230322, 12.6882945965448, 13.3030426732305, 13.7976665799820, 14.1261695848349, 14.1499407790244, 13.7122720225944, 12.9247537182098, 11.9857068901775, 10.8975519295202, 9.62293084625415, 8.20186265486921, 6.74578945161239, 5.40796298625173, 4.34605635211064, 3.68814073987062, 3.50577693763167, 3.78869060652350, 4.42490758274026, 5.20426466826687, 5.86204719724194, 6.16129629004797, 5.98349048239127, 5.37512166132239, 4.51347830628261, 3.61173227650245, 2.82888864940137, 2.23593771907048, 1.83610214877894, 1.60252940303681, 1.50375661143898, 1.51166476345846, 1.60074379941130, 1.74685331232132, 1.92791289939314, 2.12547072498189, 2.32576502208277, 2.51979714497249, 2.70263936429807, 2.87239409212799, 3.02912819319809, 0.940137068732055, 0.975889392626321, 1.01487076475651, 1.05876035020866, 1.11022734736570, 1.17222542804948, 1.24653527418860, 1.33197959112864, 1.42318074121202, 1.51080437555082, 1.58370599640577, 1.63241103046983, 1.65244818468030, 1.64585658752975, 1.61998352854213, 1.58414362717846, 1.54599696937540, 0, 0, 0, 0, 1.44371219856101, 1.47678383050616, 1.53688786050227, 1.61567928262773, 1.69856483431866, 1.7704449494099, 1.82179996350593, 1.85242568123711, 1.87176717880221, 1.89585460621644, 1.94088038579939, 2.01396453507321, 2.10403531722876, 2.17872407094179, 2.19283540370433, 2.10778475397795, 1.91262732692944, 1.63369508909225, 1.32615447957068, 1.05273034101848, 0.862535190925361, 0.780654754585628, 0.81033019850482, 0.94221818904408, 1.16383536907563, 1.46540847182790, 1.84193693851122, 2.29292302944723, 2.82106569533526, 3.43044967863505, 4.12424553199568, 4.90186856467112, 5.75581987459988, 6.66895748061567, 7.61359535989933, 8.55407723726236, 9.45325548844007, 10.2802197381240, 11.0142092677115, 11.6422054105729, 12.1525880542070, 12.5255697225560, 12.7216429219752, 12.6753583411735, 12.3348472040677, 11.7383740124419, 10.9446852039132, 9.95151747934865, 8.75591687676917, 7.4081264134003, 6.01910050400593, 4.74211475321368, 3.73812106318327, 3.1393066725737, 3.01900719997446, 3.36723467703441, 4.07410761766882, 4.93296374264173, 5.67880276340669, 6.06702697031743, 5.96739433944242, 5.41757558500513, 4.592450504489, 3.70698982387233, 2.9225673607012, 2.31242542198641, 1.88372574324765, 1.61619752025296, 1.48604497533583, 1.47113203530700, 1.54843495700823, 1.69287680709756, 1.87941417065286, 2.08622333930752, 2.29683744401105, 2.50058081155786, 2.69174250301902, 2.86821510562679, 3.03013683520428, 0.94354564375181, 0.983787386357153, 1.02675280552026, 1.07295699757722, 1.12371510950438, 1.18074845445232, 1.24517546475670, 1.31618367801439, 1.39004416549649, 1.46020800792066, 1.51882724818684, 1.55927229317398, 1.57849612815685, 1.57793900104003, 1.56232788310408, 1.53695717193831, 0, 0, 0, 0, 1.35271072387667, 1.34672504611843, 1.37785678824035, 1.44819982498715, 1.54703011471877, 1.65436466257631, 1.74932452688019, 1.81887070844607, 1.86308633196447, 1.89556572055070, 1.9390322954291, 2.01639759254752, 2.13810363653531, 2.28969692155518, 2.427504372846, 2.48982672335683, 2.42285040369026, 2.20879317432130, 1.87897606141514, 1.50288071153121, 1.16013063439487, 0.912573335938535, 0.790591133594649, 0.796045458530972, 0.914487103973513, 1.12747697504965, 1.42005384450062, 1.78319316238872, 2.21331005740126, 2.71064434367517, 3.27732646536599, 3.91519716760642, 4.62329005734311, 5.39510456168936, 6.21621757327717, 7.06327301242258, 7.9056052297844, 8.70999107284356, 9.4469034688277, 10.0945462295239, 10.6377911612855, 11.0628781323255, 11.3507040461026, 11.4727456489421, 11.3958976497151, 11.1004131347047, 10.5939821656954, 9.88658154300633, 8.97332299910585, 7.86228671352143, 6.60515880166245, 5.30766424451044, 4.11621685142323, 3.18646404006103, 2.64746228968406, 2.57146590101964, 2.95124046979819, 3.68553460661292, 4.58003896186162, 5.37921139998847, 5.83940340887789, 5.8229104324573, 5.35607422557408, 4.60293024962532, 3.76997450626262, 3.01328345100888, 2.40527823300771, 1.9577693963065, 1.65955376513281, 1.49713048904909, 1.45637228309705, 1.51806507254699, 1.65697080329399, 1.84549145126302, 2.05860725754754, 2.27717769870547, 2.48879719654197, 2.68687859175995, 2.86900330070003, 3.03529057594503, 0.95100699763883, 0.996777418088754, 1.04493853403867, 1.09489171735182, 1.14666407008325, 1.20080029597647, 1.25775824488018, 1.31698976653930, 1.37618399211406, 1.43123344170487, 1.47719934470206, 1.50996994964733, 1.52774809125958, 1.53138611245173, 1.52313790116606, 1.50445774682786, 0, 0, 0, 0, 1.25717033989132, 1.23631649997316, 1.26567685675133, 1.34927921487272, 1.47323274442430, 1.61079077120577, 1.73390142958542, 1.82514919323654, 1.88487390658289, 1.93156622510922, 1.99585310968938, 2.10856640545299, 2.28413007258993, 2.50438077278172, 2.71289653815108, 2.82930920342713, 2.78256120706929, 2.54710393882458, 2.15985337690282, 1.70642682024983, 1.28551561074783, 0.97335542336343, 0.806345766466208, 0.784860642541372, 0.888796920438674, 1.09315143126948, 1.37732370797529, 1.72802632558869, 2.13852609768343, 2.60665928553805, 3.13271442675496, 3.71731220065095, 4.35914436375287, 5.05260755479131, 5.78571780613993, 6.53906689754941, 7.28675649935905, 7.9997713338195, 8.65082460150697, 9.21808220509489, 9.68525907585324, 10.0381560450378, 10.2604089776522, 10.3321653603728, 10.2343516080589, 9.95575171538123, 9.49350282273242, 8.8439393319599, 8.00210252152164, 6.97951179241517, 5.82576825235773, 4.63806265082522, 3.55043386770376, 2.70615779064204, 2.22498257869636, 2.17526501123687, 2.55386996610945, 3.27295854630929, 4.15800711278785, 4.97239170287795, 5.48289914436722, 5.5499692083799, 5.18702264977242, 4.53896565214011, 3.79326171665902, 3.09279857136931, 2.50610459938342, 2.05040417954058, 1.72595044009793, 1.53189208252267, 1.46381202181983, 1.50738416128486, 1.63787149840531, 1.82552799994552, 2.04237436114477, 2.26670819978793, 2.48441575204783, 2.6879987672148, 2.87466592179464, 3.04445098675135, 0.962638766407284, 1.01493860768696, 1.0694611551687, 1.12455298837906, 1.17903163013805, 1.23233516045771, 1.28427466268385, 1.33447119597981, 1.38179651568390, 1.42422544856909, 1.45931987873487, 1.48513962227921, 1.50095527745115, 1.50705398216142, 1.50339897192472, 1.48784167048130, 0, 0, 0, 0, 1.15582885129295, 1.11845060027401, 1.14687235533435, 1.24701547383466, 1.40101680322886, 1.574053465753, 1.72959445735005, 1.84504100250775, 1.92092301293643, 1.98122831494475, 2.06546046634203, 2.21333398343283, 2.44384371760246, 2.73507944527938, 3.01716561082883, 3.1899368554317, 3.16401988849397, 2.90558224317328, 2.45740739780048, 1.92214812768634, 1.41864848471555, 1.03836076112613, 0.824060586871835, 0.774576625384017, 0.863875564125216, 1.06009187759571, 1.33678016028384, 1.67630866118825, 2.06882214094618, 2.50985322138440, 2.9979826054215, 3.53273226158439, 4.11250145569231, 4.73249455572551, 5.38289428164228, 6.04782807996747, 6.70580904613466, 7.3320351253735, 7.90199073879248, 8.3946253993592, 8.79320211278241, 9.08352898775428, 9.25152754880851, 9.2827756499107, 9.16487693270687, 8.88988780971758, 8.4528090167962, 7.84811864990748, 7.0730449039241, 6.14113140479597, 5.09867483929346, 4.03223862561108, 3.05970217261452, 2.30697453157639, 1.87990324937794, 1.84043047804881, 2.18969061962957, 2.8559619426594, 3.68989268434652, 4.48195280417731, 5.01857471122153, 5.16452133132806, 4.91978395647558, 4.40311269282096, 3.77353370012533, 3.15367626124512, 2.60543954053048, 2.1520488739111, 1.8070468380001, 1.58389552573572, 1.48899451597961, 1.51361062547930, 1.63402370037281, 1.81875932438784, 2.03720584533219, 2.26531873101537, 2.48739127399064, 2.69504803998947, 2.88510824513838, 3.05747959769399, 0.978389826513545, 1.03813366409216, 1.10007752811983, 1.16157462697492, 1.22031632545043, 1.27471197345863, 1.32395084031110, 1.36774223687365, 1.40592127165896, 1.43820233855814, 1.46425397202840, 1.48397280984886, 1.49752542336446, 1.50467194900804, 1.50329881247949, 1.48794868948076, 0, 0, 0, 0, 1.05709619079297, 1.00305150595891, 1.03220828539262, 1.15217992513101, 1.34038110092724, 1.55282393715889, 1.74345625430759, 1.88385599320229, 1.97465376049709, 2.04569999655414, 2.14595535941778, 2.32458327286331, 2.60559224037445, 2.96366597768010, 3.31578864106576, 3.54230933990802, 3.5357812336089, 3.25414662311207, 2.74587039503826, 2.1302653105808, 1.54590855345934, 1.09915102497817, 0.838997519291495, 0.76273694887476, 0.83850002303247, 1.02768326158842, 1.29812302143778, 1.62797108260356, 2.00438808882176, 2.42075480076785, 2.87409929395491, 3.36297456965993, 3.88554367635094, 4.43774166523155, 5.01166154797571, 5.59455071851085, 6.16890329556817, 6.71394387367587, 7.20819344433113, 7.63201776894453, 7.96882915560246, 8.20456069716965, 8.32655819498416, 8.32351701974324, 8.18669176875442, 7.91056465626032, 7.49141734951126, 6.92599733293301, 6.21523289241848, 5.37472215879375, 4.44700857293932, 3.5069433059011, 2.65422556307159, 1.99458964805460, 1.61716226714645, 1.57550060664533, 1.87426515142982, 2.45859358391074, 3.20733255644979, 3.94401805812457, 4.48238796568358, 4.69733798684732, 4.57603232131514, 4.20631227259223, 3.71189458582795, 3.18990842922118, 2.69353254025187, 2.25217334812197, 1.89351647770082, 1.64594462224690, 1.52696437239695, 1.53367160366248, 1.64371328895448, 1.82433426272097, 2.04273146507718, 2.27286457470668, 2.49765381101943, 2.70795405608894, 2.90022442043484, 3.07423178856951, 0.998021522634223, 1.06599193535286, 1.13625821691098, 1.20524093898920, 1.26958929611484, 1.32676579415690, 1.37537343261551, 1.41514899165220, 1.44670231100576, 1.47118287959050, 1.49001119269525, 1.50461881104138, 1.51591961397429, 1.52320460244987, 1.52253001599029, 0, 0, 0, 0, 0, 0.972530748310331, 0.903652747420896, 0.936146147682005, 1.07891424140846, 1.3040367114461, 1.55766448773798, 1.78362889201175, 1.94733442562736, 2.04942578295794, 2.12567843298615, 2.23457370640998, 2.43476691847413, 2.75550769134523, 3.16883327409701, 3.58008607076567, 3.85213060874572, 3.86123366657837, 3.55785080230452, 2.99540733027766, 2.30800631595915, 1.65177413137852, 1.14629653275103, 0.846065077276777, 0.746906208714226, 0.811640146078131, 0.995542024076472, 1.26124249505557, 1.58304567249008, 1.94539200193690, 2.33971780030030, 2.76167349935783, 3.20897824116357, 3.67961965035758, 4.17019935526695, 4.67448772742593, 5.18245530312672, 5.68012075060947, 6.15042970961559, 6.57499702276399, 6.93603977479963, 7.21763948728686, 7.40599676237211, 7.48926813769046, 7.45787634505296, 7.30529734448447, 7.02822804455271, 6.62554792895963, 6.09779696280771, 5.4502614749264, 4.70058043875242, 3.88733193833194, 3.07339783517054, 2.33983097283263, 1.77134631066104, 1.43921123844401, 1.38734951416898, 1.62270673564244, 2.10646236722098, 2.74633362867571, 3.40207518672835, 3.91981417491746, 4.18918162452068, 4.18612518308838, 3.96577393150584, 3.61317407285830, 3.19725774590358, 2.76125180718354, 2.34035575503723, 1.97599371421654, 1.71079927613797, 1.57274383841660, 1.56448005581144, 1.66520486009922, 1.84136756699013, 2.05853715091498, 2.28915460822616, 2.51509137194218, 2.72661114233193, 2.91988532118113, 3.09454875014395, 1.02109811365829, 1.09790342533427, 1.17719009048300, 1.25450575084211, 1.32554067992114, 1.38689493588371, 1.43663133811434, 1.47447683105750, 1.50166585111370, 1.52052859982120, 1.53393542575763, 1.54459492985968, 1.55404924406943, 1.56119995998691, 0, 0, 0, 0, 0, 0, 0.915847593483214, 0.836178187324251, 0.875480130812127, 1.04332674785114, 1.30606534444417, 1.59982787176808, 1.85833499845374, 2.04086468873261, 2.14802588501659, 2.22124836777596, 2.32801635511758, 2.53592940752266, 2.87944091474338, 3.32909590659129, 3.78127729870511, 4.08506749972566, 4.10379415256363, 3.78185336753706, 3.17637374494268, 2.43287500555873, 1.72107155818744, 1.17076414429705, 0.840588188079475, 0.72505655214225, 0.782638398039884, 0.963599267521557, 1.22626441339956, 1.54170030578401, 1.89201579739259, 2.26696334976238, 2.66100738159669, 3.07117041737781, 3.49532733412199, 3.93069437616132, 4.37251379082112, 4.81311646953738, 5.24159839168944, 5.64425894952087, 6.00571113154896, 6.31026924221787, 6.54309629105133, 6.69087657669489, 6.74229376488013, 6.6887408728011, 6.52514406252388, 6.25019178285313, 5.86570934984937, 5.37637703463917, 4.79176790447123, 4.13124097277968, 3.42930154841628, 2.73724520476704, 2.11821535980161, 1.63660232929412, 1.34607659103837, 1.28045981934670, 1.44764883334241, 1.82300341445903, 2.34171244382718, 2.89992350191968, 3.3781526383509, 3.68364261009139, 3.78353529376821, 3.70155861445238, 3.48457317695637, 3.17341483169433, 2.80105752002886, 2.40749067506522, 2.04615779488076, 1.77198432394136, 1.62185467835522, 1.60322642431847, 1.69687763630723, 1.86898490450481, 2.08416487647675, 2.31393362349772, 2.53952899506404, 2.75086226826116, 2.94392521474323, 3.11824870798495, 1.04698870124727, 1.13302591180298, 1.22179279190668, 1.30802470296969, 1.38653678222321, 1.45315414868666, 1.50545649829038, 1.54314808464400, 1.56797825694887, 1.58325629897395, 1.59305535739375, 1.60114856913319, 1.60961659810622, 0, 0, 0, 0, 0, 0, 0, 0, 0.81691646749394, 0.867125300745832, 1.06128177128617, 1.35988257768077, 1.68951397339454, 1.97448497955243, 2.16845745132994, 2.27202631803578, 2.33168781075535, 2.42284394184180, 2.62091209999590, 2.96522795905121, 3.42629756241166, 3.89521364154706, 4.2124161656575, 4.23296354613966, 3.89720643703607, 3.26426960091667, 2.48644635383678, 1.74157674767460, 1.16551106082893, 0.819179027180778, 0.695990753155584, 0.75139246948324, 0.932172577397676, 1.19358073071636, 1.50426052920568, 1.84448284332969, 2.20262009069874, 2.57215357606824, 2.94954499328021, 3.33261809474438, 3.71916167562529, 4.10571197600133, 4.48663879076049, 4.85369981623029, 5.19616183053425, 5.50143883339176, 5.75602686729301, 5.9464551535049, 6.0601320482048, 6.08622711336624, 6.01675634857708, 5.84766706022691, 5.5793693166554, 5.21648480606116, 4.76753249734669, 4.24580282314573, 3.67182507608913, 3.07601097925181, 2.49889834633584, 1.98726553989541, 1.5869197986809, 1.33521914606134, 1.25612577941662, 1.35734387230074, 1.62599999458328, 2.02177020221556, 2.4747138105083, 2.89875488006732, 3.21978978640451, 3.39908688355389, 3.43302494959382, 3.33424684601163, 3.11813968400205, 2.80797251378519, 2.44698704747002, 2.09779480929386, 1.82456958601457, 1.67081156251671, 1.64764684741713, 1.73734479132087, 1.90635779973579, 2.11910753107059, 2.34686295539809, 2.57070788873595, 2.78048174931621, 2.97212921515105, 3.14511870004991, 1.07488233402268, 1.17030687045977, 1.26875038845306, 1.36420104678364, 1.45068622401101, 1.52334886742425, 1.5793545116302, 1.61839580979482, 1.64266533324465, 1.65629750065933, 1.66436886814943, 1.67154218303007, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.859988926328235, 0.925387645432164, 1.14571378157589, 1.47581342112195, 1.83384838008954, 2.1361120403578, 2.33163001235434, 2.42110196592037, 2.45524539856815, 2.51582174010639, 2.68445471255491, 3.00477213172692, 3.44883593178079, 3.90673049854943, 4.21631183063711, 4.22989168356035, 3.88617155301026, 3.2442822533598, 2.45783834117892, 1.70638443567208, 1.12692378908942, 0.780509371398886, 0.659702823351634, 0.718496349117792, 0.9020081073232, 1.16385755570947, 1.47121450837058, 1.80307376959759, 2.14675786597573, 2.49497171626316, 2.84374669331355, 3.19091299455228, 3.53479653522567, 3.87307431254636, 4.2018756273931, 4.51524726296719, 4.80504711380782, 5.06123645568000, 5.2724558151044, 5.42676050042888, 5.51249437202479, 5.51940221771552, 5.44002264525108, 5.27109890601879, 5.0144804236469, 4.67718291527662, 4.27091814387309, 3.8118625830857, 3.3210717114422, 2.82492775611449, 2.35430162974645, 1.94159241695243, 1.61634970510073, 1.4015304432725, 1.31202473176993, 1.35451811405628, 1.52532890180802, 1.80463870786004, 2.15197834004424, 2.51133629491611, 2.8267262644497, 3.05668703867201, 3.17624594293406, 3.17035656642909, 3.03349663987821, 2.78042638937409, 2.45575336694569, 2.12764802490539, 1.86578134979490, 1.71749999905522, 1.69622209978043, 1.78553685769358, 1.95272359282419, 2.16280027422348, 2.38750286356452, 2.60826803791570, 2.81516136192555, 3.00422340300394, 3.17490815514169, 1.10381703385098, 1.20852101478370, 1.31655895366297, 1.42124541840417, 1.51591497159556, 1.59512964508367, 1.65572359371210, 1.69741251796481, 1.72279361400564, 1.73670819100034, 1.74506637690714, 0, 0, 0, 0, 0, 0, 1.58913223619438, 1.41598580635647, 0, 0, 0, 1.05925270670365, 1.30399724473805, 1.65876206107144, 2.03498685710559, 2.34294928940853, 2.5284247028218, 2.59243961947721, 2.58892076466361, 2.60411397348901, 2.7239117871326, 2.9954225156128, 3.39380705770754, 3.81254480068033, 4.09319738622028, 4.09107973534012, 3.74575018104702, 3.11429412472072, 2.34599761313982, 1.61545190923992, 1.05573713201989, 0.725783429075148, 0.617577325805072, 0.685296595311754, 0.874276045471402, 1.13801459150929, 1.44319834524063, 1.76812814386961, 2.09941166780816, 2.42917935805868, 2.75315378304392, 3.06922240301793, 3.37621589099452, 3.67281862841475, 3.95667819631171, 4.22380357634307, 4.46829496713612, 4.68238567601624, 4.85674315443798, 4.98100425324561, 5.04460155967666, 5.03798725563302, 4.9542488933575, 4.79081835849201, 4.55071524650956, 4.24284502913428, 3.88133186127395, 3.48433190076046, 3.07279612182018, 2.66921594808487, 2.29599474279330, 1.9732859808457, 1.71691514719209, 1.53762662129107, 1.44235879801677, 1.43627176974171, 1.52240752253846, 1.69706257147505, 1.94371483086022, 2.23161503426386, 2.52125760340776, 2.77150663783849, 2.94297735906016, 3.00081056505363, 2.92413923044157, 2.72079671722104, 2.43476422239831, 2.13588014014083, 1.89531933285732, 1.76136131097607, 1.74826635091782, 1.84073166298714, 2.00738559330348, 2.21460928602487, 2.43529942720185, 2.65173708957056, 2.85450211587011, 3.03986921048686, 3.20732533533317, 1.13272223312905, 1.24632293455985, 1.36358966899601, 1.47724946083230, 1.58005075000077, 1.66608872427905, 1.73196718078598, 1.77748593064693, 1.80563656441920, 1.82186428430149, 0, 0, 0, 0, 0, 0, 1.82818274792173, 1.72016401595309, 1.55700193551130, 1.36868976861155, 0, 0, 0, 1.53597772554033, 1.90652038010271, 2.28879729360916, 2.58949630434193, 2.75280829160933, 2.78039345977335, 2.72830941004451, 2.68528190015393, 2.73940138154712, 2.94029224481665, 3.26751165421069, 3.62194296080942, 3.85464596586699, 3.82925217272897, 3.48850329820454, 2.88556260501965, 2.16019138272887, 1.47590045361875, 0.95717773124494, 0.65877166581228, 0.572360077705241, 0.653835610052532, 0.85050967163483, 1.11717347627125, 1.42096130239861, 1.74003134534842, 2.06059400838958, 2.37439379202220, 2.67695382320466, 2.96626084636526, 3.24161781556638, 3.50259770530758, 3.74815701729101, 3.97598286572712, 4.18210424208891, 4.36075396658593, 4.50446462788384, 4.60443402299454, 4.65127275375803, 4.63626288703977, 4.5531137158434, 4.39989760941735, 4.18056056977183, 3.9053845573589, 3.59012602149661, 3.25406002823669, 2.91747866220481, 2.5991759676545, 2.31428090153480, 2.07277699111193, 1.87924141228758, 1.73440438482568, 1.63850419670026, 1.5949200855714, 1.61121794429414, 1.69551117374148, 1.84946241051312, 2.06225374677320, 2.30865166050146, 2.55055388604577, 2.74106308917444, 2.83352556384665, 2.79745406797097, 2.63546264693904, 2.38905259253247, 2.12603127237674, 1.91530178534082, 1.80333911765207, 1.80388271163292, 1.90252165188919, 2.06969163634698, 2.27381927211465, 2.48957817820306, 2.70052759208614, 2.89801328975798, 3.07866320134031, 3.24203739251773, 1.16047268182674, 1.28231270322883, 1.4081653948512, 1.53027180036267, 1.64091679830306, 1.73386207323319, 1.80561094102969, 1.8561470204207, 1.88887360650809, 0, 0, 0, 0, 0, 0, 2.01418402420495, 1.97624829064800, 1.88429332146759, 1.74071683852030, 1.57565607668087, 0, 0, 0, 1.83317610261374, 2.20917224394844, 2.58449486166266, 2.86486217669856, 2.99465770613541, 2.97652371644275, 2.86759278060010, 2.75711638453790, 2.73336636045576, 2.84744219422562, 3.08419094421777, 3.35507215725952, 3.52530950966963, 3.47115320328226, 3.14042553627108, 2.58087208424029, 1.91855345224886, 1.30097184626700, 0.840271230334566, 0.585374590846591, 0.527887622155729, 0.626679012147843, 0.832489312112698, 1.10257752089357, 1.40531312469854, 1.71918780033912, 2.03029545585425, 2.33016276382057, 2.61420843496804, 2.88055056744862, 3.12892949038351, 3.35969784384671, 3.57293671785234, 3.76776421208188, 3.94186102690868, 4.09120402558669, 4.21001221043862, 4.29097605444281, 4.32591917657511, 4.30704428959211, 4.22875710043187, 4.08974523390393, 3.89466620166816, 3.65470572080841, 3.38654492531177, 3.10982300742053, 2.84371874449599, 2.60355302706262, 2.39829274084098, 2.22964599656710, 2.09320019655252, 1.98170753505404, 1.88993629468463, 1.81939886972948, 1.78033608030089, 1.78883517476457, 1.85940534877062, 1.99605318128625, 2.18547832946248, 2.39478422166905, 2.57564192534864, 2.6767961741364, 2.66332683367458, 2.53425155373529, 2.32707536404968, 2.10445345286167, 1.92983436474716, 1.84558890843558, 1.86378911776330, 1.97072235947375, 2.13899429322787, 2.33962223127864, 2.54954626345937, 2.75394380164527, 2.9451195256032, 3.12014276090564, 3.27867437111918, 1.18595047135674, 1.31511065825414, 1.44864681779150, 1.57843303827926, 1.69643347083971, 1.79624008561057, 1.87443825326451, 1.93136601543285, 0, 0, 0, 0, 0, 0, 2.15144608160418, 2.16785899957252, 2.14820253853788, 2.07882004428627, 1.96271667087556, 1.82926638892322, 1.73348908286837, 0, 0, 0, 2.54982295880739, 2.90541488482461, 3.15352329687586, 3.24043237613358, 3.17009607183148, 2.99974886426401, 2.81740345559856, 2.70969959801621, 2.72816397847552, 2.86332985971484, 3.03927896800437, 3.13851951428038, 3.05282821077945, 2.73641011421366, 2.23061882110381, 1.64504013412787, 1.10788737008959, 0.716468790280311, 0.512806000269353, 0.488623369603515, 0.60665191459664, 0.82208438674549, 1.09549046658595, 1.39705821044548, 1.70598346089853, 2.00847460191902, 2.29598371206182, 2.56390483545322, 2.8105093472821, 3.03593638340988, 3.2412156599455, 3.42738749676315, 3.59478404302079, 3.74249423233591, 3.8680071662102, 3.96705070318566, 4.03371567002569, 4.06103561038481, 4.04219082045169, 3.97234165321069, 3.85077014853933, 3.68265790155845, 3.47968141934326, 3.25883838660123, 3.03950057885107, 2.83937676540556, 2.67054750625636, 2.53680934213301, 2.43325180583861, 2.34844118940113, 2.26893998786809, 2.18516611111501, 2.09678572660448, 2.01524643982469, 1.96142924738289, 1.95818318054281, 2.01993211659863, 2.14312681804187, 2.30160260188047, 2.4503770832384, 2.53935243399608, 2.53338289364685, 2.42929154999747, 2.25953243925632, 2.07931202733739, 1.94427691908829, 1.89100205875764, 1.92904601158496, 2.04523934393604, 2.21460125997096, 2.41111114475552, 2.61430439073402, 2.8111982755683, 2.99517584889536, 3.1637975036378, 3.31683700654693, 1.20811063964749, 1.34343611054927, 1.48352257051535, 1.62001447179709, 1.74472404169159, 1.85128780450055, 0, 0, 0, 0, 0, 0, 0, 2.25610851203507, 2.30456781263028, 2.33881140971639, 2.34122637984402, 2.29910136927369, 2.21573094371425, 2.11890438431439, 2.05945474842546, 2.09494824937105, 0, 0, 0, 3.23085001614218, 3.43693271846854, 3.47448795653554, 3.34902735700967, 3.11702236962071, 2.86375195333720, 2.67270206297544, 2.59482500609754, 2.62622289095952, 2.70442325756072, 2.73064634307501, 2.61357143475623, 2.31443496760008, 1.86779887676710, 1.36554349466498, 0.915126777142455, 0.597915673658236, 0.448577993970889, 0.459094835268186, 0.596530133416168, 0.821075779667278, 1.09708573932872, 1.39692330789751, 1.70074174564101, 1.99504000482028, 2.27131258069640, 2.52499367503291, 2.75452039344010, 2.9603882619978, 3.14420568951296, 3.30782125493992, 3.45258834864133, 3.57878975055936, 3.68522007563787, 3.76894981696584, 3.82537057286111, 3.84870060595031, 3.83312820316907, 3.77460717037644, 3.67299051428576, 3.53382069757677, 3.36891350158564, 3.19507503161619, 3.03089436455697, 2.89233678433220, 2.78846749367076, 2.71877045640911, 2.67312552894624, 2.6347446672627, 2.58552063267218, 2.51249767926561, 2.41358853397694, 2.30035601024567, 2.19602761519184, 2.12827746375067, 2.11843893406658, 2.17081927974661, 2.26683709461991, 2.36814661873962, 2.42988927325365, 2.41973767887059, 2.3334382677585, 2.1978440966363, 2.05933648360871, 1.96434499586503, 1.94263432220751, 2.00073852574286, 2.12592085823554, 2.29572799126509, 2.48728263585603, 2.68286896858281, 2.87143736413667, 3.04748950901527, 3.20908548219699, 3.35610768063108, 1.22604506057333, 1.36618376375796, 1.51149646899304, 1.65355354641900, 1.78421819221163, 0, 0, 0, 0, 0, 0, 0, 2.34789685662057, 2.40845413416048, 2.47159455942912, 2.52496139211373, 2.55155656496459, 2.53909369520177, 2.49059728757422, 2.43155284246791, 2.40768225020221, 2.46948798159920, 0, 0, 0, 3.53862790656612, 3.69571964862813, 3.68083836417071, 3.50116054516308, 3.21163213829372, 2.89359183302795, 2.62616721611798, 2.45881418270592, 2.39262949090085, 2.3782798814911, 2.33554799706293, 2.18996274470457, 1.90983237280123, 1.52306842303713, 1.10406243944429, 0.739750171634011, 0.495749881858436, 0.399506344069225, 0.443344558959055, 0.598740635461294, 0.830984311298498, 1.10833924712990, 1.40548630030094, 1.70367792390586, 1.98982753210891, 2.25556440451787, 2.49641424251601, 2.71098419981336, 2.90008058148339, 3.06579545108281, 3.21064608412376, 3.3368336581044, 3.44564476698143, 3.53699626747860, 3.60915052859866, 3.65870287991286, 3.68102082351696, 3.67131340106537, 3.62635058298124, 3.54652923252766, 3.43761047028734, 3.31125367573521, 3.18365479363746, 3.07220547462993, 2.99092102908619, 2.94605959441686, 2.93352069821074, 2.93915247915308, 2.94220024476678, 2.92115701161484, 2.86053175900124, 2.75663524714938, 2.62040230265254, 2.47565919754716, 2.35235539647253, 2.27611572902241, 2.25751268133508, 2.28576694832718, 2.33102843506127, 2.35613328098747, 2.33347911679211, 2.25856455726405, 2.15256798552461, 2.05255193639809, 1.9952128903169, 2.00314599753532, 2.07967446787523, 2.21242684136470, 2.38146506925647, 2.56705178813062, 2.75420362719664, 2.93377357033393, 3.10134663493129, 3.2554526412217, 3.39606347133714, 1.23903912121117, 1.38249131269775, 1.53156446701519, 1.67792781627440, 0, 0, 0, 0, 0, 0, 2.37558064060418, 2.44436689354214, 2.50873926007134, 2.57734105000107, 2.65242379262148, 2.72396788656705, 2.77483241507891, 2.79202633007052, 2.77741333966449, 2.75353108568906, 2.7605234457676, 2.8416420119923, 3.0208696560738, 0, 0, 0, 3.91207927758807, 3.84506437763035, 3.61566723194194, 3.27662405486756, 2.90438724617906, 2.57281359890838, 2.3290360976616, 2.17822678137015, 2.08299063422304, 1.98026459945442, 1.81123195549146, 1.55082885982748, 1.2208956190649, 0.879716887738974, 0.595306331979489, 0.418769654631335, 0.370927418846663, 0.444493544282463, 0.615119260895567, 0.852928467641754, 1.12993777245864, 1.42311336620650, 1.71485702721190, 1.99257692882189, 2.24810859326581, 2.47710924276053, 2.67835397636956, 2.85291227474585, 3.00326826667825, 3.1324781816075, 3.24343354064689, 3.33825490148798, 3.41781844730609, 3.48144313316361, 3.52683737457090, 3.55047851625861, 3.54859769363507, 3.51879161662979, 3.46197123667605, 3.38399295111442, 3.29611356696794, 3.21357847103744, 3.15225316105981, 3.12405164835344, 3.13261532252379, 3.17087221251100, 3.22161501778013, 3.26126807530427, 3.26597905445538, 3.21844207421044, 3.11357039717430, 2.96123026587739, 2.78470152775824, 2.61448594389697, 2.47864116439284, 2.39267284379267, 2.35328674026335, 2.33977229945632, 2.32373005447298, 2.28321268344814, 2.21404157464721, 2.13204274449874, 2.06521527069588, 2.0407754002183, 2.07435270493022, 2.16615325656306, 2.30414046780150, 2.47076976958298, 2.64928019857049, 2.82725783486654, 2.99732172966528, 3.15604101124509, 3.30235350404580, 3.43628994501087, 1.24661611499534, 1.39179213671918, 1.54307424172695, 0, 0, 0, 0, 0, 0, 2.43060842126561, 2.54237249483591, 2.63024833964687, 2.69890941290796, 2.76714144462936, 2.84740751009105, 2.9333628480457, 3.00643340627799, 3.05105829361992, 3.06663280466995, 3.07211920444284, 3.10200531795, 3.19271331889607, 3.362816040078, 3.59646762917577, 0, 0, 0, 3.95602813629378, 3.68433378704683, 3.30672322120981, 2.89402542326643, 2.51415333603156, 2.21119166855654, 1.99326343734887, 1.83312934868986, 1.68264151616750, 1.49668531171301, 1.25606097455875, 0.977410936433074, 0.705073415315327, 0.490652503607115, 0.3726733705991, 0.366242537884173, 0.464478173035092, 0.646756393582717, 0.887527138594408, 1.16221195493624, 1.44991052148943, 1.73415985423387, 2.00291134841989, 2.24826211170257, 2.46603201507261, 2.65515739643772, 2.81692277379015, 2.95411690466575, 3.0702144739631, 3.16865379173592, 3.25223637194869, 3.32265162033971, 3.38015282538813, 3.42347679573661, 3.45016881417882, 3.45747430365819, 3.4438171971261, 3.41059109544556, 3.36364217678308, 3.31362398699383, 3.27456159269035, 3.2605425831304, 3.28127816805857, 3.33797006692024, 3.42109133616192, 3.51118546648375, 3.58279748225431, 3.61060329287770, 3.57610505423249, 3.47306754052286, 3.31009256323332, 3.10924546864765, 2.90050156805307, 2.71307869610434, 2.56628393903703, 2.46358562581604, 2.39313401835895, 2.33530717421169, 2.27399040375227, 2.20568721950417, 2.14148044362069, 2.10112150936363, 2.10318092279693, 2.15695554667143, 2.25984236239613, 2.40013789612733, 2.56248563412111, 2.73281547739397, 2.90100891705192, 3.06123527352589, 3.21090193438083, 3.34927089972272, 3.47639424058882, 1.24856530173493, 1.39384819316798, 0, 0, 0, 0, 0, 0, 2.41819411523256, 2.59777130642435, 2.7567185519997, 2.86513147984249, 2.92852500415571, 2.98265142049340, 3.05686560052103, 3.1504889786602, 3.2417121396971, 3.30979107320048, 3.34990577481436, 3.37677519958257, 3.41942873702670, 3.5083315627451, 3.65797351069995, 3.85271982266417, 0, 0, 0, 4.007093672664, 3.7025015391757, 3.29901939373993, 2.86127284730575, 2.45074073164693, 2.10783817275225, 1.84245188969289, 1.63545452101794, 1.45098207452119, 1.25530784147137, 1.03417868531941, 0.800053756191255, 0.585859332504032, 0.42974064283669, 0.359908028759545, 0.386812262300497, 0.503974411126009, 0.693939455739319, 0.934853627055834, 1.20509874496898, 1.48569362645017, 1.76126063304262, 2.02032306415148, 2.25528359349319, 2.46214924893792, 2.64000798219648, 2.79031214266137, 2.91607281156416, 3.02107191851490, 3.10916366862723, 3.18369185760342, 3.24702644914452, 3.30024234475556, 3.34302307732855, 3.37393548274495, 3.39122131776857, 3.39412192162006, 3.38448067878475, 3.36804591506348, 3.35471139344925, 3.35707968699715, 3.38728238679617, 3.45277645656877, 3.55249620645451, 3.67489914944607, 3.79894447591149, 3.89806790394557, 3.94619400389797, 3.9241712628075, 3.82489394376102, 3.6556847256857, 3.43707534556907, 3.19790021684427, 2.96768524257795, 2.76856019292168, 2.60977070252456, 2.4874308694533, 2.38999328011322, 2.30683392472665, 2.23533581345614, 2.18261792169177, 2.16135563743933, 2.18268329549423, 2.25047675977652, 2.3597724406411, 2.49921817826900, 2.65538723697543, 2.81653760622159, 2.97450283377708, 3.12473866714307, 3.26531820069744, 3.39573267870688, 3.51601611227033, 1.2449510949895, 0, 0, 0, 0, 0, 0, 2.31877747181360, 2.55084585109469, 2.80833448869359, 3.02929729686779, 3.15896040672430, 3.20428289247598, 3.22641672531111, 3.27986866984907, 3.37214302074471, 3.47605982429608, 3.56256010020446, 3.62054739521273, 3.65977952285755, 3.7041803454781, 3.77939621530557, 3.89740574913533, 4.04435529505723, 4.17905109559009, 0, 0, 0, 3.66949889339742, 3.25334363040277, 2.80615975372559, 2.38264213361332, 2.01902487876089, 1.72583035069756, 1.49001085173346, 1.28533599837908, 1.08712593126027, 0.885141371675876, 0.688678137370672, 0.521807461035736, 0.412193878879833, 0.380018890060422, 0.432142670980614, 0.562482154738458, 0.756181810512439, 0.994438459794531, 1.25813413037513, 1.52997879692287, 1.79561860253198, 2.04416773214968, 2.26837091071543, 2.46444202821530, 2.63160950406052, 2.77144855090943, 2.88711640423451, 2.98260065428365, 3.06205251915758, 3.12923194458304, 3.18706739104822, 3.23734864047664, 3.28062353217357, 3.31642609256387, 3.34396355340408, 3.36327289038583, 3.37661251973715, 3.38956346404198, 3.41114763423052, 3.45241031205621, 3.52342286889907, 3.62938988315687, 3.76715524019138, 3.92354079582932, 4.07646899151008, 4.19888987740432, 4.26456325590382, 4.25414232936117, 4.15993644465779, 3.98809303836819, 3.75752527912844, 3.49562352749531, 3.2316566977389, 2.98972379035988, 2.78373564014786, 2.61652823940039, 2.48351228821768, 2.37890062550632, 2.30103503282786, 2.25391263461343, 2.2444692072627, 2.27779224768849, 2.35338367218992, 2.46443725431281, 2.59998236025051, 2.74824163246063, 2.89940567576053, 3.04688890518693, 3.18715256019502, 3.31875582467781, 3.44132381917822, 3.55483591674010, 0, 0, 0, 0, 0, 0, 2.15489970590758, 2.39081310549088, 2.70536239050772, 3.06090377551620, 3.35795956294746, 3.50897440518838, 3.52297505081532, 3.49485470341704, 3.51245175323197, 3.59397755823822, 3.70480841404044, 3.80449022030639, 3.873613293625, 3.9162838016825, 3.95173549867233, 4.00202500133583, 4.07825614238096, 4.16989339296694, 4.24318720787045, 4.25135957634614, 0, 0, 0, 3.17225638684078, 2.73017172866809, 2.30993363850969, 1.94320406748616, 1.64016164728746, 1.39201138625677, 1.17975080823682, 0.985614424206795, 0.8025231631086, 0.637532847885169, 0.508182716659592, 0.434364441369483, 0.430310037901873, 0.500258716036647, 0.63851807622943, 0.832315555040257, 1.06531253191588, 1.32047370033431, 1.58199314447030, 1.83648436200484, 2.0736685340943, 2.28666395635014, 2.47190749946052, 2.62875642069685, 2.7588671134083, 2.86547380412696, 2.95267819454637, 3.02482133384418, 3.0859645345613, 3.13948119527874, 3.18777236391576, 3.23216367810119, 3.27309063424794, 3.31067927201531, 3.34572652678189, 3.38086839897939, 3.42146738918477, 3.47560620802839, 3.55270554116043, 3.66074686442612, 3.80274081265035, 3.97363091380934, 4.15893836037867, 4.33599842838345, 4.47777238419762, 4.55832138912471, 4.55848161148757, 4.47024800846079, 4.29875988683818, 4.06136748756696, 3.78390747897819, 3.49501707425565, 3.22002482595880, 2.97638274496369, 2.77228129909174, 2.60880042454835, 2.48419006422399, 2.39774760134698, 2.35116558412482, 2.34698391725088, 2.38564914090003, 2.46335043303097, 2.57196584870496, 2.70094187243720, 2.83987470665108, 2.98049811821300, 3.11744443498035, 3.24790922524557, 3.37076801120264, 3.48569302136469, 3.59257900027179, 0, 0, 0, 0, 0, 1.96510614229525, 2.16942873207622, 2.46280470152225, 2.87093302981427, 3.33763845491763, 3.71985841195565, 3.89201955996671, 3.8656092079168, 3.77475026536904, 3.74600362628862, 3.80993827792461, 3.92305779597308, 4.03135851021596, 4.10563873491944, 4.14385710300896, 4.16098935517456, 4.17668454579957, 4.20272383323769, 4.23329174013053, 4.2429180806114, 4.19454052733131, 0, 0, 0, 3.06065031214002, 2.63618381206430, 2.23306592381181, 1.8781284990826, 1.58042843272462, 1.33390934270248, 1.12478018673622, 0.940394008315007, 0.776105981994396, 0.637496821658005, 0.537514653805246, 0.490544793255309, 0.506612515848655, 0.588151344607697, 0.729859942842646, 0.920622062654355, 1.14607947867995, 1.39093655089365, 1.64070410028482, 1.88292047271246, 2.10793042001900, 2.30925350613365, 2.48356273726449, 2.63033277275432, 2.75126354577641, 2.84960477071336, 2.92949108748288, 2.99535775748613, 3.05146331679129, 3.10151975726206, 3.14843711414796, 3.1942261370379, 3.2401446022253, 3.28717307000321, 3.33681757410609, 3.39205077497573, 3.4579829735831, 3.54173388500537, 3.6510979911925, 3.79201022130004, 3.96540309783438, 4.16452844429218, 4.37390824581615, 4.57065809261371, 4.72813692459467, 4.82106392634924, 4.83075555117925, 4.74912859131509, 4.58050067337631, 4.34078528062473, 4.05426525912366, 3.74869638275875, 3.45000764026545, 3.17814193689904, 2.94530956246004, 2.75697134059101, 2.61458888613107, 2.51835699848749, 2.46839430296415, 2.46408142618946, 2.50252613540869, 2.57759000024291, 2.68032584311639, 2.80063312452758, 2.92923049119615, 3.05904075064743, 3.18558675791509, 3.30655731470082, 3.42099705265026, 3.52855370291116, 3.62901647669827, 0, 0, 0, 0, 1.77244922681495, 1.94359970066235, 2.17435363713948, 2.52460626678491, 3.02565009375498, 3.60282356621945, 4.06970043177021, 4.26286776359110, 4.1961567218787, 4.04254961855753, 3.9669779498333, 4.01216789613556, 4.12557411215034, 4.23934601800604, 4.31414771842082, 4.34169391885483, 4.33314815465628, 4.30679707310553, 4.27645971817758, 4.24222999890118, 4.18753563607219, 4.0849828395871, 3.90876804178728, 0, 0, 0, 2.52814598084648, 2.15301131862877, 1.82153524313441, 1.54109509184299, 1.3072045346518, 1.10969925072650, 0.939628180391214, 0.79419349647664, 0.678082935892959, 0.601160465165412, 0.574071901603192, 0.603997806084035, 0.69220674997142, 0.833795014777213, 1.01897728925256, 1.23500633057837, 1.46806706349688, 1.70486432452605, 1.93383459535406, 2.14596362264024, 2.33519612783253, 2.49845159166775, 2.63531120363672, 2.74748531143051, 2.83818568113983, 2.91150929674246, 2.97190150957415, 3.02372425215154, 3.07092847630907, 3.11683170539890, 3.16403046986294, 3.21451190805152, 3.27002915913330, 3.33273130182279, 3.40588278105038, 3.49432389992020, 3.60422769509665, 3.74182144749493, 3.91110453897710, 4.11110144082727, 4.33360127366316, 4.56240286010961, 4.77470094026124, 4.94454327889799, 5.04756569962799, 5.06578333141435, 4.99122424271838, 4.82755965237284, 4.5894149877291, 4.29957267669513, 3.98473974877174, 3.67092494635606, 3.37963969114084, 3.1259121379487, 2.91840608806161, 2.76102165324091, 2.65475827376112, 2.59876869971583, 2.59033354202060, 2.62434512058174, 2.69318929233023, 2.78751851551428, 2.89771772549129, 3.01541416037564, 3.13441940329611, 3.25087229609419, 3.36275656333311, 3.46916897940182, 3.56968009734216, 3.66396289281138, 0, 0, 0, 1.58470883618565, 1.73502766441058, 1.91293748271447, 2.16544683257109, 2.56279486334244, 3.14071030794898, 3.80962124506377, 4.34822143472737, 4.5625616679788, 4.46801453198972, 4.26831134239462, 4.15880707713804, 4.19171357318822, 4.30688595677406, 4.42476880035141, 4.49705839511362, 4.50967433307981, 4.47044307900645, 4.3971506361736, 4.30675574453578, 4.20618317953089, 4.08813920853112, 3.93466889864969, 3.72704295875385, 3.45666894480143, 0, 0, 0, 2.07119345927457, 1.77153447615679, 1.51696945227641, 1.30373832209976, 1.12412172397465, 0.971788558414307, 0.84532620851451, 0.748933935238174, 0.690484264697459, 0.678174931411305, 0.717341715064971, 0.808562478853373, 0.947342251813863, 1.12499555121899, 1.33012327782522, 1.55020887240436, 1.77306835145094, 1.98802249249218, 2.18671472401152, 2.36353430355025, 2.51565455685885, 2.64275303480229, 2.74652211509233, 2.83009040977700, 2.89745726584049, 2.95300543293126, 3.00111668580166, 3.04588818196336, 3.0909447941045, 3.13936399280101, 3.19375729885602, 3.25655272678010, 3.33046259982005, 3.41899429843264, 3.52671360829156, 3.6588974593937, 3.82031683572445, 4.01320455905818, 4.23489384431806, 4.47595838785879, 4.71972970936481, 4.94372373201054, 5.12288798436222, 5.23394880968571, 5.25976584826393, 5.19261651848062, 5.03567216853659, 4.80241207716812, 4.51419053256754, 4.19655349565783, 3.87517187638026, 3.57235651203448, 3.30493488999421, 3.08376397042768, 2.91450441882712, 2.79884787394118, 2.73545344532717, 2.72035274358822, 2.74713253033366, 2.80739463046763, 2.89173615357247, 2.99105436225786, 3.09771388920992, 3.20617693777928, 3.31298428740456, 3.41626448554906, 3.51508274826301, 3.60889977955296, 3.69727166427682, 0, 0, 1.40762850517197, 1.54356551208450, 1.69184062105183, 1.8731953670748, 2.13897022493002, 2.56499922078711, 3.18930796011415, 3.91429815709294, 4.50000495051887, 4.7359189632402, 4.63751260733886, 4.42391051723218, 4.30583069472527, 4.33998243423948, 4.46159729941088, 4.58386050158338, 4.65211122168397, 4.64746249937767, 4.57491313819493, 4.45241172893453, 4.30086310124321, 4.13463683569654, 3.95583914784051, 3.75554805686767, 3.52141052758602, 3.24706978452943, 0, 0, 0, 1.98926544665286, 1.72672626326508, 1.50364941129365, 1.31643121693145, 1.15895130047359, 1.02670983981757, 0.919318892883576, 0.840740438080126, 0.797596361491718, 0.796524857007629, 0.841709965392032, 0.933371164639679, 1.06743530404756, 1.23616251375303, 1.42932555000198, 1.63558552166351, 1.84381662366256, 2.04421756417642, 2.22910289706122, 2.39332030253168, 2.53430107868726, 2.65180966256681, 2.74749683820238, 2.82437102693737, 2.88628442542472, 2.93749580103737, 2.98233361193315, 3.02495599808626, 3.06919786732236, 3.11850971285308, 3.17601367169845, 3.24470271999271, 3.32776162479576, 3.42888834359992, 3.55237961749726, 3.70269327697016, 3.88329507548647, 4.09486493876461, 4.33329713894825, 4.58821014935076, 4.84270664801166, 5.07481954142049, 5.26054212545999, 5.37779567929201, 5.41036819680875, 5.35087569738822, 5.20210074949845, 4.97649669847743, 4.69406139213703, 4.3791044158219, 4.05663461616103, 3.74914895739608, 3.47445266574726, 3.24477267635244, 3.06696422013101, 2.94328978443445, 2.87225556851223, 2.84928663597351, 2.86735808637113, 2.91781627508257, 2.99146594492362, 3.07973671498197, 3.17560163018607, 3.27399728079993, 3.37171249340596, 3.46691809257337, 3.55859634057817, 3.6460842941179, 3.72882937020616, 1.13862439837727, 1.24886650514417, 1.36948426978059, 1.49964412963501, 1.64438996768607, 1.82517052719911, 2.09350010878334, 2.5247872389276, 3.15666083030701, 3.89225552970043, 4.49355225877902, 4.7512440155177, 4.67912065116954, 4.49227214427259, 4.39772056850018, 4.4504005229523, 4.58479882844077, 4.7126502454617, 4.77643622746442, 4.75380896887505, 4.64746264417377, 4.47597619611878, 4.26469412878976, 4.0357064359194, 3.80035946397417, 3.55818295357547, 3.30244306870974, 3.02840488196622, 2.73916485990489, 0, 0, 0, 1.68613205732468, 1.49764140040155, 1.33955628661032, 1.20676675017779, 1.09603487279523, 1.00771312839694, 0.94565792284478, 0.915708967998724, 0.92352189044543, 0.972584307882505, 1.06297865845425, 1.19106585655980, 1.34995342006370, 1.53047221973131, 1.72238265750590, 1.91558238798266, 2.10114324511268, 2.27205856250902, 2.42364193695782, 2.55358327388246, 2.66172502758510, 2.74965738377641, 2.82023944527764, 2.87713688734118, 2.92443420540394, 2.96634394541410, 3.00700845039080, 3.05038017292837, 3.10017489650203, 3.15990716064601, 3.23301746388505, 3.32306490053411, 3.43388304152265, 3.56951146775960, 3.73368342299261, 3.92873710150251, 4.15404228724653, 4.40432849588217, 4.66852444425504, 4.92972589817951, 5.16664160640235, 5.3564066501984, 5.4781884719715, 5.5167386353996, 5.4650598735507, 5.32562276022907, 5.10994847528762, 4.8367403357636, 4.5290212736803, 4.21089402139157, 3.90457121621668, 3.62819985390263, 3.39473276272095, 3.21176472159953, 3.08200647099949, 3.00403636300597, 2.97312711434449, 2.98213939266291, 3.02254327649321, 3.0855383628711, 3.1630995098901, 3.24871690625825, 3.33768106160447, 3.42692907913671, 3.51461402193046, 3.59961227680278, 3.68113959991685, 3.75854999474245, 1.11490596258492, 1.21746500400875, 1.33068383281863, 1.45450530104452, 1.59435789685668, 1.77064528031373, 2.03102038182961, 2.44464496781032, 3.04615125821035, 3.74786587113109, 4.33361166215026, 4.6124521682447, 4.59482299030328, 4.47309368174986, 4.43226194717193, 4.51950275586099, 4.67239466126442, 4.80696185054038, 4.86635970273613, 4.82619117443242, 4.68734542981815, 4.46931732357689, 4.2020657613266, 3.91531380231444, 3.62918653984859, 3.35090920151279, 3.07857027120059, 2.80850865145037, 2.54130773842145, 2.28330441604469, 0, 0, 0, 1.49627862836685, 1.3687038680505, 1.26181845743125, 1.17323545602336, 1.10381984026965, 1.05737032628166, 1.03921924669722, 1.05439418625223, 1.10597119191249, 1.19403621593253, 1.31539332251495, 1.46393547665058, 1.63147790773773, 1.80882702315909, 1.98687704209767, 2.15756457675672, 2.31456160881382, 2.4536481696328, 2.57276978944406, 2.67183856559807, 2.75236943549468, 2.81705053303882, 2.86933128311166, 2.91308235090138, 2.95234843607927, 2.99118869513595, 3.03358762271483, 3.08342231653485, 3.14448183374219, 3.22053442124954, 3.31541223226893, 3.43302813442487, 3.57717939961188, 3.75097766648094, 3.9558239429871, 4.19003354662125, 4.44745280482681, 4.71658261542471, 4.98071670219097, 5.21936939559485, 5.41087735489576, 5.53566808379867, 5.57945757748482, 5.53565264610614, 5.40646021084725, 5.20253818515901, 4.94134473227312, 4.64458285894915, 4.33527065787538, 4.03498744117652, 3.76174652067782, 3.52873937263188, 3.34394498578749, 3.21040388575408, 3.12689774071283, 3.08884439527264, 3.08932215177195, 3.12017781666368, 3.17312847740902, 3.24070023644204, 3.31684010147145, 3.39711819912598, 3.47856486557535, 3.55929020988994, 3.63806475112512, 3.71399778931041, 3.78637001794014, 1.09188406585655, 1.1867702646611, 1.29248502285010, 1.40960799480358, 1.54351256621766, 1.71224839828413, 1.95665150208050, 2.33539928410403, 2.87823049050663, 3.51277441276375, 4.05909081491502, 4.35706205085785, 4.41262912877952, 4.38202306676106, 4.41506387530762, 4.54694250801797, 4.72122996233016, 4.86256092159563, 4.91752384880367, 4.86088023275456, 4.69216262974548, 4.43190627704159, 4.11454351739848, 3.77696500236929, 3.44729903186153, 3.13954011472925, 2.85578267679157, 2.59297731198958, 2.34920209157961, 2.12615141084551, 0, 0, 0, 1.49755876290754, 1.40059186639343, 1.31981750612936, 1.25340045363647, 1.20253355948688, 1.17095424720170, 1.16363583998975, 1.18518519957772, 1.23843776633043, 1.32356824330926, 1.43782813687044, 1.57585420666493, 1.73039404158674, 1.89325804686860, 2.05630992345363, 2.21233555811269, 2.35567650262400, 2.48257261001142, 2.59121848286486, 2.68158788063999, 2.75510984330572, 2.81428678899658, 2.86233114190169, 2.90287038404625, 2.93974003022505, 2.97685883170384, 3.01816680517532, 3.06760554537202, 3.12912569610113, 3.20670623982507, 3.30435215808875, 3.42599942789833, 3.5752179017429, 3.75460085695245, 3.96480234437206, 4.20333669498829, 4.46344220671707, 4.7334415696771, 4.99701285825899, 5.2345827483786, 5.42572474939115, 5.55211703978422, 5.60041989595217, 5.56444165565444, 5.44615335437923, 5.25539853989353, 5.00842806379239, 4.72560355894371, 4.42873133488814, 4.13850587877219, 3.87246163913000, 3.64367013681048, 3.46022305632848, 3.32538005642876, 3.23818658337317, 3.1943814793407, 3.18746330208466, 3.20980903123879, 3.25372439221187, 3.31228648502577, 3.37986222514606, 3.45226233985309, 3.52658938352087, 3.60091146253159, 3.67390994985792, 3.74461106900567, 3.81224493941861, 1.07026372592183, 1.15767372570678, 1.25596290001564, 1.36623166122068, 1.49354227807448, 1.65295242759273, 1.87713148341531, 2.21237822158047, 2.68267893268369, 3.23360660254866, 3.72772623666776, 4.04120458491798, 4.17510098685708, 4.24382238112272, 4.35645092704759, 4.53452146745413, 4.72906247793486, 4.8754793372483, 4.92534616398045, 4.85345392640295, 4.65837899491003, 4.36168923319156, 4.00184922242105, 3.62207651767243, 3.25741739369703, 2.92755470080684, 2.63777515042005, 2.38528066070761, 2.16578277520868, 1.97686880789185, 1.81778416012911, 0, 0, 0, 1.43283751776409, 1.3776574045039, 1.33294131738330, 1.30006155026154, 1.28266535875656, 1.28544065420169, 1.31269079214767, 1.36711047025258, 1.44901241761836, 1.55609417206325, 1.68370340475189, 1.82547681178858, 1.97418850148329, 2.12263919522315, 2.26443942996105, 2.39458202732166, 2.50975319985863, 2.60838672753998, 2.69051037117643, 2.75746020998052, 2.81154441660302, 2.85572583512572, 2.89336891448340, 2.92806894752807, 2.96355770285526, 3.00366475391114, 3.05230939433117, 3.11349988367112, 3.19131620122957, 3.28984079623043, 3.41297828528225, 3.56408388323718, 3.74532934735591, 3.95680116655056, 4.1954512070155, 4.45416664332298, 4.72132138718432, 4.98114392550232, 5.21506143432146, 5.40390405984195, 5.53057917658037, 5.58266121171737, 5.5543471500008, 5.44738719195837, 5.27084540303876, 5.03979450009628, 4.77324209110322, 4.49169477508484, 4.21478572154111, 3.95932616506175, 3.73800960507951, 3.55883626972672, 3.42518456319499, 3.33637499933483, 3.28855506352506, 3.27575104890068, 3.29094978738854, 3.32707814990448, 3.37775851987497, 3.43775702151722, 3.50311069402926, 3.57099686599909, 3.63946020349719, 3.70712029912735, 3.7729484145144, 3.83614744096230, 1.05059323138323, 1.13087615675246, 1.22197194862392, 1.32541294291459, 1.44587712931296, 1.59544710315555, 1.79883585635717, 2.09034255719478, 2.48834934379523, 2.95565331388578, 3.39571873548935, 3.71969112487733, 3.92407593324908, 4.08323790930754, 4.26728812773101, 4.48487708465108, 4.69454378572426, 4.84252456992379, 4.8857745234712, 4.79968566091026, 4.58226556324352, 4.2560094943269, 3.86270598960471, 3.45071520924541, 3.06063788586858, 2.71663980272575, 2.4264126234485, 2.18715980685862, 1.99248488111799, 1.83648697312294, 1.71447039876835, 1.62186020976991, 0, 0, 0, 1.43315322641093, 1.40930783497610, 1.39365712881330, 1.38972313711766, 1.40194330000757, 1.43438413650957, 1.48965793663878, 1.56824224821917, 1.66827322116090, 1.78577794962549, 1.91523955296635, 2.05035159590123, 2.18481135739359, 2.31301979123288, 2.43059396593474, 2.53464680133075, 2.62383840278582, 2.69824315324739, 2.75910024129735, 2.80852051411542, 2.84921190239315, 2.88426460526933, 2.91701241017701, 2.95096424534415, 2.98978482442097, 3.03729644191089, 3.09747304258166, 3.17439673711927, 3.27214015030528, 3.39452535726587, 3.54470236477056, 3.72450713125474, 3.93361927040213, 4.1686421514235, 4.42234140006735, 4.68334514347253, 4.93657611682778, 5.16453420500296, 5.34931661981225, 5.47503418827409, 5.53014333930387, 5.50921381420093, 5.41378391913419, 5.25216481698338, 5.03827513751599, 4.78976323370399, 4.52577784684331, 4.26477057386836, 4.02266063635552, 3.81158143786094, 3.63929021490754, 3.50919552224571, 3.42087317162883, 3.37090727092116, 3.35389377212846, 3.36345767262729, 3.39315213198819, 3.43713443567222, 3.49055921210406, 3.54969101241148, 3.61179884275513, 3.67493254270021, 3.73768256547729, 3.79899474962318, 3.85806703563638, 1.03325387607961, 1.10687464537406, 1.19112843878319, 1.28790968793202, 1.40156533395809, 1.54167127229001, 1.72626878057395, 1.97960205263942, 2.31529352933870, 2.71033873780678, 3.10208487827513, 3.43069359999023, 3.68892415037654, 3.91799136017974, 4.15580723134169, 4.40055926803801, 4.617364837776, 4.761921955517, 4.7962097365191, 4.69664270489517, 4.46107879851684, 4.11277370652571, 3.69591942877376, 3.26255888644113, 2.85727044937054, 2.50742086337273, 2.22236948890332, 1.99918118831456, 1.82970826033451, 1.70522967938628, 1.61787728654501, 1.56022685912558, 0, 0, 0, 1.48483415696717, 1.48075581838127, 1.48139823889911, 1.49012918915727, 1.51115481018967, 1.54834594319383, 1.60426802117389, 1.67957638294644, 1.77283249562845, 1.88070870109337, 1.99848808897871, 2.12073290583915, 2.24198791538204, 2.35740130019072, 2.46317971917133, 2.55683789874721, 2.63724696623977, 2.70452082302163, 2.75980050194440, 2.8050010787368, 2.84257647646803, 2.87533905124877, 2.90634876356742, 2.93886623280203, 2.97634880644253, 3.02246038491342, 3.08106272256651, 3.15615458925371, 3.25172196751327, 3.37145794096708, 3.51831301921288, 3.69385928252499, 3.89750659422779, 4.1256931092233, 4.3712591805505, 4.62325941245907, 4.86743077891069, 5.0874033445071, 5.26654582738454, 5.39014698227567, 5.44751581797809, 5.43358064469267, 5.34967549440945, 5.20338162621793, 5.00748598189253, 4.77827966838813, 4.53351859066436, 4.29039448893895, 4.0638215384846, 3.86524741905452, 3.70207545761200, 3.57766838960735, 3.4918205483228, 3.44154346827729, 3.42200260213301, 3.42745595229838, 3.4520698398114, 3.49052212974591, 3.53835029975639, 3.59205566148708, 3.64902266776875, 3.70733884248895, 3.76559905886319, 3.82275205697845, 3.87801077488972, 1.01846245416217, 1.08596522231222, 1.16381248583751, 1.25419754674637, 1.36124003210115, 1.49266035111562, 1.66154860969250, 1.88467476778556, 2.17203327508198, 2.51086928716400, 2.86321941941278, 3.19041952939142, 3.4824721337435, 3.7563694313197, 4.02657666236156, 4.28386604965095, 4.49858415629745, 4.63396194058052, 4.65639639560549, 4.54375292320476, 4.29421527669551, 3.9316014103196, 3.50145035698493, 3.05785732260728, 2.64768642865787, 2.30021115575356, 2.0257936816726, 1.82131800644783, 1.67730883421136, 1.58290445186134, 1.52779889669951, 1.502352376644, 1.49741853310843, 0, 0, 0, 1.54617351681349, 1.56201919569497, 1.58252643284234, 1.61168624875025, 1.65320372197589, 1.70962099791543, 1.78177549000019, 1.86863522675990, 1.96747919031069, 2.07433860155178, 2.18458668021080, 2.29355877779082, 2.39709958854758, 2.49196454494462, 2.57604114984397, 2.64839437858394, 2.70917084321743, 2.75941435387429, 2.80084957162299, 2.83568250710539, 2.86645059554793, 2.89593561591211, 2.92713409675187, 2.96326518301462, 3.00778663548733, 3.06438515160104, 3.13690550363198, 3.22918224913165, 3.34473898025788, 3.48632907306034, 3.65531802881571, 3.85095750287805, 4.06967021184535, 4.3045312942045, 4.54516109536225, 4.77820586802213, 4.98846872528999, 5.16058942093507, 5.28101092454485, 5.33987000619984, 5.33244332687322, 5.2598698631536, 5.12902386399512, 4.95158436521112, 4.74249505279488, 4.51810302132087, 4.2942938334519, 4.08490497321481, 3.90061472432456, 3.74839308402287, 3.63149391202176, 3.54988638616927, 3.50097956319621, 3.48048348697432, 3.48326383195433, 3.50407551075807, 3.5380993159726, 3.5812513256948, 3.63028136242496, 3.68271435522076, 3.73670730937121, 3.79089076093828, 3.84424155941835, 3.89600443054483, 1.00628450053785, 1.06825865148231, 1.14018676351800, 1.22449483517342, 1.32516748811905, 1.44868247823096, 1.60480818602342, 1.80528950962512, 2.05757388542862, 2.35542634965344, 2.67687346563795, 2.99700110650081, 3.30398627309056, 3.5990315277161, 3.88140372352312, 4.13730045076750, 4.34099988058508, 4.46147455888737, 4.4690569874273, 4.34357869198301, 4.08406587048391, 3.71469055258403, 3.28123798308875, 2.83818698333673, 2.43300278861692, 2.09563385729956, 1.83687165924124, 1.65345353278183, 1.53502820183057, 1.46924561667954, 1.44403316447306, 1.44809904623695, 1.47104611969705, 1.50381369589417, 0, 0, 0, 1.63478623209085, 1.66609180875735, 1.70266706244031, 1.74807695669765, 1.80485743188951, 1.87402634875251, 1.95493465655361, 2.04542469077374, 2.14221869209131, 2.24143715793677, 2.33914293089052, 2.43182083095639, 2.51672975443408, 2.59209801750564, 2.65716601138003, 2.71210658593476, 2.75786901082306, 2.79599587643666, 2.82845551482373, 2.85751872134787, 2.88569156780901, 2.91569939648281, 2.95050323441458, 2.99332020555260, 3.04761410124275, 3.11702027317715, 3.20516985569721, 3.31538332339215, 3.45021683045662, 3.61087265356914, 3.79653054311968, 4.00371405095934, 4.22585669459168, 4.45325044777678, 4.67352049583792, 4.87267077966629, 5.03660614712572, 5.1529013130225, 5.21250025893569, 5.21102205537556, 5.14942275344968, 5.03389464444246, 4.87503641814197, 4.68646290701431, 4.48311307836235, 4.27954539912761, 4.08848056159983, 3.91977556439039, 3.77991253393513, 3.67198616007347, 3.59609659303435, 3.55001102511492, 3.52994637662036, 3.53133973092166, 3.54950337848745, 3.58010055222968, 3.61942061876687, 3.6644723613827, 3.71294363399539, 3.76308887384712, 3.81360105817135, 3.86350604353301, 3.91209354538042, 0.996655591760163, 1.05370603367693, 1.12022717078657, 1.19880518452999, 1.29333869910162, 1.40951813781563, 1.55504160932863, 1.73852716919131, 1.96572042201598, 2.23402009374511, 2.53069906303622, 2.83884580552865, 3.14555961857880, 3.44282014443302, 3.72109729032250, 3.96420436485056, 4.14935747902563, 4.24996585389531, 4.24008381783721, 4.10208774651978, 3.83635042886715, 3.46719090748236, 3.03959109257189, 2.60684843471031, 2.21548120520981, 1.89501860542648, 1.65621291542219, 1.49573783798510, 1.40280427343256, 1.36416340103234, 1.36656089973262, 1.39753509727659, 1.44577223949901, 1.50164149353872, 0, 0, 0, 1.69940219038339, 1.74045076831376, 1.78367494537268, 1.83252342060699, 1.88953878419951, 1.95591315812570, 2.03135254734056, 2.11421529080554, 2.20185335078485, 2.29106648824451, 2.37857776565024, 2.46145209784892, 2.53740374672383, 2.60496813430901, 2.66354198166961, 2.7133182876486, 2.75515579481555, 2.790425581881, 2.82087166210826, 2.84851067773448, 2.87558108508614, 2.90453742903638, 2.93807249482535, 2.97914053403599, 3.03094884344276, 3.09688274474900, 3.18033076747626, 3.28438409974449, 3.41140031192302, 3.56244958618097, 3.73670291857426, 3.93086962743357, 4.13883060572379, 4.35162318277508, 4.55789605529798, 4.74486601706752, 4.89969012057047, 5.01105170345668, 5.07068392321108, 5.07454557358913, 5.02342494185975, 4.92286080789125, 4.78240454584048, 4.614370362514, 4.43230521222256, 4.24944082318072, 4.07736605110765, 3.92508959768323, 3.79857134489516, 3.70070876640221, 3.63169293953141, 3.58960740414762, 3.57113310107799, 3.57223732322918, 3.58875504330334, 3.61680901372792, 3.65305401990703, 3.69476462429895, 3.73980914588502, 3.78656171495677, 3.83379887443283, 3.88061150569851, 3.92634383747083, 0.989407728698556, 1.04213052576847, 1.10376034408225, 1.17696688075729, 1.26556474609777, 1.37473199680037, 1.51090990359831, 1.68084688469862, 1.88915561297960, 2.13496057993436, 2.41031039821192, 2.70250120504745, 2.99809930788061, 3.28427924783234, 3.54699840399249, 3.76914675151517, 3.9302376277605, 4.00732973160839, 3.97820402500549, 3.82832655604089, 3.55983521573081, 3.19699389919866, 2.78306891704274, 2.36884365130202, 1.99859309867743, 1.70053382984475, 1.48502213047514, 1.34877078337863, 1.28093975424263, 1.26787973984197, 1.29563923771478, 1.35098376483591, 1.42196159329102, 1.49853501916205, 1.57324087574687, 0, 0, 0, 1.80560319499509, 1.85467028327924, 1.90648308643058, 1.96359997542579, 2.02737717919741, 2.09784437279557, 2.17382553264225, 2.25323839000422, 2.33349158066208, 2.41189905363817, 2.48604413014339, 2.55404717218354, 2.61471636915147, 2.66758559629159, 2.71286234827063, 2.75131980770798, 2.78416960957234, 2.81294699353731, 2.83943003899967, 2.8656020788393, 2.89365342823949, 2.92600692687918, 2.96534258856354, 3.01459057483643, 3.07685932248257, 3.15526783463227, 3.25265952718128, 3.37119198466342, 3.51182450310044, 3.67376250228009, 3.85395824962838, 4.04679776858659, 4.24410776079991, 4.43558100081747, 4.60964294561013, 4.75468128549187, 4.86046177807934, 4.9194888290629, 4.92805980257479, 4.88681278320138, 4.8006653181217, 4.67816096010097, 4.53035180776468, 4.36942361811347, 4.20730035515056, 4.0544447612906, 3.91901041669511, 3.80641734175127, 3.71933918077137, 3.65802377540445, 3.62083087191931, 3.60486195556032, 3.60657199078188, 3.62228240622752, 3.6485504640882, 3.68238520641597, 3.72132898766727, 3.76344210428365, 3.80723415188373, 3.85158030231255, 3.89564753572349, 3.93884061408813, 0.98429787646103, 1.03326159955897, 1.09050345666027, 1.1587009728831, 1.24155260481659, 1.34385388195948, 1.47124219558739, 1.62932247570893, 1.82191435815329, 2.04877499839305, 2.3041516128958, 2.57738153752452, 2.85488098937414, 3.12166317231885, 3.36171658247996, 3.55787751785972, 3.69159670941005, 3.74316411276498, 3.69416507256708, 3.53355004138851, 3.26548786938717, 2.91399038194909, 2.51989680138182, 2.13047003590497, 1.78677878922676, 1.51507530275764, 1.32507322294075, 1.21362104225962, 1.17013513994537, 1.18095524036117, 1.23181212222478, 1.30901375964012, 1.40019842897687, 1.49506382632774, 1.58602211400506, 1.66855789820847, 0, 0, 0, 1.91593119273262, 1.97021830948827, 2.02729475213662, 2.08866700178163, 2.15465422702087, 2.22449386526868, 2.29660445356706, 2.36893267133387, 2.43931395042686, 2.50578848741466, 2.56683376591396, 2.62149676240963, 2.66942974094464, 2.71084952258249, 2.74644932077416, 2.77729428030962, 2.80472775562618, 2.83030694517231, 2.85577578789859, 2.88307179711184, 2.91435310066615, 2.95202335657251, 2.99872623432513, 3.05727868949966, 3.13051453411475, 3.22101848822217, 3.3307478129108, 3.46056468380693, 3.60973583212125, 3.77549026505748, 3.95274989430216, 4.134148404891, 4.310420962064, 4.47118130159226, 4.60601605699508, 4.70574181628952, 4.76361399626521, 4.77626702454272, 4.74420774369438, 4.67176844664525, 4.56653116140943, 4.4383348382603, 4.29804884102675, 4.15632499922834, 4.02252339695444, 3.90395250507901, 3.80548900346554, 3.72956647211429, 3.67646194807557, 3.64477487520872, 3.63198556538711, 3.63499473849683, 3.65057365005089, 3.67568729899854, 3.70768435709699, 3.74437185871179, 3.78400734350301, 3.82524514110234, 3.86706823592148, 3.90872614967556, 3.94968705695471, 0.981036071702848, 1.02676872825389, 1.08010272623824, 1.14365412906355, 1.22095655141006, 1.31646116195585, 1.43521582582284, 1.58205197982836, 1.76018281647741, 1.96945865787537, 2.20503343437007, 2.45722560941292, 2.71257940388393, 2.9553992238202, 3.16908661654145, 3.33690594419035, 3.44205843645630, 3.46782711644265, 3.39960824302985, 3.22999542184572, 2.96526149277495, 2.62897480103630, 2.25906921047412, 1.89865225923299, 1.58499175659681, 1.34197732615628, 1.17853384399147, 1.09171741080109, 1.07141391264593, 1.10422847657316, 1.17585349463411, 1.27238186323125, 1.3812269060421, 1.49194644144224, 1.59690328744549, 1.69157590400225, 0, 0, 0, 1.96798807420075, 2.02425101958404, 2.08113605459916, 2.14028257041227, 2.20226301117679, 2.26667549503418, 2.3323749489044, 2.39777657097369, 2.46116954781212, 2.52099113709973, 2.57602848683248, 2.62553457249673, 2.66926211157664, 2.70743260523844, 2.74066523282422, 2.76989195770565, 2.79628175417964, 2.82118981981359, 2.84613860395416, 2.87282784717024, 2.90316165223405, 2.93927274628812, 2.98351839911336, 3.03841999871947, 3.10652044778438, 3.19014197561672, 3.29104309626787, 3.40999753215762, 3.54634763504836, 3.69761411754045, 3.85926316037331, 4.02473044808846, 4.18577194633775, 4.33315374539383, 4.45761878309764, 4.5509957735821, 4.60726662691539, 4.62339930864516, 4.5997887043824, 4.54022101725935, 4.45136960544761, 4.34191925879745, 4.22148073690825, 4.0994842164245, 3.98422584361197, 3.88219318035069, 3.79772803230727, 3.73301682463156, 3.68834467431102, 3.6625185328149, 3.65335860719038, 3.65817100830655, 3.67414040524932, 3.69861133520263, 3.72925422973035, 3.76413283697369, 3.80170136213877, 3.84076216108501, 3.88040992021412, 3.91997907834917, 3.95900143987746, 0.979311034029364, 1.02229205775147, 1.0721680678856, 1.13143485886290, 1.20341076835116, 1.29219580857105, 1.40233175382803, 1.53804545194894, 1.70204388366240, 1.89405163606996, 2.10958020972056, 2.33950805204987, 2.57072578573078, 2.78759998542917, 2.97367000485966, 3.11289599287481, 3.19012468016824, 3.19142974571062, 3.10586681109293, 2.92956528473920, 2.6707781930074, 2.35244652773382, 2.00935304903594, 1.68017947925733, 1.39815266260958, 1.18463689477061, 1.04770624142637, 0.984661949470643, 0.98597820315383, 1.03869732096663, 1.12866570663423, 1.24194385528637, 1.36587140622321, 1.48997731017580, 1.60664915183881, 1.71140712328495, 1.80272077296229, 0, 0, 0, 2.06929903150842, 2.12583437037089, 2.18291647623716, 2.24133357567293, 2.30099220621183, 2.36112118327016, 2.42053748055964, 2.47791942225485, 2.53204449077602, 2.58196455067183, 2.62710764351679, 2.66731016601749, 2.7027942038143, 2.73411095327446, 2.76207242665669, 2.78769073790838, 2.81213840371748, 2.83673553122336, 2.86296157274309, 2.89248134216544, 2.92716793399159, 2.96909989925006, 3.02050763379118, 3.08364586813093, 3.16057698217558, 3.25286476453081, 3.36120005789846, 3.48500597472935, 3.62209544511033, 3.76846952381531, 3.91834233539642, 4.06445195652672, 4.19866669197048, 4.31283219163133, 4.39974257567581, 4.45407618486782, 4.47312776998936, 4.45719891115245, 4.40957132718672, 4.33606838609358, 4.24428875081898, 4.14265391153049, 4.03943577364762, 3.94191821561482, 3.85580392676124, 3.78491825368888, 3.73120117151686, 3.69493058650575, 3.6750930293345, 3.66981271150737, 3.67676266588647, 3.69350511816347, 3.71773488893094, 3.74742353704180, 3.78087934827008, 3.81674756277165, 3.85397673728144, 3.89177268076191, 3.9295537614436, 3.96691349968626, 0.978811843109271, 1.01946837906650, 1.06630223286624, 1.12164285354922, 1.1885505831545, 1.27075370299581, 1.37231321674407, 1.49692438927756, 1.64684692717403, 1.82162151526949, 2.01693897554637, 2.22413318643129, 2.43062455487792, 2.62126966687782, 2.78014676099454, 2.8920773804575, 2.94347406883842, 2.92296048642173, 2.82292454011760, 2.64268418250945, 2.39218161467503, 2.09355814720675, 1.77840296234867, 1.48101409742367, 1.23063663191078, 1.04614054584052, 0.934750456596723, 0.894015125933936, 0.91503421466933, 0.985373241680259, 1.09115695617991, 1.21855130716731, 1.35494897618424, 1.48995086990437, 1.61604138997588, 1.72883111972684, 1.82683959265194, 1.91091058144659, 0, 0, 2.10621418936578, 2.16223725410227, 2.21739593564350, 2.27265625171364, 2.32818241411175, 2.38351766946127, 2.43781797107382, 2.49009037723629, 2.53939968804596, 2.58502078281235, 2.62652818101244, 2.66382658629306, 2.69713513763487, 2.72694303654151, 2.75395515748654, 2.77904381137935, 2.80321797676516, 2.82761502434076, 2.85351305742739, 2.88235511952733, 2.9157702913391, 2.95557189481672, 3.00371074194998, 3.06216301976961, 3.13273945040791, 3.21681576815996, 3.3150039789277, 3.42680683954659, 3.55031947369334, 3.68205494739546, 3.81696768237766, 3.94872517779301, 4.07023552496618, 4.17438335134649, 4.25487343613724, 4.3070444723829, 4.32850735839572, 4.31948764853555, 4.28280575995636, 4.22349846125699, 4.14815388816216, 4.06408325652751, 3.97847426209068, 3.89766076357059, 3.82660618233877, 3.76864585513503, 3.72548040648186, 3.69737020207634, 3.68345726015809, 3.68213681708541, 3.69141231260132, 3.70918844571650, 3.73348041622297, 3.76253814718622, 3.79489892332317, 3.82938932733947, 3.86509819439984, 3.90133833873526, 3.93760845985712, 3.97356028292907, 0.979244880162183, 1.01795147529461, 1.06212356346342, 1.11389150802058, 1.17602722529847, 1.2518697372102, 1.34500694025926, 1.45863855938017, 1.59461955421556, 1.75231766960331, 1.92758300810687, 2.11223058217109, 2.29436658110745, 2.45960443192772, 2.59281621847570, 2.67980439949160, 2.70846674460336, 2.66968257027097, 2.55870547052601, 2.37752105626718, 2.13735494166486, 1.85939315401696, 1.57214381566834, 1.30579481432334, 1.08588638419100, 0.928962829448148, 0.841442264914652, 0.821094282804529, 0.859620791347573, 0.945135456532062, 1.06411881368398, 1.20295004925268, 1.34918519305629, 1.49259043743587, 1.62581605746341, 1.74460974968725, 1.84757140950584, 1.93555914829633, 0, 0, 2.13592503119266, 2.19127291609556, 2.24462843709787, 2.29709769004391, 2.34905418649294, 2.40030007142141, 2.4502722836937, 2.49825120252474, 2.54354062067395, 2.58560047246548, 2.62412583588802, 2.65907590544851, 2.69066390647160, 2.71932283670051, 2.74566257969313, 2.77043187975579, 2.7944946633991, 2.81882499487175, 2.84451918228573, 2.87281769996791, 2.90512416949716, 2.94300435378202, 2.98814599792895, 3.0422617162897, 3.10692330668493, 3.18332768137331, 3.27201162379451, 3.37255249873985, 3.48331039523361, 3.60127790932314, 3.72210082377877, 3.84031260540725, 3.94978880962711, 4.04438068691073, 4.11864169976094, 4.16852907054392, 4.19195520162539, 4.1890850445569, 4.16232157451352, 4.11598168746814, 4.05572430352232, 3.98783677107463, 3.91850484407253, 3.8531827101939, 3.79614743736494, 3.75027696936118, 3.71704468214806, 3.69668709894072, 3.68848091498736, 3.69106205181875, 3.70272975325042, 3.72169706773265, 3.74626945930657, 3.77495102287576, 3.80649006462926, 3.83988180699983, 3.87434639700080, 3.9092969332162, 3.94430697036087, 3.9790818290311 ), .Dim = c(100, 100)) rgl/inst/demodata/population.dat0000644000176200001440000001400014100762640016450 0ustar liggesusersstructure(c(1.42180393552915, 86.5899178491882, 58.4279463385297, 72.5782084880812, 94.7650395805866, 90.716798083558, 4.69523086857405, 66.0275494756707, 99.5966041105792, 28.8464020557810, 32.5199596913345, 32.8230902358943, 76.092718318592, 90.9491131042477, 67.7715461039384, 92.797656673891, 62.8763250044725, 37.8377486848826, 94.8318271447979, 16.9384257460335, 66.7528590475565, 72.7664750532169, 86.8409342723528, 42.6672130775794, 99.405982755219, 9.87878796385573, 74.0013561791278, 73.1367197183745, 95.3562400020557, 69.6064585052911, 74.8777135121351, 78.0631738216763, 93.8781220125682, 56.9874829819862, 61.3674564946833, 63.7014637339631, 72.5482760946146, 88.150868900621, 59.5874643583287, 36.0187577356162, 75.6129656479724, 58.5589693499633, 61.5365704196823, 45.4041207738696, 13.9846302678307, 68.6129614502687, 81.1038195579554, 54.9328748464894, 56.0090012748281, 63.7824110302102, 71.9080963099627, 76.2898655697447, 68.1971407037222, 1.79949925742100, 34.2445376879174, 67.752421253536, 70.0160933011249, 59.9881388477488, 62.1375791537896, 67.5026055163477, 55.4749773697637, 67.6559503769167, 99.8921368552586, 99.7317640238283, 59.5870514252659, 61.1156890017716, 67.7897419835883, 93.7373116639762, 64.8624836653151, 66.1630357404153, 70.3541452797023, 50.3392945568402, 60.5756891936938, 65.6381806437015, 70.7699265549355, 84.263331400059, 36.1455168687146, 63.4268691110022, 50.8403640938551, 84.6038580009723, 99.253448377888, 44.5136280754846, 18.3862017952805, 35.7157337732417, 84.9943843632923, 96.2500336638768, 51.939143733573, 73.937482003108, 20.8390646918768, 13.3791143487625, 2.59180364981103, 16.35253761228, 78.7863353881487, 77.0761412272873, 12.7493216227156, 97.408350521328, 2.360943911914, 49.5031567931881, 40.9086587196003, 89.0041084624836, 0.153641843226189, 0.7205303565414, 2.12973220584209, 1.95184155151989, 2.36672693229437, 3.97881615724853, 4.6945903958973, 4.97023833854362, 5.02848534249433, 5.93632710737556, 6.5305134302309, 7.18124749660055, 7.59205544134417, 8.11782658102872, 9.7053179911583, 9.69966472967054, 10.7491681958896, 11.7805969476189, 11.8846419362548, 13.2638113615252, 13.6102190943924, 13.3331649454155, 13.3510625511294, 14.2866348278910, 14.9188862315656, 17.1073522001289, 17.3771351386274, 17.4970376938342, 17.6769213814467, 18.2937976371715, 18.1794471174431, 18.4072881564515, 20.2907827372874, 20.7863900870053, 20.8977102997940, 20.7898134065768, 21.4861476674877, 21.7151264355786, 22.4866743996941, 22.9652880267625, 23.4036320422319, 24.3239211351899, 24.5629717030476, 24.9067464934910, 25.3250969786023, 25.569835321831, 25.214928868463, 26.3005548932358, 26.5032754860593, 27.9258713661520, 28.3114428871105, 29.1348144906887, 29.5927445701307, 30.4762347883257, 30.0503599176301, 30.0058225611238, 30.1513380348103, 30.9686341509616, 31.2913000003182, 31.5440713840872, 32.7657602884727, 32.5231659352135, 32.5262426292818, 33.3124010171537, 33.8478211625125, 33.8467915869427, 33.7026977228706, 34.0596679268078, 34.7846046615822, 38.1673741083982, 37.9665159877312, 38.8029702374719, 39.0682120522177, 39.5640346008735, 39.4240171975978, 40.0765304172124, 41.6115850103115, 43.1095386110501, 43.3832096504008, 45.4365823266182, 45.5690791790302, 46.1239852830125, 46.6768080701299, 46.7602784573008, 47.285367886742, 48.2420712810108, 50.5906685558592, 50.5316655747899, 51.3195670861564, 52.8660801235275, 54.8554989863782, 54.8768757654533, 55.6908773693933, 57.0974418796826, 57.7205567191636, 57.7134194371089, 58.3266436293085, 58.6607370311536, 59.3980795544102, 59.9830194632018, 4, 3, 2, 3, 4, 2, 4, 4, 3, 3, 8, 2, 2, 6, 8, 2, 4, 6, 5, 4, 8, 6, 3, 4, 4, 2, 1, 4, 3, 4, 4, 4, 3, 7, 4, 4, 2, 6, 3, 8, 3, 2, 5, 3, 5, 8, 3, 8, 5, 1, 3, 8, 5, 7, 4, 3, 5, 4, 6, 3, 5, 3, 6, 3, 5, 1, 2, 3, 3, 2, 5, 7, 3, 7, 1, 7, 3, 6, 5, 5, 5, 2, 5, 6, 3, 2, 4, 6, 3, 2, 3, 2, 3, 2, 7, 3, 6, 4, 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 7.57114372433513, 6.85515173418126, 7.52609590470221, 3.5563844241623, 7.14112545928597, 5.12301007753458, 3.87663849439702, 5.79586417334239, 4.70184865517279, 6.21920562188609, 5.44360907485348, 4.51873716824026, 6.33491917603443, 5.20292601299676, 6.59676653073395, 5.81501493098883, 7.54559052637168, 5.6635169145202, 5.88625186391175, 6.18255547931158, 3.9011827688165, 7.92338945754762, 7.08656410296135, 7.25722570643227, 6.23413330258138, 5.88738222841769, 6.80735796658865, 5.28594790472374, 4.39548032693523, 6.12184517302476, 6.74384685192469, 7.60827115628042, 5.07457171988406, 8.50778221649775, 4.38150950099637, 7.52973226807595, 6.5506735931328, 3.87367222602665, 6.3649749543402, 5.84328626826638, 4.12479223028613, 5.88500632343836, 6.93493363615338, 6.66363247928469, 4.65955611058411, 8.15391551804086, 6.76397691227767, 5.36981173805678, 5.98744841170566, 7.11136219546026, 5.78287045204801, 6.14081537593665, 3.82726802701466, 3.20879873107543, 6.17821147407116, 7.37261655390293, 6.52738206698354, 7.04683222470034, 4.8916109987783, 6.56523496429719, 6.83082908120187, 7.87149902967823, 5.62770948691443, 3.2651491532768, 3.59665266985329, 6.54074671207657, 5.77568350127988, 5.96246550437346, 7.05488722838375, 6.38605274449675, 4.96442316344611, 6.48378363921246, 3.84255493400238, 4.38857837779543, 6.19366965736775, 4.84260035340659, 5.07260834973452, 2.88965797522147, 7.15143574153486, 7.12539568924814, 7.40644952344348, 6.59220641889174, 4.81483959103117, 5.32577121795078, 4.23104750753301, 8.90629459075072, 7.92242700824242, 6.06571137725015, 6.31187612654388, 6.60321800321983, 5.8189575929551, 7.40216872384802, 5.58163040684314, 4.68926346360419, 4.50539905884038, 6.21368299483713, 3.96679382670128, 5.61336655902108, 3.52559103095651, 6.69183050760578), .Dim = c(100, 5), .Dimnames = list(NULL, c("x1", "x2", "x3", "x4", "x5"))) rgl/inst/textures/0000755000176200001440000000000014100762640013676 5ustar liggesusersrgl/inst/textures/particle.png0000644000176200001440000003676514100762640016230 0ustar liggesusers‰PNG  IHDRy÷º=¼IDATxÚÕ}éz$Yª¤Êž™÷Ö™R80?08Ç]!åR™u»Ô_·ZKJr‚Õ0@¿÷M ýs d$~ÞëS"™DžÏªé–õ…„ú¡àMþ´êùùù¸ @@ì|Â$Ã23ùà‚?÷&à‡_^,Ø€ÃàÙ&pÒF óñÿ¸DTJ P>¿Q9Z3’Nð®çͨ۩á¢W2³R⬰9Qá7Ôˆ¿! ˆ(} òŸoo@û€ØÂjb‚  ™@:5ÀÛ+þÓЪY& ÑæøE$ ‚¤NÎÏ÷öøÞXˆLk[§ó³ÌˆÈ<ÿÎöDFþÝJá—€ÉôÚæëý (4XþèÈGh™J*ʺ'À&GZ|ÜÌ@$32'/ú§ Ëô˜òŽÖ‹ˆñ1¤ˆŠ$tG|_*õ[YÐÎJ(¢Š2…Q“¬”äŸö ÕõÊëÕ$>5þçõ>™>…–µwÀ§RÁ°—HÉŽ ¥‘ñ·Tào@Uul¿½?Þð„¨ÎSKC@•)îõqàÖëA%G/‚q‡Áª3âïTË?-€\™­ª¨$ ÀPyï#ˆJÜL…䦨T"3Æ„•–ÛáÇQˆ”ŒˆÄ/—Ë¿(a±w±}<y×èV+¡t½ß[Vú§(•ðHÀ‰”DmšáL”þYX;¿Ñ€Çãnõ¨Ÿš€eÂ!…‚±H23Xïãëý;5àÈðHàýO `™™ŠV¥»?ÿ¤ó«H§­õoƒ\QÞÜËÀ¢”à(ß7ñ_ËêÑð¤H¸ç5ZýˆHI`w~Ð)ƒûó†¬Ä˜/¼É׿¬Ãkò?J禉$0ÚQ€Ž¿ÄÒ ¤Dx’ZF è¬Wõ߈®€´añq/ÞŽÄʇËçEvu˜Ë+ÒïWtd›¢œá@½ˆ%ÃÕöõbЛ 2d«5Ö}†Ö(Ið©%@ K‚¤H"Ó“Á±ÂÆŸ@¹ª"òïu†õÔ¥0‘ú*ØÝ¤fõY^¿:CI¯ß°M Q3#“:ð3ÕÁÏ  T\UD>ïãf]ú<ÊW˜àèkä ¥ÙˆQWÿê¥B…–‘Þ¹rD,Ìð÷ @¥T_' @»š…Šoü“Ý|ÀÖ!êiè{4P9·øO5`ЙbzDdѱô <Þ›T D<› ´Å«Œê¥'¸ü.ã³7ú[/£È_{üà Dd2$á„{)¿MÚ Å¾?¨é$¡[d¿@JC´€É2™•Žô<3 -€HGF—ͬ üw €É? ƒU•CT úyLÆ[Î*"93D7HØÝ[ª]þàPiAw‡Á'<2#‹Ä Q™ão€´ÿ§¨ˆ¨ ¢&Ga¢ÉgÅv…å«)Ê IWà® $ÖªßïÏQ…ŒŒ„f†#K‘‘4àüÁ|à‡@Ü· N…¡ °ìÕÉË Ö‹O@%9PX…¹þý^Š‘:˜`½ŽÈz¹‘QÅABà1¨ð€Àóó@¾**b"06ýTùyI )+-ˆ‹ ›Æèú• 8;á¶™@¢àpº†Èˆ†ÅáPxäÊ ˜!†çT¿E•û)5àL™ß¨ª‚QàX‰êV. õ§ˆ|¢AÜ5€Þ`ƒé¸ÇUÊF–ü`>ðCPUQ&@VH¹(C 3CÙ¡2i`[镸\ï3"ÆWšÎ1Ÿœ¹i@ze­?”|*€­üUšIŠV*&D¢7D¨sýÿÝ¡€ ¼ÀˆLyá3b¢ÈAŠÂ‘é%!08¤ ="ód~ ùuý»ÐöþfÌŒ¶|ˆˆÂ €ju‚´j” 0îëMºúTýò X èKUú$@’ˆr|tÿU ” ""¦ñ·`ÿKl«þ6ÈÐø©ªŠ³v’­/'{3Ô7df(¡v‚#¦ÄÏÁÍè30h7ˆ_€b7 Ð ƒ•ï×+­"¾‡IùŠ`8¼”ƒ/4 ›¦É<@n™`  ±Àç0FÚñ¥ciψX-ƒï4N¾€T¿Ÿ )€Ã²Ã!:2T håîähÊk $‰´ €\F!:2­±å8K1¦ú;˜ú &¢ P1¸Á×±àk”­«¨ˆšJŠ™‹èxš” ºû{0äÛ½5xs‚Fð" p7X¯|CCNØ_­2(Ãs>Ïo’…þŒ´Z]Ô=˜…¨ªAZ ¶9ÁdÇýǵ5V ”­•£­E¦ž2pÏs¼`=hj@›B×N ÈO›½_e2=b|I½ü¦‡mÝ0]è¿;Ç“…¼âe,ùs”¹tåõK¸îü’šªªÚö§”öÕ;ņIvùΤC~)Pfïªjf*®PUÓP5á×Z ¥©`äUÛU¢ët‰ugÒÆÎ ÀJy»U–÷‡*Ãê+*´(§H_eÿ´vÿŽÊì ©dÈ´_~F‚®p9("Úñ Ï°q¶Ý uP@Ç0‚Š@Õ®ù‹ wé8*$»Sü%ˆ¨št|?ª¦ÔæÂ( ck˜@—}´Ú_^výhƒ±a‚@ ɦÄ,ïÏWúdc¤ o§H<À[øþ§ 1ërj15IÑCúU™ÈJ˜äªúÉ÷|ý%—S¼¢Â¹%N¦ÆÞõû-€n–v¸;™” ³RãŸö&PSS5ZýÕŽ­èÛ;˜§o7yk‘åÕAû/&":îWÀYõu_àœx_yA àäÿĘ̈þñO à û]ô0Ó‚vÚêå5Q‘ƒÐ×J†1‚†Ï¡dƒ£˜£øDXÔ·| €ôŽûÓ,'ÈL°Âa²ùñÙEó‚»løÏ àÿÐ}=øJ¾XÁ …„èÖhĨœ`§ýÓ;ÜÝ^:A_¨@m.*ñÉç0FÚ 23¬T¸0Hœ ÏúRD|J ø €ì¯ Êøý&VáñÿPEÊaa†3ˆÀTUd>€Ù¤&|PÓþ·ß(ü˼`}ßÉ<ÀWw8È'Õ«jÐÃSpƪ ÒÃ‘Ï ˆ?Ï£zêRbý,2•ât“vw{Ðþþ¾n·Ö7RÍô°ÊÜæŸ˜‰¨šÙqÈíÍLMÇ!Vê¡**@ª•ÒÕ| [S·4Ä¢Tªp¡æi€ŠÊÁšGеOyÿŽÿ¦ŠÐMêOL§(TT”ÎoÆçŒ‚=?0±·Æœ$°i‰Í7c¤5€Œ÷¸çÔ„ˆÂ8OÉ׎ð¥PU±ÊÖ‘bj¦’L€ÿ ÃBMRLtë@…Vh󺨲"úQ² ôÌBâ¤3|R Nø3÷”ôdø*CÝSÂOÄëlà…DÄ´ÀO Ö©rˆGW¦Hm¨Uß úÿÚ¾_d†¦Z?“ýÿ¨yÕ Üz‚'rø‚]<§*܈8xdFžÔ‹ˆ€œžH÷ʇ~@¨ª±R¨UØ&PñÏÊ n& 3Lˆ˜œVý‚oM£Ÿø/—ŽØ8Á51£1¼ÆÛ#ª;<,±©33Ü!鎌Ï)†äéD ~HLi"ªüÐTcü?t4À¡Ý9:©ªêª ß°yÔ 4>¯†r $¢ü?|¢Aù€¿ªà[ÅQ– dfxÅÆ* Ÿg Ê$ø8`¡ŸX5íævµ“ü5#À¾ÿ§þ½©Úq\Ø„9Žã8Ì6< Þ3µ‚"RÕ¸ªÙã°“Q/ˆ4Osê~ÝÌLd¸Ü«Íþ¡ qӀ戨™Yƒr0ÃûFÕ-\B«9j*ÆNQ“ þS ”ÕbgÉ2SåXaŒÍÑAŸÙ蘉–ʈ b€Ã`g4¢š£ˆÌ<3Ý+YðˆÌ'm"Œ™Ÿi€˜™TìÅlܾd}JwúÀðÿöx|{¼½½µà‡AjfVÕƒîìJ3+÷ºáBýÓ7^ý?†ºPõКÌÅÀŽX®fQs>:Ÿ•Ôñ?ü±°OUÓ*r¶Æš3ômê>QL2QgxA‹™áïw‡fœ6tÁžÌ 7d¼‹žé ”³Ë8§øq&ˆùD9…\ßwÑ€M$…?ˆr"•ô‹šlö K`!?€8ö¯_&– k¨ÚÖÐt©"›«3Dð]û8åfÎ?RˆH†»GUÐIH$Ÿ ‹ªqÏÐ5€ªª™Jwÿ!•ÌÓ Ìªì…ªXc …‰ÊQ5ÁÆ“ÃB uù+8Hxèîpnè/aoçDEDf8ù'X2üT˜YBž‰bQµf|-­\ý`]ÎWÑTl} *Æ@Y‰ÏQ~Ùv°´éÕ"ÛÖ †È”€o©p×a ?°;<á QÒ‘ç´Åƒ QD¥€žtŠžåÓ}þ'€G|Qj@µºG…°GB X ò«à“ÑààôP¨ª`õ› q~¢qiq4Q2NjM CDã m”œ§D fª$àл’ÄVm›JQ:TÈŒÊcl¯UMÍLW7ç®.Qàñޤ¼–€˜ÉtÐÿ®)ö¦(÷w¿êì4-ÂÜååyÀ7@åPMv†`&úë÷­ N¼ñ¹XÙŒ‰ ³ò`Ë÷àH.nðíyÁ~ßXz¤¤Ÿ•{ã¾Ól†HçÞØPœ)x§ô. 7ln“im1ͺ-¾W8L¡…ƒÙtd®33es<ŽãxÇ%Ô—F¨™Ùu ¯—QtŸ]ð8 ªfÍ< ÙäÚÌZ[´½)A®¸Àò Ò¢”b€•dÑc‡@ÌŽ‡‹*ô[7DG†KÔUa9»ªê!éÕJ$Ödhϳü¥ø‘Uî>QÞNP¹ÿ;‹¢'ÊÛဓy€o> >«È–õÌÌôby:î}h³ÕÙ2ªJNn ¿u“­q-Sµ½èן´ý JV‚ª6×ÂÊ?K¿ŠìT±jÉ!UÄÍ£ÝJ‚]L Ô1•Ƙ&Æöxù«€©PV‡U!vªÀ~ÑæõªM¾mYW7'àd‰Ã€;2NN”M—€oUaD5‰<2Nâ<…ßpM T}š‚j0$Ú ’;6-1@q¨[Ì©Z¯ƒ•bekOÀŠ®% ÷ï”Ø=¥´?¼Æå*Ì¡Ë_¢ÂLGåY ù|þŠ \`%1i Àƒ]a˜hèh€1ÐæBpTZXj¸:E[8S%RD›³4à¶`5> h HD„WBtfväÏ¥áI¨š <2ñ,Ào¸€ÞÒ€‰µí5MV±«0 j¦v¬v>Žòζ|`óꪊbu¨·o_4Z»iV@¡6V)ØüÅÅÑî0Pó‡D6š­./4ÀX¢²#&í|:ñ=Úu¯*þVÀLQ‘% (Ú~3}ZÌ ìûƒš7“33Ü*Ý<À"Bfz¤ˆü_æ8=wÉpHñ3Q¯²ÓDªLw„¸‡„û«( Ø­ z-¤÷ÙHÈVl;´g/CT…¼½=ÞÞÞÞðyÖ'­›\%9ÅÞGÄb›ø–)v 9¹Í…–./ÂàÆeĽß<vGÜZ¬õZkž©¿ßì0µÃØr× Nýüí{uE5FÈQ,t>Ø…%7aÍŒ ®®ëuü`‡ˆêaÕ U)fHAb*ÇúXè,ùç‹ &ßv©è'uñÀ(þ=, $cÊFF†F¹ñ®ïÓ öFF¸G ?fxÌi“³Z†{"OÏ»,ü;«=Xý>èø1“VC‘#ùÆÔù1¬ò«hD· yßÃ< »ÁkâJ‡¯(‰Ìž™~yFûPÁhp6o0â,œ„>â.€·€ÐÑâ!*¦Ðc4b]fª8º?À¢ç ű­KÜñ_µŠDݨ³5 {f´›¡½C) )X¨º¿º¿ðsœà™ãφÀžÄ"ÝÏ\㟢› ¬¹Ùà6” ÂØ…•Pã/.j*Œs“ôò¿·\¸HUkÑŸæÏ N«Éгª3Ô5zÆWêÇà²åâu_@V|”­šÚØ--"ö[eX{¡Ø‰½£º ÓÖ2,ù‘7eü‘!!‹¾¤o­K›—«ã2»µºd¶È} DÔ$:Ã#"ø˜šÈÊ;Žå â`;c‘"™ SÑmÅV–ϹòsöF ÂWwtò_P*­î‰|Ò¸2=<½cFzþbáN²ñƒF†ônîîîó¢C>y_ò³fpŽ4q‰ÿ=h×]Õ„f[ ?Æ,"¬”«é…\À¤hu›;»´e§&¶~ܦét'Ü’Ðkþs{?2-{#‡=*ƒ_eƒd¬¾ €® FtÍDQZdDÕ¶äbåÖ:6+,7$eÏo°‹n7‚»Ðˆ a|t¢±/Š$TTÑQí’àmÎKŽCMVYÍ»V³‚ Àž\1²M¯ ¤ \Ø2Í*È´‹”Õ+j…˶§k.¸ €®¸Ñmˆdöêl¹'Àpô¾£vÙ{Z§=[{Ô‰¨jΛŒý‡tØ@Uµn3Ô;“NØÐ,¶î]m¸Çdò½àSwNõg&PÕZÄn7Kã—P¤ˆº–&~x~S9ì0" ºgÈv{kkRëbº[ž¬£66`+ÒØú~]ˆõžÔ…¿.“ð/Œ¿Ãöœ|½lv/pÖž!åÆ%¾7U;f§^nòr«"F6åæ0ëò³ÍèÅoj^k;v_¥ØÙ«7~†Þ‹‚êßÇþ9ý4,Tv÷5KšWç Ô;ŽáðmÍèÖÞ5“öÛO¼þ%¥ékº!·úIv‰UÈ™jÇwÖû€ µC·ø_yAE~3ã]™ò LjG­Òxq{á ÿ…·¯fiµ´äŒ¸ËÄÿ¨À¿&BÜ=¼Wg<¬"Ü#,§è…ýDµùùw®†ÀÙ ë¶xz#tˆ¸—/¢fÇñvÖÑ×®À0&K —ƺjvˆ1È"d˜TžQyJBÔƒƆ®™ÇC>¦yלö×Cïjí±àý,ÀµD`Å¿±%ɬ* 䣞ßf˜‚¶Û¨¢ 593³ÇN¤Q³C—Sì©+ZJd¢t‘€2ÒÇqÔlßþ§é–íq²yúz!ò öq=YH2°ö ©1›Û^ÕL¥²UHçÿ‡¦´×Gxxt/0»EvK6q>Èx0”ßžˆw7?OOÁ3=R‹5ĽPö™`z1y-×ôQ 1˜u³ð"33=I¸|œöhŠ;>Íü¼t¨>æ»&㳤EÖ €¨ÊÇ´z»Ô忉ÌÔåT ŸºÈ¶p³¡_ªÒJ¹-Ñ-VYuÓõB•U…&¦‡©X±LõŠF¶Ú±| t°¶\£ÊcÞP ˆ™"¶0ùª7¸¸¹¾ Jõ3—°ª¼¡dê48&—0æ;s |Á1¼ÃÔ>«Âœ„_6®JKmû_ÖätˆÂ¥îË‹>Õ€} ×™]ͦ‰‹«/žOä<ó#ÕjèDõ ‰°ðŸ&i ¨‡¤¯A¯0ÛG·¶'lSŸt¡c§ò©@vÈ£û^[›På•É `Ov´ÛWÂÊÌuwÊT8[DV"\¨ØVÆï/þÌ´_Òí›.{E(Í‘Z}÷ŸhdËa÷ßµ¯×ÃÈm‚IXÙ›\WŽ2m×Á.o(Èö¸AÅ;;·5;Ùkƒí6/p´Wù)2°Qì_h€âª“F}¤Êž†¯ÐvÞ_Oa÷>NB5¸'½~Î~€z1eŸixÜÞ?Ùÿk¨:òCÔ`ߟ£1*o5¤‡Ê¡ ¤&úÐ#!j‡â E†8À°^X#ÁÈ”­2yðãêýö:¾îÅý %~/îç ƒ†³•u¢8¿'ãwN^BœÕP(ÊŒgužqF†Ÿy¦G1ˆª/àá‘Ã|ãIbå,ÄŸ»{'Sï'ÝIæô°78ØO8Ž£˜B=šQƒ$¢fÈ„Ê^TqF°Ò&£ÙÑ5>zw_n,ÐË*¿Àeµãl=æÊMϘȘ_Ò™ºÑfZü(]wŽˆÙÑÊswö/¢@xOƒ\¸Ú—"˜ô8ªgã©ÈP{˜fB·CE5Ã4ã<Ï4ÔL‚Qëyžî!åù3‹ò¨QÑ£@žÃ÷€v t‡éÊwLíx{`‡© âñ°òév(ª’™€jºQ'ÊHŽÌ䆪<°cÌ BŽ Ò¶ž™ž/ßÊö¡²üÒgrðùSY7ìwõÛ½™ k—Ü/¾ù²Êï¾Å¦5Ÿ €v~¨ÀW"øê€Bwsóʶ¬p˜IF¤¿,ÌTQùocŒf×ùs ¸zNžÃ’Ïð×ò©­V+cèˆxEŸ‚üÔNôÏ~ÿ„õý>hêWß—÷ßð…€™~úó¼nÁ8£IšÝÿ“×µ_j@ûýb—*!ù1øî×g!lÍ{ «âöƒÉõ³¿øÆŠU–Îãõ‹¼¹ 2¿^›ßI,E7@¥S».3=EUòįK@^…ÁO}À÷Rá®|~Xµ¶SÊx½—dA_zS—쎿~3Ë —ûN€H¸ííùâ‘Jù3#+Ùb…Sî1ý¬’¥ù[ÀÃLÒý‰âå§™6Ìž™"~>O÷…?Ï0«–·jFdí‘¢Õw4}‘ËÁia÷µþ#r}`Äô8Äþþ<®ûéP]62ÇÛq<h2ÖÛ%;7ä¥!e"ò«<àrøH/WhÖîTCLÑCþ<Ÿé¿ÜP5žíζÚa=µ†&ÀÆæ’hõªìs û³<€?)¯蹕y1¹ó³zÅkŸ@ÆyƉøŽS}=YµÄ'‹%O|DDe·ùª>«S}š\‹0Ýðµ™nzfÆBùú†dOÖý\Ô©FìLHg;3?ÝÝ÷޾—ÛþŒÞóþŠx)¸š‡@DÄyô·ÝSx;L¿ kŸD%{¨ð ‹ˆdêwÂã*‡Ë±èOD ZûáéU[j] úHbôG"×ççNÊ—øg™© K¡@Ŧg·ØÐŒ€ÈŦävýun¿iÐ-¸»të·Ú{דGnŸ÷îÈåyú——$?3_`D%Sjìå%p@!¾_ä ‹Nù2¸þÛœñ5;ð ú|ç)x>Ÿ_åöŸ˜@¸§(ñ„íËí.µ]FÜ ^žÈ·C3S´ö=ÏFvP9ËcÍfœçs~aªÀÅÜë‡Jï̈óŒô÷ó|>Ÿ§»"Î÷÷ó ãô@œM<x„{¸»KºC• ÌdsÖ3ãfk4zæº\/nòªÅW*D6î^_Ýs?±w¨Õ¬ÿ.Ù‘£=¼{AN¯}@ "^‹ÙüöÈȬ«y9yá9#µ{ÝÊéµ`½ð&ÛÝ1gÍgP†Ñb‰ ïò¶EÞ^µ?Ž?7nXqáx¨»!Ø;Œê‘W>`c4pÌíÚ(bˆš%½+d•/ê¯Ç-ÒZ ÛÝC]‰&µ®a¸>©’ì æÛðêUΊ4µ•«ûÚNýË–˵ø¹%|ºÃ•»dй»õ-®m»>fåÂ\Á®ü˜·’kÒ­p={=º;7þŠˆ8wÝpB0UðóÜ”3b)®¿Ö‹Aä>a´MóîÍT3–éèejo›ÓãÁÈ<Ò |>–Û×cDÒkÛopÿk=>€DÜì?¡¶íךìõŠÅeÁÊž·¬EìX3øÛ»Ïj]ÎÁŸ*—íxŸ§šº5Ñ¿N}–æ-5‰ä¬ÆÍZv=K y#NwŠ#·7¶x»¹^[Êeî¼1:­ÙžQ*áÓ¢µ5òön5Î.€8[5r@ÛØŒÁoQàâu×TFû[U%™éîçÉ+Z9¹ŸGuHð1°aCö\ÿ]ä‚ôïkúÉ=€xdˆ, Oð±ÿds˜©ÈaÞý«5Ô­¦*ߨýç „ü€·Å0Uð4—à[jZ­>(öeêt†~Bqž’µ°g}ã†×b!:‘¢f û=É'”8OOà™á‘ü9Ù˜þ"à¶G(û–»l “ÊŸÌ-e×T4·xè)jP½ey‡-HÔžÐKc!ÈÚêÎGeþÒN­ÿí¨Y¾L“÷ê|+Kkø>üu€!¼OÖ†ê ɵts3éµ¥$†8Áˆè\Œî¹yº\–OïÈ<É#ÜóôË×}}_Í®²×&V/óž’© 2Ý_רÙ×î:?Ïóù¼—TlÇÁ¶z6&éþßÚ}¾”=£Zoœ€©51gŽiQM´É‹´¨ýËúÓÊó ZO¶¢2" |(‡Q÷ßÇyc?iÓ¹âü­-rÒÕQàÊÚ\Û]¢v;¶6Ðok#nMó4îÚ™Ãä›Âdlc®{ä tX±{ºÝOOÈËjðª-î·ÕgÙ@miœ­7Ø2¶f?{"<Ãá}¢6"Ä7Þ Êsîõ¼yly `•“ܲ nYîãD ©dw\züðÖ¢rtéœëérmjŒ1Q€ÉÎ×í‡uIØ. ÷£x™l“\þÖŒU_h_¯ñïm¯.œŽ¿V\øE ¬™ga<Ó‰–L$ |”À€,ÃLÀèÝC¤€›(Ôfý®“qÄh@ô(^Ÿç:Í+x,– äÊN«³N,ÐÏóYÕ`FÆ—{Ä< â,ÒoWŠ1çÃ0£z=ΜÝbGf;'4iæÌ\fÏ5¾Ô€»»¾ä‘— òîßæõnu|ƒEQ3NÕ_KŽ5/8(òòüUÞFº¯gßûÅÄr‹‹}ƒ ;3ÍÙEœqÁjEûù|ïeÍw ˜ˆqq¥bž1³«ã•˜FS\þ4÷ód»£ðýšðì`î·â^X&ÂüÜÀ+³q²ØQô ˆê®™AÞ;C7Ï¿ÚÕLìqÝþ¾-5¿ Už} %øüzAh. GéÐõ^n vLpKòUãíc["²'³;`]DzUä!½?¨–Âäq¨¨>â²K Ü3}c3û¹¿²æDEñv«ÿû Ó‘^׆^R|VcæÜ¬¼à=~î§Ó²ê{ÅîïåjñŒHÈIÜ~fæéÂç‹=BÙ™ Âã¹PNäý$öÞÈKÏx!¢wó Ýq+?8Z¿%üå1ûóQ "û$׳¼k• Ø~òç hÁ]1m¼#{œÓÉZ?0¶”`~ƪÿ£=ÀlÄ¿¾•?<Ï-þGF3ì‘j˜ä„o,ð›§i—qU™4³ŸyíÊ|lO8íu¶¾N n1–Þ–ݶj-"÷,†ð®ÿ¯2öÃ[£#ÿgüxÊ¢®Šw †u•lë­äTì¤8ˆK„x¡]¢g Ú¨C\¢µ¤r¢xñ‚É)½‹_rÓ»àŒ6P0}Àéî¬#ª¡#¨Ž÷E=ž¡ô\IcîÑßr‹u¯uëU~*€¼E©€qÁx°`#Ü©Ä+ÍÈk‘„ØdCš÷̦žÒ™öÅ”ŽõY¿4ˆ¦1³7"úíA6pEs/GÀûœ÷ã.Qhïí÷†myÜ<øyUyÜö ?Öõ™ÞO©Ø.Ml—¶QÏ¥t¶´z{ÇŒøàZ·y]y]’¼ `4Ü鑨*`Ý¥&÷îк787©gÏðk(êÊlŸÚâ0øv‚³5eör†Î:}å©n™ej½z¶æèM^Íêävj—óº[qäu#Ï>°ÄåêÙOm>Û‚Î38ë᫹šŸ8Á<=2ª³SÆ´¾å:á_Õ÷3.<ÉíãÎÈø .´07FÉ#ÜRýIAk€93ÝÏóyù¡/$x+ŒçëÁI% QÛ£îÂ{#¢>¿¹¦½ðêål¸¦RUP>DˆUY}?“‡Ö/˜g®e³B€ót÷¾Í¾Z6ŸD­Khª@¾™ pXòš ÷HàS•oÄùÞùOmU¤¼ñÇýg·z9H†>¿¤ æHÕœ[£Y+ÓÁÓÚµ8ì$/>NÞ\·Fª±xžˆqŽ,5ÜO÷´¨¶ÕÇ ºíy¡/÷WçïW‚Q.à×J3¶ø^öë͈˭.ÿ¡7 +û`èMšZØP+ð–ûÒ^tó_…Aˆ©pð•OS1^’:ÖýÁ:IJÞ€‰éÁ#k.áà•9ÎÞKûŽÞýI–Ó¦ÁÓc̈”¹5޷įG×P[åφÀßÙ+6nï¥ë#×KU§y㥷/¨ƒJul­NËÙœà˜;èM·ÆÕÚìŽÕƵþ»FŠ×¹2§·õêìž3´óðb‡7™Z­ÝŸ™76ä³3;˜ëé&;F¼3lÜ…÷˜ËQµï un\xgÀÐ7‡0k±*,Þ65ÝnŽÆ~n¬Õib#z­ÙçáE> ˆŒ÷Ž1œ‘È3¶bß ¯ÞT¼Ìy>LúŽ<©Å¢¦3Á7rÂÿÃSZoµ`¼v>`ò^b…$Mà1[¯&; óÂÞ•3{À“§7ûPæø*›éúîsHRy;µµÝÔLÚöã( 0î<¦*je+ õsâ²ôÖùÞ6€ö}uîÇ4à)ÐXç5á}z´Í»0ð{™_olælFãuŽãˆäJLóÎß®¿óÙ8ÿô ÒÏð>:Á ‚Ã{õG*ëÜÌþ‘·ÖÏ…ÔXë T>,¶îPñë#Þ׳@ûÅIîœú_Töù}{, jGŸ?3“„}_H™p_N ¹·GÒ¯—.W1”F 뉩9 ÒæÙqÖë —h"ŽòtóJߥÎDfTÝXò×g3CX¬9¾ûTØaYðXY‹$ž~ÁixÅÿ{à÷[žÐrºGC¾0AS!ÝZr^\‘>bo>Ìuä-ƒ}5s̯H¯úR^›«3¼"Vy@¸;f×7fôàŠðüÈD p»w_ÉÞAz{¹V&€'¥,›äœàCÂ’Î FÝ:#$ÎH¬Êx?¾öüL½Ø`ÎìñdÆ£âSîž#k‡¡V ÷Õ•:ܹ(±õ;ìf‰+ïlc˜5ಷ^Õ!˳./Ñ3x™¼­®íýyx—á/×ñµó+0àͲñ6æ|">$ ¥’[`Œ>¶ÆŒÁWar]ìz÷En›Êh»>WñÿÄmwÃk'¹žÁÝcE!{®¤¼Oø• ëÔæS«ýA6A9õÜ;{ÅjӉńËÒ˜ž,<¶ø¯› è•…>'7³Ðèèeßüq$„ý6dÜŽ±¹;q4ž\Å“‡ˆ×‘öÏÀ×Â6  -W"T{Îë„`i€™¤¨AæØd¯ò°Þ<ÚëtŠÐ×€¹7h’~†í4 Çt‡A6ñŸPYáUúYY à}4€yÐw£@ô\TŠm¸…JÏÂO?y›Ñ@~°e‚öî3¸Í \ªÅ&†WEφ"Ÿ|`Çõ*çª@§]Á“[¹žã‚f®k"ÔTë\íºù0ùÀÁêðÑ[O™<è‹£ Øvýn[÷úÅ,dg„vžbð犹4çéÍ\àhUƒ UîcìùÂq/ùž4.4Á¹ß×O+¿Š¨¦Õ´Ëºÿ:ßXë ðY‰ÿzªzÁ]U ï_¨ü´›Bqí@­? [º§‹,õÙî‘Kt¹;Œâ‚®Wž×å¡tzFWðHÝ¥³;Ör5#24 ^oÚèckœÂ ‡àìÁÃ¥4à¼ÂæcÇM«âLVMõ4.$?&V¶Ú«`kô¥|žômݾ6W–ð Õ¦Àí¡¥YÀz3y5 ½›€J2”¨&‡GŸß½Þ#<!ƒõrt’/7¬¼°Ç·y»AMy^Dª50÷X«f˜%}W°!§£€N¸¦Ò{—6ïïAçœÍœ€¼VÛÇ«ú‹•ÕxáT‡ €È.ö{# õÒ#V¹üÓ袦’£•÷õµù=( йT£Ü°¡\íÆÌÎÅÙèõ!l¼ ´BÂC{y-N$<£4ÀÙ­NP¤ÉE?)éSÛW àñ'\7è-ºœ?!ŠÐËÊ‘èÍÑ‹ØS^q1Ûf/J<'g§Pg³r»øê™ògÀõ¥5@í1;ò¥z„˜Ò¯¡¡€Î²_æsÓé‹Õ\N‡ÜÜ–w\mêËx,Õî ûÎñr1À~Ú f_44:Á>–Æ›I½gØVQÔÇVe@pÌîcè÷Ö&æB¤WPºÀ‚pÛ¾¥p¢pMxFC š ŸÑ§æ2p¢’?É+\îó{~> ð(ÈUtU&>€¹Jï?ÍQ¶I.£²"Kç÷OyCae®çû,Øë…9Iz$AR.ipùÐh€w+Þ!©¯^íÈÈ\~mÐíÌìǘÀv{iƒt`rY¹š *ÊŸücœÁÐglÃuœÔ°cƒùý-«_  • Tšy€vŽ<ø@ƒž}±¹ÓšÐоVÏŸ~ÎWg^ÿbNV3>é:š7l˜Pž7À,‘þ€3e› @Ö‰´Â º;AÞõ9¦rm„´Í/ï½›¨àÒ€™ßˆí®NºöØzQ`/ÐK²¿,€»Hqç0£©ú 5!î÷vÃ@uÛCX·¿¸²‘öÑ Q»™™Øy°(:ù§½ éLïœ|`§Ùã×°MC† TWSLDB͉ÿð&fc 9g«ëÖ\Í5HŠŠ.„,ôòýÀ¶+‘‹!|öt{Ô,Ô“|˜ÁéRùU° *ò˜3.eãYgòQ=±Á;˜º˜h§À5p™„­§^4¼2¢zn%<5qH¾RÒkö1‚eû134ùCëê¿/€¬µçSÝ® “çÐl鹺 ¦Ì}W‹gŠèQ[Á¯Ÿ´“¡HÍþ"Î/²/Ð÷3œ …‡×L4´Üaîôúáþ¶z뷤شÕ.§KìVÚBÁUE%0¸ˆöZ'‘µD>™;5&òBVeS¡=û@“æèŽÞG[8g¡`kY![ë~¯ˆ©i²úƒD¤¦*^ù$Û Ó:þ—¤ô *ò§'ØÎ¯×Œ2ÇŒ0FFJòÈÒ†+JÜÎâ÷*."f¦1õ?8BQs>WÕ+SLÖ=žlÿÛ'PµõfFC87Z¸÷®Ê„”®Ï¨¬d Àý>`OöîþšDµJ>¨–€ízƒ/sb"bs]ˆ§,ts‚_- 30f'ÿö†„QÀcV¨DBàŒqÕü ˆ¦NÍ7$ê>2×ü­º“åyŽd-dEpˆ®{½¶&«!Ê|‚x@ ­¿r›ðdÀ"P\¹Àß ÞðÕùaÏOú$½²ýÕW–§=_ãòò×0HË)>§8¶é¼§üý›ÀÐßw<;üµ´CÈ~ÉZe2ÂÊ|z`b¯>33FCgÖ#‘"ò©„ŸìƒÞÆ~’]î«qòg‹ï¿i€ôáú¾D$\Ý'Û ó% •›l/‚ЬuÑSÿ]ûcÑŸï”ß«ÿ]ØŽ†ji@MÉÍDìÀºf/]7 ·Í•QG] ­ù ‡š•åu¿<öîcOjÀ™÷‹¿]î©” €nÒ¶;ÉóÐò°›h@X‡-ƨP+hS û€ütžÔ§iÈŸÀ\|ÞL@·Œ&Pó3'HÏ0uy}ÒˆúÍdt‡’éÑëó8í {±àЂ¾¬ÿÿž È«$ˆT ¥à [DK&æÜÚÚ¤ 42¢5 ê “ôÀEŸ—¿_/5@$ï&0–0áè¯ðˆSÞˆªõ+b_„Î-^ürö‚"É«äO à#³Bú®vߢgëgN©üèB' ´Õém³üG ÓµÐ/3óág*2‚TÚä>I!nà¿øK5iGðÕÞÐHìw²ÿû@X¬í½ñ  Øú'ÌO2\žFðãìÛÿ¼šp ÚWZà £*¨pwáèðâXEòv6ŒR=SÔ Õ_ÈÀ~ÿ„jÓ®ôed[ÎNw;?PVæ{Ó(ñ¡Lr_|¤Ÿ€r]~ÐûxŸ ?ÿ°úÆrN§Ëõé"Fêx7KݶˆAÓ–þÀÏ”J"ø‹ŽòùÓ‘~—j×¾äkšüq7®§—Û¼@24¬åÀyÙ–î)¡,öN¿ÿ`Õ÷€(nØ<`µÚÈJ£.ØRa©fhã¥Ïv#€šÛ‹Íûÿs•ãÖeQ*ã… 0‚^¹Á´€«t@E@â%€¿:~R#ÖýòüO àú$K`%Ü@îæè7¾rvã+3ÁÎŽ€H>OˆÊà¡ÛêÔ¿çío `1`I_ãrµ1¤¢!D®¿…Á—£Œ l-C%ÏSEí5…¹8Åÿ5Ðkj¼Ù<Ø7»eÕ‹*³.3?`§O$݂ɩ§îÿïÀžîNpÑâK1â~²*Õï| \$Ã{ééNšÂßÈüþ˜ÚÕë…M`£6H8ãr }¡XCÂ|Àî®0Á¾§«ç3E–)*çºW÷ß%€ÏÞúî–˜ÞØ&ª?âd‚Ô^ݪ·çú;ÿ˜tÙü…!òBÅê ±}ßÞo5ÿFËé]‰’6MЕPSÒÙW›ò¦òƒ&ú‚¸AfÿZèí«5`/©9‰vJì¯Ãì¿O]䚀1þ™·@Ø—Ú¾ÔÈÒ€® äß.€› $¯¹ÿ~Ýåb]ÛË?dÿÊwhFŽPŽIEND®B`‚rgl/inst/textures/sunsleep.png0000644000176200001440000024061314100762640016250 0ustar liggesusers‰PNG  IHDRÓ?1ARIDATxá®e[–eUö>æÚÇì¹—øJ¾ ‰„T‘ð½ˆ"ßݳ×´æÿøoÿPTĦT¡â6pѹ3Æ=ikô$T6cl쟙H0xNfÈ02b{ìqS¦9òıNû$GÛKu©›ÜdFO8ã¡S쎸ÅFN;ð¸G{ä(¼ô>£½ ëœ01ô‰iÇ}f'•U±C<Ñ•«+›TªÕªj4°;J›‚Œ€ÇD&DNHL‰ Ò³‹t€"J&c¡­Ýb‚¶éºd×Ý»•v§‘d™=ÝÑ‘ ›bïr3‹…3};ÍDøŽîn¬®,¼x©Ý¤Ý SêÆšÒ$`3DضÔTÆ¡´´1ª Ln\LT£cB¼ð¶•ŽÀ*Jhd421š: <I; ÷™=ƒ0¶³LˆÓ‘¸É¬eP«¨7§I£FÓŒ#Ú¡ÒÈÈdÇ ŒŒ Ït¼'†ždé‡=n¬t4£*Tj >““L'`9rT›ú‰Ï+;½8æàÑ£a£aCeŽF†´•OÐF¢£±¦JÔ¨$7œÌèhbé`TµH¡iGc#ѤÒ)Œ‚щvÙ Òˆ >ÉagD€Âm¯:rŽË ®f™šê;1!í¡á;k¥LµíÐ#Dâj'ŒFÂ&]^-X6Ð^³ø}hz IxÙŠŠ…µT¦  'fæÌSÁF­ÜH š8$@Ö ) DLâ¢b¦ÇŒ;lºcNf&µÊImÕ'4¢ÀÖTmQfœ$™#'óÑ~â'IzÆ3™‰'“9£l2)DíŒ!Ï<¿&±‡N±£ˆ-Ü„ÑIgzP¨àŠ™N2“Ð'£Bb‚£v…iÓ&¦1‰SšplÌÇÆF4""Bt`àD¼‘IŸðXiº&†';yÕ;¢žˆ­•=AvbNLp"¶Ñh¢p ª76YãX@ˆcOŒ9LªBwfã=V*;é舔@¦!“B† Œ‰;í©÷vÓ+‰&AT§:Ñ ’Qzf°¥!±hh“ £C›;&F6=r¢tâs|d÷Σٽã“$MF*Œ‘é¤ñîÐcÛkŠQtã“92rh¸¶‡ F£²Ú)#´QÓgœ04rÆ„i¦V‰;áÀ£É0a¬;™èÀØ´rÂÒ=CÜ ™ŒM:ÙI pÃj'Fdã&&ŽÀkJ7i†d2` Ó$55Ìi¼Q]Ý©-Ú®¬lh«$I£{hØ=:Ä\CØØðކâ wRÇQ£äñL’2ˆ ;Æhb*Â$PU)Úê“8Jv‚îcÆV-qs0ªèêÆÅŽÒ‘ÅjMMÍfú“ÌÄ*кL )§z j¢Z€ÝUÕlÊ€:V¡P)ÆîŽÆ¤µ&bªÓk:Lj6lÆØ¸Ø¶ ŒHÖ6­ûsÜÎ,|£Ûjh i'ÎIÒÈè$3£è<à tfwÅR@3A‰Œ‰ Œ ¤"Cì£cO8d$%ÌáØ=ADˆÎ8ch'ƒ'ÉÁ´ªƒÁ” r²Ö;š·%%Ü„H¦ÉŒ±Ìv÷Êë.݃Ó}…GÓ÷ÌwàÉ$â-?“;“d‡}ì$•ÝWIÎ`\[)nÙ¤”l'Ú•škºì€ë¬Ó<Ø»Á %6Üpé…Å5•†ë¼ø%ú„CÓ=é¸N22úЄÆúØÇzè!Ç jš½£C2I6h±Sš¬:3鞈à´]P'¡ÝQ)Ð6•EÁ›ˆ#B°éÂ&w&P-lrÓ›ùb'G3CÝ$IÊšš550Ú ËV Œ ¥7m]%JK› ÂÊ .àØÑHfª-`GÊ’»¤ceÇ•@)÷´SMz葈r )®~ã+Mœ¾ÃÒ (àÊÒWß“êÊ[±ÙÛ{O7.D§Ù#æJc#ޤ £N34Ça¹[Av[hWI³miÜ$ ½åŠ3OØë­V0!j;“]BLu¥Ûš'kh¶åŒñßsn¢3ÒÐèÄGÆ<ñ˜“œv& ’ôÉNFwÜГnºÑpr6”©…†FÆMr öÈÌ faí}ØŽuµ„c™™Ì;FzÌɪˆÞÒqÐD¸YÇhRÅ0F7RJ“€µ‰Ý€TKiK¬%$Ù$A1t¦ ÑíI¢‰è$b-ÆDNR ÁÔâe0+Di–¨¡Iç8CÕ©Òd¢ã·¦ £*öiãLUGØØáÅ«žxØS~í<&扇U†H®išÖàêN""MBÂ㌠' ºúR1CŠÛ7eð ´]{S-Ú™ IçÌ#N4ª0rvo‚*Ø…ÐÈ HJL0‰:ðh\É@bpŒšHwÌŒ²bâàÁÙKȨÄ‘+„Žœk{Bð„ ƒŸ5dLÐîÈ„°3GFõ†ÎŒðˆãC>™3s¢mF%°ÔÜãsÂD»aCm&˜2R”(´48Lº¡¶IÛ³sšd⣓IŽĮ̂±N2&@««M"Œ*Úh[i‚.T6æHva£†º£ÄJ4G¶D@#IàÆÒJ'h'‘Ÿø„¡Gž˜Ü3=é #±Gž8É™Œó„Oœîذº‡‰ÏÉ'}ä”ÏLJ128e£´Ú¸q³ ¡-D,ã¶ÚLÒ®!PiPMë6ž¨MÒ6AW׬-%iT‹ ml¢^½m51'c…N´—.šV{&¶ ÚĶa#(6`«Œ*RY]èÄÑ#ãNsì`àȸ¡òN®T9‰]m† šcŽNPÆÎdmŠld–QÚ‘Sb‘—`»´3JéN°c+ÄÆª‚€«XBR§'$Îxš,a…ˆ«-Ù®¢±‘‰' ÑÁ¶´Ð‰Qa&IaUÓXmSBD6!éZumVƒq ê$ÐDŠ5Qˆ&$qò>nÒñÆŽ>Çg9aÌÙ‰ J$ñ ðÎ0pbÆè‰Q!mäÈ™;¾nØÅî1ƒ¤XX4Œh(àÖÆ%Ú†$„Ü]Ú¶™H¥ƒYSp¤¦Ðv¶«ÁÕ*Ÿø°£°J 6”Ðq&qÕ©Ò !t寕«˜•´Åb'¤æd&QCƒ;:Jz☡¡êàØ¡c'MvZ{å–µ›šT7¥» mív1Ý–-A*iœ… DŒÒ%´kµ*Ф 5´5AàÍîT¤š"–bu¥¡a…”n)‘öè8iI¡33¢M4ÈBÕ“Ú72v°íhÙØ ‘s&v2£Ë&„a≓9™'óÀ¸Gg¬LNÒcSØ}bì¤ Çšî‘'>1òä8ã‰ÏŒ§ŽÆ=“O8‰ñ$Ç&vÂgVOÉ0rMn7™°À!)?áô†&¡Ä²ï‘ÈÓ$*º-ÄÔ6LT ²TeFu2épÂØÙ †„àÑÁT—©K ¬)]ÒdLÄ<ä$™D'‰& k{à°mÌÞÃʤD:ôõ0§+&Q[Þ]ªVU¡°m“ƒ)¶ÖîÒEm—K»7 ¢¶ ÙB@a©“‚ ˆÐ VÒ3dD84í6mÙÉ¡NöhìŒÚ ªjH‚‘¥:晤}LHœƒ‘5æt§L20ú`LØP!!ú˜Óžòã<öÈ¡ÒßxÒžxÂà¸û‰Ž9rèéžÞ|ºý¸ù¥¿§¿åãþš~ì'ûI?ú{&´Æ—]І»½•Û‡q£¤íB¡ïÞ ÖÚvb Zi÷ré¶Åà H—®2ÚV Z%÷DÙ)•µ­R Pp£º°EvcºmhdD®v6Án{Ùö¶»»wãÅoû²àe/½»m6šM_¶-åÝ\ 5^÷Ý÷ÂîÞR+R£t lïB[¥Ø¢ª˜¶ƒÔÄ”M"Z§‡°´m·ô–+‹´(“„Ji Ú\»!€ ‘P¸@YuÖ Ý ’öàƒa‡@G¢ŽÚp’Åk{âå‘Ó=0rdÜ£ñ÷L† ²g6|'MÀjñ†ÚÂÆw`FYØHìh† CeSbgîHÒ°ñ>ì'+Ídn:Š-¶-’Ýî‘5©ÔŠøâ+&~»ŽÓIêlt¤¬hATIœ8¨JÓND€2õR•¶ªÅ‚VH¡:IY -nÙiÓ¥X‹Ë¶ ûz//´ØvÛ- r·[Vßåm¿{^ý—û§ïËÏ»{·_ùÂKÊnýêßÝBuÛö±‘¶Å€¶` v·h•¸ðÒBÁ²»7ž5Hi1M°5 ¥ UFN&ˆ¢R( ƒ¢‰š `4fjÊÐ@ (ŒF¥ÑÐv·7Ñv°¶ÙfaGÆÕ7;î¡“>ñG«¬Ùg˜¬ï&HG¤P…Ö®tbYL¢’T)×61’P6Qwdì„3<ÃqOöØ3é“>Þ_ɇý‡þ#ü% I[šgÆRd&`!Dt´¶ÁR¢š™68=ǧûµ š(ÀÁ ª„D‘¦Œ†Zì¶‹èªÔ“S´v›LšQ¨06¶õzM5åš-§LmãÒÂKk‚ÛÝ{o ¬¹ŽH÷¶åÜnËÝþ°—,ìvÛ]$½J¡¥°E¤8ÝÒÒ¥Èʘ¬^dY`{¥ÔÂËâ¼Vê6f@¥l+m¯l#”mHaºÙ=^@«@¡…)Ê@—XÓ‘¡uë£ÊS‚çNšè„㞘Õ¤ÎôtÓœm÷‰ÑP1éÚQìœ3PÙ“D&™pÒNö&ý|ä¸Ïñ—{èÐßcìá<ò1SNz&G>ð‹œéÄ'DŽ}ʉƒc?ðIý+þž|ìçäŸä™<ñwúûä~?ó+ïNýŸÿëÿÌÎeOPÒHoŠ«H%€‘¢RîtÀ¶r„"*€²tLAŒ) ¨ÅhÜå²ã× ±­* ‚+£`0¸yµ·£¤µÕSn2²*ÚÐZF —fȶfÂÔR6¨`yÇÚ¥«.Ô ^^ (ôêXk —²­¶*»b©¥I ôR `‘F hÛÝ!àÚ`ep[ZXwÕh{ Œ+¡+E·¬¤ mG·]U¸«¼´«°@kâ²Ý 6å–l[‰7å®’M[Ò–`¹â¶¨”"µÝ ˵oಠ»J;tI[²¶)F(5vÂm ¶ ¢MU¶e/*î^QÖÿé?þ—¡”¥Ckt‘¬@M¥2@2¶ðÚtbÓöˆÅTSЬØXH­BRÞ4Û•ÜKÝ¢EéeMF) ‘RPP¤˜äŠ(Ø7AÛ “¼Æ¹nvȵ¬IkÚ•ÆC•ÛŶÄ]nÅ‹qÕÚE[LX «ÒàR*-½,VÛ“RjmŠHÁn¦6¥i`K,–²j &`‹ìÑ[JÈR5—ºEÚFfY»TmËZ ¶íÒéj«,(”–ÚjpY±voI²½ɶ@Z­mi&åí+l!L!ÒØ[À m¶wL ]»ê…²t­”Ú¸T¤‹´¨»¥Á[¨ÿßÿß¿kÏf-ö™óî}к ÑbÑÄvEd*e«ª±ÐE T$¢é^Ü FV¢] –²KFÚh­u ÛL -2˜¸´r¹±S¯šœÝ*°ª29íJÊÔqìØ½6æJídÛ Õ©pGÚª€Ó]µ­T¡A\ÊÞŠNÛ˜Ò%å ƒo;¦]õÒÕ)A¸ºêDCß56‚Ôh…Ô°WWº[³ÈÒøÈv…,GúöŽ)‹ÛUXÂÖ˲ÖÝUKÑ Ý­*,éêf€}Ø-Êblw(Ð]¨E½)½Ó“$ÓéØ&“Ùc‡N7øÞEÂîݺ»mo}³ßÛMréé[J1»Km×ÿé?þ}¢o3Ö ¡£ v[ga¤ô`±jÚuT¶NÛ$ ÂŽ´Æ)+Ô'Ü6º:¦]‹ÚîdÐË’tk;±‹Ó]'²HÚ†WQºÕ)H++6ÎÝ; b‹ †â‹º/Ͳ&¶c¤í€ºUˆ)[°Ä,K…¶1¥¸uÒh*ŠúîVì¡$¡l;ñ¾•E3ºnx…uÒî¶«bÑRJªm/”b·Œ)¥ÈB(k¡an7–J±» ÝZ)×b³] Üw D[ , r¥KmlZXâ 0b;Ž­ïãJIÂ*s·Þ¤­]Š-Rº‹%´À­_î]i_Hm—äíÎݵÛ) 6²¥„Å]ã¶©`uã–“aCMG¦,”A›(N–maéRÅ ŠU»+5ÁÒhꃨhµ@[€Ýi£ lÑâ(TB›T]©¶¨Š qOoLÀ¶J²€Ö´Ü.] Úu¡…6HZkÀ¸¥fK±®%‘‰hcUUÒUƒANsY ´(Qm1E ÁIåpÛb8«¢¡1fYÚ1AûJaOxâ£yäWràÀƒ#¨CìŽ ždì±9:8@Hrì°3wèI?Ó'~Žÿ8Ï_g~?üõðÃ?¦ÿ ¿Ýßçþž÷ãÊuÛûn÷î½u÷¼ßyo~®/þ\ÿÜ|›Ÿå½½Ë®-Ö#‘‘X¥ÛTr’gÛ}oÛ·›960±é.](&D·Þr¡aRÊÆMÓ ±«Ä骀FD)–´´éàJÅ‚Qdøá¾=Ž …’2-T–R¬È ¨Æ¡Ïî¨-Rµ[êv P,¸[È.ˆXØâÝÆ‚(@ Š  a µÛI[n‚ªUX¸qÌis­- ”>†Ž]\1¦l— F:ÝGŽ“ª«Ë"¡L”àà˜RÙ#'NΓg–è1‘V{b«Û «Â2”=ål¥bÄ{Ì€-¡°SRN:ô“ž˜ôþaÿá>yŸô’nzéRÛ²¼—÷ågós¿wù¹´Þ÷ »Ü¥Ëmÿàß{ÿ¾ß?÷þÜû]ïzï”m· Ö¾l/,lÚòhëÍøÈP|õ%š¨b\YE9¨âÅF¡m£@-¥»2G#'92ªƒ*:äâ&ŽC‡¶wưö‚Ô$m+˜ö”d K[ÈK^XCÙrA ®¡›¶€q‘LwÑ%Bõ–$€ TH´pÝZ,)¦Ú^}·ÛjHŠKj˜®½3j§¨:R…ÆØ“`ÞɘÀáÎ0Ùuãj ÊœÉTߤÇs’&|æ &aì3}‚î :hvÜpã>‰B4frè¸ Ý ÐvljËîHbB¬,!“Oüõô÷ñ÷ãI'7s§/å¥ïí½ý~ï½{Ûo÷²oû­?å^ïúî{›ÞÍ—n)ÐÄSc5ƒê‘Qƒ«oYÜòî¾» Õ+½t×Öÿå¿þÖ•ÖnzØé³¾cԮĻžÞÆ’a[UªÂ %€j÷&Z1íMTŽi{“Sp%-ÙÑŽrYÛΤì«©§}ƒ¥ë´%Zd ‡ša¿B™NSšPªuA܃W…C/@6L@¡Þ€wÖÑ…Ö e…˜µt3Ó­@Qd„Ë;F_±A†^ T°wcLÉ%¡º­ª{@º2IÛ ©Â¶Ô†¸BGf¥xìo›‚Âj¤B»MÒ·dôÝ ¶5XéV„8íB+¶-@¡×f[Ãv ÂlÐ…´-´é”Åêå²ÍØK)¤K«…]éŠ.p{C£wï6¡k§¼Ý€9…öÚMpݽööܽãèJëìÞŸ{§ôî^z·%ÈvÓEnÓ›6Áu1ïÝ]TwŸWM¢ €HIÀÖ‚ÀîFÛUc Â¥j(l[!€WSʽÖZh/,‘[²€¶QaÛÞ«U¡pmi¥le°m¹Ð$€½¨B P.\K×R{»ƒ•ÒÐxéÀ˜n¡´ €‹+iÕ ”ºHE¨®ÈŒj«˜šJCŒ´Ò1c§ö±‡<æ1Ó~†Ïq™*‘é}†ç0iR­‹¢²Ê$“Hë4´ (€ëvâBŠ.·ÐÄÓܺµ·ïÛ÷{ß?»?ö_ïþ¼ý¾Þ;ßÎå¹;?ŸÍÏן;÷¿¿üëúíó÷=¿ós??÷ùóžŸïùû>îùéç×oŸ¿{~öóÓóÓùv¾õnܼÝM¾íÝü}û~¿tG¿ï÷Ͻ ƒÛ}÷~÷g÷în:»Éí´O¥"F31-ÒxZD…–"&i›$Rv)’X: ‰J‘b‹¨Û…K¶ˆ°[¶–¢&F’`uµ—nŒ J’¶”ßå¶Ü䦑emí¥C¥¨ n[PAC5í -Š"E‘× +ÚJiA1UZJÛjŒ Q Ú–VŒ!™d²²³÷´BB»Ú3}tÜ©Cí:ôè£iÓ 0¢ÒM6Þ‰±‰BĽmc¤Û¶6ô½ÛÐÒ–"ŠŠ¢ª F-·¼ÅÐí–]nÝò½~¯?/?×÷ò§~ëwýi¿í»÷í}ÙïÞŸå]ß½k[îݽ,~é6ÙäÛnæ»mecS"CÙÍ»Þë¿ÊSßwïò½û®ßÍŸëŸËù®ßõ{óçõ»¹ø½ï»j¼Êi·÷U`媥»5¶g&:mÙnL¨»Òhʈ²†2¶VÃ*ÑiFÇ`Ì IFÓ«i}Ì„P‹-]¢f¹ú®%†œ–  •V*…мãh¬b’&±5Yƒ&Bª‰¡JB€NÄ&c&àÚŽ Ç~bôל}’ãý¤áŽ'1Ån²N3N90zâH‚HzÄî„‘ŒJÛH016ŠÕɈWD«ÕD¥ïÞ]ØÝò³-¹ÝŸÝŸí[¶~ë‹o}Í @™2]"”Ö^)5ê.[·@”º¥wŒ-/ýî²~»/Üörßåçõ¿ùûåîó½ù–{ó§þëò³ÞN›ïË¿nÿ¼þë›ÿüÃÿõÃÿõ“£)v{M4É£'Îd’¶¦:m¡€G;‰8:Q B iU I,ÀrÉó?UbÚP,Ý(mÙlµÊhL$‚…ªíº¦f…DÕÊhT꣊°Pcyˆ FS@  qãj'‡2˜¨coÜ0ÏD<0“#C¢gæÑiÇg’I‡M÷Ä‘¡ÙNí(Ú™™\\‹´-»] H  È11¶ºPeff&-{Œi’™('‰ª-m-ÂÉXî½ ÐvUlØuaÛÅjËEØA á=pB70»[(¢]wÅêܽ]»Ý-°[wsaåÖw¹·[–ÞëÖßú6·{»ßËŸò½ùîü\ÿ~ûçËÏËß׿¯ÿºü랟ÍÏ{C·T]º˜±­-…¶”»EA¨AUUºÑÀDµ…’´Z-е†H¶ÈÞý³}aaá6€”¶E(Yl‹dÝ6¤Zi\Û¤ÕE(]²ªxuiÛ… ´É--€‚¦`Û&ˆ.Ji4jP…@dB шL¤t'Š¡ìMŠ´lK¯®@3Á.»nÓÌY„o¤ÛÛn‹‚*´€lt²í–·½mÛÄKIVŠI[(ˆ05äèh¹¢"@è”ÝM<‰ MkÁM¢d¢¨ÊI††’G9ç˜÷œÙœh“d¨l‹Ç˜°,Dm-tí²lÁ”ªµ w{ïnçݬ.ýÙû]¾»ïõ]ÞÛ÷ò½~×?õ}—÷ö]Þò³YŸÁTq¥´M<Ò «j’€²hÁ2&dLè`ÊàÑB¡PLŠ‹D“¢¢¶·u»¶mD€(m  ÕÊv¯l­ ¨ -\¨ z4Q¨"àVÈ…«(™š«Ì$š€M:£ì˜TE 3f숬(‹Ì$¡]XliB»X%6Q-‹”Þ½t Q ¬,ܶÝ£Jé¶ZõîªàÈѶèv³¸E“'# Šð1—®LËm0äÇždÔFwdfŸifŸ‡ÏÌçÌÇþóøÛýëø9üzxNŸgžñ¯'¿OŸýëð+üŽÿ8ó;ý~{ÿ9~&?“'ìÄɉ9qì$‘ŽÇæhºAÛ€mDl|Y†--ÅÝiÏÛf÷µÀÝîB”„ÌÖõ|;þ—ÿöïƒg«~éDk¨ X,53A×JfX¡t8ã~XES6™.€7L!q¶7']z+椉+»ÑK‰sCº2 ˆ­‰ÝÅXñ©¥„FouPºJâ¶:åŠA³m-ƒŠwV„•J[XÉÈz£°©€±ÝUiq Fïz‡ºT3°hcÛ¶‰-ˆDŒKÅR#­€H÷nµXG—•H—èöN­4Ù6eS X*ª»U€Þ-ŒU ¸§!°ÀVR¿–j6K ì¶‘[Ľ·f[n·­÷ÝÙ iˆ¶½“Ënèn ¶Þ¥½ÛÊ–¶µÓÝ 0 …í.mn ˆwï¥n*ŶmèwÙKŠ{{mKWú®O··] ¤liA;I·¶Ke•R ,) Û.H»,^¸—û-Rc•2ÝM¥1x%@$ Jo¨H _yK‹n cYÛâe—v»Ò² n¤ °Z+ë‚)„Ψ%5érËD"ܰr³Mw`Ò(4„-×4¶®ìt¡ÔTl[14$ ¸]ÌpJb 5Êm/ U-`ŒkZ ¬Ü.eSµlíímÉ€°¥îîuKÛbooõê…Š‚¸ Ò ¶t'äæ$CަÏìžçþ:÷þùô¯ðûøÏéÿçô/ùdeŸø{x²¿Òo$};û†ŸéíöÞßîûÞûÞÛ®}ïýÙÞÛ…uk/û¦o¶R¹Ûo÷2l» ‡ö´BaÙöµË¢RÚÊ•q¹ôöÝeó®[Óή»·t»´ºÈÛÝ*…možõ`²Ò´™Fôîv²#D‡(@¡A¶°vpp'—n“¬¶µ¾g[[ŠEƒvSZAiÓFU°ÇªjrqAMRu©Ŷ Zy3¦‘Þ±¡ƒ'êÊE2‹ôX˜ nTµ•h´I •„¦è º£ì‚Á»+ ÆÀ¨[@PU3¨&1$)–‰i‡˜] !i«Vжª TP½k7˜ Ù O0$í¸Ÿô·û×ô~‡ÄN~…¿â/ß'}rOî'û±÷c?:w-n-ï ÜÂOïŸ}ï»/ý^n}×[w ¼×%·ìå{û6»ØùÖ+»ÙÖ½œ5o¹¸Xsm»®/yµ“B¥°í»¼´f­÷®ËÞö§DŸ¿›wŸn.{í{»KI‘ÐÓVp¶ÍLZwÒ¶1I(hÙ»´QÛM"&jâŒÇ&#A!¡µxâ3™]P3&ªîLL0q’˜4ØFœä¤q'‰y’‰ab"Ñ 1Ê £Fà 'Qò$²xgFÅ B’ñpG1Q XÒfc(•!ƒÑQ%Ii¨QÚN2ª1 aËÀ–²Ê©M4sÈÉ™8õq‚ƒ“3‡gúKÇÇ>‡söùô×ñ÷ä3ý5ü%ÏI¦¿äé¦jFŶ³ÎÚîL† wÚIŸÌ“†9ži¦IÚÞf›íü”?úê¶ïåÒ­å´GÝÞ”t -…Û²\ùiÙ»}Û[Š%˜ ·`¶§ °Ýv×vî²x9/,­’`Ò„¶ˆÕpIµˆi£‘¶ £* Š”¥&m£&ì.­hÓKo¡ÛÝ\  ØÒØ¡IÀ¶M&¾ú…–•*ím[AÛ-ÀfMacO`Û^ƒ* *Á! M‘m/-m [ÀÛÙa›r» ¦²²¥bÙ°Ôz°°®¤mL\,Ô¢–e ¶\@h-» ”ÔZ„34õDH!'Ð;£i²gœ0'Ç~â3|Ògü5|Ü'{Â@B¸†C£mWº¾ÜÛ û„3<ÏÇÏã3!gTáxÄ1ÓÞº-ܲe+"F–öÒ/¹Ì»ý©Ûlíº´´åÞ¥›ì€w÷m–Ý^¸í·û³{Û[–.Üvë»Üånw»Ë½¼»ïRý–ŸÞn··Rºt»«ÿëû·Ã” ré±8²êîê(P¨¬bì** ¡‰uÓÅ“¶`‡#»Â’PoeP- „ -¢Š] &Y·5Ò• ©4>Ü–k®AˤÕv['I©†*åª0í¥Ð©KU¥”LØ¡·U™°Mƒµ¥`¶«°mŽ]›ZI»tœÐÒÊ^C¡ªÚ6 Z Ñ@©ÚZºTŒ„¢‘¡…mµ-Ñt¢-`h‘¶Û¦Ý¢¬ª² …³Ö ø¤'ì-6åÛ}_QÙ}ûm‹w ÄþÜ÷{ýnVî½æHñnûî¹Ý]^Ê–„Ým£B©ìÈwgéÛÖ¼«¬lÈí¶iÛ©—[ —л5”ö k °û½æë-KѶvÁ{Yêü·_M·zÈFZ6É.âLºë,`ØE´©+‡(1è¶#Õ€ wÜÓPîðvU\E†îÚ( Œ)+Ì¥ƒl1Òq/3}™‡Ý°ÁÕ¨AfM\Ûaä^jRu bu©&\LJ¥‡Þ®„Iw3RBj-Dš,Q–”…^Ï‘í÷ÌÄö²Æj  Š¥‚¡Ji¼tEL‹åRälìF(K·‚…#]®ïx°½î^\º_ÊÈýŒwß>sðd?Ù-Ê8ïî[~ŸÎøÿÿïߟå»ý³ù+ó×óݽ?ïù³þkùóíÚÏä× ¼·ï·_|aË¿îvïŸÊëÝÆ.­ÛuJâ· ÓmÙu–;•í ËV¼¹¼W»ÓÞÝ*½{f»jzoÙNÙ[ …¶í‹Þ½íø¿ýïÿ…€,¸ØM¦]G˜¨J‹‚€Ô¥¢*PÑÀ°5í;DÒ’p½Bjˆ()µZ [ÌÔ ¼«S”¦Y!Rʆ¹ÊÞd ˆR Q íMŽ\™"¬2ÚVØpôÝkæh¡®-¨ºV…ì}O¤6)WOÚ„(6²ud &îe´P-f#Ï‘öȶÈ]Pv …L¬±; øRÃÞ5«€€;æÝ¶ÒŠŒZå ?(Ü·¿‡<™4ýé-fXØRZŠú×Óçq—½Þí÷}!¿†¸mÿlÞíÏýüçûjÿ‡_9ðç{êÏögërËvþóöçægÞî¶Ý˜mÙ¶;Й}ë §üÙîõ 'ÕíÍÛ}ë]—BÚ¥½t—¥-Ö¥·´·µÊUÙr»Ú÷âüÿ%Ò­QBÑBu¶7ªi Ó’BÚfÔ²¦²RrÚN†`¶°ÓéÚ¨gÂÝoµÔbY® 5û’¤A®9lsÏÎJìB*€n‹¼”jw“‘~é„4»7ã4˜°—È5L­ñ¦§ ÀÖLjÁÒjc @Lip·"\glcÆ ²[$n+Ð*BÉ¥OúI?!ú’Òw}·Ûž˜nŽ…Ý“°4B!o‰mïÌ¡e‰ëx7¡m_ö©à™FX¶mæÛ~úþóÃ'Ȫ˦ô]m2ÝýÞþž{ž«í­µÛeÌêz·=÷²ÃÏ~þŸïÏ_ã/öÏÝöü½ïÏæövù5sñgû÷†ÎeïÞnêÝ›?Ý?/­OªŽ}Rñ?ßþ\|²õ¾÷ü¹\ûÞÞ ÿ¾»Ëí¶î¥¾·âv§\ÈÝ»×m‰w×ÿøoÿ6\£o{B¥M„ÀU¡@ ÊÙV[9fp»*átõJ͆6¡TOKíXš¼c° Áµ‰ÝN ÒQÝ M­wW¥Õ¬kÒ[,F„w<Ý7I ŲàÀÞWTD½­šRUÔ+ž¡+lŒ1¥0 .[œN§l'Æ…”HÛ{âRºAêšôÀ“\–m¸ÿ˜€Ø·"0w·µ{Ÿã3v=‘»WŠ‘·¥i;ñè˽×òîz•»ÛNüG¨¼Ýe>îgö÷qúÎŒ,Â[„,¥·Àî÷œ¶ká¥}ò¼¥mxû®Ä%¾­dßwwI›—û-ss'oUÛûç›ÄËþùé^.~ïýe2L›të÷6ñט¼Ãüyósß×û6»ùÌ´ù~îÏ·náíf¢® û}¹œtÇý)þoÿç¿[•¥ÃéHñeõèÊl@¬¡0…§ô¨,ªï0uÕ¶A9¥ä&c«ZÐÒ(TAƒ)`Ú˜]b 1 ìRM €÷®ƒd-kÕA#ÂBV™ÎÝš,f,T¡…&Ô$¸@«'aKlKZœuáDiX){¡5(ʉGnw2¿Ž3ùó¾t¸?jÆ•mÚN¼Ü{#>å™—8cÐí[Z–û¶®nP·4}·»´MEžp¼g '+ï?³í4‡î·oqd»¢zaµÞÚ0K]íöûÃ¥[ÎdÜï½ß»3Óî»#þÜ |"åvϸx·-?ïþ}ù)ßË»s²mF»ßÛ@å>Ù”—,|÷ý.Û<:ì·üß?þ÷·ï}»¾å>ïÞK’™wïÏÖÿúü[Ld&‰”.A#¥¼’uÅ1Û;ª hʦÊ$xú¬¯‘ÝA¦tÊqת[¢beÌ[(cJJÕhÑ,…›uW†¥º…R¶$ Hw|–Ñöâqfèn±¢  ±:…j¨À î“=U‹ Å{/µGh«¬mÚÍG¥™ýëÌ'l½íî7c²Kw§ä¡XÙïúÝ—Mf†Jb·,l]úÿ„wͺ®ëužu¶vÝocÎ%É Eñ'“’b;ÞòQäÃ’ª¨Çø]l°‰%­µæ£÷÷¹¯Ö8ŽMÜiCÄMªªoc*!*õH/»\Úãüáä›gs_’Û!ùézkñøŒÜ"mª´[µ<[Ä Ü¢äñsûµqó©3Ö¼–-èóÉe»·~_?œ›n6¸jZu)m·zÒS¡@ßO~ô™{W[»;#“à GÜ›w¬ÿÃñ/‘@¨i%(•„ô*9V ’ŠQÔ0*HPY½£×*#Ñ$`ì‚°ÈÊŒìSõHÔ4–Qâ0 É$ŒiÕv¬5p™ "©Žó*W R½Pƒ$msSY5ƒ„éƒ(%ƒè$W *â%Ž:raÛ¤F¶0Ó.$Ù€F“ÍË~i‹oÛªDˆzì\3_7c¥5›jíí½ÙîÈ›¨z'doû¾$]‘LÓ4k,Å ø‰õüÏÿ¥¤ji, *Ø¥ÆP›VU;L‰LèÈ!G8Sƒ˜9`×u]ŠyA%IUT*^¸Hî4E²ŒJáo‘Z©•$QÑÈ.Y)VK½ÂòÑnEÕ©%…Jµ*Ý—$Ë`¹PP93j¡¢’¬Ú F;íjÇg’ãI+e4b¡` Ó´¤í*ZTnz4mf¬v†—üÜ+‚ÝR\ü²š\qDtíÀjsƒé/çÐIxÈXÞYÙmÈBæ&n´­ÔÛFê¶‚¶$›µÏ‡°ûmøp¬ =#S†ÖêÞ@ºÙÒcd³?éîÚ~‹W)ÝÖÛµ23ª~ÞüxI®kê‡ýË H“Ý•øZÿ\¶‡t+kGÝ’dä6ˆ'i–ô6T[=»ÏͶI“Ä´J»}Ëï͈lôúÏÿ%6Š@¨–!FgY·xè•Z4u•‘G”ž¶*VÔ“‘E‹pƒ:ž¦Rë–µDkEx ÉDB¶ÒÚU„$¡AhAŽ5€ÉÓBeÑcWD%½¨¬‰„¢ S伎Õ}á-h+‰$!9Z˜RŠÍ†M…qM3ó‚‘ïæ1{EiÀÖnÎXÊË–ü—|ûv6ùñù´‘Úlêcv‘+ üá›~ýe~ÿÚç³ãžé2bÏ‘êÛxNv³wQªÍ¶Ó¹Ž!Be[™–ÞèT3û¡¾¦-ä9Žf²{ðL\¾yž´¨ÝSOµ/ó>Ã^˜m›à6ôÎÌÒ?ÿìÏF©O2Ú¿øèØG¾ÝÒ»ùìÙ­2·…ý>SØ.nšÚ&7º›%ï»ïGM$@˜¡UÛîúöR¿‹B7ú/þËYIÂÐI‡¾¤¸ÉÐFH¦’²„ÑõLÄÔU‘(ǸT:åÛ†:ûC$mû:¦¼„ÁGÓJãÊH "IV¤h…A¸ŠFX‘¦d¬osnss…;Òk§ÓRõõµ´{çåûm ¼7n=S¨löØšŽ¸i÷<ê«ÝÎ#š ‚¾l÷îöÞF6k!¡VÒ+ù‹þá_>4sî~mÇÏæÇƒ™qöö¡6¯Ñ_¾üñ‡ðñíy÷ó~Dz.™mlOš–± Ršùùd…«DœUÔR€¦jw£î·HR"ç5PžgÇXrò:YøúòêªlÕÚÜñK5dú„{müt[>¦›¦q¦[þôÉÏJHð}ô4”Û þaòÍ}YƒªÜúsÕZ ÷…CÆ=Óõ³7}Ú<õsõy~>z?Uëé댨’Š–Mw³èëf[«¤ú/ÿ«ÿ¬–Ðv¤; Ô‘KÁÕ5ê脵L%pÕG É4BÖÈUƒô¢hª8’ÉxÜÅ2@¶•dd›×é0ÕUª3ƒ(Ì(‘i+÷…%FzKºßä4ö¡ù0ó¡ölDúšgäDD>Ê0·Çé÷ãÂ;M1PÇ~ûáÎXõõÎsÖÈògú~Z+dªJÕ͵_mLå6ÛúØ¢öûÜٿøõÛ9Ün¯}ž;÷ërv4?n6>ºßÜoߢúÒœþ(o~û‘¯›Qle]ñ쪕ZWÐEÛšÙv˜m •v[t·ï›¶¥õtŸãf· ´L3^5é<éMäÒXw_6 ÊÔ·ºi"ÚsòìVziMßåÝóy±÷»uÌ–§<Õ7öÛáG©ÛÌ–ÖÖs)£WÈnÎôÃýpíåÞçGúõèëæÏ_Iyî‡ûíŒrK¿¾¥Ë;üŒ6®Þ,ú¯þÏÿ‚ q:¨àVâJGŽ(X¡H*P„#pW²ºu]ËR÷ø{$%\%g Œl!cD°ŠtêPÎìÀëœvg €1GÒl#Åç¥_•3Zæ•À×729ÎXAm(vÐqkõ›l7É»#ãæ_Ñ»Ròíõ’;ôÛ ªJ9GUXUFïä«'7—=é–¢V¨ªCШ©š0¹G©õ¡ýÕúø¨_¯¼³‰e[u%³U²–ίê÷Èt­þÜŸ?Sü²îFÖŸ¿î×"iˆ«ÒB«›†ª¨³«=÷¾×%ÓÂ,EûÔNÓ¾‰S*«iÒÒ†S¶93+ +¦¬ÛeÓW`{U§=Ó+Dýb¾yú¡:f¥[DGLã½µR•ˆÚ‘Žy¯ÚEû—ߨ›çžÛççÃïïü\¶Nú|s^<¾î¾WÛ*½Iâ UN¬ÿæ¿þÏZh¬W-g+ ²(HRê1 ’BTT™ÊZÉÒBíÓÖ•ÌKƒäÚ@ÉÂux¥{ƇŒT6Xê‹h^Ce ãÑhÏ”jtÊö›$ÏmUêSU铜©,(„€ÓDDîë˜õ=|CÞ|Þ69#Ð {†àesÜ,šaºkEŸäå¹é-$Ž´í¦š)µd C‘"üë‹ïÆzÆúzv;"gÆâuFU/µë#Ô¤¬X~þÈKsf?ËïïJÚçâLÒ,ì’ʰ­}ÛyVO’òs‘ŠPXº©ä&‹Ã +º t÷Ë:êY\GmÛt[mM´m¥$6n´F¥B9jPÄPQ¡M¢v‹E™eƒÔ_f?W­ýõ@÷ýè«ùñ™;ÇJ‘„õ¡Mr«ÏwB§=ǺA.ÛDÿÝó/“©8î«gu§‚µEÔ ˆ,© !ãÊ$10ERèkDz<ÓâkÁ(͘3þ¥¶aGzÜöERCq%kч4ê‹M±-"‘DéH«[¶µ;öÇX݄핎…È^£ñde:Þ+‡³¹ÂÈB¯áÛÙq…›1dñš>Ñ×ÝÀ G¾môÕ^5ÕÑDU=ÌØÏ&òí~s9%3Ùk/†=pÜ×·Ao']µZª ¨Tà õ ¢è”ZÉlDe´í¶*#€RIh`§¯ò„F#úšZ:móq2‡¨€?Nž+!£<¤!ÀPžMf>¿î>õ×o9ÖûÉç£ÛlÙTò!3ú¼ü\îW–~¨¿¾üí´¹éü~›ÒòUBÂ÷òÎÞ4É/Î÷Ó±‹žÔÒîý6|x>Ó»þÓ³Ù÷ô‡?Øý‡¯ûûI@[c²É6[‹5Tî*[É »à¶¡Oä®á‹Þu«›¤É´l‹<Ú]šM9ÒþÓoý˜y‡ÝÍÏw~ì§×u÷½úÛÿöŸ©I…íÑ´žAÝVñÀµP¦ÆD–c+B¡’$ (RmŸHB&ìT3l®Q=¡)i(²©Š%Ô@+«²HAHã¶ÇMé‚= §UG.¶¨"N“…c—‚ÚªÂõè%I¼(XFÄ)RäÍZ~iÑ^ÆIªeI%®R¤âw4 KŒÎ©ŠÐ&IbA±Œ4 ²¹·iý’  HjmF\a«vßíP ±Îy=ï>¹ß^ñ¼÷ŸúÚ’Jˆ½w~¼÷ÝŽ8äÃú§¿H(å¹iø=åß¿ŸgÑÝsÎZI?/?žýÃä?ü6ïíÏ{?Sšæ¥GJz~¯¯ô¿ýàæâ?]ÿÃ×>+Ò¢—1hØøfúº)dai[UI6^@ëú¶ï妩aÓ$6k d²ß|ÿòèÒÏ÷û5/›[ÿ ÷Ù÷nnõ¯ÿÛ.’-$*¨êŒa‘–ÚÖ…£"ÉnZkœHX’QYÒ(À€–­eŠ@d–Ð!#äªHj++íX-ÈE*¢I¨¯h%…HU: ãB%CŠÔñ‚P4ƒÈÈЃ¤’ñhZóÒ´{<ôf^YM=rÒI{æÌ‹Þ´^í«:¿ZߦG}ÂWµÄ8É•šA¥ßGG½Ò‹Â˜ÒßLÐ;÷Ã’´é†ÛVzï}²m4 ÎŒª¥¢Ï³A?ïù¼¹»È›Y*èk÷k-2â›ùß|Ï_|ŒÌ³üüº¿Þwú£ýãÛÝÒšµê÷ç|{íD¥'ù™nçùîÞÜ}uF÷¯^=dÄ[ç2»úZ>—¦cµà€Ó5Ït¶Þôݦ}Ò VÛ‚¶”fké½Y)z.»ÁæîUݨëö›õëGÉóµW=/Ým>ožËMžL‚þ‡ÿî?S‘ZH,!¹H¬ä¸#S¦E­­e *@dIЮTK±Á'[YÛmF2 Œe×ëEyùÃôض •ª•]Z\Õ¡ÝŽq%Ijz¬š< Èi³® ¶Ž8ƒ˜Íývôí5»ñ1gÛì ~ùðùéµ_··ÚÆCŠNRuä6¯c¼ª¨5/aËíY}wÏÑ—ûûª¤|Õ/‘p[àˆ2’è½ý0Ïê÷­Ã·#¾Þt+ôqxÖ_åËÏW’È•œDâu^iÞÛŸÏýzr;Hû´¢ˆîŒ»yi~f7d3Ö_ç/&Lºú±þã›??ýº¼;·¨Þ>EW{Zió:ún}“ß½ŸË½º{ÇM–äÙFÈoñ~{i%)¹Å¸×eqÑWš²5ÒMÊ ß¸´IÂ…@ÓÈmT'O0­h)­ï=äÛ¹É~U¹ùuæë¾{÷Ù,ÀÉVÿÃ÷Ïc²NÜ©…ëN#A§C‹RKÓƒ·cL%U–¢ŒÔCkD,d.’¡ƒ¥”‘c¡Ú ?P¡;täD!^¢Ö«.«iª5R$•ž"Sò²¿ó’¾Ò»ùþðí FÐ=åèÜî˜A‘òZý“烯å½Yñ^Î4W¶FucÄ_}«VŸ·Tß_¼D­ª×`ñ„ŸíS!©|›~µ‰I&úuúñ¡ïîXL?W_·ŸŸúþ½A¡?>ÕÂÒ‡G„]ïÍ9³Ù®#^G#íæÇòõÎ]*Æj¸fZiNcú§Ÿ÷ mížoŠÕ\~ß¼ãŸûúŒÏMªª)%Â.©Êç/£táw$ôÕÞ'_h³–mo…îNÕ€ÊØ«NH›ä’[ à¤øÐnÞÝ*;‹JÓ-ÃæZÊ6Ô¢@²ÝUV}s÷zîfïô¾¼É’.Õÿå_ý KíŽÆM4n¯T:ãfl§H 1T8cµµ\$(­fêΪ’¢Úm[ ÉÆb+iD ¦h%I²ô’–Bj‹Š5º>TC«×uÕÎ˦Ç÷»Î™ývðL2$çD†cmîË‚n‹>7ö¼ùÃK±TÞ&Ê®l¦²(Mt·é9êaßQüýC/Wm¥T_ÉWôÒoæ/ü"›]?Û—õëw91¼F¡Ïòûê¾¥W{úÇŸÝøœÚüx7m)ÙÛÖr-Yjó–îÕg±^í‘¥Ìx7ÝæÇr·)ï͘6Ó„“Bûû£ßo“h¨¢Ÿ¹FÂòf ’ºmST%BíÖ¾ËÅ›ˆŽ¼m‘T"4²½H7RšÚ¶H* xvßÛD´­\Ú­vCÝ€¤öÞÞ}Z=»›>Ô&w º©$ý_ÿöŸ—Xcì6Ž1Š™®ëºT W„X‡ „a` 6X­ ŒeUi5’‚î¨Õ˜J–€ãì«}„Z4’pÓ•5èÀ„lY½á4rÎŒÚƇvØÄ÷1+Ž|}¦ZJ‹<ìM¥± EãîrªJ»Ê0n#¦,µÙÈÒK¼”ŒU~uöáÞ~-ŸÑ‚ៈ¯iÃç CØÛŽþp8Þ-[ý¶ü¼šéÀï_ûs’+ ên›h4 êÞ½mã§”/*z›D§¾Ü#×ÊêÇænš„¶¶Hv9Oýuï³T¹´Ka{Y²®Z¼á´¨»H¤A!®1Åt¡F²Â[R™*Ê (I“¤Ùì†Ïê¦wF^Å·O“¨„ºÅ}>pÚ¯Ê{ŸÃmÇVs·“ÝMjõoþöŸ#KG¦„ؤrÓ©bPUp衚¤cˆ$V–©*Iãª(cÆH°FMm! ‚H EØõè£rÑEF‚r¶5 {5‡<¼à¸ùBõ¸Ògù\Ž9âÛH‡ça¹ .jQÉäÏ·3ìz{Ó©â¨#kon6רd»!M»ÛãyY.Ðwë³yjõv>Fö½»ï ü|ú§÷‚žô¦Ï²(äùÊ-_©êÛ\:êè•ö½›*mm“‘Q?ì£J}?}BµhºkŒö¥zzªw,t7?Ÿ|îÞ›Ë<ÙÖI.P²I% Ú’^ÙÊ=Ðøšûäv[µ+ íR4ûÜç> ýÛ¿ûqB  ²¤i‹VU•ƪ$Ì¥B#Š£V²‘Ѹ”"©¶F2qm·$¹‹+ᜈQ!aFArÑÈ-øeK±ÉÆ6Ò ©Så~íKBÊ2£Z‚£ŠŽGÍÇ©uÞͳ1~¹ð|œ±MV¢`™ZîMoFê1¼ e•ÔGª6×3ŒhdUÆÕŒHd*ˆÚ"@žñËØTq[¤M+u%÷Y0RµÂ½«¤HBçU[m²LÏËI~[ ïË q´Â~y‹ Ý9ª‡µª¶€‘èöê¡·êÃÀ­¢á¹©ìÓxµ†ÚJJšm›VÛšIœÙrúÜþûÏÅÒ–ì³÷}Ñÿô·- ¤¥c«"Ö•=`ˆÀPSoa¤ T¶„e!«­¤ •+¯<Ê„Zm#Ϥ51ƒ!ä®ë,9ÚlèÀK}I•,PÝ.8sL_ΆÍìÚÚcÙ=£¡àVÕJvý´ ëôÑJ\$øöbOS‘Z CP…¥ ®áBaF`Ké71R+‘9Ú Qõkñò:z/·©ŒÛÐ*m¨«3 ù~ô‚_¾Ñ%ð”À~¾©9pÄ>œéW$ñ!HqŸ|­T=¡S#‡¥A1½ÍÕ;ÝòÞ}ôy»¡åi$>ŸýyïvÞOoÏoû“´œ™yÍÔÝõÓ~ŒÇc®Å/³ß4¨ï«ÛÏ/®8“ ûÜ‹JŸåÇÃo_þ‘û¹t[T´´©D:–¥$nŸ»5KL»YþòuÿÃyþüõõ÷o¾÷ëëS žç‘þ§¿ýI’Z¶Q„„¥¸Ø¨Ž ŠQS0#Rzd #§’€`„ÀhëÈ¥5á…J]„å$ §/±‡ò²¡¢RÍ J„l$ÉöiÍZ‘ŽÄ¨GzÜi]cë(ƒ%ù(ËÇiÚqT‹‚Wi1#yéÝX}y=ØKßG £tK–Û”*• M)H"7X‚¼j‹–38¬Z,óNÒmía+ªR)ÉT­*ÊŽÍKü¢þÕ‡>¦”›R%ú}{‘N¿UGÝ«¯Ëçm¤#©VúµXlòsaX´ÏõòãÇûç²å¹yP›¯§¿Ý~=yî~¾÷Gœ(Ú3ó‡ï{f ἤq¿Ÿs´n23iþü•ß¾6öÇ Ü»ùzönçõñ¬žèóÉõ»Ü6¥«(wË‘ûÈ´@ËÝ÷³Ð|›y}ÈËçóü“ï÷—ýúÇ?þãg~>}W$’îJÿö_ýsIµ±­ÖP½` ÈV…¨Ñ˜`U’‹PÄ ¤š–¡’PWò´)Œo{ÚZ¡#u, \À%5Ô:…±Xs 8ƒm™V’4R»#™HcáÃŽ×A’)Ò!²>F#Ùúvtog¼DϹmV(e/HúæD¸FñÈ#Yú†^êÇhá)˜Ü®…y•o/Žú®61y_!$"ÜŽ±4á¶ÅØlÚ¦HU€Tp„Tgùuªêe$>V?nÅð‚Bá}Ùð»mdÀÕÕ» 7 ÜÛmZ¢ŸÏc&›_÷Y=í{¿®Ò|=úÜ|ݾ7ï§ïd9›û¼|挪ñ‡|‚oΫ¼&–%Á}i ¿?ýóç>Ï• ¹WOøÚÕsã»ýªSÛúzn£L¶¼ mJ$`÷‘&I¶7À=Bû<ÕM~õæ>yö·w¾¶OEP½FÿÓ¿úg’4Ë"‹äNU3QgèY*!# * p $j$¡¶R[KÕ6ÒmãŽÝ-’@w-uäJ’¤A°c¬žº–ŠUQ¡ÓvFT¨y µþvrd[5ßà˜c›Gšˆ$¶Êi)‹¥'D`ZP+1VÈØÈÑÇôõ"¨Áåy‘ò-Œjý, …( S8uCXy¹OÑ­F5÷"I´%º+™#@†>è ÅtʱÎpiUŽÕòD-Kß—VFg"4Ú—lÇh@gâïçOŸ÷óýlólŸÒ8°x+![«Š[_é½¹ÙÛþ2|ÌÇïÏÓté&Ù¢Qûlr¿ÞÏÞg·­8dìá¡þÊÞM¶»^пû»26­e¨ÕIË´ÌXU‘Ôöh¤-E`¶$ *@BŒ€RdŒ[äP0®‚Ù=Nè±Aj„lŒáhl$µªªCŒf,‹]¹‚±¾>Žúª´=òP” 8#aTЂ„ŽcIÀ­‘E–еÂGCP¸‡DG=&Ë-Uo)D´²˜rŒÊDE„óŽZ05 .)¡­  [I1n§z /1*¨"ËkpÑô®ž%ª ðT…–wIPRîæ¡ïþþÞçr·Ÿê?g~åÙ¾ñ³}§»$4~È“´«:ca§¯×Ks E„ùH/±dŸ¯Ÿïû§Ïûönïö‰ïèÙÚþ0ñíÔ¹Ïó:óÛÝß?uÓgùåuÿÉ/ßîò?÷ós{æ5ÙKáýõõ~oÓMí2÷ˆ&j³O¸þoû7E㚊‘$Qz„*l·H•,ÀØIl·•Dµ1Æ-´ŒUjÜÖV‘@"íñPPÅ´Bu¬ +F ¸É’$j`YR•éÔ#F»ÆÀìË6ù>¬Q}˜ê ]…•4zéDT#P‡C –#Žhª#ÚJ·íEø¸f¥m¡gøj÷ME Âèo)çÈÊ«ª•B°¸Ñ—HCŸ¥jJQ‚„ZÌÀ’Ä¡ß_:á)¨‰Zf ¬Ô¶!Qݯ‡Ó]½# ´é“}??öóÑÏÛwòD7ÜðuuËínõT)‰Z¾ÒEtûdÕöLÀƒ×b¸»ª„jz\-ï}~|=¿ÿÌSöÞ¯÷~-©[R¢|WÆiîJ7úyý†Í¼¼¿ ï'_·_ObŸ™óÒsWro~~=JC RÑ£ªb܃mÔ[ý›¿ýk1Ö¦:Z,«SUÙ¢-²-¡" ÜFR©TEP‹À$ªÀ XªÔjgšHS!U8â£H#I$¤Æ’$[Û¦Àˆ‘­j!ð`2¶Û—9â›ëã#Ô©*°G^ ER\ÍR8f,¦nGR*K¢°•ÕCETêïÓ# ·½Ñ]$´Œ+”ËÒS0@Š´G,jgh(z½JtÝFï n+WÒ¦V+t@eÔT)R_æµZšè¸7¤¢YÉÓ¾+W-Kï%â® «ß~¿üñ¾óúãçóõ¥¯<3ЧٚêëÞµ@Ym'´¤Yæåa_0-õm›km6ɼŸ÷óäsûõõ<7?ïÍrëÍ}6íÒöÝèòÞÙF®:Û´”¾7îœáÍŽéÝ(l·B­H}€Ù+©¤¸©þÇõ7V±(fBcBÇRÁ:R `K€$TB –\ ª µÀ –$%’¡•Œé{PF*’]‰TŒhk»*È<^$äHV_Ô2­ƒ$‡AÎhˆ<‡÷›ÑèC9’xM£J’ÔFLG̰ës*1AÙRaÕæF ´Œ±qy¦Y4üzú,w5†ö±î®ë×TP„ð!›ç­3œ£Ï'[½Ü?ÙzZÄ]ÁÛðpЇo.âÆM[>¿%—õë²å%40¤zÒ'Üôëíô¾ï×fÈ{ûÇùí­?•÷»?Þ7-Ò–÷*á½O=¯A²ìM@/3Y¤•ÉÇ|¤÷fj“Kò<·=W¹ïû¹½·_Ïóóý<_yÒtŸÛ%»†<]Vébe jµ-,U­‡JÔ£fZl •cCG…J6©¢¨¤ÂÖr ”‚ŽM‚T€#¶!eÍ€†e *$‰‚ ªJU|K–¡²J‹±ãp¤Š @ĵd³g$ëEGîÔ¡4òÐ#Wâ%$Ž@Ȩª¢l©ªÊ¶ª°÷Ñ‚¤(}$Ûg,w;˜j ˆbÀ‚P°Z$J5£CÀV<2ä š’°ÛT3Ñè†RK6„×a$U»<ŸË{é÷6«‘ž÷ûóóþñÇ~¾ýïýñDáë¹_í­ÉÜî}îçCð†¨OÂö"¹ãëÛë…4¯£®dKЗØ<ßœÿàÛ|½û‰>owŸ¿øåÕ›¿ÿíëÏ_÷._÷;ÏÞ÷Wž­º„%ŠÚ½V´Ù´—m´s³• Òê¶X¾-¥£ìJž´"EF ¼–§•þÍßýÍ`¨D%Cm µ#Cq…¥š n;€ARð‚d“P@’ ©°¤¥ IP)˪̵°ÝâaÔÖíµmÀÄUcÎ6’F˜.K±1¢sTO.GéX z,»‘°œVºhlÓôeIq{fÔfª¸ìK–´A²h…êojú~¸IÊÁá¡Z3ê¸#©€I våÁ`Ñ@-ÍbÕfFßÄ9Í[¨·ZTçY}åê×[”o¯~ŒnÉòšæÑ__ýýýü~•£äîþøÚ—çsóÇŸûç÷þØÙå¹ÙÝgóu³›Ý`ñnŸ'OºOuλ7 ¥z—g><®|èŠÊs ûþC®_þª~~õ¶îs·ŸW?¿²›w¼Í&{7QrQîÚb÷V¯ºº-û ͶŽ"nC+Ns+¥…Q‡"P¨h àæaÔâJÿöïþzªªdC1C-¡ªEcKEÊÒ#SÀ’!—ªBIHjd«ÅTX(U¤RØ‚B¡Ho±¡ˆ)BÀN – kdiYa1–¬@eêH*긇‘1 š£M¥ IˆHýMV,5 P›ªÃ5cqÆ%ïG?öV&¾S¿ÔïG–¤„z¬Šæi«±,¡Ž$(Õj†o®KV/ÉôyXÕG†\îåÒc"‰:||Ï}Ã7?ßü~ûû?~þè?üñçåüòý[ìß~~5ѼžÎÏíÓÙÛ¯»w·e/Ïj³©¢ûDÏæÞ‡Láé-CÓhé9¯c:c(iµŽŸm÷>Í®Ÿ»°»­ü~úÞ‡îmÓwVíMh7ˆä‚ÏòžèFÈ7wä›X›h«$íES¡õ“YWrnûšszyŽœŠ^ýÛ¿ûOGikÚvdI–^¨¡–…KÅ€„Õ‘h¥¡#uad©EP *µR´¢# ÙI1PP™àÓAGdA;&qËÐwØeÁ¢!`ú’ *ÃÀ;¤üöÕ¼ÿøçÏÿ#?¾žDnÁçîV¯mîÍ–¬ž$ÐpS4YRÞ½ÏÝÐݦ~öI†¤i-ɯ3Ûlß{ÛÊrå3ÇRû¾ûܦ)õ¢/w‹)ݽM6‚½›ºûŽô,›çx’‘ni£Ò- Ý+)¥’C‹Ç÷îËÊ„ HŠ’VUýÛ¿ýgž%•°ÝÖÒàR[Æ€T¬¦Â²ÚZ4È0£$2ÔÒH»T²å¶*v ª<‡½šŽ$̘®dK¨¯0¦¢ÅH£¤¡’TAZ·à´¦m-µ21ˆÊ*´hÆj=8É„ª1:c¬zŽÚŽP±E«ÎKµÓ›aÒ }ZI” 4Jm5U‰(M[„<>㼪 «¦nGØn·Ú×ël2²miÝ÷ÊHõ ÷ãtì&ûèœ~.?Þy‡ÑÕ`éãp—½œa¦Z]u˯zþø{¿Ô¯¯çó™¯Í÷St£Šûh“{oÿNÒ¨hzUtE›íÞ§ÏjûnÙ(´MQÒ±+c!v·7ÐD—×óÑ5¹Ïî²–—lšÜVj/ÈônvŠnî^æ6*VíׯiAwW¢¡’Ø[‰R¡PÑJӮѪ®P.5Ú¢û·ÃäÔˆ6’l*FR-[.‹‚Z ©5R@j„E ¨˜`G ŠXû¨‘ Xª235©´hÔ µjku‹¢ÈÒ¶’jÛ6@©ì¡°HhŒG Œ• m+°õ²¬BÏøeI±4 D£—jô´ÐH m‚Õm½í6GjUjÙ¬5…cŠ^Ò‘Úµ5ª â(¶©¤ú—ïÇ£¾Ó½EJzˆ´çÀ/“Aìõúþ¸þýúË/çû÷Ñ9¼†½¼/U@ªÎ‹ñþéç?üñùã義5?ž<7_Ožênv{oïÞûdÓ ±¥Ùâчôó}k‚ÊM&õVÉ-SŠ›TÒ¦HïÆž&7›»ï›°ã£’tYŠm:!…ç.í–æÙ#ÜÛuúÜ'Ý6Mëî{4ï*´)¢m v‹UJ¨ªhÍQ³Á.u]µÛôïþõ_KR[!iB `Ù`b\!Ë€0CW2E…RyP„`j”¢H‚}ƒŠÊ@X®kd*™ä5ºeÔÖ¨B…Qî ¹J*ITW=Ì%€ëÛÙ] 4HîzŽ$5-BrŽ4Xª”‘^#Ó‘D ’º^šôn+7+M¶…UfÁ»›…ÅÝkqÆE¢¯ñ$²F!WmÈÒmOŸ_?Îiž¨’˜S÷*·Z½à9½·ÑSýù½ÝúË÷óñaAÙU…]•ש¥ÏûùÉŸ~ÿúÚ>ÏþH¿–T©ž›Ÿï½·÷~Ý˳ûÜM§aË)‰Ò¼)í¢±î* ¤‘Ä̤òÌkxß•mø~ôá¾ßû÷?>¿Þ„¾÷R!¬#M{‘%ßû¾‰š=KöðÝ'-í½“ì³)ÂJºY[É"ãf‹")MUÇjHå%sˤÿûÿ×B¥#oû‚HÀ‘$TÆ¥.ñ)éø°-¶-¥¤­}Ðm^ãÒ¨nå ¯RQ ‰Š£‚m¹ÕhŠ¥V–ÔTš©Bv²R`ž˸I‰4mUj•Wt9„Ö>â}TkË6àbÉH½ÛgPÃðbŽîÑKؽPã-—’Þ°HR“­Šnö¨½P!ÙéHâIŒ5ÕXÑ]õ¡TƒNóÑî–õ4ºû5Ù_¾}ÌÇKDJ/Uóä¢Ï»®Õéõ¡×KXn4‡ß3ü|÷sߟÙg¿ò|îüÃûãfãgyߪMxï}?Ï^îæ¹üÜä6uºO ªØm•MeÙ¸{‘ÆãÑ÷_¿}}}%ùxù?øþ¡ûþ>þìüÿ~>×ï{YÒûl5‡DPõiI²é7—–¶ÝÛ$b[¦KÚËnŠhRTUO: ”RIÍ•¼­D+5X­¡eUéßýÝ_X:²DÃXB¦2ìÈ1ÈÅ«Z‚VçìæØRA@3h[AlQIR+FÄLÉ(–j•¾,3ãU™‘aHÆP€R¯ØdPÛ ÅJ¥¦m%¨ E¶¬nI‘f^éµ8blÔèÐHB{Ô3'ÚƒŽõ"ÇÇ–E!hÛÒ]¥Æ;(ðÜ.¡M¥J¨¢¤ƒ`pɱ¤ž9#hp‘®šöÕ×Q†uÉm}EÒ¾G¶õz½,@ôöniïÖæ5Ñ SÔ®^ó ôû<¹O’üøz~{øÇww•ÎûynùzB©ìÁ¯/ŸÃ?üéý÷¿¿ßï|Þ¶yJÚÒî®Ü–ñÙ»ÑISƒÎ9îFDz^žo'øþý>óûWŸ@Õî6ªS‘Ý‚KH ì6´» ÐЛ5öNÓ‡nŸô´Ý¦­hÛa#ÃL‰Øl TP¡jéŽç¦ÐÛþÝ¿þkµ²)¨ŽÆ2’Bk$Eªd°8RËZn+OS„0]ÙÁN2©’ #ƦÈÕê„UÃËn…1 µ¦ ™t ´rRÓX§Fª°ieÈQ©l§+éH#Ž­rÎ{4·É¶ÔÒ€GÖµÆp̈×H`HQ)jû¾ÍJ‡I ïì³-î²0’é; U™FŒºsì±ÐËiÍÀ’ZgùÆàB‹èõŠR T};ê/>úëwý\¾n¾%‡·Ïé±zûuùõ¥on!Ò·~vóüöüxïçûýoÿøzЫäýäó}¾ï nö`ú¼ð…Ëóõ|íÙÍÏÈʳw« P)I9@CUDsëC@‘¦~^3}xãTô^hâ*rº»”P)YÙ÷n‚Æ·V¾¦~W&Ojí®Ú.m£˜Vm=7õpwíÓMAP@W›ÈÇ‹þçý7R)R ãN]ÀS3âÊ¢ÉRU* š"I¦´’ ÔµíÛJ¸ZlÀnÏÈ’¥±äZ{¬v?DÕH’4ª»…6 º¼šµ,Š ‚Z:²UÑQh¥Aø[;Ï9g&êÜÍM¬1='–Zgt¤j¥SUŽ–Œ¹Ùmé°ûµ»«U¾ž¶.zß[É"-x„«ZG‚}É6vű×ÄÐáepj_£ãJ:fËçW¿¿4å•þÕw}¾ûóê+üúÑïȇ1~ú|IíûêÐÏ«|?þxÿ—?¾ßiçõRïö—oþúz~ûÜÿççdz‰~¾woCZnÛôF‰¾v#žn3·ºålZ5´ë9mT©‚ª›[·UzFzh÷3uÑÔ—¨*Ù¶©ÕÛ**ï.šfÛJÓRª8´óhÑ;}]Ó]¦)(År0}¤¹÷ÎLý?ÿû¿‘ -k<³vlƒEF•¶T !TdÓ¶$5†vf ƒ€ ÉjGµt¦¯aìCgì"‘%dUbAQ¨P¥†È¤bÈ5Ùr­Ò3—Ö!™½&c1êvÛ¿ú8s¼å†Ý½»B3ÀŒ:c H B$¹}¿ÓÒ諹OÞÎrµ¥²‘ EÖw…lK+óÂc£žÑë àUšÛoâ ß^LùË}|ø·›÷›J8¢Û??Òú‡“ƒùÞ]tøígùçÃ/eùÿþÖ¯ýãoÏ:ø×þ…õ§_ïw®îßÿ¶ÿëïûÜÞËW²KrwOÊMÛÞütÓ^²QZº©6…Õj#9¥éÏ6꨻Io‚P;ÝÐT’ÀMeH¦)'ÄÔ¥lã$!‰›¢UšJU»,kÜv%W!’¶n£ÓîA«‚ôÿúïÿQÉ€$)GC/EgL’E>RšBÆlK,ƒZ†Å ã`©F’i©5)G¸¶ebéå;ž#lu¨=ÐJ#Œ ñºJH‹(ˆ©ÑöR5bD$!-[‰×´ŒÂ™¢3øŒ¶«²áœ~6¨–Òó*I¡t¯lŸ:*“j»ƒŸ›ï|îÞU UÈRU©ŽQ­Ö’µö B¡öGÑtÄëå„°õú¨} '¿¼øešêçÖþ(? áŸþ¢,Ÿï>ËÿòCóªŠÅ¾é/^å®%½Œa•-ZÉú0ßà˜n‘t´wõ\>“esÕù\>;?Ÿ}’Ö¢#ݤ”ΰç¼Ì‚^ ¶-3FÖ4Í=缎^õiˆ~1\þâƒo’_ýùÖ³=æû‹ŽžÛÿð;1úíÍŸþø…Äûé;â0{?ßûõ9ß¾y^<ýúùõçŸ?ÿý?>ú©¯ ‘ÍMÞO¿¶¢Ïjw·zG*ɽ˜¦eã$ mßUô¬Ø°Å"%YªÛb5-¶àJ[–¶vmr“ƒ•µ¢XÒTd‘â¶k),›ÔVoªUÏ•¬î>•·{8Û¨±&pcô§.·dšàGrWÿý‹Ž-A{lI6¯T°|>TQI©¬Þ‚²UUÔµI”b ”¶Ò(ƒœ`I¼lÊÕ’ékjäs,Ü´B%‰"¹°Í¦êTÞ–¦¨”Té¥J ]|èKû«õíÅët!Š&[#ÙªÅKö–À´RiÃnîÃ9GG‹ŸÏûãáç»oÍnD¦´Y¨=î‘ ‰ñ|¼ÔnBŸý|2Úã«èìþüùc_úöí;Úw#ÓDõIoîǯç—ÿÝ_Îÿþ?òwÉÉÿçßó7?žùþ!»Rç#_ÏH÷çs¿‰~òçw~þÌo?ïssëlo»ñÝÛ½Ë\žÖï‹à²I…²Óv­,¥w){ ¯}#—&±&åæR$µ,¢ÒV<ÁXAJÖµnãji 5´ÄuÝl ·H¸<qÊÂ&%ǺY¡[½Úˆ›Ýr<›J½tñ({<Û¼p›7±Lªÿù_ÿ'&c[#«ÒHÆu£W:ƒ¤A-’½»H‰Ó„n…ã%B¥Hª$¨¤*¯z(ÖˆcKµ9Æåeiú­xÎ˲¯ÐÅIÿÿá[Ï­ižååýƸŸ9ßµ"2³ªq·à«–Ú;#ýe(ªºN‘,a5m,˶؈sŸù 7†ìêÜDFÄÚ¼›9ŸçþáëJS˜0í²w6ÏŒp ]MÔ&‚ܨ„¥«]R³ÝÜÄ¡ù|äæãv‹kO¢¥öX‡´ï·Õ6áÚÛkÙKf¥¶ÜîKvŽO7Ú\ëûÇõýÒ9C}¸ÖB)Êݾ/ÝoÇãñ(ºßŽ=×I÷ÙÇ9»}>š¾ »{µ³×íðê5ÝW\h PY//ýá·úáßøñåŸüN?}?}^Ï)¬cÙz?÷ÇsŽ›~÷ù‡…÷Ì®_Ïy^yû˜Ç>'g4{vȨMfv}1SíØ3ÓQï¡„*WÜnPÒ!BOv+PBÑuƒÓBŠv!)n[H jÛ¹¡HK«@•&F(ìVj¥µ5LW½aEj¢ÒR‡Q—›“ 5­&h¥Ðˆ©¤·+ìUFZ­èî¡ÿâ?û?ÞÔÖv„Lm‰.Ût-Ø:°‰4–@­«UÒÜ¢L›4š6‡Ö4ª"\Qâ1Òò*K_‹Ü|H½Q¤›}(Ë,ùð¾Û–ЦÚ4iÓúhh;T4“4íQ5t&RIE@…šwÄeû‡åÏK¶ˆ¦ÝÎÞ WTjBgyw+틱ûì$Çîºrܲïwï}¾}œ³ùÍÍŸÓÉÌûôy^Ëzœç5´­âØhZ Ÿ¤C}ÒM¼li¢l-á„ÀÚŸ?¾w-_O:rU:ð6œiÙ·T¸Ý/ëåQÂúx\×îsrŽ®™6j’°Ó3IÙ✺\Ì‚yÄÓ9mR:[Zš&bÆp© º€4 (x¦¥…F¥)¢íªB4 ¡È@Zh‚€…`·€‚ CÊ(U×öV«™s­z7Âe3Ïî…mž‹Á@T3­iŠ'£ÿÓö8H䥬%Õ‚e–•±Xµ¥›@[²äÒ r+¤Ý^3Ú*]]%T"±WÛeŽÊÊa°—8”e[˜š»¼ÌQË·£5íjÛòœO ÝÜ4»ÒL°®´éæ‚V¶ªdÒö°%ieYDÒVýL{»Vˆì»ôq]¥•%-ɾ-§²ºlÚO·Åç™÷÷çíX7÷›;ÏŸ¾¾þá×Çóä…ÞפR{ÉÁÌ.Çt‹£î­Z­²¬}´7e-_Mi´VK´P\¯”!~8|;–<[<Ù·h±OódM[Ú–6.»ìŠé4çÅžÉN3‘<{®iYW’ä´g“(õÊL¯¡ååš €5Ù ´[ ¤T˜Œ¦´¡k+Ý#5]«l¨*T¢zŠI¥v,u#GN‹f¥¤¥Ð)’DGè:•CG’2®S´È0^ÓYÙaE³Ðô¢·aäE¢ÿóßþ§Z’-’eUº¨% Ù]qGTƒD ít2U’ Beh:’ÔÊ$ºÐ%±Ð‚eËw¥Eס›ro­UõF殺¬U*;Ò•\£Iv™fšVpIm3 …®®j .Ÿ_ŽoÓƒLiu {_¿ñüöÓË¡¹Ý-lŠ×¾ÎÇT¹®óšÛòsïZ÷Ûº®Ç ßn¼üð#^+úöúZúã·/ßžþ:¯ïÛ•hU’@„U²BE£¾Ô÷êнÁa£-j«v8J;³„[XòÑ~:t[âè)>º›:’]×0éÐÒNK4ëŠ3#rí9Ñ5I}¦IIvuí Þ©ª«3t§Ag®°eM[Q´»-´Ùe%átN"¯ö¢*Ñ(GÚ †H%ˆ«Ú´Uä¥ÝM+V`­£MpS’ª(TIZµØiV´SQJeÒ v7«Ùc‘R­X+£ÿòïþÓe‹X2’jd@Ü@EVT#‹ªª¥%@»ˆHMµ¶ƒR«´ITxEY(’–XÅFíÝüp`{¡¥¹-ßÈZöER/é…ºP¥µÖ™>§×hÒâ”¶l,H)MÁø¶äö>1?Þ›L›Ç™½GZâxœ3Ow>¯¥ävó/·iÞÏ9Žã½?®µæ¹u]ÝsMD9îüîè§ûZ^Y¯Ï39߯uÆG–Û…£i!¡VU%5¶_êC¬n) ˳$Iôºsc#á°Ý§éÓòR£u_ŠçÝ:›=#îm‰&MÙ‰Ú¦×fª µI®ÌS=’&Í5eíö „=uBÊ4*“iZ;©X™I­4ª˜Ži©“¶›MC¡Ñ7 ‘$¤&xRÊB£4k­Ý¬·êÑ´…¶”­zS ¦R;A´¡‹Œ•a1éQz4CTPŸ.ã%ë_üÝ"K¶ÑêHܰ(`WZ„@RE¥v P9[ZN§âª@‹2S¹ŠûNk÷†íö]óƒcé0/G]k>¯£p4^Ù—E´t “¹Û>ŽGõqåìšiª=l‚& P ‹ÞŽuSfñT“é÷çÌDÐæÚy?3Ó¶²É,Ï'ËÇÑÎaŸ#[¡Ç<'Œ+ÜÞnYPuÙ»³”É’o°hM…Z–jÉáI½;b¡ͱ$ÏòB×1vW:J"Ÿ«Ûë¶òcýɺ-á^Yّͩ]G’víΦ¤ÃÚ“©œL¸Ê ›^Ò¹÷¤)=¯!Ú4ò™¡s%¨;RiK5h’“ EÆ0UÐ"W ¦­»ÓVjOŒK”APS°né‰Öàƒë²\Ú˜u@k]¹\©-)iE@¸ºº‹T‹à™Q‘“.±}i–¤¤ÌHk÷leý‹¿ÿO rA ɽ{ÕU²,0BÂi„¬‰*Z¹$©ÆZ)bAJ"À&T@´šØm°Œ²¨Õû:>©Võfܹ™E>ÝO‹›+wZT˜TY’n÷SúþX{8»Ò¦‘™©ä¶€åvnÒ§Õ[{_98óËÇãÛû~<¯kúÜçÓ5m‘Äafy­ÕU(Mž£ÙhÕÕR SD§j¢d|SÍÈL-,“Ú®³âcz³Ö*ÄÒ>–—zó2¹áIÒPçRÔûòøÅÒM´íºÂÉ>™5î4iÜgÕÀÎ…®ÉîêL'XÉ®v¸2WšˆjÚ}Mž¡"í†ôJÍH"aº«5t¢”*j )JË-5aJIÛ´Q©[j©*cѶ]én#K “\‡—»#5’’ŒµÚL:ÕRwÚ–µê* &j!‘Û´KJê6«I¡E‹ôê,yŠé¿úgÿñ’…]ÂÍZ·K ¢º*-ÀÑÊ-PV((二$„‚ä¶ZHie•bÅæ¨fyÝ,)Ÿ¬›XÑ»{˜›½n‹"•%–‰™r¬sÈx‰JN·0¢TezQoK¶Ùsõ:ߟyÛz>ç×ëûggï·@—²¬š›r?n‡øíçÛÌœÃ㼨¦m{È¥S«-i6xi­v)(À²—Ðt­Õ©VUpWE´VÕµfIwëFa4ÍP²B¶û¢õÉ]‡9 hVGQNB‡ÔQ·vtifzÁ#ÙÕRš“Ý´ë9×H³!hÏ>Ó‰D/šáÔ´«4W—ÚBˆH™Æ´i`cÅQÁÝ2”¡¢ 4­q•vˆe ¦¡ªÜ^òÚ›¥ÕHA“´;ÜìÌ…tÒ—Š.¸RÉ-{Λdê$iÌmº£9¸•)JÐõ÷ÿ±eE¶ì:9Œ°hE+“C$G¸š¶¸H”¶«AKÁ%jÕUa DÖ²©àfIÉ7õ@/·ÛÒ¬lÈÁ^ËE½iÙjG*2/®IdS!Ô#Õ9×’ÖZÅÒÔC•JÕ´{zTS®k^Ÿ×n¿¼ßŸÏ×÷EIÓF ­×Ml{½¸?Þôr[ñʤeFçœB–M #°V&TnW‹ÆË‹:‚ ÜÂr¾›å¾(ÇRénC›Ct›Õu_ZG¼à&X\0F©€$];M©÷°Ûsòœ^ÍÖñØCi&ñn¯ì5MÒ)W4É5½`ÏÐ&jx¬dM›t¤¤‹Fš´U‰ªIb‡¶* ‹^•fË&ÁTKS­1Gfh#õ€ÍQâ„å¤ Ø&3ÅÊUd.éfÙn²èUK´1j'9HâªÕîv= ‘H¢EBÿüïÿ÷T ÉÜ܈#@.`© "i6v1ŠKlÓÂÝ\’*I¸Š®Ãr±dõðº;V˺uËw¸ëæåyøÈÒòìÒÕø¶°PÑ­{âXB1ìRTà™m[–\°–Q 0pëŒJ»µwžy}¿^{­ª¯ÇÖ/o×ÛsO™ 3]ë¨PéÜ|s;Ö‡o·*Äþxî}×2*…E{_¨©TŒM‘è n²p[€:ÇaÀÖQÝÔÛâåܪS¥Ð8.,­µÂ-ÜÝ›„Ùæ¤­´HõLw];ô9ó¨R%MÒ¼Û3{h£®h&çÎÕì:Ifo ñd*ZF¢“i¡‘D 6ÝÑ‘R2].Mâ®6pTQãQU]’iA%²¨ B%qWˆeÚa@•Ô#ÙËM ¦ÛZMÀP §»Ýû 7zí(¬aÌ,ht¶7 þ÷ÿQ‹uƒØ¬j5ò¸·‚Ö&‡¬–ªljYjÚâ¥Æbð!ê¨KTËê,­ö0–^œ›WZÔº›ûáUžWÞªš½8²"ÚÃt4»·%›š¶W±A…éÌ¨Ú ‡YËa$tumYzöù8y½ÞÏKø“ =·¾Ÿ¹šÇÇÕ0’Û¢–’c-ªûÚ/^¶nÒîÌ(¤SIU—} n6}ÊH XÜ`ÕJe° ‡r€¥ƒ%ñ¢ú`-÷H%Ô™ª³z'©¬C}©îí]]â´¶Ú¢ÁÁbÓçh¬jv®Ý3yƒ+ dÚ²ãiw3Í =:Ó瞤WÙ{§DÛ­q±‡ñPÖî©Þ®œm[·]uš]UšÝl%\‡58™eK]˜2A ·D^7Ûëh9wɃ´ª˜t<«XÞ¥ UiÔLŽcYêœçv›³ìÌŒRÃ0©5WšeXÿâoÿCp…ukÆîªº¤N±,*) èZJ0ÊbI…— u¥6Hªåµ¨¨¡Æé8GëàÛKH¼tŽ¥e»û¶r³–dIª–#´©Ð"ƒ¥.ŠìâóyRÙ–½Ó‹!¬R¤àÕƒ"j»“©Ê¯Ïùõý|žÉõ´¼Ã昙”}ÎE…C“]I²ñÝÜ:ë@;’¤´«1R8Ä!YÅ›¸Û·è`A—r£––Ž¥õAtˆ›P¹Á*@Ä„]aìå3|7az¢ëÐSm¥«P¦§Û%Ôkºçž£«û$ÙkfŠˆªŽz†Ý<Ãu¥í9“x¨h8Ë>–i‚®s†v2ijÙ¢´ –)ËH.hV:-J§‘¼ˆäÅa÷¶²ŒŽÛÍ–g!Ñ=šœªŽå Fé&뙽,!«WØÓݱ´XFË”>ÙsiïîÎUÍÐ’™4qÕCX+ªôÏÿö?¤*•¼ì¶HhÅKšµLÝÚËMŠ-Œd)*„@íV56¢‡:Tc:–M_Öqh¬Ô¬¥ÕÞV!Á%W2É ¢E®œq¦33;Z«ª¥CdM2ky®]uE´÷3ýýy×$Fm‘Ww¦MfbÃk]«>èZkÁ¢«BÁØnÛ‰¬Iú"-ç„FYè&¯ÑrC¥CÉýÙ‡-ŠŒÕ%–tˆ#`†N˜X:Ä'øÑÜà—xš 6P©=£½ØœÃNÃì>Ûsf†´’ 7­º{wßüØ­˜ö¹çš97C$ËV¬¯qøxöê ex^ûÚL§ºPSl°ÐâëP«”óÌxöžv« 5ZÇÑ}~þ|‡oK‚cÙÄFõsös®Æ×È,Ašã®£¡$ U<÷\W…ûíæFî•ý|æŠv“ͤWšdÚC^Bkë¿ü›ÿ@H`U2•\æW,–ÔŽ±ìC„H^©² llaAªC7‚½(¨ G†E—{’$\,ݽm¤¶¼7‹@û¨*ê¶kùP@mÛæ¶¯™L Û‡‘-Ô;¢­Ÿ{ÚÜl]ÑΜç|ÿ¸Þž3™½”b9!M:ˆ"ZI]m­ûZ4‡8Ti–nÐVChoôÀK#÷v3èÝèÒRYôÛ¨x¨Y‹C=Ð!j¦M•B±ù¤~‚—›^šc¼ÕGôCABjg3·UÁUBÏÝs:MRiIº/‡÷Ȥ3Ó2èqõš}óºëvÔ%„®çÌÛs_ä¹çqéýÚ«Ø-¢/‹ÔÏ ­–?ßïZã¨êóÊu)°¯¹²g`!ùF–oR,îÖíî&]É¥Ý|\{Éæðbèmá6h_Ý3Ùœ;•}x-¹tϾ¢ c’&WÇ›Nºƒk¯¢.-ý_þæ?¤‚LåUõ$µ’B•P%U’Z„À °Më%$Rd‰æC—,ö±Š–Ž t[¢ct3 ,¿(«`­…š¸ÝnMM½¨$ƒÜU2+ EªP;µÕnvïDžŲúôùV÷|æûÇy^97Óf:%…vfátÔÁb/ë¹0/Ö±L•ŽmϾ­ãpì"^ÌMkÅPP…bÉPÖÀb¹B7÷ëPÝ”]Q÷³¹›—ƒOâöîžÕÐZ‡êhO¹ë7w­ôL¯­+}œ <Yõ¡E_®#&™Ý‹ÈMÖZÇ H ÝŒ®«Mú˜ëõc¾Ÿ=“°nZiw®Ï·#í¹ûœßo·®!Tt(nÓv§{v…9Ò³Ñ̼ëÇÉ„žÓ«ç9õ±–dèn~¸{ÑIŸç¾¶âÞ—®­)¤»'õá£:…vSP3ƒ*ï逦1.-úçóHB’$ÆåP‹TK•í‚–„…!ª8L)$°ŠÖj©tÈKU…—<.#«’K]àê¸K¥-,Iªe$ ´íãf…ØâpKkI rªbäB‰˜ÍfÌ~\©’Üǧå¥Ù¼¿]çÌÞ]É„LÚUÂN”ꨒô°K2ºy–¥ba@,Køpof©=|IE,£0b Sp=²±Xâf–º–X´\©Ä­¼,~8t¿÷åТûÉN˜ÅýàÅu4ðòY?¦}Nß/=.žçÉ¥NݶB°KûjD6ç&êŽ •š™ëÊU5óö1¯W»7¶‡k-È:wÞÏ©<í6Ç: L—\Weà¼ö~&l©Ïç^kÝoëî}»»<·÷žId'°Öó<ï‡^7y>û1•P÷MZi© /\$‚š§)3r‡==w A/·Õ¢ñ·ÿž*£/–I´PÞ–I¼MÅ QeUÕ r¡FÒªFø.¥©êªâ†ÝKZXR-¥ve+€ä,/ÀÉMN¯·‡FíòZ+‹Ã0DÌq¶ViºîòT–¨+  -¢‚‹=‡fœ°¤ÛÑóÚIFfï¤çÞÌQ&3CÁÓF¢-tiÝèZ5¶È=äu^ò*./‹eÉ=¤Ã¢ž[Üëj*Kn 7s[p§ÓH{£Å§ô~èóMŸ_z¿ÁÖÞÝìvé7·Þ-ƪ¡éŽŸÓGôÜú¸¸v“¾]ŠHh:QËr÷h†’Ýfw„UµZçÞg™ÙûõÑ·kgdY«·ã–ÆK‡ÖdÎ0ò“,Œ<çhÕ^’fvÂyíTiM÷ÛZìµdÛa·iVC»—tÍNÖNf2IÚ”PÁankµMeBI;çնAŸn™¢ÿëßü{ÐC•µe-y ’$aˆp`­1ÆSìÚÅ«S¡¢7-uÛKªðá-ãÞÊ–Œhk­%)¡êÒŒŒñÂáš™›|;Öͪ9¯Kè~øðZ·èfp]´l0,Õ­c¯T24ÍÒ”ÂN÷)„ àE 0æ<;CV3MgJGHÓªí·CEÊP¸>àåèË¡»úéàeõ~è~`I ‰e®K¯'ˆH(”ÞÐý†îPׅĽºß»Ü»µî%ì­B^ˆÙdtív“rnÞ7ÏÍZÝ£÷ÝŒÎðL¯è³ÉÅP¡Ú0t6ûP`/²÷9Ý“s´ÃãêsOë¥ÕÕeM§,I77ɞݬ:»­pKµÍM %!5D–K4ס4yURÐ5“vªF»#h=íìkOãM$¯mlSeGIwNÙŸû\ò5Ls`4“ê¿þÏÿ}ˆ„‰XrAªE–$MñÑ"$ K¢‚‘õ ]FR¼šzÁÙÜÐáb-V[-Ê×ê͸#yEY4bêæ mghwÁí}qM,íÄ^¨?¬ús—² Rk±VV‹ v‹’¶–ÒÒвÐ:j ºŒ eBÛÁi¯± ¤½{*‡©Ø£uôn‡n÷¾ˆO7}‚ÛMkUp¸­ ËEjÐQ†µ°‘HÈ] ,Aà÷º‰®‚Pû$—ÎÍþèl¥Lúؼ=Ku»÷ŒrñíÁ#½ÊfDØ…¥\MÙ4a_‰ÔÌ®ÎÎ9m™ uÂYPSѤ žÉRgÚf"IòB]šhÝåeÜžh¶ì˵۠¶W·êD[é xª+ÅÍæªD-µt ¥Ðvïì D¥ª¥æy^«!Ý[MMSµ›®4Ѧè¿þ›ßêBhK‘±,YI…T#t¨Hµn4ªI‚^k9±$‹¡«­ÌÍZÇ ã‘t_,û¦Z]µ–,AÖ²H±ÐBq%šR¦—©$®u=ŸÇáJÖ¤÷FJ3ëî/ÜM¦–wI‡‹¡"ÜR32HE"P!·B° ¥ J e/SF*WHYÃ:º–ïîwn˜»IxùT[×É s)î±pä—®;m…,´ªŠ%«T¸Üà.>—;>`ÃFÝÝ»û{¨D¸®¾m?¯<@x/£kú6JºªS$з¹fO4ét¦„^ÉD)ŸétÂjfЮK!3‰IÍTiµ´Š¦±‰“›²!>V›î½ƒreÂÎ0ì¤bÂtŸ'»,ޝÎLW‘“¶íxP²3’Kröš¶É0àVau[B© ú¿ýÍÿnù0EcÈˤ¹Žã®R E­½Zh-IT52B¹©HB–L^‚ä°uˆå9ÔÃu¹Y‚%­ãP •Ûö2`ФŠR¹ v´ÔP-7à¦]ÅJi™`q¨7d!wIm[ÝV×AG7±nd ¤¨,q,5…UùhK& I‚ì¶Ú €X‹¡––䣇¸­®$-d´¸-¦(œ'3TõH–n]ƆV‡% ~©7¬²àŸà¸Ã>Ä O*ö³y:»;çåÇtʆ3<7×É{Ú’ê„·êŽÚs¦éÚ2¹ZÀW¦ÑÝdtM«\Uƒ¥k‚œ¶P6qÒM“–•²Û²•„ÍŽ—%€sÀ(ؤ¹¦{f¦Ö±›óškÏ™H«U‘Û2ÕP%Ù•;Ã’ñ¢Q2¥IÒH"G4­mB)*ú¿ÿí?5Ën×–@jl#‰‚Ð,d­*Bæ# bd-Q¹tɘ±X¨æ+(K5º¹«¹ ÒvYàî#XMÓeäÅ*‹R´¤¢ …RPÔ…¤R‘b©Tµ•Pè`×³Ä š&¬›X¬©I3¤îËM´ƒõUUF‡h‹QuHëèlÕ¥’º„,S‰¼z¤u£"SßpI,ª;BE¥ Šë` -dP9ÄðøîðQÞÄ=QÅ„§fw_ÚH}°ËãÁû©~\zOž—že (¢¡Ð¡ÐÝ]…ÒëÌLŠÏ½ƒìU˜ÝQ¯¦›T NH©Ô {æT]iOFIÕ4mÛ–a¯Î¹“Ëm„Í1½v³$«3ûÒ®4³aÚ™© m)´m7]) –°[—P—†Ð…&“V(PÒ¤l`š¶úüí?-5–²´$¶e7Y d)JK—E…±P±\X–‹`S‘µ¼*-[,6ÒBª—"÷I×±z ,³Lƒ¤‚VAH¨¸ÞòÂP‰Y Ђ-T JUHYÖ–@¡â:²è°Að²´ÜÐs-s¬²Õ°„p+0 ©G°°d±Vm£6•á€-/ùh FÂ!CñE.Ç VYâ·ðW𣸕øOx‡Kì2jºßéfŽžÍð¸ƒè't+†Oð¿> Ão𠼕‡xÂOºÙ'3Í©¹(úxøõw.]åœ~\<6—˜ÑóìLv(Óî¬kö´WjšhâpïBv²-I”Ž4Ñ…ÝA«m¡I›²¦ ÉÀD"Õ^„V‚¡è¢4Ô( ]¢ít;.p4Uš Tt" fµ•Ž-¥é²È -´År‰’ªªþ›¿ûw$/ 2‡Ô¨­Ôc©‘ á¶ÈÅ:¤DPÅZª¬…,‰KQ»0ê²,»]–ÛXK=äRK˜®QT©ÈT,T ò"`¤¶E —»chQ ’ *¸DB¬¶È­*©JFZHZP!d³ ªr,iauŒ$ݱø¨$-lé¥ú\>‹À³Hý\âø>•á·åÀ%Þůð žå ÅæÖz¶¯z¼òí•Çîl=wŸ#‹Ò]Þz¿ú^O{…†$£VÁ{öÓšì"BãÒaR&€vgJªŠ&Sˆ£&=7Zi›Z%š‰PÛCÝHM (r`e¸¡òÖ©ØH ¥v–„„¸µ­d*-”„Jk•ͨšxº[’ÔKQt6µVBˆþû¿ÿw)’®ÛbÉEŶS ,!KKƒTZTU²,¡P[Y­m°=‹ŠÅ•Xò¶¼`°-dÕRÊ]Hˆ"º†âBÁUEY @jk»Tj+ (õ¢P[]ÕH„`ʲ(Åj£%Š#IªÔÆ:2˜*ÒBBÔ ÀBÑZØÈZî ݰ+¬—k!³€—ò;ñoÁ?.¿Šï%â3üuYð9ü >‹O@yŠ7ñ*¾—7x¢ˆ©¸Ê7ñN¾7—r±/ÞŸœ›·~œ~ì>ÃûÕKÚéQ¦«Ó4í¦EEhSNJ{%‰§“Pº'¡) BErlƨmQ˜dU)PdÍÔíTHt· N±!¬ÕeË=%¹ÓyY‡äiu2¡„å”é´¤N3Ók5{«4ÍQÜŽþû¿ûw$Õ>BU["•"yƒ­ª–T÷ŽJ£,l-9m RÌQ§­­[Fƒ¤‚±-¥B’°”Ø,.«á°E‘)ZC+S–$®‹¥`µ‘W[’œÊT¨È¸”®€…+ÔËSš  0VkVÕV­$ r,\$$|”‘…„Är-$-dUbX•%Ð à,*‹¿† þºýG£ºÛjù ý HpPå„7ô ïâ„ÂÞá_Ê\b+WçM¾=x ;Ïð¾9z†3Tm5éY]PÚ–4Ôu¤+™Îž\»¶ IºœÐ„E³l Û:÷ùØÙ™D¡d% Ž&³UR*Á”¸ŽF³Œk©KH‘ ºyÕÌÎa&ÞD íI’N ÀŒ÷lp’%è¿ýÛÛ¶dSS‚Á’%'±¬²HBµ…p¸ê’i9Œ`$s€(Zie9xqx%#ð*@uˆe¡6HKÚFȲ ¨Âm°ÛbÑÈj"°©Š´ZÀÄE€T¶´Ð¢Å¢ƒJÅ2ŠZ/@ÕÖvÙ²‚åb!É®UI‡±‘º uP³Ë@eyá…~(~p_Ðåß„¿70d·T³}EFå‚ÂÕ>Åg´è‡DùýÞÿڱ¯é+=Ih4ÓkëyeÆÓ=º6¥WI¹N]ÙLŒ5S¹´º†Ý´‰$’Z©¡…’¡½öyê¹çʺèÔ{_;44UÚÐ ;³Ð2²l/a-¹Y¨m$Uu—È¢BOÔT @}MB“ÆJJÓ*$Hi¦•þ»öïÒ«`ÓÞ–Mˉ%Õªêe·h©’j7Åb¡:‹F "GÈV+W˨`nR™%In#Õ¸Ý7– ´ˆ$uEc`@4éh‹U* €HPÞè@Õ!ºX¥T•ÛZ>ÔT¥B¤h©µ—£j9­d-I¡H²ðª‹VƇkWÕ:º–@^l|—ԵЪot¡C|wñIüÉ?)ÿDÜ¥;D‹J å½¼«ŸÊ)=‹Í.n~.±úAÿ—y|?>ÿ›ÕgxóÏzž>@·rjBFû¤ê<ԃDžà,{(´H♞—2ŒÛq褘@Q‡jÊBC[Q ªBãt+@e÷9ûvšj†^™T›Ñ0ÈêòRsÓ²±…ä¦44M»¬‘u¶è*¶lM£²åcf/¯ivÝ sÍe¬ÿöïþíUUEH:J¥ÚÚØ¥Æu9P,¤lÓ±IeH¸¶Q*#C$5Á £†šƒ…’öÀ‚š•…¦€1Œ¤…䂪HF´ !Šd¤¤RÁ(ÂUµT¡RIJ‘Ëd¡â! `¨Q±0HHµe`d˰ºäÅ¢àuÄõ±ªàÕeÉÈÈ•åƒåʲÑÂ78`‰OåÜà·ð›ðéï¬ßˆ@ÙíVx'Šò1úbm“ò+¼4ÿ‹ægnÿ¸%û«¯ϳϓ‰®éTÒ\—R³ÑÑ  Ú¦šBŠ=Ó]І•tµ¡À"¹M¡2 Ftº£¶Wû¸öä#=·–ŸmàÜ}}>?ýðé¦eXFdQyÙ(MUf'EigjÓP4 ÙMÒ³!¶;TM”kVš«ä™”Ò€Ú$Q2iEØ ™˜´-m²:³¯vÚiÛV#;J m“´m i™fš4M®äši•4IÛ&ÐéÎtÒ=É”j’ÔIB3M6)3TiF¦´¤4̘ª5¨PT‘a¢TD„À”À )‰:DPе0tè0CCF™^›ÒD)) ©#1LTšM€¨¥Ó‰)-©¨\$€pÅ (,ôI,ëEÜ…ñ–~_~jïêäƒóíG»a¯óûz{çñà|jÎÎ0éµ}ÕCçh¤ ]p#v}ÅiÛPC rD)¢ÐN MU9€,¤„¦¨ZTÕ’?ߎ—Û§ÅìsöùËs×§Uͳ×ó|>{øÓm>ßòâªçýè§£ŸW?Ýx¹ñ²úù¦—c^>Ýu{ìYÍÒe_Ë^Ç‘C¾É˽-^¼îîÝ,[HÈ’šQä©G5E h¥©Ôv ÁRVÆb‘ÎL§Ih’BUd§iš6U¢4)´MRíA´­*•)3)i¨`©êl ʤ[m›´$CJÓí”i§Lth ´tDiJÒQ3 ˆ¨ %T…BBÓIg(´0d˜’ÒÐRP[`hÚf€BBô“¸SÐÐ3\íÑOðƒø+ó[ô/§ÿßÌÿ¤¼j"eñ’û­?Þ;q­Y«–ÌM¬ÖRÁF&¥F ƒ:%’[… BHÆ«–Ö²% 4iC1¢PŠ*Ë«kõ~h¥sçû:üòânºÃÇÇãy>³÷AœYeÏ~ž×µÇ˜ŒºW+X䓎Oëøl½,¿ÜŽãð:$LÕ!:W¸Ô6‘²àX>,«&I{Ñ+C1$QKK¥U#Z¢Iff&mK2“ÑNfšÝ޳•Ò´É´M#´Ë$…ªÀt†d2Ó–¤I3¹:CÒ¤m43ɤÎdfoÚ¤³‡‰RrÒKM”!i¢– ʤiÓ&¤¤LEh˜ h Ju¦{:!¥4Ó”ÒRš=¤¤MHIII˜ŠÐ@[$€´((å^Ð I€´Ê;ú0âà "»ÇíEŸÿQnK|®f¿áóïô›Ï]+v±(•„d ©ÌÑÖ «HQ"#-BV!˽-–%UH…mÚÐ’z7'Ïû|~{ýÓ¯ßúúþýýã:ç—·×/ooß?ž_^__?¿|ûþíýõÛû÷·+¯k2W›a·;ÚYÐå¬eÜEZêZHÊÖZQ‡œÉ³¶r´K¨ã뼦y>×y¥IQ7ЖN;Ðf¯¶-¤™fšj[OõIwA Ú´mÚ6íLf‡^ 0I²W58IÛ$m¯í¨ã4ÓÌÐ’Îî¤ÚÃlÏV›½“4éÞ“$;ûœóqÍö0!UJ† ”Ôƒ&$LII:›‰Zf:!%Ä$IP¤ÒÒÒ:Õ )‰RØRR*ÝPR¡B[B’€ 78Ä'ø¬ÞÅ‚H¢kñ¢.ôQý¦ÜÅ'økø!íèE÷ß6¯í÷œ¯ýøÎ*Øh$Z5¢¥Ð6!¥‹–F¥E$m%è”âBÛ$j+JB¢–=¤s]¯oß~ý–+ï“_?ίÏùòúþ8ûdÿåûÇŸ¾||ùøøööþú¼¾>Ÿùúöú~ýüíËûuýx^¿žçn¿¾¿¾žï߯ëœY´=–Ä%%ɵ;WÏKgúÜó˜y^×ãz¼ïý<Ïs¯Çc§oïï÷¹öÞsÍÕ¶Z°ÊŠU[-•ª²(õÄIÚEÚ=šáš6d¥l¢T%‰ Ä­êkæØ8"’& Õ´ I2ž¨-¹:iÜîÐ!“ìQ CÓk÷õõùúvýñ§¯¿ÿÓOß¾}ÛçÞ;$TLµ§¤m#B )¡† 0eªI{jW»ìM6{40›kºC+JÛ@¡ ‚ *²ØmbªmÒ¹P„Z*ª «^Ú[¹¡0,­ò‚îó~…<Úïê¥îu}ãzèú®Ç«¯‡®f—i RM+â´fØmªB!ÐÚ íR ´%aBÆA…”LÛ \TÚ:ï×óÛ·óùúññ—¯Ïo_ß]?6ßß?}}~Ì~û˜+¯Ç·÷sЗ·×ëò¯¯oó×__¿¿Ÿo矾~ÿòñ|{|¼½¿gÏÛëÇã¹gwïž×u^×ù¼æâÚ3ÓëìsçcÏ5yœó8óñØ×îû3¯ïûÛc¾~l‡rí™äñ|¼?>T‹8…¶Ó´m’$m’+½&™L ±»´HLiiEiZSÒ@]µÓVt·™¤³gO;%™FÓ³Ýé@·RL¤Ýì0™\Õ4ke½ŸÏù¯ÿðóûûO¯o¿ÿã¯ùöøÓ¯¯_~yŸkÈÐRèPšÀ@¡Dê!¥""V´%›)¨…Ò ‚‚†–Ò Ù„(---E“žÍ(ƒÚV­¨RÒ¶€0,±„aÅMh ÀSúüþUóûîŸÚPèÖ>ÙgsÑi!dÒL÷”ª»ÙÍtvgÚÒ6%QÔ SeH:%%e‡´ÝbHHT\*9%!ÅÓ·÷oç#o¿|ß_ßööýjçóñ<îëãÜÏ=×~¼½=¿~ÿøüòã÷×ÇÏ_>žW^?žùåýûëó—¯o?ýôõׯoùòñý}¿?òý9ïç~ßó¼öl½=ûåc~ù¸¾?®¯ïÏïëíq½¿=¿œWøØy;çûûùvöíÔûÉóŠÛu}\çsÎóùþx\×u×u]aW´IÒI›´“X4XM³3tªi‡ jë"YM’”´’ÌîŒ:dkÔÔ@Q­ˆK”vB„æJƒKë5Xu£$é ÌðÓ—ïþòúúòË÷óËëÇëÇó_þñ§?}y}>wÓ¶m!µdÓRh“@(í´S6J(JkA mÛBK -i#­ŠA±aI‡Zhµ ÂUŒ Á…/í?Ÿýú‡¾þ¬ùhž Õ@``Di P©U-Œ«U+ q¡(i uÄ”ZE$„ DBÚéìÎ蚊6R™½_¿3rûËëÛóê—óñúþ6å<¯-ë—/oïÏY¾e®k¶ÌÇǹ{~{\Ã}y}ýã×ï_ÞŸ_¿?ÿÕO¿þÃ/¯üöñ‡_¿žÓÇäÜl¦3;L|ÅçpÚKÇ–£÷ÇõL/|±®øìuÎìþùëÛ·÷Çãýút{¹fæÛÛóñþdPKãJkM%º¤Ù™† -ÁLH ´¶išiGtImÀ!ÚõQµ%ihȈ:i‰J…„Ô¥™vLÕM'»­¨fæûóùË÷÷çæ×_¿½?Î}éýýüø8ýþõÜ[­Zˆ]ZÕÄ:j:i" %íT ´¥)™ŽµQ¡-¨‚v”t†=jP-ÍÐA…ÂСiC+ €@p€á€ VžíÏ>¿÷üÊû{¿~á|Õõ¡Ù"GÄB’(@[Q„ÓÒ6$ÍЪ̈́U)Д”ˆ–™N“tJ@q7M»§3ì°‡ ;Ú¹ž×ÞÏë—_ßc}{ýøúzýüíõ9}2‡Öí8þüåë8îëåýõõ—_¾^ûý9?{ÿõûÇ/ß®Ÿ¾=~yÛ¯§þôåý§ïç·g?züú~}{¿Þϯ4ó<ÏÍz}{¨¼¿½gBÒ A EÙÐÒv" 5¨i¦Ú¶Mh”64!eJªŽZÍÅóì¿å÷á_øøhQ†LgÄVF€Ö” ¥C…¶C … Å£ü¬ù•ó;_Q½ËõÁõžçWruBÚṴ̀‡V¡3Í0CBk ¢2í å0dhiØ»µdH˜vÊ“i ¢RÛçu¾={¾?®ýóÛÇæÓüù—ïWtÜŽ½ã¥÷÷ǯ߾ÿéç_ýöq=Ïﯯ?üð›Ûíþú~~y»®è]óòvõíÒë¥ }{È÷׳ߞó˜|„3N2Í$oÏçuž×yeoi€¶×¾ÞÏóãÊlí–Öû|üöÇÏtûÈ—_¿ÎÌm•¢…&=ÝL÷ûóñ˯_ÿzž¯ïï :L¥’Ò¤Aii2É´¤ieµ…”MZH IFîôR1¥¡Qk¨ ¡)šN›v(Ï}½=ŸÐçóã™óýãý7?þð~>¿|{Eúöýúõ—ïI$€vHhJÕÒ’JmC§¥ªFÚ”Vm›v hÓ6ɵÏ/ßÿÕÿðÿ~üþO¿üþåüþOó¿þ¤/¯=Ÿ½PÊm›L™6"ˆ.@C ) š2@á ¾M‡ì^'vK²ýr£ƒKžìKsi†Ð W4!C‚ °ÓÝf8©tuÖý¨J§mSµ²%aò L˜4eoö4Ós眿üüíÛëc£_¾½í<ÿõŸÿòÛÏ÷ßÿôçÜœò»ß×ùqž·÷÷·çº¿|ÿöç_ßoŸn™ép^×N?ïo繯ÇyžkâÇøãÚï»ç\{+{ÏìÙåXoÏëLë$çt‡–Õ³½’À$þñ‡ûù<ïé5× ?¾Ÿnˇd¨Èjz^¼¿_?ýòöíûõ|ö—oßgΙ‹ªJ«DSƒ‹R&'0jL%Á4›VˆÄ­’ÕÃQ–¥v2mÚ˪*«Î«_¿ÝbŸ×yæùØ¿ýÝýñœ>ÿx÷çÞ¯ïïûÚÒ¢‚@tÈ"jª’E—ˆ@@H)€‚ 5¤Ùz¾ýÏ|ýŸzýùÍ“³úöó·þúÊÿïÏýÿÀÏßÙ¡%%RPC n*€–@-lØbÐ@€–Ž OÍÖœúxdÝûãoûÛ¿æ‡ëѤ¹ØC¦W¸Ò¹4›”Љvxœ½Â®öôùÌóR`”ª®·<½€tJ«= _¾¾þòv~Œ_ßÞ>Îswíé3’^Îçh­ïïïï—áÇÏ?¼¾=çÇùW¿ýÝMyýþmöy=ö"–þùççÛVEúùå¶4çóš½JŸ{¿}\ÏJ‹É]Öqì zéXhÕîMܪ¼\Ï÷¥L˜YíœÏç ÷Çn÷êE‡š°gžçùóûû?üáÏøË/_~ùúü¸µ…*-4u!êl²5Û7GCÇ’C"aöRIVºZž’i¶4ô"C6‘"šfVv{ÑÐ!¨ÓÌãã$Z·OÏÇ3ã¿üùç…þó_v¯óº„L™Ð!0«*RM”ª¥m7„€´%С¨PZ‘‹-%ß~ÿ‡_þ×?\ï{Ýn_ßçׯo½¿<6çÇžø•?þÊ9ì!í¨©’‚$J‰.´ÅÀ†Kìv·€"!Á"Ðé’J?}Ê—7}ýê_~ÎûGÞž9ƒªû½¿}ѪA3<¯î‹=Ju K;ÚiFWõ¼4Ó‰Z¥JIuM¯“½97×8ÅBõ±ª^ï×sÎk¿~|}|<ÞŸÏ_¾>Î= ëvÿþÿ'O–mK³,AkŒ9ÿµöÞ§¸•ªZéæîQd IŠ 4R²OáAèÑã… Å; ÐH@"2j7ó035­®Þ{O±÷ZëŸs ¾ïº×vÌYß~ùôòr›3O§ÏŸ¯ëå‚ÄÓv]OwÏ/×€ïOÙ·m%Ï ß,øð8Ω¨üpz—ç ÊK039+Ç`­äyä NÁsú²à<|I#–äš<ˆ:üæÍÝm»q† ÚA>½Þª»Ü6 @j 3þòåãÏOdþßþ²m;"AÙ¶РAd8É$‚€Z ²›h © ‹*ÐÌ mÛ¶!B[Û"€RÃ’$ºOKîÓO_¾ÛôT2ÿüíÇ/ϯç%c¬ÛÜÏww„!A Õè† Ýд&ª¬B;hÛ „€²›6$À0^þüÝÇ?ýç¬^Oç××[`yùüù¯¬j^wl¶«Ù¢mÙ˜ÔKIS† ÐÀ$ØÐض-7-€2J,@M’Öpu^?ÅñÂ}çÑÞn”m¯A+,°D¨ &ªÝrµ[nz6$t¡e2º8)ÏÆ$Ã(›¥××ÛëëíéõÆÌªy»ëéq?6æòåùùéóóËmÿéó þîÓ$~ÙŽåî¼$ÁXŸ_ž÷ûÖk®^‚DŽÜ¶kòèíöáÍé²èë»qáÑ—Óz¼¬ã²Ä²ðqY×¼[Ç9±ž×åaÍÇs¼9çÃe}{·>ž—ûåw§¥¦[rÏ®ùp9_·}Ö‘p(,³;ud«æüéËíË—m/…â—ß¼·”dÈ´Ñb»[’`˲[ ›€a[²í(´L9L¸ÕC’M jÂE“ aš¶$ DRÝŽY­[m5·Ëe,#oû|¸ÜËþáû–=±dA¶[´!¡›\ì` ¶Ñ²j¶1Õ† I¾Þ^¾ûR\÷ÚŒ(sÓ|¹Ï/óÛÿòÇ×ÏsœNF€i H°Ým´áI˜v@h£áIÜÌ$I€iNƵo›ç•/jàó FX¤a²„½‚„É:Äâ‰H`¡–ÄÙ– F‹ š4lÑp m”ÐÆ4œ¦ËÝ8 Õl¹ëËËü²Ï/×Þ¶º¾Þfñá´,üéõV‘þôtÛ&¦cDüñ/OßÿxÌÎóÝE݃ùòåúùé¶_«?¿Öç§ÝFU~ÞªâùõJÏ wí]Jàœd¢´RéXˆ½DŸÐ‹½ÂƒÎð]öÝðÝ¢û“âñáòôôœ  m¿^ÖÓmÛ/ëzZÊ6a·ÔØ»ærΗç[9¾yÿîõù5Õ¶$¨nHm[’$µ­ÖlRÛ’¹ÜeÁCÝ–mIê–»i·)$«mI-ùè>¤–ì–ÔR7ø§¾·T¥ã¨Ëeìóúþc"Þ¾¹_Âïï/iHjØ„à† jŠÆ„d·`£a5Z®‚ÚjT£¤nKØëÓþòt—e6oÛµƒw÷S}Tï#×Þ KØ;„@™ A¶AµûfÝhh À ˜@ `©üj¼š8v¨Ø…íæmrß° ¿L; ‚%4Pl‡Šm÷qpV¼¹àá„AVA€m2$‚¶iÃF·«<'Ž=µÝ|2JžÝÛÖÅ"ŽY·c~ürÝ…ç]ÇÜÆÂ—m~ÿÓsÍBÆv§»“5ë¦Ï/·m¯ëí6k~ÿôåç——Æxžýñ©þá/_þôÝñã—ý§/O¹®³ûááMÍýóËë—ëõzÌ\²t¼îûm–l â´eØ  Ìu@„$HÆà>ç’¹]¯KFX®: iO¹ ÏÖm»ª¥jÕ¼m×u Ú†ìY’%I4 »n•-XnÓ°,ÃpÙ²¤.Ír»­¶Ô0L,µ$Y-Û%Ó`·¦¦ÝGw Õ^òÔ¥XNû>øø9sy¹*‰·§ßüêëo><Œ¦ n»iTC¢eí膄>à ƒ"J€ †6Z°a³ËUhÿüÓ—êÞÛÓËËŸúôñãÇÿòÇoýÈ °½Äw?ü¨´_¯èRË€»Ý²AÀž›uEßP‡Ù@`D¦Ý¶¶e™7ð™ü!¼‚ }Çus÷jßßñ(2Í+HÀ`GÈ6zâz°í*l;®WoWÖD@Ú®²9`7Ü É³êº÷mÖ6__®u½B² ÷~»íÛëšùãÇO¼¼îŸ^¯·Ûö|ÛþòºsY>¿ÖÓÓv9_¾ýþûçkx‰nwÛ¶ZÿüÝ|xz©/_nO›??WsýñºïNV¿Þ^9HF0õQûç§—ßÿåûÿå?ýñþ¿ÿîãçò” ¡[³»m²Ál°íxyù¢öOŸŸç¾ÝŸNAwÛ²e5D5¶[ÿüéåãÏ·‘+ÝòAU»%[2‚ u—-0ÀSmÉeË€ÑU–lÛ–;r·ª»%íSÕ ©5eZ¡Îvì{I8v1"~ñõW{[u].˵{nû×ß|óøx!ðÃÏ?ýùûŸ¥éR5ûå¨kóµû:çuviQ4àaÓD¨Qíj¨Ð€äjÈQ®ýÓó×ïß]~þ²].— Në9cÈ(ÍCºÞ^–ËÊÏ/‰Å2dª!Ò  .ãØY7Ö†šð˜ÀdˆØÃ( @àoø$~‚ ÑÄó–g¶õåfÔVÀ“²«q4o;^îÅiÞŠ·[C€4`[D°–ZB Z·£ ×­??Ý>?íÛÑ–)÷ÄëÄ—kÍÆËíøüºÏÒ±ûáþôååFä±óº÷XÎÏÏûé²2ÆýãXÆéõÆÛA€GéÓÓñãOýóËñºÅ¶CZ_o54>þp=ªîÞŒ@;^^¶ïzºÞúûŸŸÿÿñÛ¿ÿáé?ýñó¿ÿã§ýßÞÊß}~úãO?ýñûO{=sk4)rº€°m›ÿÿëÿôÓÏOÿõ»Ïÿí_}óÓÓ§¯Þ¾Ýöý—ïïï/kŒFi÷·??ý›÷‡?þ¼]þWÿôoïNϯG÷ñÕû7a€\’&‚”Áá" fPr3 ÁÎLа§ú?ÿ×oýÕ7oN%Ü­)‘#?=™‡/ç¼m³jæˆËããß÷ñ¿üþû¿ÿËKHoÖ+ï/¿þðx½=SxX×÷o~þôóé|ùþÓ+Ë"u£ý«¯ß¼¼÷ëý]Þß?¾y{cqÏYri½,q^4MrÿîçïþòcIŸnþòó¿úæÝ‰çï~üQ÷ùtÝÿî·¿ÄãÇXŒ;âñ¿1¾¾ ^`´ €$C¶ŒðüøƒñõѵóÿȧôŽÓw?OžÎx|ÄJc¢j¶PÂÞzÞâË+öÖý)ÎÀ–i¡`l¶ À‚ Ø…€Ýýù‡ÏGÇ^µõLÅãÝúÕÛ{IŸoÇŸzþøåéÝ»÷üóGÄßÿþ»óiùú›·s›oÞ<þ‡?|zÞow#—%~û›¯þùÇ?Áõ§/ŠE߼ᗧþá)ïÏážß½àánÙŸ¶<¯çµ—¿þå:0.øðæíårž%Ïý/?ùãÇ K~úñúõW§û3þÕ÷O¿|úòzË2èx¸_.Ër9Ÿ×óP—³fKü¿ÿ_þÇÏ·ùÿðí»7ër<¾yx{w:Ž~¸»¼¿?W+2’ø7øáÿõoÿôìö‹_\õ:¬¿ûíã¿øÝožoÛ·ßþðxz÷öá»~|÷ömõõû»Ó 1[Ñ­uÌ‘|z½Öåõåööí;¤ÚöBð|Yøñó——×±÷ñÕÛwO××Á8„ÿøŸÿø/ÿéïþé_ýùõöåùøý?}y¹¿“¦¿ÿîãù¼|ùrý´ééY¡”æiõiAu+—üðöÝ28ÖEr0L˜X’“Pp3ˆ$qûûËxÿæîùzÌÖ:–‡5ß|X¿þæÃõåàéñ.nÇõ6üé‡%ÏOÏ/¿þæÃ~xûöOü®õtZ¶ëë?ÿÛß}ý?ü ~X°,ÎàˆÐ`¬‹«°M@ȉ» NoâáÑqOÀ½ñ@¼.Àowð=‘$m@Rnã ܈Ïà÷ôÁ¼ý¶~ÿ{|û <\0V<ϼð@7$Ò,Nûç/øtEïy>»e5dJ B "$ØÐ‚:ŽÛíåËñéõõùÚ/×]ÄßþêëÂîÿæ?ýåóÓ/.÷çÏOûüãÏŒ8~ÿÕÍý?üþùr—§Ó™Þ~ýW¿ñõúóóëÓ•ßþ´ƒ§Koâçk°tñý ±?ûrÏ»Óøøéõë¯â7_=Ûüïþ›_.‰*~üøùz6OGáùºýîrÉþ»·§Ó§ççî–ø›_½=nûrº<^Ö———eYŸo×}ü¿ýŸÿ÷ß¾ìÿößÿéýûÇ•¾»Œïïþõ?|ûåû×ÿá¿ùÍmßïïOÛ<>]õÿýO?¾nøõýÊ•óõ;p{~¹-Kn›®ÛÀ~ô:’9¾y;><ÞŸžw¡¿~x“ øôDQª»óù¨µÆÚÝ눭°ƒ‰4»öɹe©‰V>Üe½»Í:Öˆ÷C$Öí¶ï·ž%¶GÄìëѧŒ1|¾[×Áˆ 0Fp5AOÄ(É „„½€#؉ b{y9¦1ún]TÛÃy¹[OAc]ƒ—óùWoï¿y÷æÿã¿ä}b¤8¤ð:±7ˆÃî˜g¼{Ë傸ØwàÙ~OÞ ௉·Ä‰¤m$m Wp£¯äÏÀ·ÄŸÕ?òxöí?þÈ¿|r'‚øú»È¤î°ú‡öŠnÒŸýibÛùÍ[Þ] CE„»l£I ´{P‚öíóË÷?}ùr›[?™×£ªú_¿½;ÅOŸ_Þ½{‡>þÝï¿ÿñåøë_¼ùí/¾þö§ÿá>_å¯ÞÞ…ñ7¿ýðïþów;ãë—ÏŸžÿé_ýÝ_žZñýsýá‡×¯Þ=nÛó¯>¼ýò<_¶ýñnüüBSŸ^ô¸Ôñtà×ï×¹_åo{úßþ·¿þþ»/‘þý÷· ÏÊý¨or½[õöòË·?~ü„±üòÝÉÎ Áùã_îî^÷ãtwâÿé¿|îúóÇãq]:/èyoΫa ii¿Í®Ú[o–u»§¡óbÈ»Ñ鱬ËzâÝù2¢—\Du$Ì’2#šmǂΪ$:Iƒ-Çq¸Ž¶& A¯—ÿúw¿¸~zùËÇççî?ýðùéóÁÓx}¹ýî·_ûVóÝ›ûÓ²>]oÿó¿ÿË?ÿÛ¯5o·+~ÿíó“øör·ÕñÕûÓï~ýËÿÏ¿ýÇñ×ïþøýçßýî›ßÿãÓÿóùÜiä°eà_þöáéy»¬ËÝ ß½ômÓ—éËÊìÞ1¾yàõæ‘üÛ_Ÿ~õè‡_}}÷ÿðÝw?í»qw~s‚­_üâ>j¿¼ûó·Oo>¼½g?~Ýú¯§åãÇ×Çw—5ù¿û»·y:?=ïI“fÒîK®§1–…pC{á¶÷î~¾çX¬DÌ¥Ø ò20[÷0s}Y—eŽLKŒ1kžr!iˆDÚMƒ :9À<®„¬¡n¸uh]23×õœ« ð’£ 0ÚGàĨnì·~ÝöºÖýÝéi{9q¬ë pwÎË)×»K@ƒ ŒpÒf¦ ‘$ɰˆÈHX ZвF‚»ë#à9o""ê8‡îÏ÷ûíJW¦#ƒ ¦ï9îsy;–wo–·ÞÞ¿¹ðát¾ Зóºñ;yÀyR+ûÖ—;^Þ‚wƸ³i˜üò…x0î‰;b1vã‰(ó%ñ <Á?ƒ?@ÏxúGpøßÿ½äûw8Ÿðã¬w«VÚ¸Î~ºêãgçPûøùÉ_nO×éoßþô—?åéa«ƒðéá¾÷}ÛŽ¹õlþôRœGSû&¿îǶùÓË”-Ç1ë×ßܽwÿþas{¼lïÿ鿾Þß#Äÿ÷¿ùt‹õþî·¿ûfvÝ_ÆãÃ23ÕA°ýáOßÿ§?|>RKC£ûúïßýô—çPõöôeï¿ÿa*ârŠšzóŸýâü§÷û‡ó?ûšw£ÿð]uð´Ä w”çëußY0 Áå…sy;âÿð¿yøg¿|óíç§eà².ü—÷aÉ|Ù¶“Qc°üpYGDd¬”ìÛõu’×½$ÃT4™L’ìÌ@·çApuY2h OcÇl kIJ¤¡*+Ëv’VÓãÐ^]uÛ·‘ƒv ï×u,k&:¹„“!„d C%Y³ö}ÿù¹ßŸN/}DÄ%½däÈûs.ä8¯D´Ì%¹a Ã3›ìÀ"0È&záÉê5£ŽÛ’°´S#º"êñr¯cªšT,hÓCäãrz\Ç›Óúx·¼½»<<Þç |Zøíÿ惿¾¿Ã×x|‡¼gÜw}| ׿1üøøà“ü}0À/À3ðìšßó§ÿBÿþ{oÆzŠ‚Ç½ù޾ý—o?~òË®ÝǬ×íö|»í?¿¼f¯4µöiYÎà äc»fžfaߦ‘ëQÛn×ùñy¿m;¹Ì9‘Ñ—…o/ŒÌ%8›o—Þñ¯ÿëë§í²¾½Hš³šž{Mbžê–Ç Ã è¿~¬—×:¼_ã:ë‡-á¾,Ü*Æ:¾9ëûç~sÉß¼‰?ïwÏÐãýyY–Â|:ôz3è2é>¶ÚŽC*’ýõúüWoÿî›wþþ‡Xøæþžÿä—w—õè#*4âÍi9 ]ÎÝmFÕÇ^ÕÚ«3Sò ÀÉó’‡;h.AЈXÜu,8åÀ&d{$NëX2AìDÈI˜´"—[Ížû‹ÚÓ}&a9pÊŹ„q ³ÂivWKv»—^®w‘{u,Æea –sòèÈ<­±¦#GãÄ`¤EsŒlÒá¢IÎŒˆh»ƒKšš×ÓXë¸Y^Æ7Dè»uIpÎ"Ù+ò„å1ãÃåò¸,w§å¼ðþ”ï>¼]N+PX aº;ãW'¼k"ñË_ù×ïûuÇåëÃØ~òQñÕoƒø¥ùOŒ_Ò2ÿD| $ðÜŒ+½…ŸûãŸâËúü78pkõèuÁ±ëé›ðe¿:0±ïóév=ÚOÛmÛûõºïå£ã€;–N,—‘ËÝ~Û4·Œœ_o{s Y³ç¶ñi¯m+GJ"Èp‚™Á®­™ŽcB[kãy¯1Ù4§Ð *¡†G£Nt,Fâ½ $RjÕÄrX h"(ÃV梥{.÷÷¹òñþtÂØÝI>ï¸íh(b‘z»^çìFøêýÝß-×» ·þêWoÈß~uŸÉÓi¨lãíý)££sÒ g.ݽÉ5µï[;F`ŒìY̼ŽAÌ §²{‰Dw§¨Ùd›‰)@’±¦ÞÜ Ý@³™2sÎ#¬u,×}.°#áId’Ëš"h•§¦zº«Çõ(w5ú´œÔ½†m¤å@?œ/!岬`-ç1¬ ŸÎkêZ"#’´Û벘&Ûâ˜ê>NËð<:­‹Û³wÀƒðÔˆ±.lOÑ'be>F¾[–wëúv½?Ÿâròå4.çåôøVd8È¥Á“O+Þ7ï¢×³¿yKU<Üy,ìƒþæ—œß!þÖø}˜ŠþÑ>Ü)µk'¯Ÿâ»?ÅËÍ?ßø\Ròé€Ãs¶ì£«91®uðÀó¾]÷Ú'_·ëm?ŽÙ·½§YÂÁ˜Ïë4-Õv£håvØ\Ú Æ¾÷uöõ(MMÁIƒŒHb8wKŒã°év™§[Cc´ ‡l;ʤ톌¸n-h8”ÑÆ4Õ8ØË*- ´1¬Nf ž/ñxÿ c¿;/ù¼ãu·eµªfÕœG øíÛ»¾¾RI· ø« /ƒ žÇ¸;¯rÑêÁÈŒ–_÷Ù ©\HÛFÀ € §û¹mvLè²Æ¡[íD&Ι`XA;Ž IC’ .ÄiÉj˜U'ú4bR#}æ)É<-%¹mU©º½¬§Ùzºä9¸Rˆ0)"Ê\Ü#1 Sf‚$— %ÖSœÖµK#˜#™¬9—1F†ÔžÂQAîcˆ!ê,Ó¢ˆ cQ³/^Ïo2ߟ–wëéýéáþw'ŸNËyɸ_˜5t’<ã¼…ð¼âáâ7 ÜìsàýÅoùî-N¼3^éï°† ==o¼–¯…§‰—ŸŸðróËd-¾NΆptßfÝJÈóáÙ›o·~ÇÖqÛ®·}?ŽYÓñY>, Ë„“”²*ŽYKºî=­½ ªfZ’áN'#´rÓŽ°ÑÐÑÂ8U°r±`»ì¦ÊPgA–÷j ´(õ RêPV3R‘œ-. %‚AE¦¬Óš÷ë‰Èˆ>¶ó¶ûÇÊaC`•.§\Ï×é%’©É_~ýhõ8xãrZ˜š­£°"ÆÂÙÚ÷²)‹Ð’C–Aƒi´­ 2Ï“I/ËèvuÛz˜@FtŽ$H’öBd. ¥m»%‡N‘pt[n §…‘–¤4Êå.x]O× Sr¦Ñ4‘P0 >G¤ÔeàÏ9€>3Çš^û¼.ƒ#TÊ‘ ¹$!Ìýàì  F( <Ñ jfDÀaŒuspMœ¸ÜŸüË»Óúþtzwº{<çÃ)ÆÂÓiàPÁV,Á\”kœý˜~ï‡M1îüæä¯2~ñ ~ </:~ˆãMÌÂÓ†—¯…WãºãöÙ/Å/†€j—ÔuýÔ}LWqc¸Ç±ï‡êº×í¸µÏ©æa©ã&Nc·†Ø’IäëVpعû^<ˆ­d­¶€3 Ñt/±ölgë€1ÖQ°hVƒtÉ1cV=>œ­ZÖ1t1²Ö§e5»MäT-"Ö§\2‰Œ`!"GØ]IRvºC‰Á0l«b¬áHÖ2X  ›ˆ0”Ù!ŽÌF,°¤È*7sœ†A:!ÂABÎ ¡°ÖÈœ¨ œ\F®Ãc¸6Fð48FîGsÖb„j.`&G C‘AõLjŒÀ)bM]V^rÜ/ñîîîýX߬Ëý9Þ-±,ÁSz è‚ ,%}Z°‚gûNXI q:áþ‚¯îñ»G|óIoÏøþg\',¼¿\ñ|x [± ³p5®ê^9{›êëÔËì—[cb“g±{ïZ®û¾OÏÒkÍY”´Oí ¶sÎ9#ME³Ä2%Y>Ì6wIfC7‰G€mìšàâGD %Ê`Z²¤åÙ3|Y†33ùºƒ3%—dÃsÎc ¶jÛŠ¾¿»¯YÛ6 aY¢$wÏÖårš²ªg{adjNÙvDœNêY³(EŽ‹à'˜KAm !¡Ž=AÃGûhK04@™i¬ju +ÔIKªD Á²Ë€aƒ¦@Xp”ȉ)•€Œm—Û*Y£¼6†Í)N  ; DÓê 6(³U†“éâ”¶²:Ɉˆ-¢mÈA ”m›fwT§ÝTù80§\`ØÕVHtSQ#*hК ÷)¹—À™XKf#‰á…X‰h$XFIr³5{q/ì׎gÄSáeãµñzãµpÛ°_q¼x{æó z‰ºñ§ Ÿ'_&?ñR¸Çác/÷Œ}ïãfìžžÇu¶ŽîÚ{VÝ*¯szÚånGÏÂlTAÆlWKAIVÌÆ”Êv³Ë4„mK"¶ U[ðÑží’‚Kâ1S¶mؤ1Úa €Vò<ÎV†rÞjÞ¶×ý¸ǾmÇm¿]·yûm;¶ãØöªšsÊq»ó¨š{í›ÑÕmé8¦äy”Ö»IØ Ð­P/­è`S€²iG0 vVY5aA’e«0Z}X’ö}W·dKdTËp÷ªlV¡g‡MäÄl4À)•]‚7KrÉû”ˆiV„41u4Ë”SFwwCæU:³æ.©½;Ç옮)ÙPÛ²E6’ÀHÚ¬Ž3ÌÒ]S}4ªÔ µåq̶\•×âÞ!ÝVÙ6”AÚ`Z\0BX‰39ÊR¹; ÑQÓŒa·Ñ®Ò´7bBnÏæmòzðÖz:ðeÇuz»a·o»¯ž¾ÜørŧgÊjMyVw©ªK%¹Õ–S€Ñ}´fmr#b„ɤL(PÁŽV´enÏ}¶bO£¬šÞ ›¼í¼•^„ç‰}ÃqcíØvÚûãÕ?Ýüóæ§|¹úó_v¿¸®Ó·ƒ·©­ª¦æÄ,ï{o}šGy¦fUêî)öÁ:Ê¢]1«÷Rµä€aÁu·,ÅÑ‚Ùmµ%4rŠ@ÖQ)G$!̨š&wuÕhÊ,7Áhò4íð´‚28ÆP¸aC1Rp&bP̰M€AcD0mÙbhÉ‘ˆì„I˜B G.Í„‘™`$# ¹£% Áa#”¤†A¦AÂPÀ –E$Ád6šL"Èp¨eÈ”IAm”›0a›b£%›@H¶-«ÕS˜šD‹6›‘É” 02ªKÁ–à µh6lÛ Òr0жEfæÒA“M‚ÜÛX¨j¶iªpÔ,¡¼XIAŠv”=Ž0ips¤!4TÁptRéNctGmd¥ýÕ[ù&mž[Y‡÷]*a ›°Í˜ÆnîæQ>®Ü^ùe‹~·ÇO“O;Ÿ~ž¼nñÚ¼5[>jξÇÞùØ&võ¤fÔœ˜.Ën¸£ŽFSXZ©btZÑŽBvuµ«ËÝ»¢«» $GcJm[ºd™pF@XÇJ„A0eš’aP¶m Ztâ8:Hi²HÒÒyY‚£å\¢ 0#m¤#9bQÄ ƒH"s,cY“ pY–ÌDPdp!)&Œˆ ’‘hC ß¿»¬f ²è„ XŒ”:h™4Èôˆ0dÐ&a`D CA¶B6"“n¶2PÖ@$†åJ&m ´È€aÒŠááÚÀl 1úÐLF i”•IÂi1Ôœ¨…¦±F•A€aƒ¤‰ô èd€X‰D­Á:e$kœ³‚^ÆHiyç8ŽœëÈs>¼_ïÞ^߯iœN©s6Æ!éå(¹›”=À…IÇe`$3¦—6‰±’çáËàýŠ»G_îÐë ^Ÿâ*M¢›­Ùdu¡—>ù4ÙÓ·‰›|´æôìž=o{Ó·Cmv¡;¶ž·Ù·ÆíÐF;GíjGI"»]´%1ŒQ• 5›ÑR0$‹†RÒi=½nS# !Qdvô¡€DÒ]Õ6v­KØ’´PÓÁ a{T“6ØaØÁ°ѤÜìfF:3BY Ðaؘs7c Ô-f¢Ûš_¿€e 9d$aT h€&(Á°M“š&Z  Ã4@Ò6 °„-#Ã2)fئC\b `%»ÅH“¶0dYÊHX2$»@˜‚— lTb”…Ðò2B"é‚h;“;3ȱHAšs‰\²Gb œF&EëyœÄ¢8Ç8àH>ŽËWç·ßó²¬k»Jû!No‡v±t®Kì18s?- ,ˆˆõĸ¬¸[qwò² Ìë·ÜÄÝíœí=šVÙ›úÖ•ÍåpošÕ˜Ó]Þû˜Ímr“ª±M·ØU{iSÜÄ£¼ÃGÛ MØ›‡ BïL4”¹Û2†1u˜CHfÛ´Ùr¹Å¥"×›A³`·´:Ú‚À€„ (#ìŽìêÈ”„¤;K½$Ó €ºÍ´dÊm’‰Ù’h!À`ƒ´Z€,F˜›áž’¶°Té€)Û°ÜdÀ´€m³Ðj·`„é’aÒ)l4‚A“pË@‡DØ€l$@¶ÁÈÕa¨)†@ #jÊS´‡cRŽr–XBx1©NxIÄ@RŒ†ˆ†Ëšp‹²›²¬VÑ»úè*uÆI D´Ðn²å”àŽn·º»cÔÈÞf5Z솼€¹°ƒ±s9öêªE=9›S]Ön½ªwäk³ª§´×TMìÆnÜ&_oÜ7ì[yê˜ÇëVÏó¸v½v=ϾÍY³­¶}¾Î~)ÝŽ®òQ:æx9tkÛîv‚²áÀ˜ˆ]8ŒãhÌP¹Bp{¶Û!öAV£³åìCE.Jl2"X&\SS%ç4aÒcªIC¶m éNÐA‘ IAŽá2au² ¸(©CZ"C0À‘$ á%ba&H™ž¡ZÕ+”É:é`Â$HšÞžÁ@ ´"`‚2ƒr1,î&’”˜ƒD‡¨¹š°’056"Sh¶#6Âí ‰°± ‹HFn/ á"’°À m  €ƒ–adÀpPDˆ\ A‘† f“0R=‹é˜îÁa9ܨeŒáh0§Á;šL%z0Fèî4Î F8ƒÃÊ$‹½d.#.#ÞæÝûÓïÞ>~¸Äe¬ iùå6c–·fU82íNçB §-ˆ4¿9Çi9a=a „lá&ìǼGásó Š½%´ËÕ.ÏÝG³XqPÍë1÷›UåTq˜·®Ûש­0ͪvE¹w¡¶§!à&ÑQäad°[LVÛ‚C@¨ºcAƒˆpƒ±‚4D1:Ô¤¼À”g•H$Y@£CŒdO{e¢Ð0—e™s2H33fƒ„à@€Œˆ‚ Ã$Úm%]²„Šƒ ¾w˜†š)±4fdtEAÈÑnÑ aÈAHA6‚6(@˜$i7@ሠÝ0ˆ“lƒr¢I[d9,E†Ú‘†HI&Ј´À""H8´”;0¬$ &ˆXDf¯K®SJzɱI&Œ0×ËéîrZ—s² i1Ä%Âèä8“ÉZçà›qúÅÀ/ß=¼9–eaöœ¯×ªîY›X)#éääIcQN‰f`$ÎËét^וK:@I»z›Û­^»^å=ÃÝ šÓ-~º½ +KžÚÊ[y—{º@€ÖÌ1^šðëŽéØ‹[· ͘íƒnÑâa,ÂlXI° ° Æ”«åLµa‡ ³“‡£u˜.‡ ¹@С´ä²«F$-wÌÄÈž0‚@„a@k.ëPbwÓbFQ€UM¤aQ !Õ:㨎n“‚óÝÛ‡pÃ@š†AFØ2D…VÆ´`{1(‚à   ÃI \̦lÂ6ÁˆÁp»&lDh# NË^È6–#Ò°ÝIŠaÚíÌ0Ì%l4Ìa“K«Êà8Ê#iš “v$…Ò< à2ÒÚ¨ûX-1yb,KœîNy:eËÉNg`¸c0GàdßEÜUsÊ_½»<Ç]œN\Tûí¥f{jšYE[P(Ǿ œ2HôÐ ŽuŒ%/§õq=e$ÆRÄܽ߿¾ãÖóun^Ö"lÑêÚo½ûñÒe;÷Y˜‡ËˆÊ)¶…8`MÞ+ÚÜ+6ᘥŽ7wÛìh` …†Ì6Ê6c¶ ” 6 (Ó’„e,µ"4(CI˜mtu&”,çXf5ˆ$[‚Ù®&CD eIÄÃÑÝI’lÚ*ƒIÊ‚Cv$i!pdÎ> 2G«“I@€ízÚ€$Ól¹Z‚E·D i©“Á‚»a[6&lZ Óp i›b" d¦AÀ-ÀQe•iÂ0€D‰ 2$ jÑaF´T˜ ›¢Ù¦Ñ É(ÄT‹ÑS}8« ØaEDÂ0lµì¶hÈ¥–ŽéVbY–õÍÝxû¦ÖKq”Xv¹wU›‡Y6¸H2 `ŸÛõå³j?ÏÓ×Y_jªãóv¼ÎÚ”ÓËÑÚÝ/+ú6b´¬ûÔX‹'qíX6ÆÖìÊn…çæ“ù¥ñ¢±+_osïœ^ž^¶×ççíöôº]·›ürÌØVÃ]ÚgOivw£&ªÃ"šê–KÝÑä ÁmºË-7YÝÁ<ä*—ºm›H9ܶ#Ì(£" h hÈ` š´Iƒ¶À–€¶ÕÀ„@8$Ù6ŒPXP¹ Ù²"»"2€,GK† Ýp0Av̲š„[j¾ys±½0ÊÁ¦,hšh›L†l²…M ´‘ÈpL® m3,ÃBÐ` hÚZ `ÐAÚÖ`£Zˆ ·mptË´a ÃL Ãdd«2H£¤h˜1©HA€dØKŽ Ý,«)õ)âár§å|:AD¤=8‚ÎT¤™Ax Æèýûv^xAßoî>Üîî¸ßÝÝ…ÆÜn‹Œ¼„gÏç\ÎG&ðºjžîN WOpÌe­`³/ë’‹rkä9–eán=Uß6í{lsÖ~ÔqÚ¶—@ÉÓ–Žš» <­°ÑÓí<Ä*‡E¸§‹,iv &±W•²èCÞ íœM›š —Üv9Dv‹„$›œf2 5β¹£º;Hš€4v ŒaÈ#" µu롞jd²m‘­¶ ÃËHV·%·r]Ü Ã²’²¢É$c)5aCà€‹D9,ëªÙ`óí› šÍa7a˜ˆ@!#ii—{€&™ê& c =@c0e(dFÐAÀRBM¦ì IhÛ„B‘1ȶJ„Ì ±’m`„UÁ´ƒ©pŒ²FŽ€6 !f 02&:‰ˆ\Ü—óÝé´äcD"ÚáבÑÈL#jadŽ“]Ïûº„FDâ8i$õøøîãÂ^N 8_.9r\¢7ûËXß§£>_†/ËåÍy9¥Ë–œP»Î#Ö5"¢Oë)ÂSý2õºë¸¡óú|Ï…QGo…”:fÏÙ¥Q1m°9‹›` îíä¸î‡Å0!+‘í6‚à0D¦à€ˆ0ˆ˜„©`Ž˜ÁæL&#Ó°Ðz—22íB"±Ëi,˺&.ÀdÒm3cDPÊ1¤Z×eÓµà{;ƒA-$#F›RÇb&–ðXR'æyáš:Ñ—Ìàpšy!Nkœîߟ˜=;[«—Af"#ˆ2x=ðùöú²½r+ïóP!ÂáÍjvÏ#fcgg€…‰,¡G †*ÓFDvL “錢a“ra3hÐ)ÇB‰AÔ‡Ç;TÝ3pb&tN¬E:ѧ%{x,áAÌtÐ8 ŒXÆèt\VŸÇzâLªNË›wVŸ3ïÎËyt€[kÇT²är0#Ø' ºnûë±u÷>=÷*D¡j©Ñœ„჻T3Ц`a»8)¬Æ =»ÌC¨ˆkM# @jD§¥Qŧ‘‰Ö$/Z6h-4ÃòTs,P°™ $;œM”Ë^ƒšpD8dv€Â”M@dÚ `C#IÈîYðȳܲ,äX9§!#ÇÑG"˜kJ–š D—ÖÓ¹[ÂÎ7o/’GÚŠM´D‚´HtØ'ˆ a4 kDÀ-#ƒ ZD@¦AÚ$¨$„iØÉ€nE¤ÔÉ„°‘„ ˆ;À0ÆÈ T . –IÀk¢HX@‚{FÎXVƒ–‚d 3Íä ë’X€i€\˜ ­ÐJºD,w#.ö1Üð’Ôe‰9†Ïƒ—Œ5bX†Ã^"xÊ<Ÿò4³qsÏ¡Z„á5§…£Ì:žn×›¼MqSÚQšHæ æ«b6Фµjï†c™‡ ¡n4ìì©& Ðæ-Ô‚l4”ÙRGêC0ã&9êpL*§!b‚3Spš6Ò¸rQ=ÑX²* ÈÈÃ0d2 `p˜´¦ŒŒ!-;º¥ôe€ ™"ÓÆ0ÚvŽ tM·#,Ì1ÔP¸ˆ®`°­¶AD„v#Ø0A&¢Ý"vµl¢Ãl4A†Œð\hQ* Û¶M²Ý–iBpD0D[€ 6|H ‹ 2‚$%‹ í4XÑµÑ ¸ÚÕp „@‘$C.©í”Ù"Ün‚¨`ɇaäÀPË6¢…nF+È´2‰A¨  DZè®”ÙÞ¦ì%fDŸnsVOÏWÏWÕµçuÛžU¯ëH¢LÆ}ðÄ0rC§èeðþ”Kx&¥ #rGqNfϱÇÜ㪾›TÆVY}D„Ú6\ÓQ¸µa$͇ã°ËªˆTÀ}$xȇ Ø6m´B» 1-0v`2¦½§³Ð&’†1“m4 ‹`“†ÑF#š€ „aÙlÑVÓÃ9é€ädˆ$È"´Iv[†™Ã e »†M£Ñ""(›@DZ»E²È$ !£ºWЈ†4FË“&’$á`Ài“†ƒ´"D“ d4FšZ&mõ´C– ÈBÀ0# ² ²lÚ0d„- Àl4ÛÉA£ÊE˜†a›6„ PM…ìV϶A]š…&–ƒ„Ñ‚¤–€´I5saÛ6‚ç‡G’LC€&ݰݳêP5m‡E›&|·®pd# ~5>»?y¿¢_]Ó¹ ¯ì]ÞäÃJŒôH­­<ŽÚ§^~™um¼ª7x3Û©ÎRö„5¥B7'³å6z¢…” ¡*¨jŠQF[Qí¶e0íBV³ Œ\aØf‹DÃSl A2 ‡@ÕlÅ4p»miJÚ@[’ @6(’¶ÝÈL·Õ¶$Ê Àv0¡‡l‘¢i†`2-KhA (µÁÑHR-ÀíÌ ƒAÉY8mgi{’I® %§.ƒf@‚1yfd¯yBÝä¬ýp6èg"„ÏœÇe<óL»xìᬛ§ŸåæCúÓŒüãä‰ÿEÿù9¿É3ç‡Y—½¿3ÿÿ³Ÿ“ÿuÎîáu_ií㟒 Ó!Ÿð_?ù™ >3¾’üý÷þMþžpžý³îM²»M¾ÉóLý½æÕ'ÖܘÊ-×íDO­K=3=…À" Yó÷kvï{Ÿó³ún3¹äKÆ$±»ú$¾ªÏm':gzÛsNB›Ö Ô%„èÅ’L\ÎDJNdm2âM?ÎÚ“iáÐÝÉȶ7Ìty¦ `iÂV28gZH€œ#õÞ3$vu>ŸÝ Í¿þ_ÿ`!´HH"`Ôê:hf¦G7ÿïÿùïOæ?ÿŸÿç»Ï¯­‰mO¬È`¥Àá#i2úœçœ‡ø÷Ÿ?$CЇ±ë9sL{oÌÌgfÛÁÏNß9??ÍÀÊ$F2‰@ÏŒ^î>ϧnæPŸI2Óƒ'L&fSá¤Ï=;÷sÂúèÈ}ʇþžùëy~¸ÿ8óûë¯÷þžü­3ó>üóÚC=G9ç ç½+æ_ÿóWÛ™§ÝœœÎe>N³ÉW’Á6“Épιß?óã„ùGû÷±Ä­fm’ÅCcØP9Œ)âÖÆc y‡Ù='VÃ0Aªa‡3g.3£7ÀÄ2ñkH¶÷$CgânÚ:Ïèó ã “@Ë1y~Å»>É žœIÛ>ñ’“Ÿ¸·=*|ž3/¿¦è_ÏüwyžéLô¯ëÈÈ4ðWú×3ž{é89mïY†¿aÏ<õyò™\7%çñ*Ï÷ÝÆ£ûü|ßê==C“~ëÊ<ç%µïvfJŸæ6…™>ôÝ^¦Žó©ß…¯q÷‘”IÞÍ=|<7ÞÙÅñÁl×eÖZ;Àq{ÝÏZ‹É#ÖdªÝrΓ “…¸h92¶;œ%ÛÚœ½u&s²›„×'‘¹vÊ<tûÍ|é¼³ŸÕãqîH&ç|& ·/93ïýæ_ÿó»íÌ“kC}8—F D$™à¤”>ÏÏnbÙ” 2)„H9œæÚ8ÉÅÔ9„t‚" ÃQÁ€lh 9‚&±ÎàN"§šÉ¨2ÁŠYúœÓÝ™yìÌäd&WàyŽäƒÌãö(‘-Ƕl999¡÷“ÙÉiÃóÎ/ï ¿â#¿“‡æ¬}R÷ WMÒì¢þ<'sxm’¿§ß믙_‡ß™÷¢äœ÷ö®oïóó«nfþ¼ýÓŸsÚ»¡†Ù݈3tã¹Kz¦×ù:ÕM[n*¸¶œ(´.ó÷š™wlˆPÖ1 ^ÃÐ*sɵÏÄ·ß1ÄÖyH^ ’P Û2æã¥-Йqå(5‰É@«rЂZ #9éÞÏ™»§q¶&ÊL:èžfff¤"i›þë7™0q%$ÁÖÌÐ:d pTÈ™3óy÷Ï ‘Ï9ÝÛyÄz)›ƒÂädiÖ>ZÂHâ6™'ÙÖ`Ä žPMžv'\zæœUœ™’$é& %çÁVkæÌà¶ñ@èLÒN˜‰Ì‰É™0*yf&c¹~ÎFÛžd{f>tÎùÕ÷ÌΑÄM:^ÃÖê3OÑg×&“³•÷Î×ÌÌÒ¯af»3±¬9­äÊ„µ×ó%­LKÃcëÌ×»LQ=õfrž¼÷=³uÂZ3ƒnîè ­±ˆsÈï¿~oòçÏŸM§Ý[d'PxHÆÕÌ[s½ÏœÚdn`;¡í&‡“¸2‘š‘ÎŒlëóù$IÂj¨Ì„“I¢´h0]ÌAÄC2™É„I",ÙQ»¡LNž²'32zôÉ<%w…gŽ3 ª&1Y™ Óð0c®N¦vΡ>ïëØd€íÌ'“ XkpÆ®[5cÆL=ÌO™–&’{ïÞív»÷nw{o–ÈíüùºÍ~{õvþ,·KÙ¦ð-_ïß÷ûÊ¿™ÿì~9ïwïuÉŸï~÷çÿ¾¹ó˜ÏŸ“ŸìÜ·Eîh¿ï­È¼M:wo7ÖÊ»Ý8s–yá–:@ÅUŽsÊÓb‚)Œ‚`’ˆ$°HõÄ!ŽÄ9“U™ýx’™ò3<ðÌœ`r±ÝÏóüÂsü5{¶ó믷ïw;ŸžÉ¯²7—0é{7çû¾œareí0[>Á,Ç»¾Î1ÍMç¥R8™Ò¯üaÞ„\B3?¯[š9IË5 /¬•s‘Íy¨bÊÔy‡™Ù݃ -áàj6íºá“£m¸…` $ÁÃéç<ï.9»ïa^<‰ue‚寉i2®ƒw&˜™ô¶ç´79j°éaÖ•G”‰Î<„@Txž-ƒíkþ÷ÿþ½Šœ|Ö &IRv Ò,>‰Âœ§:¬dÈ¥“°š€ tß3Ï¥3>=ëþäÔ8*#†M€#‹$('l=v‰Az yDª‘H”HÎ*!NbÒ0ï%‡Co&óœ~?$™÷îÏÏã¾8›”±!7ŸÑ9ùà³7cfh3s 9ü°û™IÖË™~ÙgòÃ~æ³™Ò×}Rž|®õqÍ$¡íMjÍ©¼*ôÒΙ"1M¦r·óœÝ[rƒÆí¯™ÜÉ¿wÍó;g°RÃÓS,°.S0¬îÉ6%J’»¯“ìóF!íLtfêB ®/Œ4¦ºIëdÚ&““8ó<ï~Ïpo+¶$hÛ&sáJjÆÉ‰‹ü‰BÈ$ÝÍxõÃCæõE’“ ™ädÒíáxæS*LNþç¿H$I”âH%iʤ˜À&)óÄÎÚ P DŒ.C@C“féƒBqf€‘Õ3S93X³(÷!fº;3‘qœ&­ ‰!uŒ3B’DXü8ï8Í„ÕÌtý<3eVŒ•y¹;C'OžnNúîýÎóp¦;Ó Q†gÎ ?,f3Ã=&œ1‰?ñx?ã©!ÄÎñcþ:°>™7Í̤'ts Ý„’…K€{‡ŒÙ%–Ô˜3ÌäëžsöºÊ¤­ákOž—þÊü2ßö’?ä '˜ÈžsxyÛ4/ Å;ìL»e¶£@à &^ÓÌZ3Xtò,ÌÓ>sþÃ~f¶Ñûu bb§Šæ Ìó<÷^¨U­$RKD&]frá™a[eP=ó,_:‰Zc“„I2R0~Nà˜>º8þó×dØ™v3‰É Lr¹Ç8£çvŸ©™1"ðÀŠa¶3hÒ™1Õ fÂèM’£2NeBƒî‡¼qbJš^š¤»Ï†l‰!áuÏœ šDbl‡“!æ`Ý35sèÏø‡=ù½ïÛ™Ï縸›( L ý¯9ê̆¼sæÝL>™Ó~âÉ©ßO0á×gæ'óI?ɧûIdB>3›¾ä--cÎámÕ1ÑÔuæ2]Óæ™Ã!—†dB§÷­9„o7s4ëþN®Öùf¾»>MÛ+ÓÓbr£d ”ól}+ôãqó®ÝŒ™í wÎÙ>3#yŽÔºö2„ÝmİtÒ–0yÔÐËÂØzž#¸Št2‹BæÓ.œdǼšAÅs†×:hcê~&ú}sÍ<5C833R›É?ÿõ[ûy¦W@’.9¡7“pàꈑ ›Lõ H 05lg~¨“®•|Ä„A…O²³6Af×gʘ™½&Ñ>r§d&®>fBIˆtFKæIšžlÌëÌɱÌ`74™"Ήj<ÎþHÃJrp»&9!“8TŽ;ç$­6<=Oò Ïö µ?ÉÆ§iú{æ×úžÙ)™<þ<Ï—÷o§íöçÐØ÷ýn2PL6¹jgí3œ0çÔý1àÕ[˘’cxo—|fÃÜú'‘4Œ=„Ékcv#$çO¿aš_)§.r“1˜è\Å·ÉÌS´ÀÉðÄ-™•ÀÒ Ê9}ßE$ÁÒÈ$ÖóœÝú1z’y¹%R: î.$yšÍ¡û¯D™£œø=gèÎÌ@°3ßÅñòy,»/l0s뙜²Iñßšò—™ñÂ3³Ó]ó½{†oax’Ïî@ÍÆ­Ì ÚÎ$rän„MÔ%¡Âä\)ŸÝ?Éy«Œõ+™P€µ‡œ‰$lÌ&gªôêF’ì6 ´¥-éQGûñÂä3rǸ6hB°tÎ’*I¸rJ-çBÔŒš1™3<Ì*!ÿó?¿·73q @&Ú¸dÂ?iÂeº2 ò¤ífXrâ :`LríÉ€©Ô¦qš9à\{0%IqèJ” ã êLО©û9§KÄ9»'S•Ô>Ì@’$Ôåþʃ·9 f§È3Ùœ|›Aȉ£€qšOaš9t¬Sûgg?x3Ë®&n°Éj3où‰?îN2“#ß–|è½3£$çDÜKò' `Ó‡0é"Õgë’†2q'½ CÒ"ƒš SïÉlùFpL1hæÁï@%sÊìÞäX;S%Á& ­bTÃø•1LMñÅ!/FCš¦Qͨ‰Ëˆ‡³t!’xp$œ<ᜱtœžÂ(s> ÑÚ–<šµIê¹F™334i€ y\[{dIˆ°­k†™1G iÒµz’̱À ê뢉ÒDÛc’LB$ÁÉLÒpJ LM‚çÞUW0@ˆ1ôz—%Nr]r€ëbÉÛ¡LÀ00$rÌ$™¬FZ=:Ü“ìäÉÆ{×P\X(ù;^û6í¼N™×Á¼ôeJ&1ᙦ˘Y·ã+K"oý¶e˜„¤òÌ \v3moxæ|×mÿŒ+d“qÎ/ŽJ‰#£HNˆk"'æ0Ÿy&Y"(fŠÅÄp’ºÂvkTáÚíZ¶ïÚëæd‚`2ù„3Ÿç3gŠ6¤9OtÈœ³¡Û¤GÆN Ï&ÚyN˜0•¯ ƒYüãö™?õJÊ!ù£­·®]r Ì·¾ÍuêüžLÎöNçj“¬w[G„yòÐܶ™ÎÓ9q®\lµ=††¨ÌœI¢ŠRR#““ÑÞÛr¤fÍT<ùð &GRšh*8&3™äy’iLR÷½oë’JÌa2gs>yžçsž‡äœsfÈÌy&§PqNfµAÌxr®mÚî!gˆ§ñÉÚÊ@vo‚²xku)]7µ‹„ĤA¦MœÔ-Ø¢wµ+ö|æ'iw;dΫkS‡ 7QBÅ™3ž,r+6lº¥Åìgž·´sñ’?Ý¿aOVÿ\ídÆ 3ÍlK(–Í9ÏÆNJk®üÍ^ó‡~Ã¥aS¬R/›a3»i]§y`Hv²d‡â˜Ým%ó¶orU´½áΘ0ÓkÁ»kÒxu`«ƒ¸™ä­»Ð¡ “L ž™$“´„Z\Lh[ƒ9sB9!)"“lœ¸öœ‰™|‚$fÌP›$©ÛݰÖ¬N[«v»¥ Kp5 @I(ù“TÌ\W›$y(€@ÑnWF|Bº©€õîN%D?3Û¥%§iÈ0ßµ™†¤™½©s6HµÀ†öf²X\-Æ©Ú]¼–î„9š’h¤ïYa·N˜4W®Z¼ã±ñ­ÁºÅÀŠ& œ˜¹“ŒOβ™,ÔØ' ¹Ûºoj²ò-÷Ìß.@úß»}ü{$)y±É7C³{µÛ…4ôáž–¾õ-—¼»ïÉÒ?ìža{Þ5+êŸr'†š/Ô·e†@Å’ h·Í™)ÐV<É(dIqœ«o÷!†(téÚ†¯ï—ïŸþi¯Ö3d*01ŸLG&Ï9Bm-q®,¡H™L€ˆLÀ$™C\{ٙ芅Á! ò˜ÊÜ•jPHˆ¢ 9f È“MœD&޾K—¾íNÞRÿNÅPï»c¡DD'ypÂcBà GNôchžœ$$ÑI² &N*¥’!ÉCH’´}—kši çéIŽÌtúd¦‡º5™² ³Irf´„‚ ‘ÒÆþñýÆ©%Ja+9†l.qÎBáNþw·ðÆ;!Ÿ’?âü¨mÕé|»oÖ&1æát¹ÔfšŽWnçùN^ù”Âךؚ¼cS˜¥3ŸU‹ðÌqfB ë:ËT5ßR|žLf5°jMXI: @ºûZañ…ã<™¶?°c JC3dRÈ0gfíŸ÷ûîš1#S¹TMR˜™óFI„Y“©;ƒ©s>À’‰ë™€MÍDŸŒ[¦8ÞÙIv™™è?2Ò-é|íN¶„É@ïÌAM×3A!9ZÔˆ£:y¦…¡u2ÅÐ0So›ó¼m¼äsœ7{HÝdbV'0Iýze²³ã \}’º’‡ófž™]3!³%IžúÒ“³Ý‰D$irðÖcö¸Í„êÉHÜf Y7$ `;Ì2ƒûæŒ%‰l59±ÌY׿¤)Ι›<»_el¶™˜D…$'>aêN8 $IÈHJ ÜWR@Ug欯’ÏÉgqqƒ :0­VÑ*“¶@l"Éè̱ÎÓ ÌŒúÚÌœŒjØX,΄·5 ܽQO20š.5ºÚÝHF™“)q˜¡k3;É”:0ánÿ¦·m+4Ùø™‹Ô$ÚONñ¶W @ˆ­Éɨ@È™ƒdN3ÌI’ıîÅR³@+âúÃ!ûd|ê֪ɤ„¹í0…eÂ3f- N„I Ì©\ 4PJ¶V Ÿ“OžVXÍw}Ýs^iÛsv¦À’vš¬Ä!gàRÅ1'Æ6t’¼ÈdµÉv^M2Ìö Õ­Ì8£@—°Î­€º59TŒc“œdl5·A/=IÀç4Tõ51I'»«Ý»n ™„sF"&Óv’$“Xo§È0fÎIP`24q0´½IIf’œ™3öÊ®_ L ‘PZ›Œ™DPTåèÞ›d=™aTÐghQ™õŽ/Ì<Ý¥24£ÑO¦°B«"‡Q¤‘»7„ D¸xífH^/$ íU0 Fw`ÜÄî ™LNH&”ôî=ݶ„2gDƲc¬ÖRÓ¤fcJ´g’L¥j²ðڜnj8'Æ#ïþÉĜ̣c‡Î5¶»mK›–)ÓuéZ'‡¡ªÖ«MîêPOr°¾EÉÊ›vfmf„·¢f¤Àà¸8S  ˜]š îÖ´ÝÄ$ÆÒ<“3ß©a#m²iÃêsž@ÌÚ$a{™@q‹Ë.½u{'‡ºöÌ “ IÌÜĈŠ3ƒÏîm*ˆ¶Ð ¡¡¤êd’L·HÂîÕF"Ó>uΈ;3¦ä¾Ý†“!&9$kK¶¯‹ Ai; f†$vBÈdÐäÆòî¾´»k T†Ü®ƒ’ ™– ˜l¨ ™ $…»BÃib-n2A£€Àœ)Ṳ́qQÐ<ÖPKYòÒ0“ω¹&_{3‹¥ÙžÖÌÉ‘[.]ªås–Ýí{_0aÉþ|»53ç!3«—"Õëî´,á4f®,Íùi‡I[l«Ö³T[w˜™Ý‹î.Pk ®ÖF’Ø&©fN†Û…e¼H&£f¦-Éb€ö»wLÌà—[ ±e²÷],Þ6PšÄÚNµš$3mÍh¶·ÖMVÞIâHµÃCdæ£ÁÑ·@NòàÔÈÔJg—8PËÌd’F^ÔÞ.i×Nžv>sjãl¡vkÀXÂgÆ$j ‰B2™‰F±`Â$Ir[g.U3•¬šdff ÀÃA íf¨¥š*N¶ ÃÌy²1ôÖ%lØPAM¡{òPg(Á)çvÉ<“‹Íl‘~&÷.æ$^Ž ðI«“Κ|æêÈRÙ-â9€‹ùäüMn½Ùd,œä­&«o§í÷œ}vd’´ÝÝB’g|†ÚÏtàל!N€™!ANNtTŒL’D4=ç„ó™YZ‚sÆbñÈÅyr€B2B!bÛÉS&)UUrrž b ©^’™ÔBÎxfFMŽTb7™LÓÇm­^ØÄâAà ©\bþçÿ¥ 8¤Ú8Ö™!·Õ2 #ÒÎ9ghÆ1%Ú!C’ƒ·Îi{Ž4€!N¦HM¦x2 Xûp–“çHá(tÉ$Û=‰m΃0ª5OD!É\HR%3î3gw“È¡wæÌÐÝ$çÉv“™dõÇš2,0rÆ/œg‚4+uÂø˜k'gÆë>‰`(}xàêSï!ÌIÜUF“˜sá+'©Õgb«!ybšÂ'ÙœµáÐ.=¤vcHX†4 È A­Åñ­KÎ$wzÞz’Õ3´ÍI õ|ν²ã\<äjò´=áR$=Ì‹Ï9nÓ8S=®“€™ÑZIq¥é˜„ÓæhgC‚EÖDñin’x‚«hµád tJ™Ä´Ë“þëÐvÎh—!¢âÌ)5P¢™IÀ8¨PÉÌÐKf´a˜Å‰ã”FàHµ0!ÀÉ”B%Çi¬ç3³€e¨œºÃä´@2 €É§$³é(9IÖ3‡n“G8Òì™Ó»ÂÌ`ÔÉuÜežóÓÆfÒä™çîeH’rÈüƒ6gæ’P5{2O(:'mâœCºÉ‰³Ý3šÌZÆ7¤³„Ãô(™r’žLû‚ºm€!‰M¶€ÏVNO¬ÊØ©fÒ© …‰ÝÏÌK¦’ÁÊf1˜Ld%;AònÎ)£,’q îÄ„nÈÈ&1ÓîCa6²cÄ$½bc ’‹’p6LÚš¤ëÌÁ›DNДZ™¤53÷r&$­ Ø0ùç¿~1„1Í’ ÆÜH’Ç\’¤ŠÍ 1Œd lÄ@MX89æîæ9ƒìJ“ D ¸É i¨}˜‰0¥X2ê„å$B ÚúÌÙœ¸ pb1Ѐ|þúý9™5L†3ÌsÞ÷v÷sr&~1$Ð?ïžó¹ï÷¿~ÿ ùÏýþœs—âè½wï÷Û>g(f qφ÷ö™Y3ºnòIzà¡““RYœÈú6!§ÎI£ÎD®}LbMg>ÛIfÜqË%1ü¾IhЙ'¹µ%úìܧ•,M>¼’v Å J^zòHGP)y†©›ƒf[CÖ ˜œyêµ.… ÇZlLò„jšá|¹5Ï \8B (ct;SÄ #JgÆRiFo€-ÈPAI“ŒY$à T«3!@òßÿüÌo0îã/ùc?¥by/ ˜ Iþ¢éÏÐZ:#+%¤J$c:vôôñ9ÎuR~î)!Àk_Þ¯¿$™iÚ¢Nÿ¼ßï÷æ|ùôµh¥!ZG» .;LòRÙpWÒ×G~ôôàµè&á½~áŸøOCXNÚ6‰ÐÀÄ»a¦¿„b†† ñ&šäõÕ„l–´ÛN…lká÷zŒm[“}4xá×<˜ÞŸþ)a_†ŒpaöÜB’–t *ðkë›QZˆT+¤?¡dX¿Â/ió£¯ H„ÂÈÉß»@mû’¬yFlç–ä8šŸy´ÞɇŸ*À¿xÛ¶%aç€K6|æ}þ®›˜ä??RÜË.•’²žÐèþº ÿ|nÿú|“ÖªF¾·Ý}?^‹7]ºþïÝݦ$ÿñ8"i^ýNçÌ£Ð|Ûòhl–½¾ÌøélN¶·ìïýŒÍM§Ú6í¾Ëft–Œ©1dôÍIo‡4yâ°i@½ 7I×li€m‰%…šEó‡~ÛÀ÷BÑ’6¯%šÄ%y?Süö—„Ý™$BêØFÒ#I“ÿëÿú÷b›ŒAÄÀ }9ƒg2,ùI"ôQÂ÷Âw£ QÛîŒI}É_ÀÐd_“É#¡_¢ß ‰jóæ3iÔ,äF[<~edáÇ$ `¬‰MnüR¶÷_ÿÇßÿüÿ2yïÉyôˆëã»%mb/„mæGÆ^óLrKþŒEt_óþ¤8–_s?òZm%“Š-¦-ÙÇÉKÀô{}#®éçª#IŸ3ÿíþy©„¿dÛa[°„(Ñ€aTHŒX 𠺦$ÛÂçš’¨¡˜ÛË#Ö¦¿$æƒ6ìBTÒY¤¨Ir¤xòâÏê|åîK~úã}ϸ Jøóïÿöý¯ÿ›†$hb0­&Þû=ýôÔ_²P¯ìñ;&5ü„×Kú-Ÿû%%F²Íôb*â/Ì~0æx/ŸÖ‡k2F M]MÂdGþåLKšŸÜÍô©{b”ã mXçH)Oºûš @¹PP‚/˜%)@¨Û…G b²é¯Ù]ÞóH»l@¥\È4„<Œ=1¨bûÛ®¥Xâ™~ð§û|¹Ñˆ’#&s%3}l´Lr÷¥‚Ìò„‘TéNH!ÛÉRÈõùw·òš`pS•/Y*Ù\’á €(DÝ-Q I;…lª([µð×éЀÚDл ¹-͹VQ$y*¯%¹ÚÍ—aÒ¿qŠÌ ‡ ¾úªÝæ“j"ÅÛ–ñ%$·™üKNüm.¡Îûëý³R—û›ûËýÇ»dÛpÞ‡Ÿûû;wj ÑL¢œ§þuÄɼínß픦ÒËÌé?çßd@b£2 nW/øºLÿƒsMÄ„¡¡ÊòžüÇù’tp÷•[wŒð‰ïý£û I¨wlÓh˜BÛÁÜh’f6QO?½Íyr$ŒD¥):·ØTLÑ%êé¶%$Á@Õb+~sj2°¿&yáw—™Ý’4²}zC]ˆº+ü„yÉA@>¸Ð kÜ¡ÁšâÒ&öõÁ½æÀdù|y!¦7_R|¶ô×_ɶÍ/åEŸŸ/—1~©T,O¯Û ™žGRý塲¶fsiŽ IÄÀ$ñ—–4é»xdú½m‘ÄFÀȃ.ûåßÏ,oFš¼¿éòãfš Er é;Òþ¼+FxÐôýÈ¿º}ý;Žwøè§ÃÒ–䬖üRu“ð'I´.\D‹Àç]…þÈ'u1 y)dPz7Q¢@~¤ýÆ=S2p2“..ƒDC!:0 !KdUMÚ¾„WÔ4ň$Û Oj„†×<')¡*û½&@Ѧ-dHC?ó½÷ÚšÉÔÄô©M…„!zû !…È! n’$oMÛ$÷±×–$~GÑ-Á×@ÌÙ‡”$`$!ùóÞk 1ŒY²ÝѨaLlÞœY†[0jøù øy§À¶m’4Ã_³¬M’$ðç6É_Q’ê%U ¶«Ÿ`˜§_²¾¿KÒiÛí3Ï<é7ØG! (TûålHÚªÄ1“÷j¹mºrr,¿„Yh’\òía‡†mi5¼äÜŸ6øðsµýŒh{BBiyáå¥ïöZ*ÄyLi› 8’‚ÒBS dsQKBPA.i[g 𱻿äÁÃj»-‘°šš— ˆÄ‰4 Ù¦z~€QØIŸzÛÜîÛ7mò/ÍËkŽ­}ç¶m„$$f÷ÝØöú†Ü%Ü–¼o“|Ù_çw„¿ÙrÆ&5~ ¸éÔЄ›ž·¥ÁiJèéˆê„ÓÝ0Þ ™§M’ülõØ×˜Ÿéïý{dƒô6“6äNÖËýƒ /ÔkúéÂßiÀ•do<öÜ€ûõæ vg$¦ÛeÉ[sk b>Àéýý¾)‘ `|Ì”fÒ÷.i ¹ãÎEÝÐ Ý~ɳôý‡LHz:øî«Pã^Jøt·¼˜Å&Ùö%:vÈ™´È¹Ù!Z%}© Qcùóþ4q˜—Ånê%]2ØÝç®EfLh#»ý%ò?ÿÏÿBÛ%/a^Ó@!a¤•#HØÒ„ìøµ>ØIÜå‘”“¾‰X²|æÊ¿" J¶÷žNL2-»­yFõ½þýø½çþ†¬Á>ŽüÑCašÐ$Äùk?ïÙË)¥¦ý÷ñ¿ÿIvóîx¿/þ×\²÷ÃÁH¡á¡°F$2äÏûóãýýûVÒ÷ûîKHÐoþJï‘æÁN0æþ%¬iM>¯&Éãfùß±¼Ã—>“øäãýDìë·Ñ‡÷…’…B8Úý5ѶÜÚ\òì7ÍM›·iòŒŽDÔnÛ¯?a6 FÉç5•t.ymæÂaHÄ‚@òæôýÝÅÂÉKæÚù‹ý’âÂ{asI L€„‰³DiÜ·t³¯ððð£ms‡Øö§Üö^?²[þÇÿüW€¾ù7yš@€¤Ím .Ö y‘4Τqd§¯Ñ*-2è&±¤™dhšD¤HÜRz, G‚-,û‘#å(}oÂÉð¯üú¼5O_Í)¬ð‡ˆý?þÛ÷¿ÿ—ÜËOúÛwöÏöOÛ$êå÷s]ž¡FþÐÝHõÓ×Gú’þþç—§ I„_÷Iy—åüÓwîŠÚ¼ñ·4¶Úô.—W¾øƒƒ^‚§üB÷û›Å‘_áoøµ‡üïïoƒ­&­ˆGË´?\Éíšœ‡)¹IÇ` %&?ú—MKayÜ4þIÿ÷ö¯ò횎a^»rߵǒd¸0òá[ɽ0£¼Æeù'y¡ï‰A'ÁÔ“Ò©Ú4¸ÑpââöË–†Ÿ¡1Fä#/P™¹o×÷/LØ8=S^¿ûà¹@Rfk¹DÝy‹c¤"! ê—×@)DÕÛ}?’D¼L ¤¤V>>É–%·¨¹dƒÉ÷ë÷h~¸$?´š'é{Ð8aDï#¦ô.¾Çñ}lz:µwwãè^Ãsøßü½¨Ý6Ø ôýÄöÓÜJrôàã¶ç¸æÊEç=aköq_þ&õO?–mz©ÛÊÌߌÇúïù`ßÜ÷Ïßò{_…»ûôæ–˜rÇ ¼¸ˆÃ5‰I+Ûæîä/˜·KüòQ©ïñ~]þuÅÐæ/ýôsáfÛ¼Ïûëòºt¸òåûrÇ7m |Î7Òcò¥l'Bâmô¹þu3’(H2$YnÉ–»¬?>bb~‰E‘ìã#¤&Af äîð_ï¾>ÃOþ¼ß/EÖ²©$iK$&¹;ý’}û'ê0=tï5Mʱݩi$ ܺ£IDißÈMÈ3ÏwË£±‹?iã x:—›0H~‰jˆþâƒÜ†ÉÛíYèŸû’ߟ@cÐ2mÕòBÆU w·ú—ûÓ<ÍÖ¹Yèc]ÀK·$4X“ƒm܉&†1MóÄÙm_ÜÚ]Yvmûš„×»ýÖìJ Jš—öt“¥L“ÞÌkÚÁç>¶r‰uSÛvF:Ùü¾k‚¼0Á»N’$ÉŒDæHšjnOÓþÌ÷Ìv‹/dccCšòú D(Ä$ €$¡˜RìKr Ѽþ»ù~i6"@$§7Ô­I!šÉÔÀÛ%¬ùÆœû?˜â¢ç!€BÜ.Iˆ„ØVM›eç…ÛÒlŽÝ Þ¸¡ô=@ ×,òú,èvc‹ ,Ïòžanzpz®É# &J¨t-óµóï?ý%=…@–*4y}Âm)NÝw|Ž„»`Rã347G[ÝK@ŸVT?øÇ ŠGÙ·þùì_ûÏ}wáÕÛ9ïàNÏoÑ £ÀaäuøÒ—€$ Š0¼E’'A¶½4)ɳèî%ÿé؆$l¹u[=ì80JªÌøÊŸ&¥¯IÏÙVT µ^#Óæà3á÷Ý·íî€ä5D]Áäp¸ûš—€š„L¾TxP|ªRZÖVOÓ¾4:dš¾˜×üêLÀH^AÂëkº‘d»÷(öh›¨¦ ‰>Ö6jòwßaˆHsúffƒŽ&ú'1/J;ü=?°cÖ¼9—¤’ôû;fT‰Ð<Òè?žÅÄm§¾bòþ Õ’ŒŽ#ªìÄ~‡ %È”Z-P[}´^Úc‚‰ ý9ÿ< =ú3Iš—$‹>¿÷'iB ©"˜ty¸Û’4!Ï,Hˆ4yOP^Ãü¥ßF-!¯É/ÍË—@Jp“$­I¨(ò¥/yÁ°~/·»“çáâäåµóú¨Dmª‚©T€“tðòÓ… J MÈ4‰úZ,ͯ¯B´/éÆFH ÞñHZ’èë" `6$¦&p/’«QJo´H¨#4Gó6Ó¨MC5ð¶$?Ùë+a¢Ê¯/£Hóä-?ú¨ˆ ÃoWxù9K:™¿÷£AÕmçrÇn å±”. ´ 4-©QB7'“ä§5ÿ*/!æÚ¶6$O“$@m…ôõm§4èîIQÁ‰i憀 Š‰&°mDšÓ…_²¨ºöš°ÁçN—Ke“,-}Vøû÷$4ŸžA §‹Q77a“ð^çB–J)ˆÛ}8v:„ä»/mEoݨSê”Ì$$ܤiÿñŽKè{HH¦äâ¶£sBÁùZ`ÉwHl&’`°â160é{?§ð¡ &)ùÜ£`b8¯¯„ïÎ÷F&·Ñ†×Dþ¤â1|Ûܯ ê %wÜyÜ÷MÀ±Hht\ ô¤yèü¶¦ÀwGT“$A´}äð`NUîî °ÛGÍÿ’™IÚ·}Ôäwì·ç_òk¶K5I’o¾W&˜DE’AI °áÆKH„þu`¼6Lót |é´ÉÁBBNÀ0ûÎa~„ò£ýJ¦ä¹Q]x}i¿þùGO^~Ź?ï ö][Ò– mžp1Í»|ñ±©¹p¯~þ}ÿˆ‰KüÇ\ò‚æä˾õqðo3M’¢:.þŒã½éæ/‰$9.ôáúveäŸù*$^Çå÷ë}”šêïòW% 3ýôéaó”µ™@¿/¿Þ-ä½§NmïþÚ™_òp"”0)Y‰IÌ”&£·µ@ˆÐPØ\¢ËkÏÅ5 @ÌrIÑà-Üçï½A™%{é @yïÝýMsßÞ{ Ú÷^biiÂö™§/ÇÏGº%<ìîOò ÉKÿLÿüÊ–$‰ ä)I$ƒ$Ñü«mChÑÁ°I’à×(¦!iÛ@Ô&·¼}0˜œhæ-!­ù»Kº„6©® ýõù§²óÆ–³ýA'MUnÿþýHh7Ñ$˜ cަ¿V=ßýÕ[—››ÏÐþòFš§jÏ…¾êþ¡Ñ¸ožÂ&T°e ïõ0‰:òé";C^¿)ýÑi‡¤á•ÞJ ±Ç7b‹n¢jx/Ô#œ„sê{ÉwrwIÐ’û¾¦IÚ††† M ‹ñ €ÄC‰†º]Zg¤m¢ª£Áµôu,J^Ѩ ¿iÜ#ÐWœî%G²¾l%‹¾×ï.yi*•Ðæ‘#{ V§¿ün/B¢N^ßû?ÿ}½ïïÝ÷û÷‘”8“o—Y˜ÞŸÞ¾ï_ä‰÷÷ï¿úG’2¯<õvÿ¿ÿ÷ÿ»iÔ˜Tî—wH’xúã }ÕY´r4hÛmI‡›!)Œ5}›¸šŽoæòžgÂ7%a…‘ÈÑÙþp ’ MÔ…íB^ëb0Ç’t»Íûvê±’˜´ùvÚ|#üe§¦"Æ×ëͼ°³I¸ËMªPñ”$m‘›mŽ|© HdJÅ$-\œ„‚$Œâ0Ty/Ÿ„#} ¡†r¬—äÑÝ-¼¾í <ù^ãÖdˆ/€Y ×ôƒHŽô…àsÕ´4/F¦:¢äG ñÀMœ”$ûö^oƒ i²’n¢ïUIøÇýR€ˆØç]ò.×%­lIRÿj5ý5ã IPAH(dŒ%ùëõ½7ž\øL#æ‚Zžj¤ËÀ—2ÓüsßëƒÆkÞm$€évð•ßEHHЇš…n& §i!30Lhý–”¸m)°æÅñy/?.d0}¡ÉÙ_sûÔ2“ª»PÙ4Ä[“˜y€$eeÏ=ýùåǹ9r'&ü’` MHÛ›ˆºª5ÎQnN¿ûKPc~ä'1!¤hHȃyáÚ¾$†:|×D½}I·‘×&IBóT›—à ¿¶)D²Tøb½I_N'Êú Îh1æ’Kþª-¢N%-³[Òð7QÀˆ·$M5mhX%3éST$ön%°yaZS1c¿Ò×Þ.IÒÀÍgÔö…žL¯MžÞ}"3¶ÐÀ)/mÑKLˆ?úË零ùë¯[f’mÍFJóR’¼¤TØ)Œ@ˆ…&ª˜6D:$ ‚ 8w Âܺº{Ì—NiÚŠŒ_ôLÌ\xä×öAfÌ” $ÉŒ8BØF&×Dø6Ì $i’M%@n~må^¡é{ïÄ$>é$I}s!ÊT—À„¤!L}MžóîéûCó*mI6T!5HŸÃÖ,+  J“¼Ï×Wz@íH#F,ÞªõŸm Ä—¶ IømM"ânŸS%™ÒH’¼Ô±yÙ¹×'*ƒÂk±®½G !’À”!ù{’æ½æ\’MHÈ¿ÈOO“üÒ?}iI&Øwòl“$Ÿ»ùÚGžl"ëS…äɇcïeä€$!üÁ×W 6ÿjp±m’ÔhHIn má½4.vühÎ 4©RT’ôå÷ònËk0,iû€´Iæl¦@#´MB~ä§,] ´–DÚ˜× ˆ3‚ÛŸâxBRR~Ö¦®ýé%Ý|yãÛéJÔ&iæI OxNYø•ÙTˆ†æý¶™„ÀI~évBú“¿lð#…†EH$*\BŸ~ðk»6ÒT Þíå­©È” BaX‚X²D3ò§ 2ؾ_«B0yl ÃÁŠ 2¥ï9–Ã%áC á…g¾ˆ€Èš·ƒ±æ–¾D§#‘6ävI˜MNq@$}Û¨P@j–$"tI]/à^óþž÷½´‰ K*"D$qÄ×ÞÙB`¼à¸‡ šS5IñuùÄ@o…¦Ù,™(ù“<*M“¼äÑg8×6¤¿Ò|›(N¦GCö™ŽŽPD=yï%„4<¤/¨ ôUU^ J€Bš0aBHÒ÷«‘<€,I[e×¾ü÷ÿñ'~rŽVDLª$€ð rMu "IäƒiÀ¾b65 ’$O^f·IÆâ£2Ƀ D0}E½]hL^+¸½ß¿KNK ÅÙpø(©•6•ìõå6È ;U~MÎ/yßöH$/[pĤ°™?‰PþÚ Þ B ‰×œ>4 *ƒ&hbA[Î&Byð!€¦™ƒKÞv¯¹3%FÚn4,@Øß÷r{(ýôyïÏ)ò’y@’Ìï ÷7yõ#gŠIT ^œIfÚ˜Ð<Á¤Ad¡m12@öÚï)šˆm0š7`»6“×Ü2 Ó$D]ûòJ2Ö÷Ú§‘*]¸D¦ÈÂK+àKHš´}Û§ . Qô6 Í$Ž´…($çĨàö}Ã¡Šª¾< ¾6û>AÄQ¥f((üh@ s%Éô yûšg ~w½Wšˆs‡{!’ÄÔbÂßzwÛY´·`Žh ¿t**yýñU×^¡’Ü !IÓI@ÿaoLI5·}åË×,90IC2ÜFØ-zz–oÂá)‰à˹ÀXšJ¦Ø¶E¿=®¦2 /$U’4%¡$6ç I’¨â´ñõ1îÔh’Ne;MèM L ˜ñÉ· ÀéZt)Mqs ­°9¿n‹M_Äùúsnlƒ` Ì)w!M H²©Û o^2ꀒuz²»„D@Ìh6õD#¾]i\\$}Ò4çÍ¿™(D !e š \wcJŒjª†¨T·GV¾¬I?æ@C PP®Jþ9vÂë±#3?îÓ|÷ÛàÇ£c’(3·}[Ò’o§C°¿g’§Cný$ywÎü'[œ>’D’;1k@ücŸ°„Ž[ÛvC¬­ËŸ-àp—¸×ÅÜ?NVfƒ[üٶ0Pö‚·‹çQ`Sm β]úÞ šd¢è×4²}MMøA%!ª+¦$¿¦.ͯþ$¸aHi–Øp!MªOÙ &½; ­š<È&D/M[¥Ãy€’$!Q ÍLHÒÔŒ mf0ÜÐV%Û¾ð‡œ^K $É0. ÷Xxç(›I¶Sh®˜6}&Ï‚Ij[sï§Iù5ajÈL^ºý}.Ûv/4O9€Ò›k ç€vjL$÷]2T›Ün› ²[H¶¿»lJS¦Z Ü–æ§ãî ‰3I í9éöbR²—Ê/}$+ ÐüC2½·D„ÒSÙ¹÷ð/Jó’Bû&/=x“¤íF%ǯ\¤&SÃnmÏ<¿ê/eûv Û^XŸyÂ#i·A0MY.ùöh«¶u.!=gG’m@² ¨»C%¿>œHªÉÿŸ=òÌßXH2%‰S’`Ä4è„$¿äI`–T¡ùÛþœãëÛö|æá ¡p€ì¥[Aüxy8~/¨›ï×»O›Ú<ÁI¸ö7cß¿QÝñ‹ú^6ÞcCƒß[^²ÖMóÚö7áGPBçè‘Ä÷ºóO¸°©gZ0ÉùÞË\çÒW´Ò—g;Ïk—·ö»îõÛ^RŠÕ½_ÝÃáߤt¾ôøS´ †×?Þ_ç#CÊŽ…Ä—Gf ˆOœüyç½4 Ûd ¨ Eí¸_ò‘˜A9Òi"#!f¡ºŸ + ~æo@3´…Ϋ*&aG[˜ú‚z+Ij7/äKÔhÔ•Ðü@o÷kOà73LÒ4çMTâš9Õ`“Bñ5•%G;ÝØ¡q‰ DÈ4èNM¤›‚îÕ—D tym3T“¾6¤¯Ï­ A¼Ù6Ó€H’ó¬0µ¤ãIa|ð¥èÀMÄ ·m·©IBt!ˆŽˆKãhßç£"(m óƒuVvÛª!Ñ‚ðÁ IÐ4J_•mFe[dóv}-Ì[¸˜ùR·û>—¤Û iI”›ÛnIwÓ—Í‹„¼V.‹6I˜;DSÀMÔm!I;Áß8<ùÈ'\ø‹‡iiôû¾ÿ¤ï»´E¶ ·…8u¨Û_÷Ú ©r.3MG†N¼:ö¹½¦µý»½Ñ×—Gš0ömÄÄ»ÉDд}­ä’æ×Z¦Ÿš’4JòúH§B–’MSˆ†4 :õµÎô¯þG Â¶@q;HÑÍ%é¶$óàµm $Áüò'I[ãØD_B!Œ˜\>×$Û‘/IÒVUÛ¶Ý€hA€,0×hÀ §ÂÛÔ$íĤI’ „œ»2xéŸ#HZÀd#&ËqØ [“%ßôöK+%¼7üÚø¢[Î`›$íӽ߯ä×÷ŒÞXõ9,}yMš&MòÞ«Á½F… L7·Áš@RS¨y´¶$p»o—ÓIš ñeiE´Û“k`+]òÈßkR ¡½ùÞSÈ+á3ÐÃr~Î{¶Àµ?ÐÁTiÓ¶¤$j(Ø´®tCN!¸ f3!þfÓ´!DÝœÔLM"GŽDø )»ñò¼IEND®B`‚rgl/inst/textures/bump_dust.png0000644000176200001440000012244214100762640016413 0ustar liggesusers‰PNG  IHDR,æJçϤéIDATxÚdýײmM–& áîS,µõ>úDdDf¤¨Ì,UÝÕm` `Æ \Ö4eôpËÁs ¬‚nƒ²êªÎJR…þÅÑ[/5…‹1síQUëâ;bo[Û—O÷1>5ð?;sn•î¬ö–!3"° `.àP äÓÕv€þh4•Ú€„„Jhjˆ~È©YÑB1'yüÞoþâý“õÿæ» ïü¾žßv?þ«º÷óF£„j e+Õz…×çOoÞì8þ鯛w+õ®ÈÕrWŸ ï«Ï> \鋟˫Õfw\­B&34S3€vS…Í%õgkYíá(³^}¯ïL Ñ%‹óŽ,%®Kt ŽEŒHmzµëE}žÂ½1–’¡™sÙPŠ~#?¯?¼…S-¥ˆ Ào5ƒºJ}¶¶ £¦!™‚™™™ªöUðj¦%ÏÿæÍ?ùÉ¿úWo°¿9ÿƒð‹íÉKüzþÜ›–‚•+f`ˆÈ/Ýóf·Ôc ªi¿õéê¤|»>m¾]/L­œIªP6=˜ !@á’çË|¿ž=T‹l†~húm4US3cË% Q*–4&1Q$3CDDb&äb)2g)FRÄ;&Mã`T5áôËõmñG󞦅aDD{\-D05Ã*ïÕJèEÍ:ƒé_ÌTU‹£ €‰JÙj¿zv<ÔWÿòè¿þö2A†ûOFçPÑcT3DJ˜u&÷±=ÙMÙ9Es³#®ëjy¾´c_.¿ÛàÕÇ­2Íž0Óô¦‰­Ã2šŒ°:½7â÷k¬^Ví<¼ 'Õ¢\‘ĘÔ"€M€ˆ˜ 9ḇò°fGP²"€Yû! 1”,ôeè£áæokï#98ì%ýwVË 2BåRFVõ!"‚ª©šê´jyQ`wVÿø'?ûnÙ¼;‡Û°ûðÅùýÍŠšb® ¨*iúîˆæJ©d§pr4~÷!r®gµõß½I'üæ-¤#î|á ¤ÛG¦é ¦•ÙaÙ¤'uâЯªžNrÙ †Óûà zïk+)‹q@ržQ‹©‚€ z„¶R#D)‚N‹HIYÕ5+!"Ò}_Æ_ü‰#d2µÇ•²ÃÖi§‘!!1–*˜0æ|x/df`€€Œ„ªTUÕr%§V=ë~~8¿—Ï|ߨšå1O?2¸ÆTÈíÇ1­¼JçÆëÓ£Ó‹6Ó%-?ýݲօ“¢Z ü{¯R[¥Rï><™¯NûØÝíˆ03‘bÄÌdû.¡#âXŒ˜LM ͤˆ˜R¨ƒ¯ë°…˜Á<#š€«=3׈ˆÔœ7ÜßnKÕRd:îTÕ{ ˆØ5ÍÛ>a¦ŠL ð°ªhÀÞ³"#0»i}u1/­\…Ëí­ƒÂ\VÕÃNcÍðq#ITG~ˆ»ãÕ)Í}Éæ1›Þÿêu e™uß÷ey·íÍŽE§/D0U1P¾:áêáöv¨Þ­éùÓ/=˜Š””¸®@Q‡Ýˆuëµä, €h¦ f"¥(2« ?nîS1RTѳ‰ª "ÒÕfÏÎ=ŘÕT§…RUûLj% ¤>¼©G“RDMmúDh† ‚ì4ûÅqszûz÷ÖQ8»þúË e8ÊïÇ™% Œa:;LSq6h0èÓ| ÝX9Tôuå©?ZÐÝë×óË?³ªå’ÆND'ª©ªá( é_¬¾~÷´$¼|þÕÑî¾çéÒÔzÑZ!*J³“ãR]1L²š™“Γؘ‡ÈÏŽƒ‰‚ä” V&EÁd:³–Ç>Æ!†Rˆ¦Çêñтù‚H”#Dè«ÕÉ‚Çý`¦"‡Ç‰ ´ä˜ $¹[›…‘Ë‹©Ú|õ÷±.MÅ_¿9> èkO<(fFu®á¬tf÷o»XÌÌ÷µ¼~÷.=Ïý¶û‹Þ«šˆ"‚M;k +¹³³ã\þ.þÓg´?^4ôó_”¯¼÷މ(4€¯Ø×ó£Uƒ²šW‡›ÜÌÔTM2:Z}ï‡_=­óÉC?$Aïˆ|ð‡3'îy–“ÃYëUÓT¹,¨ff ˆ„–c¡ ˆ —çßÍ?ÞûŸ4EÑDÀ™53{öªZYtý¢ìFaiOLæßΜµ}œýá\J)¥Ž>±©[®ZÈ’;­]y¿¼dS±Áa÷q»Z.ÃÇ·GûçÝb¼–Wª2i KŽ®Ä}yüîÛ¿þ!]ÝÏWnø·ÿ•}ïË|í n:_•äÜöã¦ù´ëŒL¹•B1ÏÜf'’«£ý Íoö××)°/ÂÐüä+´œ•ÐÌ ÿ·Ä¦@¥1Zäègšs5•[€0•Š1q¬|‘’ŸÞ»à@²Àt%j `LC4ÚBA2-`T·©ínväníÂßöó:WÕ¢­zh©KÞix¨£8aQ`Tñã(ó°Y?¡™ÜËöî/Ÿ¾¸1—p‹„ˆ&Jl9¯¾^îl3Ûâ‹»Ÿî>¾þ_ÿüõìU¸½w‡'•ÍÌ`œÏ©ï”:heЖÆÂP’oS¬v½œküüü7,ê±lP'ñÚ«* !Mw°‚©( ¡‘iÉEϤ­·Òy^„tõ©£eãʘ”=›YìdæÐ ÉÔЊ2‘ óÑ,Fļ‰G~ñð}Uvǧÿ4E®šZ ²*#ˆ9ÈE‘€CcÇÇwûŸÖã·ïÊóÓ‹ö×_ïùæ™ÌTÊ:|>(nw_Å7Ç?YÅ‹¿æáö¯?< €*z10`\.Ƶµˆ"3舜Gd&¬Ûíú³ÿÞÓë½°C$ò*¶Ê †әŇÚh:tûÿ Õ¯®/?{¹ºÁÇŠÆTÄ\s‰ßºv}ô=ig3Éë»ËFZò} f(f€ÄÎ5ýƒ¸²ß33šš‘ó„ìjŽ)ÙåÓ—ëñ·ÇUS¡¹lõñÒ‰¨š™™Ñá¶TœÏÛ$XãX×Á1¨˜ªšlÖhÁ-ŸúÓ´*³ÆY. ¨`Jc@$W óùPž>›JY%3bDv]™§Í¹^Ï›]~)ÒÔL£ ®Î±ª»î¨©;ÇHT˜çŸŸþþ»¯Ï>¿Üþüæü?ì3001@íüØn1éêäÕýÏwýÖR5øõîdÚ f¦¢Zbæ†ÇÒ6ÒyŽRÔT¬î»º‰csŽõÓ£¸Y?ŒT7• DD`Šˆf6-Øá$4D$âõ¸X’ªCS#w($ ­m!ãõº×g—Œ;|ÒÆm/D(bÎj&bU@?o °ƒÕ¡*;r Üݼ{ Ÿu­üì›ùeÞ¾ö˜´PAT±À†Á!¹À¨sGtö•ý²zºxýo¿úß2~³¼›ÃgÄ„€»¸¬öçùúýÅËÿÍøÅi¸}«£¹f#”lÄh–LjU@ômQ-1ÇJQW5Måž6äfÏ—ïÍTT%3æ¾/`ÈŽ´ˆªªL-³1ª>ð³3ídžRŒØO­“A*²¨g®}hÿÐN}í<W>m¨®Q @r?ŽÞ÷ëÑÈAŠ@Œ¹êªz6ûâýG_þQS.> ²åý6Ò"jQÍcF]Ö]I1‘ÜÕÁ>Úøj¿«~ôzÆßöQZ=|xHL iìnæOªöýÍeUåÕX˜ÖQ J1£&ò”’•Ý~T°Rr@tžÉõÍÂðøHºq¾¸ÿº;9i­ÛŠœóN{b‡vhlw¡ ¨¢wÒ¯.ó»·»Cª¯|ðL´=ú\®á§ßÿ{ÿ£þî)mSH©òÞ 7,·Å1Zë…ÞmÎ|/'’Žã@U|P¿¢*>ûÅ¿ÙÞŸ|Å÷Ahî%þf_ÙŽç(œ}k~–‹"‚ŸTõîmq}Ú·ù›ëøªdoÁ;ÔRJÊEÁ$Û…tÕÇÚÝr¶ÓÚvÀÜžÔYœ¦BÞ!*rÈ‘ƒfõe®Êr=ÇXAå±—*ot±­«¿}Àågwo`UƒPÈçT­$F1‰JSo`HΘ³»hx|ñ]†¶Á§Ž.ûº*éU¯w¹\ÿúžÔár»Ýôb+VrN¼«ò¾\Ý„¦ÌÜu¬}Ýkhôã¯v ðýMžáކï:ƒ‹¯ŽfK—Ó0u 0ÁP¦R÷ºOÛ;\¼àÍbª¥ë£5sï©­KTpv{KÍæ¶¦¿ù‹7WïÖI@p+ ‚‰ˆÙà>g)ÅÌ€À&”Ÿ™ L¥ŒQs×ËQ|xæö¢ìÙ®¶ZÕeZ-BOÀX’¨bw÷¾ÂùŒX‹ƒœ™»ú|Önn×Ý~œ~ó¿H‹¨”›Ñn­‹ºªgô«Öl) WžŽV¡º¹ëîþúãóò6+1Ѐu·™Ï»ïôÉÓîmþþIˆÚÖä¾YîÒêÜA¨‰c:=~û-w¥w< pv4RåƒÀ(ØÀ6—woÈÊ‹Ÿœª,h›Y"ÂÄ$è=@nd4s±¨Øc/βù€¥™WVGmé‡,œC#˜µÃéŽJÎ".Š©±F]V³`–“CÉ¥äXŸÆüöã^ªa{òåÓ‹”²!¬]#¹žS¿½¿£Gç~ô«UîŽ/Ž®ßÕ5þàóý·û¼¯Å¦ŽhÕ•Óc‹î"ß䪒²‡¶.cûýûõ¦>™Ë"™*òÀ­lo¼=é®¶o3hÑ1ÍjŒ#UµÞÃQ5à"¼xšÖ!½Ý$WvZ;„©­:ÔÈÓŸˆOãÕÎU!(2±{DX¡Dñµ·¬i;83ϰ“Ú¡ 2Ù¬æ2Fu² ³›øcC®YR?t]AhyÿpA·ß €lN~ðƒçöáþJìh÷«Ÿ^9Ô‚ÿe(%´=2æDU™ÛŽŽ`3ΣÑÀÎÔ˜1)ƒR*N =Å¥ìÌ’¾bÒÅh"‘I3×TÖÏÓ»ö»‹Ë“½Ð,}$­ƒâ¥Ì5çhæÛŠÖI›a9|jè0 š–¥”*¦%|³:kº'¿®DqlbÅ7QçóUyPæ,‘›Ò-´d2Â1p©`¢Üa3@w$S3CpN£0 gÞ7öð™ÅRÖéåß\\¾þÛÓ—wïŸ.¿ËO‡‡—åfû⻿q+ʤE¨rÃ5hN‚ìP•¨d›{‰±Tž\X&âÂÔ;&BZßAP÷´Á±xâJ¦2$ç“õ›®8èþÛ‘6_¿shplýý&Žɰ‰B!$'…(g$Gáº>)}êöꮞ;~Û]=‰I& !÷ýî!ŒƒD­¦˜}Vò %õV7¬JDLH"zÀܧ×ÄÐ"9QˆØ9öÌžêºraqzùæýxößþú2`ëwy{ÃáæÚ~Ú£sü祔œÈ$AÄPo IÓÌJðΊgS.Š è4`*€àÆž›BÇ.ŽÂ V Q•ÐIó0"wøòæåÝy¾ËL` Ðô©ç;T#-¦.PÉæ{h±‡4òXxä }…¿œ}}q¼ìxôlF ¢¿¬»q3Ó‹m¬0A;SÑ2ú@Š„`fr೩"•ésÍ ›F#&L^†ó\6Ãéó¸ÓíÕü%ËZv°š=¹~¸¸]ÿìô¿9m ÿ7N6›ðêÕûXˆÑù½ ÃR -Ei.æ<#Lx;&¢ ªí°-­D$‡P AAʾ:w¿ŽÿìóµþåªýîÚ‰“ÕvouÙº£§Òï2`VF%=)º½gä³+]‹ºj1{úñ„#€*hËÂíûø¤Zä\=ŠwоWE@â˜Ý¬’8•¸jx8ßåñ1<<ž©àl†&#39Ûï°q6w#ÑÎ 3Uˆsº{ú]÷ü×ÃÜ%eW¯Î/Šh{4PC®ê%aݰ"BCEмÏè«ÚCÂÊC’‰ãAP &ä“¶Xx¿¼°lrC8aqŽÉy§)0˜*’š x—a  «a·ê÷ZãWÿðŒf«† hðGu?¸±©Ä/CÏ•‰çÑŒI‘³£¦ññæbš*6"&"¢¢ÄŽL‘H‹BåÝÂÃøp«›f¸Ú¢¯´ªAa¼Ný–šæþ—G-FòõQuû×ÆÞ³©(€*QIC×Ýwê<( "Öž ¡Ä¦È¬Úoq9« eðÖ cÞ·?¿Nm·Ÿ7|À±±Ï¦jõ0‘æ¨U)ÅÈE‰ÉT±šÿÙŽ©”Rì@!æ”ÅÀlËô°KJcTv(“Ü‘ ÌD•d¤×‘×2›A:=h&ÐÏg”²Nø$1 UnˆÍ èx·é`¶j9<ã_~žœ.ËwÿÕÑÙ⡲!]ÃùIÙ6?úüÉùYXo+Ž#b’ÆYì#´'¹š/›=‚ŠˆX.": A·¡–¢È£¸Ê!PÎ3:«k–ìN^Ä.7mꬖnL%œÐ³0Æp~2o+‡ÿåýbÿ›Ïd¹æL¢èȬé·þŷͼ)9‰!úGÎuH¡)w÷—îâüý¿ýóèxX»c? ~\n›¡B;ñ0¡‰™@Š ¡Œq…¤ª€J4AÚjZ„|øÍ·4wZßÏNî*Q_o:ÿäTö±s¤ ·±4«6C9G—3'9¬WÝòv">ýUÿ-…CKfñd<5T§Â—TLÕï—û›yãêºëêºÈé¶JêåÃó³büb OúûN+²`Ù7«/¸^.¼¦b“@v— å"Düi­xæ†ÎΞ´›w÷ë]{æý&“6C%5óÞ‘É$dÑ’bÌ ªfFÕ<å¢6Á0`f&Ië™wuÿýpã^¾XÔy3?NYrQ@Ü®V®ØŽõ`\U×7}–Ô<_µÖ'WaÝ;ùƒÚ>.\…wÃÐU5BD0Q vÎ yÖ¬\Dx·_—˧G@bf—b7Xsú§ÌØiÿP/µìÆÝÝ öôÙÉõßuɘ ÈTJÂ[«C.¢€ôIõˆ– U>x#_œâîÁ^|q„ÌP œ]’%9]"`RŠŠJNýÄ!MìŸ*ä¾Û­ö[Í»+·2lëjº]M2W8 V!˜1§8±•ã0r(˜û>çÝÍ›âòú}ÿ\Æz™bå aâð ˆÐ@ È9ÇFžUŒMUŠHk(‹f¿Î¹¨Šh‘b¡ªIòÙú?ýÜ-0wÁ»@ƒãêX¿ùJäÇŊŪèÉA¶òøªuˆnVóé|¼/ŽVÿñïÏ7ï+‹TrÎ9 °;l–™ÉD¬ Þ!ÐÉVO)" ­Ä«¬úp²ÒmšIp&“UKVW£‰;"5MДÝb®éË|)÷7_~•Zÿ“Åb» G–Hâô€”SÅñ¡II1-ž‡« ºÍUÍ|ÕÌ`·)Cr5£#ÆÍÝð±+ˆÔ×+Þݹ¯Î´é&4XÛâìl¡k˜ºùíÎD®gwÖ¸äg?ø×o³_žÏS±®NuqUDqúQ§z‚ TˆœsŠýI”g`–™F™7ázã6ôä<)‡ºÒ>°‰@ -=‚™!ÂÌÄ…&`Q¬ÌŸ`q/¿ÿùq]éš©¿Û슑sd*¹äŒfZr!-‚ ‡ÂžhÞvïó³ïÑTU RÝž3,ówÃòdy¼´H‘StM›c<Ô•Èí¼+òþðc}ÒÔDj}I¼øú£>ýâb·^.áæÝ&e“1 וÃÿª*Rr’œŠ‚JL¹( þÙdºÜ‡îõ×Í‚ž÷ë‘9ÍTrCË05“QØ;K½ÕsÞï`•EÊ0òJö«ûõßl\I9I rŽÑô@‡I=\ŽÈ®jÚíý°xùÔ? ‚ЉÄQÍ‚ ÒGõaÜ^w]ß¶TÖmyw¿ÇSé äŽú>ŽØÚc©ù¨Ô#3@Ó“@GÇòwñÍ žœ/†D%¬»ý#[4É_§«:gÑŠµè$Š8¥ˆU÷{'Çáé 4e¤Ò¦¬ÀŽ)ç"ÀŽ1®Á‹¸¹•T ¶ú-._ÿ¼kŽŽ<`±ºâ™JÎE½cdž6q£Q¤Ût_°uÍGë7oKÎj¢*š ¡¹iÜ%W?¡Y@§)#™2öõóEÐ'°ˆXúPb¯5Û'Y¢õÉ7¶o]Ù¼‘—¯Ž]ÙÝï .~t·Û‡GtàÀú›'P1 “eísì½#„OÂBÄnlÄG[õÇ¿ÿÙ&ÿ\¿BuÚd‚wÄŒ*¥L'IÕÔ08‡nçG´)˳ʟ>?ÿåuÿÕ˜îê †ôý8ŽcR`ï˜ùÓYEœH²9S)¹\¶óÅö7ë#8܆Šä<¤TªZRX-÷ïGÇå~˜ü_ÍdÇMÞÀj¨7 JªèXF˜7eHË\ŒŒ&)‚ª*“)ú0Îßù1ãóêªÙ½éÿþøÅ®Tt{G%j¨ºæáéZ|}ñffÙmë º$4›`hË·òïO`?{šß¼,ïÒ¥îçåÃçÍí¨çÞ(»d„R¨JH¨àümp€$™9Ó#Á½;¦Â4*0Y)„¦Ìet•Ë´³íts黟èí̵‰!Øn57rr¾ƒ0›‘2j¡YO+zÇ«íˆ,bÔŒC{6‚yt%Ng¸™p Õç"RJιˆä,z _L³Õ¼ï³[c¼É¹]ãËÿYÐ $’u´ O·;üó¸ïÕÀT?I ÐsÚbWªþ7·ge–ëïý²ûöëàPEM N‚Hª+Ï„4é3U‰ @&ò˜¤€'×¶Þˆ˜@bï§“é ŸqVvy£:1%E¤ÀÕ®:º¿) rcfFLÞÇû´òXrœ<ê¤hˆ!@Q3›äL „bú\Ÿßüf«ülÕœþ÷¿/]?Œ ¨ÎcI{¾–¹OwZÍg!š*€M峪"æýsqó Qn†Ê5õý”ÁWŠZ!;褈A£–\ÔˆTD&ŠXåÀ>’Nú¬’Á9ÕÑT^ž5Þ2“©B¥±„ÚöY ÎAV›C{»åãÅ¢i*02£Œ¬c¦¦°«àÑ_aH(EüC©‰Sù ƪ)ó¥»û›òO~x»ªJ<{÷ÛÄIÁ¬`*¢é>­ ~p¯W L¿6–“#NeÜéŒî?b Ù¬ìú`niûžQ•˜`"=MLÑTŠ(³ƒJ˜œCS+w7Ú»Eœ‰R\Õ`ßǾ»‰P3+y*rÅ&Ÿ *±óÕfŸgõI­¢G$$R˹ZÊkÒ?ƒç}æÕß~CÖÍ©”¢ÈX’@{Ü-ë+ïV|ÿÐç*L C;ˆíѱD­–ëT-ƒ@ýáÙsÍûÝü³›aœGdÇ|ÐN+¢&A&5M;5É€Fdr(YT ÙŠ²ÃRÕ« '4®Úîn[”ªZUÄÀ´(°Àd!ð¨à<¿ŽV‘¾Gy»Á"ùЇ‡Vs€„#ׇZT€qâÊÑyFQDÍfÓ‚±*aÖ°ÝÏþ ý«÷«¾0¬f³¶+Se{€ã)º¾êïÚϵävãÃA²?É/Éͨjž98>³]<9’m6qËý{~ñâÌÙAœh@Ó|ØY‡êì <40C20S1˜ü*V¬äTÔ;BDâÆ¨¡rZ² ¤Y&½;Èr1ÇV6‹£EmeˆDÄ*2ô‹ß³½ù˪¢Ç¾‚!"1±¯+F`Fy¤¬„P©vésº©Û«›÷ïµâ¹¼‹ã0fdf+ÊUp©5žUÄþô„ò¨èÈZUD"QC0Cé6ûqûlskà[»ÝóéQ:C""ÃI7¢ À4§8 šŠˆj)Fd[k‚ŽAÄ4ÙPÓ¤¡Ã”$vݤG½< !ª™ ,ÙœUØÏã\œÎB&E˜ÜÝWÏŸ®÷·9\Ô8Ž(+@h TJ)EÍ*Gì<ãA…H°õC7?=Ç”³…•î~±¨I-³fuu ¥yl¾´tÖJê{^òa±&ý¼ªQ6|ÎeÍOžËœ•®™Çöb¶þ¸ÛÒTgMïoÃ*G „h“šQÕ&ÔÇ  wV Cí, 3#×uÓ4hjì‘©3!¢™$ô\’r½þªÒµo6)e:hñ?€E ¸A¿zõMS¿™#–¢+Ù ó½Ï>•–”~`ã\å‘N2ŠÔØ á³›¦.=˜`×;P«ûcÃ0>‹»ÈÎ 3ª³BƲ(¸)-ÔÖK˜ê¢í±K(8g ,… MŠÁYÐŽcüøÅ“å‡!Kyre«ØÊH ÞO^5H¥š»>ù€“?5a–ŠŸù’û8³IÂɲXÉá´ëß}uö·Ÿ=…ŸÑð¢/ˆª¶nËÙÉ ½)æeÈ1c5{ÐE79šqÈwýèÝœêðh©¤F „€ˆ¸Æ\ uzCºpè ëÄ­z-Û:ï¢Y&fƒ¹xŸFô`ÄX²9q<Ž®25D)ÁŠª€›:`›¬>TÞ{G yÏîYÕìú±^buÉE çœs)…¸ª<’ó¤¹È¿o2dR±ßùr R@‹¡ž¥~¿¿~êö;ž·‰2±d³ü6výjá.]·nd„²_·Õ |L%g%F=P8PYØšÆ>«¶…iäóÔ㢜 ‰¡£B0FšJF4-•%³¬~:Ñr~jƒÕ€²ß{,>ÄpR™ôÖzx‘Iy „*FÿþbÁ¤ýퟑˆP ˜!;æÛõç_,Úqxº 9舨 Äý~÷°¨k_Æî¡{yðR’c*:&ë?nü«“^t0"3ÕíÌH&×ôE‹©ª¢é¶Xï5KãC“fÈI]}@ýŒs¢Š™ X"Sâ©"ÒEÌ a0³}‹³‰'Úgª$ç1™ŽÅéÚ"A²,äS ÿ,9Òòï`uf@Œì½ãPï‡çÏ®–óÜ#™e$FrÞ“Ñ3C»j;ø‡`°Zúkó n¼…/Îg;W悎&p0SÝ0 3B3D+q,øñÞ¶zö}=êç¹%—4)ÌÓ×ûa¨æÁYr(KU—ÌŽLÈ©j΢f€|h½-1$æÏsµêZ³4Á¡ÉA5CTÕdZ…aú„h¿ó÷*ŠÎ :6CÿröÝè‡Ex§èWf¦ÄLFÍûÛÔ,Oæd9&¨sÈcUWÊ¡m½?ùR£T«E © «Û¶:ÀÐf)áô~§“ ®­Ë‹óã`Øž›„uS±åGu:ŠúÊ`jDhdƬJ&jÈЀ!EB3MbÈÌ"R­–´3ŸzïE¬©˜àà«;ÜØ¦ÊDZÒ°V†¿³ŠȦ"f&¸º ;^G£ËvÈ ¹‰«ËéjþÄ}¼'$"fž•nhg®£Ym8«SÞ×édô"¢DÜ8͈vÐï:À*€ù úF´˜ü¼ ¡Ô#@j2ùàˆ˜u’³@ö5$ó>“0V.gö–Š˜‰2•B\‰@Kœäkާ 1÷»tÇ@ªeÄ£sG SA}¨õ¥¨óÒM½7è°XS;ô;FÁÉã- È×p6öp_ŽtýfÈL)2ª¹æ w•íjàP×$ñ!²v½eM§ûo]j¶îÎ’¨"1Ë0 O‹ÅÈÕüÔÌ`ÁåR7뮫z {Fûd$ÓÍN©je0ï²1›[åÒè‚æb&„Eˆ¨ï'{Œê„uŠ×jû¸XV%ÖϾ˜¢&À‘ȸvÆIŠ(2óð>öŽ¿½™@JMÅ|ÅÅÇãŸòÁåÝzT_5ÿwâdô~ô{oüî®%¶¬ôqÞlòËæä—îöÕõùC‡3t²×ŠXÓ¬[”Tg¤}9‹8dß8/bH>fªœ1˜¼bf c(û†‰Gi5ƒ³ >MÞKsH˜2WÐ'Þ|þžäè<*  xÞÌBw|ºvcaÈBèH²:RÀ9–¢€˜Í³"ë!ˆ¤LÞËAý£œ7·=ûDþ?Û‰³õÙõÑþý«£›æiýë£ws5U[.ŸüoA÷Æ9i¼‹INŸùò¤ÚpÕì6RÚÄ5nj':õÁIʇ¥"$D3°š:­Ëj,àä}à“Âû!TR‘R¤©X†®ó†‘ 2‘Éšš9iŠªÛÆUñÍTÕ9“œrµ¬Ë®ÓG·ý¤Ÿò@E'.\|ù· $”8$K)ç¢jV†Rùq Úbâ9ÞCÑ£ ðçîWÕy÷ÍöølKS»K˜Òûu}RÞÌ[Ûmq¾Ô‘^<—ôŒ0÷åaßU«¦‰RØã’ÒÝ:qµœl?D*q©p›ŽÛì.*èH‹NˆÜÔwNt^)"¥¨JÎJUë  ‰LÐ ã0îïO®®ç¸Áb¦MÑ:H `ÒMk…&69dtb0 TÕ~{v•dŽ5¸`ÁbµÏÙwÔR¡ ñ 64{“¾·'ß5]:Ÿr óo|Ûÿ`”/jdªç:;I]{´³8—‡M㹤sAŠsp9³ÓÈ#NøPLAcö“†!”"6¡Óç~ø mêæ¬¬³z3L-ÉÁĦ¢Z*µ ùíüj÷$Ûùšqút'Gdx i~yT…=-öoîÊ·|f¬iH¸üÕ÷ÿü¬~Jމ‰]ÛýËòñêÃMb¤÷«ËýkÔ{½jÎøn£ûC.”LZóÐUd&9eLj`Z€h*­«u #‘ÔTòa5:ÈYÈDM š™E°>¶­+Eb*ªôxR«úÀPròl$ŽLGFdàJÒÕ_~S^­†©ß`ÇR Ìñ(‘8Rq³PJû›R¯Ï/~ýúËÏ»ë›õ@*)¦b8iÖÈÅUŠ–, ýžÀ‹}û&ï7yqZ§=1Àÿæm£“–D̓+"@Ž ‹*„ ãHó\é:ebw{÷òɇݓæLÁÕ’hl…œÖ$ 6—õl}4{冼ê†8Eå™>m‚O}Ê#¹ýÇûwëPš­3ÌÙ¹,"“XC²À!ÓQDDEmJ.1åƒTr‡>Õ…‡—ô>ðC³R€®šé„3€OMCÊÔ6ÝM ^ÒôíéS†²òséßl;Æ~Ì@켂á”ãÄ„ EP3¯y+•½¥ÚAʵV7WþÕ“ï|(÷ÔQÌò ªª@®#F”1çRÇÎNu÷þ^ž¦r°”¤%@`Ôm{q›g5gsõ#\ªJ•³”ÃIûöæ=3Yá œL¹LV/°Ò=ì5i=+wñdÄÚ—ˆ¡>M÷pê¹tTÅç_…'¥)DÅ<öS5hÖ q KX犤ZœÓûB1»ó6/#zéoë,‹–ƒ^‘j[Å9Üï¯ôòt:„!ö™ m,lû~ÕÌŸBQ(›û²(u»«’P#¡»»üÌä8õšïî«[\÷d³^Üß³{—Y¡•~v.á¯fiAýïÍùÊÙliÄ[5tÎ9ncí*B}ôj¹'e1K #Åáà¡ÇòôÏ÷MF×§€Íž‹ž8ºÈ,®7]î¤umꋳ"˜¬fž4õÛYSUÞ{?Á ˆ¢ä|P›¨Ç8KÄ)z'K^ßì«‹¹¯}ÊޱƌlT™M±xV‹<¹ûΞ\ÒUÙoI/Ëš}zÞÛåÊÒPŸU¥¿`•NžµóYãI¢«‚$r ÊWGºÜ¸­S}Òß}˜Sº¯{aL2¨€»ÝLöns?£` ´8žbUó^®šfňM…>1¤n»–$`VÇ®«Û´ëѵ‡Öé@“«€d!Ç “Æu*_ì $£IF6) ÌÁ$Åav´ª¹>}V£>yªPÀ׬(æ¹dŒbö¸Ççi-nål© ö<Ç“§ƒ—ª“™sž­@}ÁyÖG1ržM%öBzi¯ÇÅ?~Ñ<;*WD9“®¡|h>…·FÀ´ÝyHÚHj5&‡*fv"˜%~Ìz û§.T‘IãŸùÝ=YÛ–8ÎzBâ©ð° £2Í) UUǘ&± #ÀÄÓMò¶ƒà±×P)) Å´»±}Ÿ£b‚Ãz¢AJâf2Àüzö´ûË·ËÏÊ0ÐvÜoÕúw›ÓÜïèØ{—6ëN\½8É©{“r)JÎiŸP â.¶³Ê®»Ëcƒ|æïOíès½€ÇÌšƒ· i,ɪÝòÉ“n/À­Ë“NžÈôÛRÃÝ!PQY„bHäêY­±P¥Ûµ nÜéy¥ôVðIzS92“’èQ“ÈŒˆ–—ÍcÊáÉ}T ¨f1ð~¼ š,x‹Y r”©ëÑãÕlJ@©Ö}ýê÷–|\½Â®)X½ßÏRU9ÈÃ~(À>~,«æöõrQCÉ9ú$‹ÑöµðfXðû·§GÞ.蛵¼¸NÏÅ–Ñ$ž.àQÌç! ul#€ECFÀ;l›ùœ•h" §p‰ÉÕ̯vá9ÍË}7ópL*Dúˆ:Ác0ÉD#3#HN:‰¬ˆ²s‡]õõ.væz±š·óYÓÎÏ‚ºàг)9 ¢XDv²ÿáß;߇قZjHÛc®6@µ­Ç±7­¡\Ÿ7W×Ï5§R²Iû y~¼Pã—ݯ޽h®>œ^Û¬óÌ›ƒì­¢Šͼõõï6«9‚õ#bàI¦Ó_·ÍàþÖ9a<%¦XUWLÅ\;‡ª©â6"`uØX“ÅmêÑÀ€§ƒ]%5˜vׄ'äMpà ¦òš\Õñ<¤¾TPœ¥êp`‚0+Tmî:ÍfBõÓéízŒýUº¾~èšd0é¬í<úÊC)ÃâÌiÌgû!+0cbÚïêî_>[î¯Ã ú挱ßvŸ]w'á=!" ÑcÇm šUð!ìÛ>逵P13µ…»-¾WS@~ÌA=ˆú€PãÉŠÖt§Ëáò©ÏLð“* ‘œw¤%3dvζ™÷ŽÐLéÓN<˜‘½WjÎV””{+QRi†˜Æ^ªºŠ»ì\]Ë3·ëÖ?ÿÙ fqªöè{ËÓœúŠ·ÙW'3Õ’’Þé³ð]ÁhÛf=}¶býÕzñ½å»êåÓºúò|S×Ñ«ÇÛP'}5)‚™ä2Ö;’ø›íç•÷9§"€Dîê›Óß_?Þ†Ÿ Š äȾ0Så"Œó¡ûXVÀI+a0éÔ 9‚³P<æXT„À ÈTT‘=Ž,›1R èƒ›Ÿ\Ý1ƒŽUîÇœ¾ãËýù=qà4¤Ü.³`ß¼“u]ÊÑÅÊél†«=ÍåÚ!¦aïcSã8ªFoûcÞï,Å’Ç„ó}\¸h®¾‰¦ð þõ‡¿£ûã!êQF‚ƒŒ…€Š„~/'ûáEâ$Ïþñ³?û³§¡½)nÖ¹™Øž¼\÷˜kL€Šª 9Y œJIZ(ÔtLûÙ ´”"‡{Sµ¨¢HW¡ÁD¦£–l(£ ÉÁ!MŸbz1EAÔÓŠ¹ìe•¾ ¯¾ÙŸVX ŠKûVr§ÕåÖýƒk¶vö]»ÜSGˆÎ{—JÓã|½N´8<õÐy…sw¯upŽLÊÃÚçÙ¼:=¾8®·~5ÿ[Ÿu"rÈ «*¯›»/ž>{Ûü«?¾X¤ÓùM´“êý‡z5vå?ýæo#-Îë1°è¤5Ddž@< Dt.ÅÉnú˜ô¿5Œ<îÆ̈Ĉ”{: 04aý+X¬ž4g°8%7âvèdîûü¨H*œu–¯‡à˜ÀŒÎëåû®ß½^ÃjÄáºW,-Ò¬q›\uº†ýì¿-ïO~ïê}µ¾5‰evæïòþõ÷?ëü~U#7ùŒÀpjú)g5z°ùÒ}à)?ÝýöÈ&Má0HÎÁ¤vµR¦ «ÌR²i‘Ãga†LTDT y‹€§¼»ï^þFö³’‹”bLˆÍ|8š5ñŽnÞïÜ.¼)CíºA=©˜Ffв½Û->_ŠC0#v®¨5æAL4,ËÍî·³Ý&Ö JëóµŸÒµTFlë³7?ûQØ?\¾;º{³ßòŒ±+'‹ý°Šûoÿé—‹íþ¦Ìæ0$ˆGP5-¢j†”ÑÔ‘ÒÄOÀ¯ªˆ="Bn0ç&rP'JÏ»TŠô=ØaUĘ[.RÏCÖŠ÷ßlòýÅÅÛ²wšÅ1(±ºu…oÔ¿Ïm‹»Û]¹ÜaXïb]瘀CIO1¶GÎ_ÀAÚæ¶Õ©â,ÆTT¡>_§óÌ?|f÷Û¡ÓùºdŠŠB°©ga·«O/¹»{÷Wß»N¿”â\íÖoǧG/ÿ'õõ«a>k›ÀZ¢ÀÔŽ¢ŠÏ@3·[ÓÜå”ÅÐ$áãÎ:¤œÆ4 O‰ŒÓt rFËàAS›ŽD`vdRrU±@3oëðùÙ—;ïC`3_1’cÙ_c=tß{¯Æ x«a—ƒÏ:Û;7“sªÖÇ<ÝêRÖ;ðb¡pŽ »ê'ø›û“¥KÜïó®´KÓã™W/žJ=þéññ÷ŸöÙØ•Þâw¼¸ûþâgõ¾I÷[hý'Ã0MaxœrQ²@$Q &-üa©>ÙN­Ä¤`:á‡5«µËŽ¡â‰~<¤_©°åBž1Ry±:·?~þá›ïŸZÎæyO®°¤ã¦Yôinï:÷òôh¹F½ŸÏ\7–’R±Êƒ °¿Ï«¶ëu7+cŸgºN%6-«›5²Û4þé¼÷Kº˜9•n¥X˜ŠU²Òç–v“¿{Þÿ^óå:=7âL ]úÛÏ_}]^^þð¤ë†ŒÞ³M äbÈ¢€´ãeƒ%CrŽ'ïò'O.|Z.Ð’²†’"JQ ÇÃîä4%rÀ—£eÌTU>Gœ¹ÍÍòÝûÁvn컄žQL²’EI«þfxßílñ|ûóîå¸â¯Ý”Î.0ˆš =6r/Ë"˜æ8Ì_ø ˜œÎ¸¦ÊëÅç³ÝÕåç›7Ûáã@ÚþÃmvÞMÉÂf›Å¢ŠÝΪ?Ûæÿë/áã׫§#fžÕý}øêaƒñî¿]~µòÓ0¥\Tfmíñ??D`?JÄIEõà"f‚ÉQnÅ;MªÑ€”‚ÈPÔ¹‡ëîüÙ_Ë·KiCW<Ø/×mZh)ÆŒ& ÚËùó×FÞb¶æ‘kížPªÓ.èéðPh¶Ã‡gÿè_¼Ú®æ¿„ãóï/o4U6¹b‰Ýˆ«YéËP»Ô•ªU}ÀKëäaˆ*ù_?tcsäâz¾ÚíËþÃÿÞ”;®­Û»U³¿_uÇ{;ïŠæø¢×‡öR"b¯«3’íçÁ…akÕ}8¢ä Þ‘’£®û½Å[©ª3«ÚÆY·IG€©=ðT–²+íÜiÉ©€‹ƒ0¢ìܳy?&ûòÙiã¼'ÍB\±©Mî‡ÁçÍU¬BÉÍSb íº4u©zb7u~§ë2|ý?=GïÃçÃMã·Û»9·Ù©±ÞQ>]ìØ•Qª™/qCgu¦ÅFª?ûì—7trÖÄûö³§Ö—pöÕˆêÎÍ"Ïh7pžŸŸñz›¥YqÌÕò¡Ô ‰9%ï,:–íÍ~öY5GœfɱTË*R}ûQçáÛ‡õcÊEÉO| ÑftX­ƒ¬l÷Q$õ{tuí ÑA¨Ù‡Â¯žË›×ÏŽ2˜‚§3!©!3‚ p]ÉvÁ9³‡Ñ Ϊ¡çÓŬFjWþ.ŸóÕ&Ìþ Ì~ê~ñ6¯Þ[°úºÕ>޳TTgØíÄÓÀ%´^¡Ë³§_ξ>^)9+p¨vºûÐ7OßßíÇ&÷QÉÕsKëT9\ð£rC ¥ £ˆ(:Öt1ªÝæëkÏÈe“PS‘¸ßœžŒ÷{%àP‘䓹æq<&ù³ Té¿8÷\7àêÖ[É$îGUŸQ®RÙuÃ8Æ,Z¡õE{Ç ¥{|\[+Q‰A}ƒ\ùªÂûÒ@ÇGÕî¨]ü^µø¿»'‹–û+Ûùq:‚C¬æ•)2£ßÿ ¼ßÕ˜÷÷]u²¤6X¿Ï\÷÷o¶‹•rý6 ;ŽT´ /›=@^Æ·~¿‚ͺì§Ù7À›]âùÜ[S•b^t<§n'¾T/¼èædæ5QU…&É5þn9ðÅü §YÙH¢•³Àrå3¸úȽY»òìäýºË*EQ•…Ê#.ÎAäkê;>÷;npxØA^Çíu÷òÙötÿíoþæÿñ›öÙ¯‡WU<¶y5ïÏ.NïgM`bÖ|TûLêŸu_ú·ßv5w¦èœ•<´´­ ]¼:"©kè~Æäɰ[G'uéh)Bâ€r)VŒä„u3¹¾æGÃÇ"V9§a¾Z­GxþìjXº4RÊÊÁ[¢„wÒ’Áa"|göp³W‹bŸ°žî÷¾Êøäbœâb‰¨/uh@Ç\&s\1\Œ‚Ž™DuK3÷qLúª¤Ú}¼^½þùÿòü_?}»¶¼mƒúýü‹ãZ›ÙA1cš»Ý(i‹ÌVŠÒUZ]”Ÿ½{êf§Çz÷PDÐ;b{ÌZÍ¡!=P¤6ä¾øŽs©fµD›ê­¾ÎMmÉ<*…e ª’ú¹aõùÓêæ”ziçN­_Ó±nìÕŬ"g) O«u@4è1,æ°VîÈr½ðÔ0°cüððñ®©6·vqîJ\OyϘÍ ¨(>:H™¡ÑAš™Ü:ï™Áy3fˆq6¿»9ýûõ‡íï¯vm÷|µ†ýûÎ<Ôë}ߎ©¨ªäJ¶Í\Ð!¡§R¹gó±ÛmFöŽfÁ²º*˜Âp=TàÍísØ!ãT)¹0l¡m’3'8 Sbž"ßmÿ Ç—mîý¹›Uu7#c.1ÉÙ®ôß,^ÎÚø컄Œæ¥Ã'éóáwš”yBBî ÉÄšsYÝ„? ?Û®Ú ÈñÇfuŸ:ŠFóõ¼«{ïT‘ MFòN2úb*æ<Û°¬ïrSd¾ëÏÚ.Ÿ~ôç¿dÝnž·ðÝÓó›LÕæé½ O.XÅ÷ôº}M%Éž•;Q>Ž©ŒBÒ‚ »{±Ó”NšÛã}ØÖíͪéwÙá~óô~ü–ýBpíâeïû‡Òp!JêŠúGÌZ÷8C¬ÜÎï]³£ôÕßÀêëç¼é÷=þŸ÷¿´ú|kJdjÌÀZÐ[ü”8þ8¸oÊ:Ö*ÑOÂÇÆ}üéò iǤ†¡Úˆ›¹R01›bæÀVŒ„ ´¸ä³?îåt|˜ûÉ%OÞy1Ú:öOBsâÕÿèÛ_œ?»>ÿÈUêë5L"Ò§þ??~ÿåßô¸Ãhó¡TN‘JÄ ‹Ën‡Ëìƒ[äÁ×hãèfÁS¤>£±†lcl1Ïö‹{=òzW+:G*! ‹ã \ìêÝ:O–cîO­¤§cü?å×èŽ7¦“ãš„4£·ä†²OfS©êœK¬ãe3ìÒÓ{ó5夠â4Jw¶Ò‚ :ž&ñ<§Óé#«ANâfƶSç®»úL|~TÞï·§õ7ÝÉo?8®½dôýáËû¢é–Wí‡ÞÚ µcf.3©zÃb_ZQS •VAŸ¹@-ʹÞA­òpÁ;`rJͬgÀɈ6¥åÀ‰}F@Tm<‰AÈ…èzÎr¶G±=ª˜1•Rä íù€#0„f‘úe3Z“wÅ.1‹HTµø£#Je¸3DdL¦:6DÍ©bÇfdÞ¨™‰’ŸžêQu÷þ벨î/þdžúY…SôF`’1¸Wtû]·ó­(²‚ˆ9oQ'UÚ1e®IÖ Á\KÊ’úÖ24®t,®Ò.—±2ª :,åR/C[.ÆUÙÞ®÷û>ukºíDK’j:飌òt½ýÖfvЇU-YÝ)è¯æ—òr*Æ,¹vy~Z¥Am\?9iýg룻ˆjf'†R“R8íÚã'¼KÙfÍü®›Ÿ¤ûPs‰± ›°F·tt³Ž™CÅf`QÌ€CH±ªX¯ÞåÞÚ˜¬Z„2öm³ß·Ç ŸyE\-Ð {_ c=´³˜æíÞ¦qLS!yDç&Ö ™Íü¼%à!#dïˆAeÊY‚Èy‡š#Ö>`PÑ~O5 .÷äºÄí|æiP†¬®Ñ~;p»XÖ«“•@Êá)5dO‡¼iÈ4[Ú»÷àÉŠù*-îÞ¡¬Cš"Ë€ÉDªw¯Û'õ8êDæCbŽ¢LÖ`΢" •@iŒ•÷SŒ HÕb9ï¢X¢ ḶxŠªœf¢ àtV„=ŠÆ}/¾L ^U®+F ¤§Ú IΙS1PÑ u.y’9á'CcL`üFW?½}=ûp´¨ gãi”$âð°å†±¾Ýt}Rœ"dT'Ž](c¶‚•‹©2³¦°é– ”‡±/½¿¨ð¢é\!TÎ"3¹X»4S+]šÀ#r "’…Y•YOxˆìµ?fÏë-¯»£ãqë\Ø$Ç>æT€[?èÉlëîîCõpG ™ ÐØ‘šã<r)+€I+ûíP$°fÍŠd™pâ¬EŒØ”ÛïØ@©—Ú7ø÷Ãî!ÎjJ]—±bò˜kÑÚõ£¶›ˆ "FSD/#(ˆYÐTÔ˜Òæ¤u4”Õñg z¸*žu·fšü*@Þ[Y-ì½9O†¨¥ä¬ŽSˆŠÎ£Q•tîîãŒ\Éä* ’S$Ìc çåahé=8¥r¨ hò¨q€ˆªpt 6³€ûf¾”ûtŸ[w{gîôÜÃü¸-¢¦E€ H D7ÅÏ»¢¦ìuf†ÿ‡’ ­“‰#Ç¡r]üñÃÞC;xS5vNLEµM…ÊÑÆÙ² šç gAUò–©Ú­z‡§doWË÷r!ÛS’”/Ò0Í$LŠÈERȱ{ÇÒû6\Í.ú}py: †DUÉuaÔ¢¿Cü’ ’ekG‡â6/6Û@áx¸¯Öïÿ¨ÕïŸÄÍõg?ýͶ–èCŠ\ç¯`swô*Þ7©Šœüwç¯Þï œ‡[gËT\jÓñÔO¢ SD*OŒ ‰±wz*‹csR ¼ên­­1#1“Ä^JÎì§Œ·ƒ ;U)dR Aj¶"„Ô¯Æïì¨{÷ûiSnäí=š–bä=¡™?¦;ŽíIc8²…ï3CyÜß™¼årþÿÎËȱ‰j.¦9¾þKÉãÛê¢}øPåkî—÷ÕloDJ*ˆ†ÁC7r;Ÿ/æÍ6éðÞ}æN/^^¼ù+ZÚ¶ós7~2åÓ¡s™à)Rø­~ŸØ1ª<ÎòA3ï³Ì÷»—OËÞå"@|`À H‘Q²€«}ŽÔ4‡ ©6Ŭ©Xp.Ç.€=}yöüë_òòù˜”¢œÃÉMÈøLìrD:wP™žY$Jì5)êÁÎøé%69ν‰!–˜ý?ø^“sc²§W³4.ÛqËöc¯E\í"¨wŨ®K?ôÔžuãò3Ù7.JYüÙ¬v·à jh}LñQt “± ?†¶R‡¸ÛÉò<¥«Í£–b8É2É Z ¤@ݸ$¦ŠÌÙrVë{tU5îšâWÃwvàWë«WåÓ¸eb"ÂeÄÁ8øã°Róiº} €@Œ±L£,è·;+Ç Læ É¢|þýÃ.òönˆÛm5—Uøðj¾ÄŠ8–‚(B}ÕÚÝm×Îxu¹zŽçwoÝÑ>WdzܕúðèMl‹”RŠ‚C&ÐÇäC´“˜Ú4ÊO½î3kuñô×Ç2¯0碖Ùñ”cf )f3éºiŒ…¢W¨vXßÝçëÍÿøÕ÷NšÍ·E‘PE&¿!èc¨;âf²Æ*-¬‡ˆmÖ,äQ$ŸE¯IC&êE©ýßd™ÁílþYóË·ßûÞLJLaÆ÷ó†UuÜ„àÉD†‡Ü¶v»[÷÷ò›¿¾¡êóÏeL]åxª"""¹(Zùw>˜–"È; mLí¼¬÷W»ùó6.ǘÙù˜™ÙÁAóä ª†%#³É” @¨Ëª’‚Ôš±Áé…ýÃz§oNgGÓhNÕI#ð(­òeÈ£y3gŸvVN†ª3Ò?½†:¸¬€Rx~yòëoêÅ“ ªY={5²ÇmýÑUSv«A㉋–Ý.ÌmÛÝ‹ÎR»‹U÷ö—N†ì‚õ`ÞA¡6y¬Mt:Ȉ(Ë$,:è§h:³ÊÂ÷þþñjÝîaÏ2šÊdൃ>˸ fÁ¦à C-ækÎmU“XAm©ÀýØÿ×ÝœÓ1‚‘iöÐÁRH ª%fDpÚQ“ s´˜¼Ÿ`fT1ÈàÙ,¬ŽÛöm'úrsõõÃ1ܾ?[Ô8fßnöâQÃ*€"dZF:=Šî ýÒUcÚ”¥£/QŠ€ó~û¢'SCçɦ™Ñ”Å»ßÞ6UîíÅê'?žW+Ú±¯kNë+G 9Å)R†±€%õYÔŒ˜I³úŠ2`åIÇá.æölLïô_×ñh½h˜PUÕ´(;H+qÁÙ|`@¹£&jAÊYQÆâ“r?É¥ Ç$FÞ#V‹ë7xßú«»öÈ¢{¸m¾ þ2>£¡˜ G±‹dR„–/.à »ªŽì>|¨xô²¡.[z­þ½äô ¢è*Lɪ†ÿÅžCÁ€b€¨"-–¾‡vv{öôÊ6K‰áò66W¤õßn_í¨jž&·åE¯ãÊïKC㮺t·4‡y#C6oBP_ÆuzºƒÄj×ýþrPfœ*REçH‹ ÈÊ™§|¬Ñê—]"U€ìCbŠ:7,®t6o_¿_ª½ûò?ùkôœ‡äÆL ®&ï†×Ÿ…è„N÷%ìfcËœG©XÒ£xöÏÅ<ŒU]5kLÅP¬  È1)aÙï¢•Ç `¿«¿øÜ¾öU5kV¯¿}HW±{rv|R'˜) T«ãîFáံ5 J¡žÍd1Qœ-(Ì+}w»Þí÷}¶åpþüfsrðwƒIÉY¹ž!3HNåW¦jäœËyqÚ8) €Îr6¦C$¿)¯Åì*Œ‘^,xõÙéì³ÆIÊjB"ìA!g1³ÃGzù¼Ew‹ÆE_yǨ*ÌS>Ò£ mÛ‡9æá.DåÌÍç3nêÊ3pŸ5OÂ_§ÆW§gM6-BXæuÚjMQ‰W¯ž6ãØ×µ3C::9;ö‡™ÙÀ<ÓMáhäaº:¦ÑÏìëê³ÿŪ96®ðX´ÈTï<Šc‘ØK{iÃpµ¾ÿPnRíbW¼ªZîK`ffF»>þÒ½~=ø]sþ°‹mÔ\ôÓ˜Nx”¢TiŒƒè>60b‹þ¦÷œ{ڣ¡í¯s.%—RpìàèØî>–z™_B¾`wïš'çþúWk *F0>~ñ¬Ó˜CU§}.y‚sÈJZžŽÝ²öcNÙû¯mµá§÷²C§áá:ΞŔ•«:r…Ýö¥öî=ÃfójyÍ郕¬Sj±=JŽ Ì ™I¬[?—+ÿdÜU0¬žTXˆ}MÎ;H1åÇ„.QªÚ`qg¶÷c ¦wä~øìovUào–‹ŠËËÏÇ_½Ûï-ŽÇ‘¼3"USqmûWiöË¿k].ì=Ó´wü¢?|Œ0Ù±Ì$çCѪ– ¸¦Íoïa¦£1š(:o9Éá`ÜYª"à62/V9DZÛrn]—ƒ·€ÄÞ§ž¡kÿäÕó]wý¤Öqˆù” Ó•‰òÛïwîùñÍ_ÙóÏ¿=~¥mk6sÛõ¶‹”$cËâQPчeLfèúÊjt- ´p]µMîøÂ(ÔÐå¦}ó±B^­ºÛ2´†ƒ[h‚;sç•ýwW²9?—w{vý‘ÙIûáuzrÔÑXˆ‡èÙL¨­±X.Ï\¿¬4-ñdÁà† ±ˆóæ§ Eš¢$Œ!ÄÚ"¾kׯÖ7èΚþέӢÜnǦÇÉQ$B;Ú?[VÂ¥}€ß;^çõN›YíPáÐy•Ø'ª*æ'KÛÆÙÛÓc€öå«'Õæ»4O÷íþóÃr%"3U>”üH ıòöqXŽgþä~öáD%ƒ³ˆaý$5om¾È=. å­µrz×¹yŸÃåò¨ç‡¸ò&ÒåÚá‰ݰ=1u¹W)H–Ûx¼ñ×å´1BS/à ˜ c&Cÿè!GUCãeX4߹،$~–zJ\ÁÀA%ŒÞR“µèmpÙ?Åo–Y{Xêä.Ëê]D \)Xh‰›X«/6[‡y·íÓÿÂÞßÒç¥LpËÁuf*’SA^ÐZÎg·bß S£û,CoÞ=Úcà0{ Û\fs~û ìJáÜ`t'%s½ •~”A±õû¡ w–{Ô áœ’'€˜£ŸÕ¶~T»]<ÿìüÿý [L!|öôlPEÃ#˜#ìŽÏŽWïW/.ÝýÖÏ kŸlÑÆû--?ºÐ!i=øG²ƒ‡Q:=Zµ×ï‡[ù¸½·QóHš„•ƒˆÉŸ(xG`:<„’ X6jÓ3ÊÎH±4Î>æJóÇËFðìÚÕñ¿É_¼àˆí¤WD¶n :…ÉWúh²킆P¶ÕÉǽ[ä1+Nƒ¦ü8R°3ºåøq\Ôã¸Ñ*xŸï$7!’óÁi14›Ò´‘'Ì›~è7~±{>\Ðl#„"ŒñUSÊÉóG]iCc–q ¸Èß.—îG§ýww¼¢ ê 3 Çø8·`ÚV˜%ƒC÷—îAÔR?BPS XèüË 2SÑÇ,3³93ÜÜö9ˆ¯Ï4eÕ"Lk„ª@PãŠAÑ$΀l«ÕClB¡aj Ñ™> ˆä”œCU’#ð¾êªÛñ)ÇÛiàû0l¶B ô[˜bZëa›–Ð~¶ùðËP7–“s8ޏó'ñë¿ÙrH4º2‰âMe&^ýÈ'a÷—·a½ß”1ÎTг üÖ°>©)úPk Z¬†u‘C/m¢*b¦Èí‚ûN¦6`êÛn‡ôÍ?Y}»qÛYJÅ<˜·­ÖÒg`Bl¢€šIËæY¬Ó”G8¹ÀÀãȉóûó´hî°‹áêó[#G¦8xRÄš"Æ–Æ6Œ¡Þ·¼+òìºî³^ÞÛûõ^]^¿¹¸ªÙ1¨Þ,÷°º…?µïÎJµ®ç›’P¥.ä0h´£ñ`)‰ŠXéaÎT.n;+ç·/nµNÙM#TÁ«}’%#1#€^zLæ›ÆéÈ– Š˜ ñ»\ÁíMÒ˜‘‘*U5`矴Lé~-›»Rçm ‰ª b.¿ÆžœA +¯ß½[œ=ƒoÞ¼nž$;ŠwÒøÔ LÃXȧ¢ %öy6”ßojëR™iðgç?üƒ?û^%_œÏgbäÏBµl›Öͽ¹ñ6æ)#€Ø²¸Ê é0lâ0_1WÁišì]¥t>ùóúç°éznÃä~c—²Lƒšˆy*€ˆÿÿuýÙ¯lÉ’Þ‰ÙàîkˆqǞΔ™'óæpGòÖ@6YdM ýÐ/ÝЈ‚ Уþ1  ´ @ht“(tuYU·êæœgÞcì˜ÖàîfÖkÅɬ¢´ßyvfµÜÍ;ï÷?¢†0HkTrìØR9ˆÄîätA¾œ–„žS7Z©C+Nªæv½ÀjUrAQCQü”¸ˆ ‰"ÊáÝÉO_¾ØVϾ]<ßÁtº†f¾Ú¹DÀÞ;TÕÅI{œ¶ûÃŒ±éýÉý‰{†çJ•œã‘¶Sx¬÷É=Bi:šÐ® ƒA‚˜$y‹mGV*;²”,C$ sÍ¡ÛHÄÙ¸ #GÆ—ºOhRÅm…7.¨í9ÈnõËë“âexÉ©R&•,j&B¬ŠÖ0¸âª¿|&ïðÓ€"@¨}$ä釆˘ÓÐ2á>f=”‹“ùü|¾¨g–&é~}SOéK+©9P_¹6¯Î ž{0,ª~¼¼úKw¶pß]./R [ÏÓr˜ØJT`bîæSlΟ" àM%Å!¯–Ñ Œ¼"•œ-u]Iæ]îUÚ!`ì¿!‘(ƒWBÍ‚d¸I·†ýo{7™rs»þª oì«]S§¾ØãœáÐ s5@róÍýâ‹ÏNµ¢œŒ@‰(mûwóÛ«óÓfs™L:73€röè̤ZNâ62*äªt Âm=Ûz./ ]àš5÷É,µ§š¾»›5²YÉò|~sèOò.äMT#fÐ<(Íí{°pZ^CÓ{ØìÂe*‰À€Á;#Ô†2 %‘œRFMÐ$—¡k9ȱ½!’%‹ªwtÌ©ËIck:+À–OÍŠ:¤èÅÅWËÙ÷òmÁÇ<$*“ºž¦”ÕÌô ·¶|l¿?z вÐ\-ˆmߦÊ-œ5¦¢Œ•ßõxØ?<ÜßFl¤¬]Ûº|>·}ZÖ»P;kúÙ>³ó^÷õv»}ú‹I}õ‹rþÍ®õ{5*¹!X‹P“Ò¤‘Pï77)*ÅuÃÃt‡iH nÀª:&¨²sÞ‡@.8Tf_ÔMÆDCíâHu˜×Å”€râ¥M¦‚ËR›6»êðçûÍÏþÙã ­rðy‚G€AÅè=¢D«–wÏ~ÿáwMqïQÁ717ÄíÛúD¶E8ŠÅt˜ ø”Û;©ãàäÒ=pÌó®©ÍÉÆŠ.רqÉÀžòôâ³ÏÓÙÇu×å}ãî+³T¨cÝ A…Š– ·mĪ&AçÓÂ1³sfˆ¨€ƒ¶b|Ù Â&$ïHÔ±d2CræØ9vΉ ý,3#vEå]]¼îÄô¦€þï^=úùgŸýáÙ?8;ðƒêÆwCìjÀœúý¾uCn®®fÝ·“3ØgPÁa(Yµy·•“çÓ]³Àc@ÇXs†~+¡ßزÚíÐl2̧gó<ž¿ÓÓNB¤âVˆb“(üðè©üíûî¶¹_}ÿöÕÇþ¥¸ÚcÃÌ b”ÄÀÀ•™'mŸçu˜Ï×S2¯áÐÒÈúcPÛGÉ}Û40˜ÁÍeñÜdLZ³£Ü¾‹øß„E‰©©ÝT`srúåôùÛ…õšZèîþåËí”_JS‚Z(¬324Ev$BN:(±w‡¸;µ!Ôsê«âú›ÿÛÃí&ŠF“\¥8õÑÛ‰²èIì|ß”»³«~rñUùù¶üöÉîqË}öópqwÞÜõ7¸…ϯ·Ý»ý?ülƒýf‘Œ–bFL`iÌÙÉl gÉÝÉE’¿=¥ä¡‰DÌ`¢ Æ&Àä(§L.SßõÅÙ®uµ‹† I>ÞûZGÚ9àÿžªí'æ1N÷°_”×§‘ Ⱥt¯—_l×Ó‰ô=:é‹qÈn0¸‹4¡C±’{óÖ€,†ä; N•>m÷š* \ ŪÙÒ²Ø{æÁl’Z,š­-Þý£ý—ëòêñIó-²|¸gG9Zè Ìwe îéÖíùw_4Å]úÙ´Û? /}*w€L¤Ö-têõ™è¢?œ½\aï(ÃJ4NâÈ€ŒI’ÇLÖšŠ²Ã¬È“;^‘$FE²rwÝ번'2jzx曹ßÇspÌÃLC‘‡Œˆ,L9³€dðID²º|É©goîZ1TÉ)+Pou|j‰ÉR2Þî\±Ý†ùî|w³Z]|›íG%ÞúÎË^­‹è¶«ÂúOåÅÛ꣹|µýí¿<¯Nâ&”«êt¥K˜bk€Ì˜¢1Z\ŸÎ벨¦K¦£»4+ñQWr„Xø’|áÀTyPrÓOãÖLRĘJê…³/„ —ºÌ´šÕ·7˜ÓnßÏ7OŸ¾mg›‡Í!ŠöYUÁr–!T™D‰, ¢©ÂÞ±szÝËp%ÏjÄÌ›ÞI3Ôœ†æw€–æÕ©ÿþðÏÿXv;8_´¯ßqMZ±Ë™§·ù|r8Ìÿh¾¬d¿Ý7Íd6ËwêyŸÁÂ;çÈ2æh¼S!Œ‚êµï%uûcPdJŠÌáx6§¾*|°>R€CbÑDÍüŒÐyÊ}Ÿ÷£_Îwo6aIo’…“´]on®åqU]@ν Ó˜A:lè¤W"!;ö…F( è‡bÁÐù¢ òáÝM.H£R`}4é¶¼ ÷7O—³¼»ùL'F³Í¤täBYeckö|±îf3êîo^WåN&¸¿ßáê™'0r}LŠ./]Be_ù Ó¹´‡„ÐÀ†ÑŒ¢ ÁÁ Ÿ!DSÁ¢ œDRVS¤äè½îž@ÅÈ—\TŽ g©o›ƒãÁjѼÜå¶é…CÁb{ºm>»Çì|á il>˜’`2 ;¢-=:›K¬‡B À4Ç®ÑÅùg§‚@A«’-E?¡íÛåþÊ÷í†öÕ#h"+W·W‡`½ärÑ7Myí1#lð1D15ÓÔõ¦Qƒ3£²®Šp{±/‚®§Ã…‚œctP]uÐ.îö—œ³¢+ëÄNȧÝ.»àf5éNg¿:o[¹ÏF\Ÿ[}éHMDU€‡ˆ"@*ª©ç@3fKÙD)”%ºÂCR5äÍœ²/NV³þVÈ{Ð,·­þî~‰ßü³_¿þï‘y}ëÊ>Ît½&íÛ»‡åì‚îZU]CÿðLwWW)Ràrúp-6(É1ä>koEE¢$I Èš}'Ú7½‰ÈÈ@!KIGt Ž#:s`"X”A]]b6w\,Úõ–i»mpº\`»KõÂÇ{\Ͼx„5ö‘êÙü2ôº{Ü—ž,¥(ÒwQ4§œúV‰ÍˆMбfEF3WÖ“¯{›P)±#Ë„H®œ.Êí]×¾{µæHú˜§²§…ÜîþáåË/OùöÏÞº’õÜßøL5©Å/7«_¬jK©•úò ®t7»+V÷9×YÑ1jŠY \1i¬¨º’CYPOE,ÙLDšú>ÛQO×+cÎTÕzˆå¢”¶8Æ­L´_2ƒÆŽ$ü/£û¸i?Üô­#™ã›vò‡aóÕ @DW;œæµÎA‘- †öMù¹ÝMM $õ2§lãíÈv~’Ê’ÀYöªª(ÄdI¡Ú;[½›žéF¸Ï$óÜžOþôêÏÿâ7·_}|'µKà´#FIH¾úå‡eûûi˜üåÓ°NÓ>ç»Ùå÷His}¢ª ýúô‰ÝÊÌ탇$Ȧj„hœ˜@{Ç (‰ %ˆXPr1cáѺÀ)™TWÚ®zo¦T×îწM_TŽbïg—ë¿>̵ÊeU:Ò˜Ù‚ä¬@ùä¤peêcêw‡î>=-Cáßˈ<õÚuóºé³HÖ!3MÄÜœê®èºaÐAv°¢{¨«óù£oß}æˆæ¶Í(IÈ¡Z­¯¿[KïÞÙÖ=ríŒ{Ž wmcÌÃDZõ¥“fWrEYsJ¢’u¬-²‚t@P0™`Röà%û‚BÞIL …D #ˆQsgÈ„€”sš,ªù2Þ}ÛÓ~år±ÍCÿBG°:vÑÈaî»9Ñq&3,å˜k¹K ±]WOORçW&Y$e!ȱ<Îh ÓñÄÚàD„ä0½hêv"x1ê`’eZÒ@ÈU!´¨}–©'Ç”)[Y qjz$1‚`_Ìó rŒb*£%fpµ[îJ|ˆëœJo±Sǰô½ÍJsOÖÕ"î/ÈYÛ*$?D÷i.ëBwë·)Åí=\„9 Ž4»âhD$²”‘ˆš‘)²3êªÐ^¿Ýûzõ´-W%P(&íBêÈM ˜³‰±çqyÀÀ4õ¤1ÐYñr‚™ƒ ô¤wð^¶³jø5’Õ£IÎ Xö+!v]Š}vN÷­PYº÷³y¦`LwÓœíÈŠDÓÔOü}wëª,6=¥k©py+¸ñØï¯ÙbDÇÄØ¡ö˜÷;-O¯Þâ£g僄`ÑÊîn&­KŒÙ¬r€ÎYªú‡¼¼(öû@EÑõ™ËŠÒØn?bWÇ€"øú¾ýWÒAëŸ\VW¯?Zì8+ºïË S7泪!-ƒ)±öG÷ !%v ë`’iŠó‹ð7[¬<c?…Ã9Ö$H7Õ²:]õo’ .écñIì–Š»ùÅ«ûǵOM×l[ô @Æ„šÑÉ4hÀã ©iº˜S6ôÔo[s¥¤6Ö%KÌ\ɬ쉎.U"°œ#sXÍÿòÛÉüÂ/áæÏê_ÏÿŸÃYÌ:М†hR3zèÙkâÙQ]-9g®!Äl2Ô¹Ô6Óç'›aƒÓœ€üh5é›}rئÊ;²,FG›‚Á0’ˆ=]̳/ ‰ )`¦‰¾û¾üeÞ>úÌWóÐéÉÓÕgaªý]A$«ª¨Š2!¨ q¹ &4ì‡ õ+k{tq·ËÒÉs2§ƒtÃ3#°aþW`IB_ÝÎo©Û&îÞ–Ëa·úµL-ÉMÄDŒ¢èA¹ð–‘!=‹+ƒ+<"ûérõäêOoš>¦,ÿÉʆì ÛÔáì£Ê Ž>”%ýª¢†œNv/ïJGHŒfàƒmÿéãýíöÍ×ýiºÖíäý»v±šÍöÁœw:þŒMcJUE5ÇdÎyQí±ô©ãe‘¡ ÄüÐ ùB# úèÅ#qÀrNT6óÝáJÓ~ýòdõ›¯ß^ñ,Ý¡ú(Ä4à‰Ð W¢E‘Ö4YDd-*td }×Ü–üôá$ǘÿþžÅ ¡ Ÿ­B|Ðy³ÄÑ»4Ü- Û®éÄOK"Ë!pÒºMß¾xX³K·¾êæ³~ý»¿iqw˜®#š²ñ*`#†h ZV@ô‡œéª"r)êuÝRË–ÚóÉaÎC…¶ªÀÓYÌe·œ–ËÉ"àFÔE.çÅó ‹zóÁg˨}›ÇÕž,1´kT[.ë¢^o‘½G•̃WþýiXPì$,ÎnÖÙ¹IØôÃb½? q„èNBó~õ'¿ª!¢‰ti½wÏ>8è ÷V_O~õøÃ“ÿñÿ•ýôÈæ È)6Ǽé£8bÙ€ýç ©Ï&ºíB•îîmï¥ÂE©IÉѨֱá?~‚÷…ïÖå¦ÜnÊùìaÑ\ü0yV\>ŠÅë7ÿCMÙÛvm'CH•©ˆ*Å0½½ÝÍW‹]{;‹wski¿³Ÿ1tm9ËådêõþB<ˆù*p—÷~å\±]ÛƒÔÔ(F1“  ÚH£Ñ‡é®ÜÞ4·¶:õÜïaÂ’=?|Ó<ïŸî6êøêì¿ì6¾^lç~!I³gì•M ’’ó ª®è:N7Wó¾\z鿬ñ`óô ç—%û¦åŒÞ_Yö›èƒ @n[¬@´}àB/9×k­í¶ƒþáîɇ¿¬Rú༈MKè=`µŒ}oåòìÌyOªàˆˆiI|ºèv°íëûß>¡öNŸÉU;ނ鮑Íͳœ30ITT ï1í#X4n2yü„îáÊñ}åý-žÛËWeî1 û$…²ô˜Î¨ßW…ëÞ­Oÿ¨þ÷{¨0ŘRÎYôòtÈÌbr„@SºÂù:N.ÅšëCöÙ>N«æõ¤þÏ}þûCášêû ÝÝC^.µCŽ-̶>æu©Ä63å×ש~ô<¼hï¶M'»6¡) È`sOmŒIaŒ-¥®K –º‡í]î~7[7uÊx/û¤¨ê ßgEFÍbγÅn‚1“C1{øúEƒ'…C{Ÿ•>ô¯fÒëÔHóp”¡%ÉXcŠT±ú9~Y ¤œæ¼tïL*¨I€XNNúZoßM>¬îÖ83ò øüòÑw“»ÕGƒéæÇÍáb‰w8¶VÙXXä^ —ÞíW³Ûï÷ Ý,²¤~ˆŒSÉ0BÏó~Ü:•˜‰˜ïöeØ|ðäÕŸ/^x¹¨oî–Áº>¥fKäV§wmÉCƸ):L½ºSxØ#7WY'µË}µ¨IEX³8[–n¿›BUYÊÃp6wo9eó°k‹i¯7‹)í;ï÷ûCT3ôn¨¨{%2Uós¸oÃæuÕÝÆ“s~¨œŸø®çvoýòŠßä1ÄûýÞZU¬9K6MÏ3•œEUˆ \ ~jËŸÿ榮+&³¾ÙÓ±¡4ŒX³š³v„h’ÍlÀ¡ck^¿ýõúñY3³Ûñ.LH µ;ä™ÏÕÍÅ™_°“4=Ï!w1ç”Ëmœ´j@ 9çAØ Úï•_§ÎU4@ô!HŒÆ®’¾ëS{vÛ0ø6˜·ÛÖØ±;Ö=–%«Qæû·v½;ʽŸ²’Ãýœ>»°OnŸ”£¾åýAÄÞÝDJK<ôÅÌ5cËÖ€ØäXž.v.滕«!lQ6ÐЫfÔaÄ0È+ɶít’ÒìÛëùbj§ýìæŸ×’½º²žŸN?šo“»( ‰AD¹XÇàSçVñÅ'SÚvšúx ñÚ¶6™à}¯)¹ÒuYU ñ dè)µP…(ŒÔ¼ãÒövD¨‚+¼#ÂWpY8D:€?{ô žýò‹Ïž¹M¿Ô|ØóÊß>oonn^§ 5¿WES‰‡ƒ+Yý¤¦sðLÄD¦HÚ%*?¬þâß½j*_ªlʘ²¨DE„®j†D)eÃAvÄ´ÕzBí¾=ùù‹ÿ÷¿t¿›ÌÎ'ûFËÚQµšCV»Ø£¶a@‚ÞCR`‡ î&ýü}ö|Õƒih†² Œ{«Š¢äth5k”²@Y{öÔE( rx°«§¥zßwÆ™çŽ954!?+}ü¼šQÔª–[jtYÝo&;œÃÇÅ JãŸì[ŒÄÞ36êì°Ë…£¡^#CÖ¦§°†ß|qxQN—# ®²ÔëP΢cERQ0e&&}ü¼êÓþEürñ±q8ûlÙiÈÅlYÉîºoÞ8¿z#ÉeðÄr¬r¦´›œX¼½5œUÐîZ(ާaÛ¸9w™]l€c]Qx4°é|BÀ$K÷=»¾oÿ¸:ónèþäœE ‘™MI߉Jª]ûõwÅVý?~û·¯ö!´þãúë·Ï¾Z]Ç——kÿþZfI¼—¶-Úw×18SSUq„ êfíÍŸÚO£%¦)eŠÂDÀL jC’ºäcŠø¿‡f/„›OðÙüîÿSžç6OÖìæqWo?\Ÿ_Ù,õ¾Ü9O&ö¾o…b„ÒuÕdQiÓÆ”}ýgóÿM÷×û :Œ¹ªgéÁB¤·Ó>&Áà@i´ ¡!‚f¹ûÓ«õæ-;ËŠ~"ô?•!šY£uY-~¸ý_|ùVžªÛIwûðy~Ò•~»7ð’µ6Iqj1XgAæ¯v¿˜î—¢Ì9b1Ä›š² Óƒ¢¨)½üÍG‡kAq£ÞÓFâ1©*þ×…×lˆ‡Ï½êïÓ¿¸»Ýø ìÛ X1iC eÙµ5oܘ2LÇΧ(²¦8O¬ëû8µ‡týÙ¿þþUK–AClÁÅžÝÃì² ¾ï3šH v¼!š¨sQƒ¶y9j[ð˜ ?j~Aµ”æ¬þÊ}þCy˜Ü,>øêЦñlyCg®Ûï–JdÑQͦÕ‘ô\Äý½_Ÿü“Isþ%ãtÔ¦;cT9¦À¨€ÈöùE³N<¶QF^‡!’©ÑŒ²anîíÛX…oåÐìîÖËêtºÚöthmöáBă®IÑYãfÓ«€çpQüðåmÛe‹íŽã!™eAĪHYû”D^¾ŒÉGÈìv4MX€¤Œn ©ˆ¨ŽG¹Ù?œÈCßE™<¾zE³IXþþÛØôÙ¥ÛoÛNUÌ´écl1“O=z\·wï†Ü*e13ÈÀwþ‘ÊHîÑLÉÞûü߇,•žPc×_®¦»¯n ÝÚtVU‹ó_\âÍ÷æ.§rèú&Cçé˜NÇL`@îpØ<´\úi6¿ÿ}¦€Î°”²Tr—ó¾‰YÑ…1s;Þ&?­à°‘ézç ç,A8úˆÖÛÍ÷JCþÏ1Ë8XŒF¨yÄซ]ÆÑ,ðÞ76ä=ED¢öÖ>yV'­)”˜3º¯šÉé…ÙmjRY[Ÿéé‘ß0žìZ0{N}Là{]ȋ딹„Üd"Âtßw±O”“ pÃ÷ÑΣh?bßH{]•¥³œRÁ{¦#|ˆ‡ljU—™,ô:Ngoþ*|ô«ßnVÏÏo»õ~»ÙŠçžQ%Ǿë–âÆÛ½;4 ­Õ…"ÇÈo¦’EÄ$¥¬*1Éš7ìPÁè'óÑ"†Lì0cÒŸ,¯Ö•»þ›®æ“ÅÓéþúáÅôBvý¤Üopк‰Q†\>‚“Ý^b&”7oŸ~òìñÅ$°õ™òšg“‚Í}2$Bb}FË¿‰4äXïw«“)€ 9çxl! ‘¨C ‚IõåÝ?ý7þÛü©ÍùÝìÙ×-R¿OiΊôôÙ“iµ(™LÀ9¦€.Äõ¶ ÐGð” êVf5r~¨'RÌFê¼&£q?’Š€DsæiM–´‰ìæÕClvÍnÛøù>wûù²ÝVóÌ"’åf‘Äa߃¨EاRìéo>©šõVƒc‹q}ñìñé¬àXVUéi„_áà‰¦Ì3oŽQÄ~‚ö9ÁfªåÌ÷}y õ®~ñ¢ý«öQÿí£>?±¦éTŒC…ëû±/œ‰±'p}o¹Ñ ¥¦ÔÎ]ùŒEÁ„ì|ðŽ 5Åd¤D9ÊØIƒŸ,‚âÿ LE¹ûhÛ–›gw…u4át;«¡•†í6’ `î} 1A"Òœ%Èa‚íf5é:Ä2¢R1€w³›Í½¨“$ c4¢r1ÝÝï >ê‘/c: ·‚·¾Ùuªèeìïø/dbT£S9§î–la‡“oßawèÄϦÛ}c³>öêD,àO1`EjÃÉ<ŒsÅ÷rHÚîRQ±grιÑ¢1Z{‡€ìÀeä.öQ|dQ\ªF#Ìíuñle  :šPh“1KŸTeŸ³A Œ@Œše v€ Ú}µÁXŽTDXMwkÈ¢ÀL8NMÔLEÒXJÒÌn’Ã; eÇåÉI³iR³•rU:Bèbþ‘Êù“àñŸ1V'!& G¨¬eA#®¬*Ö˜Ñ9Ý1ÚÙt˜uˆx4j#g p:-$FÉÀ{a{Ϧ`ÊÍÙó'†ÖŒ_.l³Í2¡ EéPDtÐ⣊õ ‡–\VtÞ3èÑa”E ˆI°>ÓÔ'µÜe¨Š‚ÄŽO?Ūæí-¯úÚöþzf1ù2ï6÷êj´m2 ±7$ÇôÓ˜’¡þÞ<ã›{ ïNÇA³ŸL\l;4M1çô؃÷#«aÚnï.;!"P3QÈDÌŽS’a¯¹t›£NX"½³¤ÄÇj&f2 ¢¤”‰z$ïuTâ£ibAëµ«äØœcž¼áCŠxCDŒž¤“E[Du×ÝÝ® '³‚Sshº®šŸÌ‹Q©ÇøŸ.ÖÂ7;¨íN߸lÀQÆdÒ[HsÂáUóÍžá543 ±]£hâ]Fßuˆ1‰ã4à<™(ð°XªntÁ¦={â;IFø£f˜² 1Ò€ZN³¦U)¸¡×Û§3èmßZêzEÔM“ €<ŽEø{?[™.ä¶?»ãË¥Zz§}ßD KÌIÉ9b3PÈ!"³sUL]S¾rŽÞdƒ¡¶ËdfïÂ)Ýï÷}Ž­˜d#TžTƒÄMGBÙ0hpˆcnÇ€D¨'ÜdΙذô(=ëÜ“Ã$n’Š-²RïgìB3dvžLúæ>¢S`4%?šÏÆÅúqƒ7FI™FzÇ0Æ£0«¢k¼K#ixC¸#Ki*–tü¥cËLUrÎ?¾×ƒ0¼r–2øêŒiµÈibHhTÖ´_7YÆ>Ú¹b9‘‰Žim¨Ãi >–vèÙŒHÍÉØNZpß%¡¢â}ýFé*rŽ}2B çƒcМ¦§µ¢4í¨fã-ßç®Á<¦ª’ÅBÞQ»ŒÃ“¨–´ï@˶d#²r,`ÌrðUUh5!ÊïQŠ0öQɃC—NEAS’ã“Í“D!<&Wn{—(%bB˾#“e!‡™FBùÎb–»ˆ›ioŽÀ$Cî8gI]é¬YÖ©ŽÚ@ú05dÔ“ú²\¼9yÇ YDG…Õ§€ªäœÌù1•ŠcÀÁ2(3 ø¤ƒ3r¼AÛxƒ(à¼#LήhL•±cótB¹¡¼K3ËY»hì(w׆ë¡ ÈH lʬÚDrÎ9a£6eìÉz¡ Q¢ ¦×Á]Œ ÛD윶)ƒ/½vÛÕ²±Åã=±w6Ø-GvŽT€»u‹bž™` U8æ¨høÃǦö¼w„ãÆj0îqЗ¢Ž‡A wÞµ ®nd¶Ôw9‹žcPçÂÌžièZ#ñ(ž3„ù¤ô¾˜ÌMe1dó^Õ÷,ƒ§0›ª™d÷ ™‹Q:CQÇâI=ë Ìj€–SÖî~{X‡w÷ÃŽÃ^ˆì=ä(`»\¢…!wÞ1£©JJ1g=~Ójèƒsá¸Ýä!P 1&â);3'f@ö̃½u€Ò!9È1Ièâ’h “ø‰^ÝÇC‰ˆ‘*o9ƒ¯–i´Ûû±TÍ…$Â.…ãiXø!¿-ƒcËÆªƒjo˜ õûÌÆÓ:¨1[‰9£w >H©pRÓ¨¿lâY}r;ëcÊYÙ‘Øù6fU ue®"#eËIÉy?´ÕÕthËt1öÞ1õ]cÊypC G Ñ‚úl½gCç‡Zuàµà ë6ä²Ù©iß›/qØ?-ز<$-2:é‘ÅäÙåCÂ_Þ`±Vïs*"NcW¡®ve ï’‘Åh¡BT%iµkT*@DÍ}×< ‹“C_µR´ Òëz‹)Í’WS¢œÝt¹¾úî+¹|~Zו/|L½CÃ,ÁŘvZå=qÂÆ™jÊH –[>qÅ`yh;äܲ,@‰ Œorî=GÒú4ÃP¢04~ÙÐ ¦ìüšìv̓8ìx– iqðþ^Ài½öOâ—ÎÖ•Û;Ì‚(N"ÖtÕÀ¤ ^»äJŠCä(‡ö-ýæçL£ÚzÞòöz›ÂÊÆRUBF‡*„ä :L¹¾\î¿\=ûë8<[;‘Àm‹Ó }×Å\qj#Vsö „Éhøÿ òC±&û´i5 Ž›91¨0Š¥ŒËÒiߥlÄ„ƒ•p¼üÛûŠ“H’(ðL÷}µšqëk&T1$xß[‰Ì†ÄÌCCAEÖõÓÙá¾w‡³º[U²¬ÌL9°A½>%*™ÐFβZ&4¨Oçý×Õ5 M*²œ©‚+JšÈTq8HL³è,K5™ÎŠã­ È9%SñŽÇØ ÎSÕ¡ƒväØÂ±ô'Ij ‡€ÚnyR™ qCÜ…½7ž23¿k¦Séxêvï¦é°×l9):6dï4Z—±ë ÑØ²ëRµX}8yùŽâåî]>}~Ú9I…ĵ‰€&qmGJ9L¡ÛvÓÒÚˆo]§hF¨9› 3•×ÞLi`{#Èe ëF÷﮽qC6­¡cP´(ΗÖw™|Yx2É9'#Ö‘ü8öZFPÇà:žVr8Ä™ÃÅÏι¿sE¢±˜?VÃÈ1²n›òWYKrgƒ×"kD§M#üz»÷LÒ±ö © ¤NS)–øî*;H$á„޼ؽ…ÛøîôW½ Š&ko¥öN&²¾…o>žýßß½¿W'Áæ®K`€LÒ¥h¤ài¨výå•ùùyo!ÇEJ`€‘%šcaˆ‰œÁ‘fs£oåxË„H…Sðlå´Šý„˜G›ËÙs|‡²ß˜‹šÞ4³U„|ÝÝ{D}¨¹í-ïÏWà1Tô‡\N¹StÃÝ™uß…Ž7¡ëÕe»ÉÍÛKnš_þöôeÌÉÁ"eèzá‚ãáÐÉɧ•†ç5t‘ËcÎ9cᇽÒ‹(…e{¿³‚Ðöî÷ßOžòf(`˜G-ú\±ï3ÆFEÄЇç7c%0þ§”Ä\Z³ï‘Ùçì›»¾)+côƒy†ÝÜn&Oü«éÏ~ýìb~r†)ƒF˜£vŸÓí‡ µVÕœûÁ•mÀ@–ÄùAà`*Sxs{ò?À?þWŸ½þËï=fõ ½7˜ö£†ª§ÞÿíK\å&×ËpÛs]yvh:L[.»ìs6`÷ˆ&Yä¢xÀ_þ¼ÔYddI‘#Açë(“¢Éä,©—ÑÆ\`Vç1£úÞïQ46ÝAk4—˜# f#h†±s΃Øi(ý‰_ÄIA¡ ÿþ®»Ùn¢Ä¨¦~ J½tÛûíVLw»p¾Ìë(ñðd)×¾9¼ïÚ=~^ÿ»oÿÙóÉw/Ö—SçxŠNÖÂs=P³±‹g“ƒKÿñùÜ…|õî0=¡¶I~xˆìÅ@’Ðqý6¦G—V”·-Oßúé–{È®ïNrTïÄh}·/¶·ÿ¼9ùáq£ÖÏ$‚…‡.~wý«ÿÕæeñvùùuÜ¿Zñ®šÊC §“ØÈP’tÞ»¦ý"n¦™·køyg^“h°kÒ×§}¾Ò­;i£Òb*ôr¯½³~¢Ååum”wçˆ}\Ñ¡Ê9`bǹ£ÒºërÚK£_\~EËû-÷³ù\ÑûSs»?t)Å>e…èæ'ÏNÀ\=çí èûãÝêdZÃ6ÜÞøË>6?øÀy×ß¾£üÙ¼BÏÓEgV:DK?>üôƒC¬÷Ù)¢8Ï70Y¶Õã?˜m÷·Y6zIÀcûû]vU\ͱŠ( Qq]yPWÑá˜t±Z–ÎÝõû¯þÌ?+ö¯óYp»6ß»× 39•Mª$º›LÞd~ìß¹zÀZ•Ããæ„Þ¼½<¹ Ìsþþ»C‘Œ\e‡:@êú¬ˆìÉÞg Ñöõ/ÿäÙÕ̺äì¿îsð‚®‰ÙØ{ïî¿›ÏJ8P’HÉ4&ueÈ{Ïγ©~ü*–ëÓ®ÚdH²¿“O®o²Ip¨’Eú>¦ÔuÉUËÅübѸmSºß¾¾º¦#UcL€m›!,ž~Ê<؈‘اèi“&ÔìbQY/ÇþÐn·µœMfõùY·«fõôúíæN«zá¡âÖ›×ÙîR_"v 壓XÕu¹6N.tYfýÍý¥y•3ËŽ—¼Ûu<ãÎCßF(gßÓ}‘ø«îéí×/Û¦ÑHŽ[moèåæ½Ká›â²f8¸ÈT]QM|¨fÓîfzª×QM¢ ?ÜoKcBÍ)‹Öõd:©êI“| IÄí:èÜ\g«Ó9™3GmLz¸}w³þìÙ’SŸrŸM ,³lõdé‘\Ú¤ÅqP:jïbHëWÛÉþÚ¶ÅE}>ÿàŒbËçuûÑgîñǧ5бcJU|{ݽêÓ~‹t÷‚7íÓâÕËù“Ëní?ê;˜úf—Ë»•óyé©Ñ6 ˆD«‚uóv‹ïä|R¤PíË~;©#;Ööáææ_ü£Ï?ÿÎÙw­­¤F]ÛEårBgoª›{sžUxñøáåÍéÏ«¦މØyQQIJ‚Ä‹‡]‰W]qûËOæ- í¤Ò!ƒª®>×Ó–Î÷STõ¥“^ÏyÏýërTK’ 5‹³Tº7/ ¼»ÆÓÅÃÒ¯ž÷ñ^.¶Õ¦y´æ§ÓÉl6{ÓuÉ,™ƒö.¬@»æñAôÂgû“Ýÿùÿ²-:¼zØ÷ýÜìÒÉéɦì5ô»NlHÖ„ÔÓß4‹²Ñj¾-Ò¥5v 9öè ¹}_ÊÉÇ;¸ýUJ÷}è§`-9GH–аšºÃõÕÆïªÓÛéT|Ñù‹Êô®ÈfõwÎy Œ„ÆA·ø8½<9¿‰Kå³îþ—7/ß%ü?Ù‰(s,÷òé*ìn%p½€Ã¬@y—Ï5¯¢+@̉u*Ë‹øª¼Îl¶ö¨º»ÜyõnWjãoËɼ>lê“MN‚hÆRáCž”ÕÕwüñϧß]¿9½£6•ÖîgxhÎ,g¤ö´üe~ §{è0GAWÙYšû”³n’éê±Nt;Ç÷Íoýõ‰ÉÍ£k7Xˆ¢6‹æ Ø4kÕí½ã>Oüá€ß< ÝåœßÎN¤lûädú‡Oysé¯7PVrÐ"1†þcî4@Эû`öfwÛ§ÐÄŒ&)‰BR³0›Ï&bDÙ¡‰±'h ÏJ*ÒÏ¿¸„µÑ}QÛü4¬¦ ½>|·2`'Íǃx§éûø³Ÿ}¸ÚtËUY?¾Ä ‚ýõµ²BQÁÃ}ý ®pOxbý&¥¦évW´ŒRa=õ<´ïÔr ñÄýÅ_|»×.D ¢\þ„@¦ä"dEhY´Škô'7ýÁÅ‹p‚TMºaJˆnÎ>ípËŽ™¡Ë09^½s5嬮šÚ×*û1Wœ[âU£»†)†I«¾,±¹}UlNÏwçõìþ¿›žmÛ°k›u+Xç]šŸÃUl0 Y\ýÞ}2u÷â˧ûýMW0˜?]mn‹ð'¨\NX\|þG.–e#ºñ˜1ÆEáØYÿ·ï¾¿éú^S¹£zÞïN‡ßüៜÿ|V:S#~¯yÈT¬)iŸ5AáR.ÝÝ]ù”/³ÝÊßòé§O\¼÷prŽéä´ôqg{Gˆ<£Ò¿¡³HÆvÑïÃÌ©ó‚ÄÞ;‚YêŠIî &W„0vrÔÈ9¦ÜèdQÈ>ÎÏÚ-ã!UëT4Ñá²%¾Är´vcã¡khŽ»ƒ«ƒîl:íR¹œ•êbG’¡8sê¨MõOˆCäœ69YÚ«!3™ 2æÄóê¦ òw5«°ƒü“É´©iÌš”±j}õW•ÜåUûýrRÞÀ¾» ŽÑŒ<Å(ª‰#‰Ñ%ÇD:&ÇJ‹È÷ U,fÔî²rÓRXžâݺÜÓÉùDe~FÏ3úPÆËݺ¼[©~~óòûɤˆÕ¢¬æÃé"XÊà𾋑 D´¬êˆà}üÕñÀóº"ݤr1f RSÌù°ëÕÐ…€© 4fÔ”!Cî ss÷»¯þòî‹g›+ĽêC ·Ùa0PC*±Ùã¢l¾Ù_þÓÇëío²6Û]¶·û?z<_•š °ï›è‹~‚›…“²žÕazñ¼˜6/ÚQP…äºj¾“âÓéËׯßb—†¼.ø‘¾ ÄŒ Ä ©L‡zÒ5ð´ßO/Ú^,i%6„®•;3Ž*1Cæã”ÇÆ, bôÓ 1öµ5uYA1© ïCU/Üî.Ïü¦w“Э7ÒàOˆm·Z³­û–ëÉÝ>¤G‹¾¨dÒÃ’’ËGá nx^ô‡.ûG};íš“³Îl·;<üP?©+¼û: ˆ8ÿ¥¾8]m¶Ë½ ï§x’’J÷Ã×»¶aWqâ^K !UWÛÍ_t~¾l3à{ ù²àÜ™"!9ÜMlÇД²É¿øFê¯o»_4wÅÍ6»2 RƒH>‘9&“. âÿù,etlâ(¿ý¸*7½¤ºï¦íÄÄ5ÙAçk8ŒCT`v¡Ý|”ó‹‹ß~ºXÙ®˜æwgá!­v£݉!£*vRL(FŠ\B“ÇñžðƒŠƒ¬DƒF“Ó1ËòG'ÝЖ“a¦|ÙåhÏmF!€d %æfÖÔº4Íà¿QsÉ…uóTïl¹%~]òîñº^ß_”û§I_Wç·j.Ä8­ZS#ööSÆÌO‘Þfm'ö»V‘ÀÐ…Q ƒ„AÞïÞÄ,CÐ>±…'póâ×ÿÙë퇷/º† Ä¢~à†ªŠPU]ƒ²ÜÞv)¦”æ({Ïö¾ÍýÓÍÌ4)úà¿hÊBÉêï3ìÕ€½C3@¢(ò—Jf“äÀÈñ–ªùù¢˜]3Mžnÿü¶½Þ–.‡…W-|·mÈÌpôþ'‹!@²×æ€Ù 'pLA’å8jêÑkFHViÔÚrñØÝþM=[NÊÜ» £¢Uœ÷ŽÌÈ;MêÔLoïÑ·}Ý÷Ä äý®ò÷kÌ ÔáÒ±-/O+Gö÷¿dãàQÕ*Â,ÓÂäAŠ`ƒÐÝyÌÔËA{¼»ó]÷ùLhE1SìRî{!PCùÿ³Xˆ f'.ö±L9wòÀ!èˆ>À¬Î©:Ì8‡æöjõüË?}:ÿ¦Z”Ì £± ááÀÂPÓœ²ÈÞgÁÃQ‰DC§ŒÞ‡Yÿ\DSE•,:_Îë²âÝö£MÑ‘¦,5+ÅtÜ+Laì™hÙ³ÇÝC’¥î7ýô£_}ðÁ³åÜ'i×?«G?†þÿ^¬\nHP‚v™¼ôÁÙƒe‡:Ú†EÈŠÞ¡hö溛“ëâS}àfÞï°‚LCÛ‹ÝÈäro¡` ÁÁ´ôÎA¿$Œ’ݙ醧 ²= ï‘©`¨Op¿Í¤íŸš™ˆPÌLsʇ‚«|…ðwŽ‚5Etf é´šOk즧þôôíW×ï^¿]·×s½œ†á#ŒæÌÿdÏ^CëkG‡‡PveAfÈCé1iPD%c&BU‹9Ÿžó»tÒ?HgÛõ&lƒp€³€!T ¥'¡/UjÉFíÓ0°÷úWû»{ÒHm “eï6Ñ~º{ „2¦Ê!+em8hçŒCÓœr"'´B?­R¦TÒý„µœ-j-'ÕdY á1Må š¤¨1pLIEND®B`‚rgl/inst/textures/world.png0000644000176200001440000012537314100762640015546 0ustar liggesusers‰PNG  IHDRÅâÑœüRgAMA± üaÝPLTEvÑÁ|̯|ÌË}ÈŸ}ÏÞ}ÓÝ~ÅÐ~ÒãÈߨ»€Éµ€ØÏÍÀÞàãà‚ÌÙ‚ÐÛ‚áäƒßÙ†ã·Ðá‰ÔÉŠÄåŠÈžŠÖÝ‹ÃތׯŒÚގѵÅàÓ©‘ÝÀ’Ξ”á»–àÇ—Íä˜Ôå™Ä™Ú°™ß¾šÏ©šÕï›ËŸ›ÙðœÏñžÊŸÅæŸË“ŸÕóŸØ¬¡Ùü¢¼é¢Óž¢Ø¡¦à½¨ËìªÄ“ªÚ¬¬Äé¬Ë’®Èñ¯À‰³Óúµ¹íµÇõ¹ÇúºÁêºÒ¼´â¼ÀŒ¼Ãõ¼Û§¾Ñü¾Þ«ÁÔÁݣ¿ÂÜžÄјÅÒÅÓ¢ÆÍ“ÈÃöÉÈþËÁ‹ËÃùËǖηìÐÄòÑÑ–Ó´‡Ô´’×¬ØØÇ˜ÙµŠÚÅÿÛØܷ•ÜÈ•ÝÕ¢Þ¾óß­Þ߯›ß·ëß¹“àÀðá¯ØâªÏãÈœäÂðå­Õå¹¢å¿ôç»§ç̤è¼ìè˩ꭼ즾ì©Ôì®À챿ìÈõí¨Íí­¨í¯Êí¹¬í¹áí¼ëí¾çîªÌï®Çﴼﺲð§¿ð¾­ñ¯Çò±½ò¸¼ó´µô²×ô²àôȨô̬õ¯Ïõ¾ðõ˦ö¿©öÉ©ù÷úÀÛü¼ãüÅÂý¾²ÿ¼Ãÿ¾çÿÁæÿÿÿá–ÆŸ¨ÉIDATxÚíÝÿ-É]×ùwöj` J0"¬ D]`‰Ä$˜¢¨$3É#ÞdÖ¸pAT"‹+PÆ$\Ø ² ?'2çoÝsúguwUwUwUwU÷ëý€ÉÌýñýžï9ÕõìOUu•n„B)3â- „BPœB!(N!„'„BPœB!(N!„'„BPœB!(N!„'„BŠB!(N!„'„BŠB!(N!„'„BŠB!Å !„'„BŠB!Å !„'„BŠB!Å !„‚â„BŠB!Å !„‚â„BŠB!Å !„‚â„BAqB!Å !„‚â„BAqB"^!áí"„ 8!9 þŽ€€;!Å Ù¿Äžûs¾XS§BPœ”¤ ÝE'•9€6|%˜]µ¸ã/ûé4BŠ“œöìÙH¾ú¿ú̧˜û1o½»˜hýŽH¡&'„ 8É¥·=Ƕ#Ž/¥ô/ÿÖ•Ï{?€NAq²›ØÃ_XbùY”Ä@Îñ5¢gÀŽÌ8óä„'G>¬—}!˜åug#ÇcôDg$Oh5×!ÅÉeøÌTöv»´Ò;¼ÑèÿÝ móÇnQ*îæKú/QÇvBŠ“hX»ólϸíÛNNÍŸ¨ÿ÷ùÂ9Z¾ðÇn£?9ë8µ|!— ïAqrhgôì¸Èÿym_0µõ«Ô¨w?{6üáí£ ¸‘›â–~“O‰ 89¢¢8Nqß×9EÍÁå;ʉ1üÿŸåñà{ÎÇCPœìÐåC¹÷R°’l2Ü{¨À3ü”?/Š“Â ‰ÉîÚiñH÷ ¯é„†ûÿXžÕµ³í¦9¿[ǯ¾xA#CqRH4rsþ.Ýv Û ·ïãzÊúÛcJÀ>NûÝíYöÛöÐâð×R-cˆÜšø¢ ÅIÞ]ÔòÜ´µŸæŽ}Sã< .c7µîùÄ9ÍvŸq©¶}a{Û¦}Æ¿‘ð³‹ù•|¿r'¥tX«Ìœý•åEÙËå”#ça«ÑR÷´»ß5 mù3°ßu–wÛeÇQœäÜq-³ºª'Œ´4ýº€_q×·1 ¿’~€;Šø2?€nÄé/QœäÙi-ŸVÃlërô¹êèÊ Ÿ‘oË}‰^¾§þ—ÛõþR‰^™ÇP”ñô¢äHãÑt¦qPœdv…º;+?o›¿g_»=äápQŒëí¯ýQ^düß/ûIžæ=Y»â|ºÑoaçNÁÅÉWéÌ5g…N7-ß2®åàªE¸¹#{15öøW»2ÛAÅË3=>¶“-ý-3『â$«jÜèP½É©º×'iï¦ÃÿÎð¿ý×ÓÝö—xñJ¼Ç5´¸û·A1ÞÈ;—¾$q>4'1®ºñö–;¿9rß‚|eù­«?i6>¨T%4C×À8C奖î'Çûáw9Š“×Üâ6ªô–mYºÇöêkj-ðœVÖoñYFÇÿ²o;~œ8xor wÄw[Üñn¡8Y¸”–ÿÄÂNh7÷žÐëÏ›ñ?Xo¯iënšÊh¦–š{Óê5£ð㌭Ì>ë¾<7²óΠ8±êæ;X>ñt´]ª»RŸ?áÄj}ð3箋½¦—Ó9ŽV¹Ýª¥m3–/ßœÒäm¸å4Þ'c[ Å—È ¨fÙ<7è®)Ó®3ÊV<>ó¬j—º4ÝÑÍófÅÜRtzþâ çcDq2+³ïÞÒΉêÁ2ô9XçÇ͇4mV¿ÏˆxßXÆÍÆV³>½pÃg÷¤%(~á«ÄÉóŠB~t®ÉÖõìÍòôÅ]¯:ü¬ˆïòª6ãÏÐññÁzÕÞÜ—¡ø¥ £kâÒ‡ŽŠó®cw¼#¢ÃgÂ'W;rŸ.³ †9Ž4¡Ür7Çhe´' —‰†¿G`[úPÖ>š9>0y$r#0ÿØxÀmx÷O&WxƒžQœÓÑ xñ߱Ϲߡ!wG׌ŒÏÌGj|ÓÐÞO &ê{ϧ ÞüÔº›çyJ×t|²ãKÉíz4#nA¼ùS ÁýaרóQ¢øeøžÛ«ÅÿQëgqYM¦›ÛÏ>YµLi¸…Œu”€²¼\Û,³ârŽ$á÷ŸO´nÌò°™@ÅÏ/¸óï †³F_Î÷©ðuæPŸu½Ûâœ8ÉÜðù‹yºCëh·Å/$xÈ$r¼q߇×ÖúZ°ÚZ†—½Ø×Q§ q½Cù¾´ÙßtîûÂÀ Š_IpËt-Þ‡amýõå£Jªa1cõg«,{oÀÛòy¨øFϪµ™Ë³¦¯Ä—?{|éu,/éåŒ_ƒf–—ÛE³—›ŸïÍö,V¨­/e°&ºÛ3n¹· ¸¯¼ˆ©É­[h\°Ÿ;¯ý…æ‰Î–KÇ˵dõLÀö“ øÆO{zJ˜nñí…FnTÐ7×oKÃnPÎíÓœ8›ëúÝW‡{ÂY¯Éæl¸F)Æm_°ˆ=×<¼T¬ek‰?Ëâs¢ÝP¼ woBåx1ÛòŠuó±®…K¬XlR#;{—ÉtW·:w›¡=Ä`lÙ2I|©‘õ‹2~*½¬ËýåõE”€8Š—{7ÞÅ£=¹ä¹÷¸ectâ͵ìy®Å[Ã^Ú¼Þ~°Ó¶ëͼJIεWä%¿\¬*ûþÊzÇÉñûÿe÷#;þʼn³`]>¥Û1mÌ^?³i2@Ùs%¼Ö<1fY޵Wó?±æ,ô-ü?fåW»f[¥¡ña'ÃP^Ä‹rù¸4zÚý¤‹ôèRR´ã_ŸÂ |›càîaòÐçÙäû»ì¿ÔVÎZ—CùÙÏð ,°#"~,‘ýhŸí…ôé9z“¤†@ }¦ËyW­ÉnìãîyÆ#kÏæWÆóvž ïSo†à»üªÂåÈøñݯüZswÙB/Kz“ķÃz9ÄñÙ¦%笸YÕ;·x|K±ß›xÂÅmâÔä¹_¾3¼íXÉùïä´㘌èxßç-Ž´?p?Ö8˜l(éʤIÝh¸Äܶ]ù¬áösÏÏiZ—®¯Þàe~MÞnoä©ï;åç(žïå›Õ¶Å-ScNkoPÏ㜑·ñc9–‡ýKñœ^dwÚ§ûŸÎíž¶Qš}º\Š`ø‘ïÚ‰-}dŠ<ÛKµ”H3"<¯÷ÆÃñ™ê(ó{P<—AöøÝøèë¿>­¬gÑÞ¶í*ŽÏ`Τx±ŒgÕ¡+3Ã3änË&s%ÝcÓ¡ìÚ¦Réíh»î=}þløÛ¹m­X¾ãƒÍn¸ ¸Û6}Üý"Xþnͬ E8á½q›ø—²úÊyÃÏsšÙ;NÙéé\å[ƒ÷€GÝ­%FÎW^Q~ÛÝâÝAq»áÝbûvY IÆxÎ#é ¯uÃÇ/æÀsf¾Õ™;hÜYñžùnä²ãVge×Ùž?eÉŒßÄ­^9--Ç ]ÚSŒ”äöžçða ûo¼8ñz\µßsew?í~}';3°dÇÅpcux–˜4{ß±¯àñO'Uì·§ÿºg½üèS’2¾Òñ…«apËøêq=‰îøšŽëoéì’£Þøwxi~]Û #<ϱtÛbÔkp˷צ-å;wÆ=ÔQ<9âŽkp|øÌ™ä3;©+ौ¶q5~}ðeeß¶•b|áÑð¾ÓeõBKñx_w¾zÔÒ©ÄV±*Â×f? E³q¾æf+i ?ç¢zú”Ĉ¯âÏÜ{Ý]ˆÛ–¯áãgì_Ý|(m¾ªÇqãsžîÝàe(žbe‹æç»+ÏåÚ>»Ÿ‡¾0 ¹W–Bk˜Þr „â "¸ÏÁcþ~ö¯XÖÈ÷Ÿ¥|V™ü®ó¼4Ç=cêãuè ¼ 2’á)Òµ8Áî$~ÇÝϽ÷Á×ìëvÁl›Wä=et²•B(žñéférÞˆ¾t÷§òZ_…†GkÈÇðgvÃíŒë¶PÿSŒO çB)NðD‘¹OŸi'ý°uNû£ûÞ4xü1 O±颶AEñ’®öu‚OžC3ïí6kzÿ`;—trÊèòXºmJ}ùl–øËQ×~EžÙîwd®I¥Ûlu¡Ììæ•â!Uøcâ¿›(¿ÅVGq.÷•‚[v.ïï¶ûcDµ°mñÛ/Ò퇬+ã¼WÅ-”07ÞÌêÇÚI…xÌu-’e{âzôŸ/J‹¶”ûƶô"î3lšÐGq7(õ=B¬Æ k?{67¿tœéddÞó‡ÐìM¨[Ùc+ø…ʦ€EêæÀ•xî×u²ÇËk¸bt8fƒ³¸ÍØd¦ùÒ–¹þý†Óëb¼ˆŠ¼›*Áñb ¨¸^,(>Ùw|r¶õàɇK7²¾õðeÄWž_Šâå]ï^ÃÙ+ ïŠ^ŭ߯ó‘&¹|WíeßÕêƒ>ó‘|æ¥PŠ—ex4ŵ„xûXÛ|É8Ø—ñÅõ Ÿ?ÖëÚ’GÝoïQüœ;÷7õ¡~IñÉ_öàXÏž Jïú5(ø:þÌþÄÙŽg¿t™*«ÇÎä¼­`‰zYˆGš׋9Ä{5ÚÁ…_t|p2õMö¹¶ß\§íÅ(N/³¥(Ÿ¾{Z-ùÜΪÎr|¼èÕ\h2-°áeß4Øü-í[ß/“”OEn.˜Ý†äv_ž¢×,â›|vSÑ‹ñ™Ï¤»r>Þ¹i«ùr—ñNÐÓ¼osK»† èÙ¦,íø4=Ädî™ó›û¸” ŽKÕÿÝÌ-ד6ÙæT·ÜŽ,uÜXdza‹¹…úÌ<ì´8,ŸÐüIÞ×S|æ3‘{Sšv{¼]ã˸=¢"/y±ÿò‹Ž@¸Ï¾­óuöü) £gän›^®±×¬öxÿÛÏ #Å©OÎ&e,Ó³!eR¾Ü2Er/³šù{—F|ì¸ÇÐE¼=ëò4ª_þ§ãü~Úä|CúQ?ÍOñéPAœaƒÑŽ­i?ÒáDŽëч¯*îf`_·î¨çŒ~ÛœóÚ'/Š–M»¦Ó_\Þñnêîˆ h3[Èžd×ÿp¿Ä;ÊOñ(~<gg¸½æy²iÔW«þñµýÞñŽBi^G7K— /ëÒÐä!èNò—_VV«ri 7¿ãBBEn¯¦Ë3î¼Í9øÙöéÖÚ; ›µ‹qv¿Tžz¥üâ|r˶ÕFW!º4`¯ÆŸ¥Íhdžȟ¦u'Ë£·jk^Êͯ\r^¼c»:Aûå—+·õàûñ[µâÕ/?þ5÷'N¥%ÄÃD~¼e/tɇ͊ž½×¥Œv¿@žz'‡â<æÙFMíá]Œ?“æÆ ðŒ™÷ëlDùÃ3ªÞQ Éà(3Ûö™·%2S¼yT¡]ë]›ÝÙýrŸó¼G~ЇÕâz±÷A¤$Ò*¼ÛIoù0|õÝ^÷³X'ÔǨ͗~r…­SК6…Løk´™{ìÛ¡,ÆÑm›»\û 3Ù>*;ÚÕ¯„çüž¾:EG|òì4Áñ=+ÀWêѺ€ñ䯏˜ ú6Š¿¾âsšnmjœzà¸ú¥÷_­æ»ojâoõžà­Ü_übÏøt %ÃjÜ·ÄòP‡dïZ–å0¤H}ÁìgøFË‚[jhãìn¹*w¿ÒxÛêoûáã#‹5Y§¾gVô§†±w6µÜdäx Êe¦Àûèµßv½{Áë˜åx¿ô8Ó·mtΊ“€uËýßîV±ä¹Î†xCùmq>vTg¶Bw?ÝÃÃá白úã?n6ùN273ÎÎ.½>ÛœºµÅ˜‡þÞBæÇcÖà£Ëa°ÉŠmŸ•lN?;à·nèü®²›ïñ/š1&Í}Vž“ˆæCNK[7¢ø¥†›kÎÙ`ŸMx§Í.ñž×OS|ÖÖÁ#Íæ¾'³ðe¥»VŽá¸åh°õ¨mà¾]IäÑ_ª ¼ä•ñ¿!?[ä®ÙvŸá‡n”Ò/{dhxãø°“K©¸ÿ¸¸_=Ó®…â—/Ƚžl—ÿš û%¢Þ*>,-§^©/( ãŒ{OïÌÊnÁÍKvϽ[OEŒ%Ì.Ñ›¨f{nJæ ¾ÿy¦©zå¶úE³Ý*»rz°âÜñ/:Î#I±àú{cÁ«£Sõf\“VÈ;ëô¸üÁt|0B‡ŠO(¹äVŠehÆ~Ú̃ Ÿ,ìƒe[?'ñé€ù{~ù“›†QÂxò]Êð½ o¦§½Uã<}²Lò3ü…ùpt´æ#Û€çÊ;É}LÃò³2.o}WUø±Çê|zttÓReØž*¥ÛÈl´èýæÜ–eüIX«yÉÜ£Ûº’íÙpI¹}u»\¬-#>Ë÷hH-[†_㩲ÑÔÍØj}õ«_í´––ì®¶3.÷Ik>ç±|-.aÞ~€&ÉwP=\ã5MÀݬW^ÞO³ˆ–Ÿ†Rò]HíkÓ,ƒÌ¶I{GWã\^o)zŠËñà¹ý ™}:½[ýî3ÌT•Ýœžü2ËÑoõ\v3æ=Aü«äfCÿ¢e8ýÅŠÒÃãÎ,ųþ…i<êSå;Úé±XÉÒâãE|Û72g¡¶^ÝO³‰n;´P{ô ¶ÃãrÏÏl÷“´kažL’Üà ©‡Õ;ÁµWµ}Ñ|ô¶7¦jò¤˜ZÅ+È¿¸­ëµ¸‚MÞ­·ílG“_¶Û‡Ð{ -Œ jR£SŽŸHñ¾Ñæ-Sž¢øyï»±ô¯Î&™ã/¼ՖDzñƒ¿P'‘†î·oFŽâžÏNOÖ¦üåñZøPÄŸõ¸(|MÚhz]¾³ãõ¨¾B6¤Ÿ]Ä´g=~eç÷Oõ|øW}â1¬¾š/[o%×j¸LV;V¿±LÄœ€ß8`˜ãóâ9§ßGTë¿D°âÏæwœ-Çåü ÿ±#,Nßq Ÿ"þÕ(ˆWŽoš€¶+>ûÊdéòÌv$'—Ñmì´²Ù»­Ê#ƒ¦`Æ—§²½gŃßô¹vžÇðþo¶ióDü«©–ª»¦¾5k{6…8•‘ÔŠo?Yè@ÇKT<”`çQh÷1o…þÈ·(–ƒø~•¸Ç¢¶ÀõQ9º•qÙFóLWf#äÜŠ¿P×Á®ìgÛÈ­ÈZܱ«jø¬û¶½æ6nÕ¢°]uÌÇçWðm{ Ħw+Û")n{4{“â½Øæ^†N.ªxwM­›Ã¬̹„âmÝü"¶¾mÚnMæ4¿ü߸ꀕÛJÇ“Wã Þ¥OwiÛʸd^a£œëÛ2LÇp²£â·É±¨A;´AŸWqszXÚhiŒMa7ßH´ç•¯}±=Ìîõ²XŽ·‚'ÞFumã±tÿåé>Ÿœ«¼|¶žÐ˜’¶‡Q0œì§ø‹š¦àÙòÑN OûV|Åí{žÆËZ ßo7säYÈ‚³ñÛâu{vë`l!–óÚt¯[ßn†ˆõ«Ñÿ¢æëÖ9ËG÷Œ9.Î t’Dñ™–%…î ÓX­C—«§S\K‡­X©Ãª:óX÷ØhJÝ@}€ôà¿Ç·¨Üâ>š³G›ô«‹ðýꯦ>€=‚â+ ñÐÕm£)í9Ë'‚·ëx2ìiœ¤S\ágéH‹;¾Lv69‡â³{¶¬|Ü*Ç·T…Ó£Î-5x_<›n\³®:Œ>®øGœÜþUËÎ{æàů6ɸ&ïO/ 4ÜãXoÖ»eßúw8€HÏN®¤¸ÖŒ@Is‚_fV癜Ïÿ Ý?6¬L_ºû1=n}r<Á3fÕ í;"úm*Ý=îÑü‚wŸ\7†ÓC ÷9E¶ŸÒäA5j^rµZ«rûí8!èinÙGqF¡ó|úPz;Æmlnœ{cH}Ùq3W|*ÝÛvÂÇC ñвÖßãj\9WâO‰w]Y‡øüë¢ '(n»×•óz²×)Ù•â»(nÌÊuCÒeíÚn°e´¸lp6ÑßIl&ÓÇÁ‡S¸µâ¿ê•Ü×:ŧ_fÅ6ê ÇãÒ…w¬·¿)Î òôŠ×£«€2|n­½ç§Õ=Þøs‹³úël=x§‘8ç]]½=ÏpX=xVÜѱ¬®Å5¹wDqBfiÀ,³b|ÏíÚJ|<À>šÕ^†ÜØÞ&ôvIî’~-0[ßãá.ùŒ£ç9¨ÞM±ÏŠ[Fø4³ÆM ]T»dcÒÁ8¹^é=žéö_ù¹tÁÏ«º÷£f»Rø¬Ø8NŸedú Yè(Q‘j–¶­\â–ÌpÀëÇs©À'+Û¼·¾«Î4›nÈ6˜—¡S'×8Ÿ¬^kN´^胼f§Œi@+àûoÂZ0¬»"î^`î¤D®§Øä½oúæ¹ðI1Þ4²·W<^ÜhúнÓdx8ãòß¡•ó!Þo]é³·½PÚg ŸÚŠç‹¸cTܽ·Ïtœº¾Vø·Ž¢¸Úç¼×íó²…E.l¬k yÈLA†/,p3ö 3'd46.š·õOQ<ßÛä÷lØèVmÓv7QŸÉ,s žß‹CŸ¡ôÜ y”€ÇÌ|2ó`ܘü£ø&däøn½µx.v[ªa¹¶y ßOíÆokßï´²%ÃsÜ?}jø}ïU­1Üñ/z^Ö>!INŠ_¥Ú¶lo>êXKw·)Ì´B\Xúp鱄ïçø¼áyž€ÒÞQ^µƒ¯&3܇ñ†rúoBLÆÃºM»l¡ø‘Û®:§£§èjäqðacûÏkÞm;Í.K¶en¢·;5pÕà ÿ":²Šq­ê‚ÿÎIŸ/ rëG7Ù\}z¤ýC *ÇmÏ£éÙáµøA3Ñýi(YÖàæqk+v]]gø)² Y75®ÕE…ï_8ó®/¥-fÓbí±á‹–×;Êu'aÛqæ0ÇU4WÁÍË<üù2ÝVã„„+®5Š“Ü>”·++ŠODËo¦ÚëNŽon–äŠ_BæùŒYY=[ øè”ú0Ãqœ•ƒêZ{©?_¬ØÏ¾k¡‡ûU‡›ªEY‡Õoƒ“Åcª°]X%÷!ÜKñé]°á8NÈ*Æ7¬WËçáð¢×>'©„ K16X³enü†â?k–ýŒxæ€Û _VÜòV®BÜöÔ8®’HñŒž*Ë\ñ¡ÍegÙnnζ垮?þTÖf”"ÿÇË@ܦøËŽ(x×t}1V-N}NÈèŠÐ`…›’ô(>±Ú-øß?ì\ü[–Û»ãýŸŸ:ž VÀSâ >ü@_ž‹ö)Å^ã89‡½qvþoŸ!yÑ®RÞ—erB©r›—¤šðvÌl¸k™›Üåv¿!ÌäÉ…Y'RíÚ6º½¸Êœ¸âÜŠôÞJÅÃ6\ãâƒb—¡)ƽÀdåŠï¸:¼•|GÂWÍ>˾7Ìô´ÉhÂì7Û°±kô¥êå+®[Œ±ŒêV ò[«kqë‹PÄ9ºŒœñ­çèº.øè Œž¢øìC^ê¸Î“p÷ »fÎ1õ­üë;Í0PH9~†Zü©y9éw1Ý]7@@Š/Å#áiÏÅðÌŸ>…#í6”‹qsãõM»£÷÷1©xóyTüóâ1"ãòÞ­mãµáöjÆIYóÞ–±£¥øB9¦¸eŠ{°¶áQ' 5]ÿ¶éÛ&<TWyV<ÂáSˆ/(îúÊáˆÛç %'ù >lýÝW7aŸM¶ŠP_÷®Ë—á gŸµüCˇñtsã>Å8µøh<}vy›Ò)ÞÐÝ.q9ã$Wç­ßö{J!xŠÉÉø™U?ˆŠ¬Å-»¡íøºC<Á.雿Æÿ¡³ÍŠG\ Xª¯}Øl³â Ê:Rɱâ$ë…kVćGKE¸;ØGñØõx·¢ªû…§^Û»*·Áô}?^ñ¨‹ëV5CCluvm³*¾dxh-®ÀUmƒ=Ø-†“R ñìÑù~)ªðTŠÇÜEÝ8"Q]eîµ’.£õövÙ ñ°Ÿæ03GkMr9Ê,·!÷íóâ_Ý´¸MÖŠfê8†“R ñº÷®Í·û*^[Û+«õ†ï†µms´§¡ì‡x½Óˆ²XnÙ2˾âxº¼îuŽS|²•ä†)DBrA|²ò4©áÞŠ‡T÷-ÁOGÿ>>©·5<üÐþ‡P<¹«ŸÛnÒ¼O¿„â¾ cšó ;°Ú¿\'“ÊÜêoн ÅIñ£é7÷4ùà¯×}H« ¨Å=ú„nK²aõ¬5„»FÍû6fþPýA< Å݈ïy"IUKWš÷}àïeŸ‚Ü{#uMf5Æ‚[ÇŒ3€NJ.ÄÇ-ÜÆ¿Æ³ßƒG5v~VŸ`»µh†ãë¦Ç]>·Ã£^ë⛑FqÛ 9ñöÆïv!ƽ …{=®M›·Ž6×7+ò¹¨òþ˜BNQˆÛ ¿É²~m2™¾¯â£ƒK¸ûïõŒkl²³s­e2þ¢®Y•+µ‰Þ û6ù&°œ˜€ÇÖmKˆ;÷a½yíïÓËàäL…¸¦Û¿Ìí\©Õq¢i¸…oÇËzƒÏÖŠ.?¨wwàíÁ09Î_Kñ™Ñty §ÏN{}&˜@ÎXˆ»V}쾊5Æ÷X÷ˆx74¿¡ç•m’ü £ì©kñí/E»ÜnåÏr¦÷Mêþ·GãQ3'™:=Ó@=±âûœ ¡ƒ 7æÌe^÷(¾‹áÏ4?(Oq|°á3kÛ–hìù­àdÎö¨=Û1of‹½'ÄÓ>3”âñ'1Û›f€·}„ýÔŽ'E|ãNò£/ãO‹;'ÆUêKËÓùêò´ŠÙÛb‰j¶Ç‰#²ü}ÿ?>^üYžâ¶Æ´„xô ÁÒùs?S®l·3Ý…°Þ,zc½þe-ûU8ËËÓÝ ê#`£ª+&'û¬/ï/¨@ó§¥ûͶ¡[µøpUÇŽ0©«ì o‰;ù3åR&ŠÛ›¼²ØÞíœ#ä+þÊÔp³ˆþjø–/ýÄ`äcLš¯ˆCdÃqá€?n[Ю/RõÊÚ¥c1ØWˆ6Û´j~b<~AÞ>úÖîEsær«Ñ»a¦ÆÉ>eøvÃ_(|¦+ÅÇCí¶]Û”ÈñnH½zPövú=a’”ãZuSQ—ey™R¼áÚàÃ×mý$G!¾81®Ù)yµýfäÕéÒQuRˆá/Ò÷my)Þº+ÝÀz¿gsþŒïà¸fŸÓñu†7µ·ŵõª°¯D >ЬS\ÝNÑëqL"™no•{LZg¤xÅ'}§ÛÓô´ÝWÅ“;®•[¼‘¹á›Ûõ³_ø6«kqÎ%1Ü9Ú¤“+.Ë9fþ›HÄP¼ž%‡ñUod9ËêÏ9Þ-Ù6œMñ¥9r !"¾¾ãzº<oû£þ±´´wMÝ3€Õ3hl“…â~éÊPü›ÃöRó¾]ⲟ<+'çL×â÷×97ž3ëÏM1žë¾%w¼*Åëë0~<ã ª‡«oV7ž>ˆ"\"? ¥b\f½.k×Ö` 9ë„ø±C7­ïA¶lW³7êS%ŸÃhüV[ü‹}ÜŽ/ÆT½t+ÁmŠk+á?pº ]3ŠËxf¸@œœu0ݳmg¨x„½Í­›¼´ûª%G¼.ÃûP¯Àxô*é–ã¤êýsâñ¯¾d¸ñk.Å[æ5Ó³±M 9o!~<â¨ËµQÛ.k•ûÁô33ÞüÑ®£¨3¨¾Bñþ1³HŠW×ÃüÀˆqk9nœê¤ùž ÄÉI q¯Ô*nìi~ä¬|5¤þ´Ùæéé¿9«¢¿ªЇ^¾²Tãoß`Ï”âëº6BŠ/Ä=[ºòT|õûÓ„bÊÓnŒ×ãõCãçŸß¼–ljlŠUê(Ú†«ÔcŒ§ßýþº,1BÅÉ% qï–~ª5êšy’L{w-Lº©_äεTÏd~Fñß)¿xëŒxˆÿ€Í”⊓‹âžãé#|Σ¸q2i>µL½«úTŸ] ò ôáf\¬mË¥ ›†o»¶äB\ã#Åç{'0Üsi[êAæ~Ôfƒ•´g®šV¬ºu+Ü®è¸ü?Ä[ZÄYÞ¶îÊê§Æ7w†âænŠf-îõPœ\Àð Ö§ï¥x‡£\†ëØ-äڇǻیg—Šß»?yœ ï¥wžßD¹ŒB¼úºÕ,ùã.×çü¿š–—6ü:Š«-r•é9Òõ9¥Íñ(—«ÅW–ÀIß#[¯Pý#ÎÃfâýjõzl]ÆP:Š“v°øš‹ÚrB<½â•á·œ­R³Ø®:¥}îÙõ Æ-r·¹ÓBnÙùeý#$ípzS÷Š\Âz™5àÙ}Ò{B£<î(R?Ž®~9º;w‘T3^4Ï?{vAǽFKv¸Åá Ò e ÓgÍ61Þ–âÞõˆz@§Á^m×Q\6|ƒâq;¸ô‡®j2ø—¥ãjöÁzªK–⾜ïòÖÊ=®+óSŠx J[‹7#êõÔ¸B: ½µ8¥ø¡†7)cÆ P¼ïa´ë,üÚ©Åî¨Òª¿¶âÎíýooZHÈàsø“?éÇÐÍ]ò#0>º;èžI÷î5ÏÆbøUÏKñ¡áyl¿ªYz•±âîÕè¹2Þ¿Âp»â½/Tä6Äê{xœP$ÆÍûÛÁÐý¼úÕãˆ>ž¾ÓRj¼¤t5¹¾¼/D¾$~Ûkñ£Þ·¸éÀ:Æ^¬úÀ>0š ³w×ñ÷ÛÈ|u‡âG9¾ëTœ_ŒÇõœâMÝ«ÄN²8n÷Q?fޏ'Åørɸô¶ªß¿ò>PCÞ½ûj·8´ ^)>ªÈÑüˆçºŠQ»­£Ö&ÁsœŸ^ëEõo¡n§¾´»à(n¼þ“Ǽx57®^êÎÏ!ã«ÿ@›vµH­ºSð‘ä£ ÞiÏWñnçr[±WQKå£ ~»•x¶d»?lÿ_Å­)?¡âíâH=Ãñ¦aþÉ8Ã)lë úšrÜP¼-ÌÍêÜ.¸;0âû«7¹¬¨Æ;DkÚ²V\ŽsÊ ™7—ðtŒ«•jSó#Wó¬Hð–4ç^Ö6qÜò§V+n,wÿ€#ÛÝ¿â(Þ4”\_Þ‹f_¹îŽ–Dqg=[îPeoVs`é³2Jr%äõ0ÅÛ™ ‡Ö)ÆW)î»K~7þÙ„×â0ÎʶCêñƒ}ÞÍõšŸBÓñˆoWü“—z¦ÑÜ€nElÿ¢„¾êv$ãÛ6‰½Šâ2]J¶£ºñlx½2}ñŽâ§3<Áʶè«(düsôºÚ(Þˆ§âûGóFDƒÑÜÌÇÓϨ¸ó¿z9n›•Ó[ª«¿ oW¦ÇWÆOhx¤ÍòÛæ÷f›¤Ãôê÷ŒEñÛô‘²âûÇgšüle8®T¾j:Q¢²¸é÷vVá„ë´]ätÊ¿z-ïŠ\§\¦ÎV¬žãævjß<ŸÉÞÂÛjÜw@} ã ~žBi¦`Äx§WÄOdxÜ/¹;ãÆê¶B÷yZÀ›nuÆ»¼%¬TßEq–·åcøp”\¥x3’: ¾‚q?Ë`zìOòb<á¼øŽÝ“oŽÛmpÑ®ó¦[!;¸%c|ð(ó⹬l¯:\2|¬x·ª-°‡ñS–Ù^«ÚvF<ãñŸ43Þ–ƒï&¹› õº-Åy¤§¿£yö¬Ç•²ÒoÚ³âYã“*– ¯úXm8cê§CüSŸšÛo¥ÛèÅ™^Œë¸JÜ.oŸ¸aøxH½Æ“½ÌÞñ×ívñÛKã˜0ûoµ‹Ñ=†ÓMÅCGñ“⟪c…<áÙt‹ˆÇg<Åõæ Ò3]g¶{ë˜ú³BŠñ”OÄ5ïÇÜÎÈX†O{]PÞ^—[ÏfÔnŠÃxÖ…x—]’õ@<‰âi&ÆuÔ5â~ïÓ³ROvÇÑ­žÓq„ß8ųÁÚÿæáB¸Gþçÿl$EÅOŠøCñùÁõÍøpÿ÷ˆŒØ/Õ‡~Å çêŠ7«`Òî/~Õ¸cÓ—ö’¯üîsw<]1!=zùñésßí6®˜qƒðõñ¬o[n¤ +Û¤·Þ^;®ÃëÀø©ÿ”2A<ªâ.G{¡H|Þ+Ñ-z¬'2$¦¬kqÓðúîäd[÷§G—%íy«ÊÄqoÅ«JþŸT •Å[¼6[XGÔÍñ¨ŒGWü–É‚[:Eñtuáe=¼~Zà ʼn£™úœBúÖ[.ǽëðb$Àq?Œð…Uk‡(€xDÅu)£âÅ ¦·Ï:e]îê,~OV±ør!¾x$b‡xå¸ ^3â™ᣥkËcê®õêq6 Q<ãñÏÃp_V|üÔ²Îãå¡L;cûP|qÞÄTüîxЈº…ðv\}yl] ~T>‘yúç>5—î¢4þ;ä.Âñ§¥<ßÈx6ëtè½ÆÔG;¤¡x¬¡r¿ õ§µºÆ‹<þÐ[Ã4O›=¿-2nGÜolÃó Üdy©_’ÝÀbyáñ7–ÊÆR<›€N0¨ oçÇÑ8Šáòy\ý¬?ޝ»~'†äúw>Åø?Yë8ˆ:Ž>_cjeæŸ~ÝÁæo¡†GcܦøjÆóêˆèëq Æ7n3½Cš¿&úg.<ϺÑ>‡áÍÀºþ] Æ]Žƒø¾‚¯†9Šã®PÓ­å3Å2nPßTŒ ÅË.Ço8o0½} ÀceBsXÍq¹NP3fþÈ[3iþÈÖNgÉQüPÁw3ÜæøÜ·_e·Éx„µVÅ×3žS/D¼ðÌYà.ãs5ݹÜkãh”¡Cè3–G`¼_îÖ¯yCñ} |äŸÚ9ÃU©³ðÍÍÙºF~2 ®MûŸ3¢^jÏhn’vSÆyš!ãMO ^XŸn{žŽ¦;{Y‡1^å[GÕm¤CìI áþÍHÙО¦Šßª/&¿Ü\£ñðx¾?}šãý& ²uâ±"aqŠ Þ¹·‚³¹B¿øˆWº]ñò8Š7;r®S\ÙÝ´“ëõíïÓŒ³8u¿ç:=9HÖJÂY­¾¸¦m…âwÇ}FÕÍÆ¥jcÓân×@|µã#Åe.")]MúÂ•Ž«:êiÞq#­á‰Ÿ; ný.‹Óçv§õŽFŠÞ2Ö´)ºâÍ×ý #ñƒ×´õ¸åŠxlÅW-Y7gï^v8ŠçÕ_VK¥sW¼|èÄ?%FW»UŽõFÁc<}~$¦Ø]Æ«ÐB| ¸Kqsù!ŒïQ†w5ê%JñUŠ›]ŠsVŠwŽv9µíTžjKt;Æ>ŽÍ~iÚâÆyð Åm†O¿ÿ©¿ÚǵºEo±&ÄßÌÞñøˆ[_ZH9|"æ,‰£ø†·Ì¤ñiQit±Ì)Ùª¶‘áωii¹­×¼»L¬øoXcÎ ï!7»Øêßá~Æ(ž£ã=-qµ›ÉÈq'F^ÀĸUrû§žf¥›,›SòaˆÏì?‡O?Á„êvÆ#<Õ’ŠìGš?ó m`<…â:®á+‹â¸Œn–ÚÇÓ‡[ϲˡ\Ïøã±ì _WüFCÜ(ÈgÛ£m" ½Õ¸ÿ£ùošc´‚¼ŸmkÚ¬êV¸m†OƒâiÏÎñɶ0Šó฼§Ë§ŠŸcË6ßÎxyêOÇ;¦¥V¼{¾Þ{Sõ%¤ªtGËx¼‚¼îiÿZ•–rï5Š» ‡ñtŠg»Î-ݪõÄYÝFŒb¼4Ådž'W¼ ZÈCqy)ÕL‰³õ‹ëFgÕSfàãÕ`ùo,d â0w…úP´OåˆømõΫÙ tƒ›¦ÆK3Ü|FÜg»ÓHˆ7÷<÷m‘ùºâ³ïU0âmeÁ—_@ÜŸ< ‹±Î½´-bu‚ófϸC|µâùö6ôƒ×P\ý4r¿IkZƇˆ?¾¡­WH[5ÖÅU_žÖi~|Œx;ª>7'þÚˆ¸KqùPã+5»pª¬!tyœð™»â±ËñÄÍXOB%ýà7怜åx<ÅÛ¯Ô¿W² ©Û^‚kº[“cZ¢{Ô"Lñ¿f‰¾¡ÏdÏ6ç¢tÄíŒÏ¡j´âE­ÙšþbÜÇÝ5~oî-O Q\ç‘’Žð*#궉|÷"ðx˜?]P|rJ©w‰â±†Ô­ˆ¯¯%üï_<2ç¸âÆÝu¶±×’âáöäù7ëÈx†÷Ó[£«pâ*>ìiöO·öªoÆNÔ{Ð^Hqßp%7ß)9÷W7·Ãcº{wÆÕéæpú7ŒÓtÀÑÇé¸âcÅÛÛÈÉ/+'m—ÓQ ùí㩸†jò•x~Œ§Y—¾ñ›š›1¡øÕçÏëxwþXʇo“»°VSܽâì¾óÜøãOϘ=ªpâß`úms¼flî xßòšb´n2ê²…QGÓòø’zÑVÍ‘W(Yñ”†;×üžl] vŽ®“ŠñzT½³ú‚¯Ü³¯P̱ܺdT‰Ï´,-“«8úk/Xq¥EÜ¡¸b\AŒ¨ƒx1exÓbe<~Ö—A«ŸU\ê¶gí÷U½±òü bÜM÷`Rü/|âϸ ·®EÓZÂgÞ)¿¾¹b)žñ|WjÃ"μ8Š—¡øøÇ²v¨ëžêV¼éWœVJ’0®%Ãë/ø~ñž—ãáÝÁ˜ùð<ÅI÷/ÅoæžI”âeÖâÉ w).·v>§)–ÕÑk^[q ΙîÔªµŽ[×ÿµãóæ :¡xC곈·_ñ/"3Þžu6‡x»[³€=êtøÂ²ð¹9ûí Ô8–PãÚÅpÄ›]¯^Y>®¡°nˆ^ó⊠V–ׯxß+:+³ÏÎ`zôR\ó➊{«û3^InëI-jG[ÔVÖ[β²ýkȶ0+Ný:è™ð}Ÿ½ý’Û;½rÎd8Š_\qõÅö^Ý&Œ{á6€áÅL‹Íäæçxã®Êi2©½¶v¼ x|Ä=ß ÝîÃç)¶uñ«À}¦O*Åg/±¢ë¤ŸþDæú³vg©°Ásç®2²á¥(^—3^#ë¾kÜ–ޝÞ,uöDŒ Š:žúèÑ,-ßaø|qÇÕå5µâ®Qõ2;"zÏK—â­×sŠ÷kÈ#n©í!<ÅW· º ïµê>’»G?íφ­p\Îñ•ãñ‡Ÿ ¾ÊòÓ þæêJ¼SÜ^ŽÚÑ^ººTŠ·çxË9ް«Ìt0gÃ3AÜdܺmÛØÀh«Ü>A츶}‘ÃùÌ]¡_ZºöŠƒñ‚{"úÐk¨û”â.Ào¾;ÑNÉ<›”d¡xËx=`2«¸¼«ßÇÞ×+>÷³i;ã«Ô÷<È4ö©!:½âKí©Wü•~énÙˆ£8ŠOžYÅÍgwåW‡Oß@+ËOñj™zß±ÍÕâÞŒ7mÅölYóëkÛ@˜ã1ßõ4rÅ_vƵqSñ‡ã¼¢Â!¤#e@ÝRŠwLO |'‹H qÚ¨ÅÇ“£Û†Ý†§â¿õ[¿%SíÇ?ë·ú_ý…õŸsãBñ$?žñåæ4P¼ÑÒY¢øM¶cÈ-ŠO¶ÂÔJÄ'®Ûœ…ÐiqË~åóSãÞŒ›’ÿÖ oÖ‚ÓzÆ;ÇI*[ñdŒëð!u­Cü•8Š£¸ã'ªæGg ~<|ô·iG[ÿ7h¸5iˆâÝßlÿÛö–V¸y¬q±=‰¶¾ÛÖ©‡?¾ýbç”ÃøžkÔ­Š{õ)vÅ §ÎÅŠ·e$t“vËð3ÍèhÙEÆÍ]}êBüæÃøt#Rmd|s Ѧ1õÝQÎBñŒkWÄkÅn¸ñW^)¼¨ Ÿ½²âšû‰ÆÏˆ{Ûâ;î6}ñÛÜ}ÃÂRucÎfW”Ó#·(ž»ã‰lTÑ…x­øàÃóK—ÃðòáÐÏ¢¸SqËòt?¸íý› Ø%—o·àÃøü³ãJZˆ9ëáó3(™ñ quˆ72oKåëhéhQÜKñ€qtχñ®2C\M®Åí_†Õ•qßauE˜\? âýa"Q@Ù±ÿƒÇwÓ‹Á‰J^ Ig%ÅQÜ=-®Ádxu¹0ž^Æú|Q¾üHí[F¹Àxó§ºçÃýWÔweÓ㺞âcÍW˜¾Ç©'SÅÿ@«6|”ñ„ø9&ÃQÅçv}©;Ó³áãÃz âEã“éòEÄMè½o×/ß§÷„XÅã»O7ûy~„ßõ«ûƒ{t[…¸±YÕâé¤(ŽâgP|ÐÛ‡¯kCñ ï(_Bü­á²KKÕ;ÇõË÷ WFŠ75~€”‹§§â·aø£WNC¶Ž£8ŠŸHq‹ÐcÃ×~qšW Åëªb=ä‹¥ø[ã­&ŽË~LØ/WŒû(.ÏQïiÏ-Š×ƒc¸­2ÏEð†ðG)¾B9‡ÐOµaÝ쥯FÎgËh­5ܱ…:Ù>ü/þE7ð™@ñшº}X}²'kýǦŠÛ—>QEó|«þs^ÚoZ§þBÙ•ä‡>*ʼ~°ñfHý\£è(~,ã9Ý8ˆîÅXk¸ç, n|ÿÂˆÖ ©/~‡·l‡z/žVÚ1¾ xk³[q™¤þsË“ùÚP«ùua¸Sòþs³¨m»âçíèeP¼€b¾Y•¾þ¯Ó¸öP<˜q¿'kíL®R\“-ÔBËÆñ'lÑâÀ»×.šý‰…á™Ý=TkÒßÜ\Š×Cè¢'R|õË4Ž`»ôÔŒ+á3ýàâ*·Éºlùc'ã.ÂgÇÕÊ}ÙñÅ•á>Gß4)>(ÈÏÙÑË ø©fÖÇkâ€{?Å•Äð™-Y—(^‹m‰Fƒå}>1Û Ítì}õSã9ãn ÿƒŠ«VGqCñ§’Nix=ÎlønŒ+¾á÷ïë¿þë×:^+þ`ÜIøqMÿ„wÆu½åO¬a<‹b ߄ø+ç]¨C{€ây-p‹Xˆ³žmWÅ•`,ýaøƒqçïÃÜÓãâ¿<5|,ï°¥„8¾ }øQãÍ«9ôt”KîÚ>ÆjøÅeBŠâä¤ãá1ÖÑ<÷ÿhÅgŸs\â½Þõ?®Fã9{0þÂrÄêALJ_ÝðæÝ÷4|;âçdœžÅ£¬B2Pøp¯*VCðãͼ¸Q†ß§Yªv÷Ö­y\1žIñ‰ã:t]JïZc“¶xÃé(NPÅKV<ä³ñPÜWWcz·Á@¥ø7ÆiÔK_ï µ83áÇ!>T\Ä7>_âÆQ<;Ä}·ŸB¦YÅ7Y1¿;nã*nl¢Ú,œHÆ·ç:uËJwFÑM!þhñ Gq‚â+õhH¹–â–‡³n3OòËKñ†q™_²a|¸¬Mf'Óbþ‰O$w\A«Ô™¿ô‚tc-…Y…?>ŠÈƒé(N`Üosֶ팸ï&êÓ…\ó#잊׌Ûß­M·üÍOì•åÚ†Å÷/Ä;ÅAE.ÄŠŸ‘qú^ßV‡WŠ_múq?­6VâZzì,Hñ ãúãñSâ¶ÂwÄߘ0Þþ‚kóvß¿o?´µ?}1Žâ0¾mºúÿ¯öù?ž¾šñ¥ãÅýw2þX»6«xÒ…m-âo<¢áJðæ¿]Ç£SŠPˆWÍáMËB…Ȉ£8q÷V²œ"^Šâž›·}½çÖ=rž‰rÓ`·—áwÞg}Û5ã­Û†êÎÔ©Å÷ÙãÅë¶R‘kqFÔ ŠÏL‰Ó„vlvZϸ÷.꾯ʼnømôÀøMÃo¿›âoÔ»¹¼Ñþ×üq(BñGÒçÛ[ì!uV·Ÿ9Õ…&´ßµ¤5g¡(LgÿãDÜ(ÆUM•OÞž½£7¼V\3‡š Å÷GÜѶR-QGqãÆãeíÙl´¡Ð26ʈz¢Z<Šâ&ãÕQ¤“aÔ½ä^šÏ.ìÛÓ¶Ë+¢®R?9â(ŽâkÓ…âý8·öûV)wn‹‚ø­=X¤w|°ë~ËÛ,Œ§¸._ûOÖŒ ÿÏÿ9ÖÎm(N`|xø‰xR|÷faç¶­·,õ µopNËüs­ãÆÀOš½áÈQŠKŸƒñ7=×M ¿¾^qÝÎ>)ŽâÛº³ö<ΫΊ7ŠÓQÜ‹ñx·X­ÊÿW¹ñ‡Zñî8Ò?î¤Þ|­ƒŸc\ã#Jâíè¦ÏÝ#&Çý r„W†¯f\7'‹Û•«ñª§·×¢YÔâñ^I«w‹ø\Ï¡Ûhb¼ÙM}ðg’ïú²Zq þrÉ+Ä)Æý¦Çew×¾–ñK”â(¾½¿4ãËBñ˜•øXñ¥~xðȸš¾Ù¨ê?‘_1® á½ä§Ÿl¡¾°¢ÄD|•âU£{Å Œ»1ãéG¨+Y%îÚÜÌñ›Y‹«&oonö9E3Œ;‚y1SÂûM~»æÄ?G1>b¼[¡?#ù@ñÿ¬Ñ®î½W^Aq2ÿö]|}¥x¾Šoúl4ï¸ÏÜfÿÀxû¸ø`þ¸bÜ鏿ÿŽÇ¶ÏMÇßÕ>T¼Þæ’‡“V7t^“åÅCªñvØç•WPœÀøü€:-à€Ñú ñª˜Ie¸¾n¾RÜQæ+né=ͳ&Û¶ý|ã7Ö;ÞaÝK.“pSñǯ«Vÿš;©{ΕÿÏ!œO ñó"N7 ãÛ–·‘€QéHWl?h‡<ìùuµç:÷‡…Ý=öSÈǽžúc ¬¢P”Ùñ^ìÿåžûÿüh-˜<\‹cÖñן«_ÕçÆ‘Y뢥xÀ‚·µŠWÄ#ÃQœ 8ŽçØü¦~/Y6Îßy¤úŸæ¾®‰Ú’|ô”˜âíF¬ý½Á`ì¦êg§&Ïym-¸+¿§†û0^¯?ïÞ“7<â^æ6Û½P;îÞåò‚;›ìpzãzeJ8ЇñÌ÷¨À;´ÝéoëqÛW ©ó­Ýù4Q'õÍröx»ÇÌc¾'{š±á^Š·’¿á׃gžŠWéúa3׆|®-÷VÜ&8ŠGñ¬"øñ¯3ÞÃh\¬WÿÓ#>vÜø©ŠÏ þ£Óé¹{ú¢â#Â[È1ÅQÆÛ†•Úü´¼”ÍOðÝvŽGòç—MñÝKq_Ã?g7üÁ8†{1.Ã\ˆ£8Añ)á´ž<_"üïxgQñàÏ\+^¸,óû OßqoÃïŠÿð£xÀV¬«w"ŽâÆNÏUqÍôi„ÿ:%í1ÂÚÏŒáNÅ ª›Šþ99ÿa6bõaÜ«Á 8ñÀrœttëûÓ™sI ÷QÅ/·\}â^Š»Gqãlü’©âú§®Åä'8Œ¯-Vt<Æ_[PüGQ Äûm]>÷¹8Œw”ƒxp)>|ôиNŒ8}0Šo›§e€xï¸éÞ ÃÓ(Þ2®~ÀcRTúOÿI›Ô)^?ñnø’âÇo×p| â6ÅÝnªpq:aß‚8ê™ ^9~Oý¿« +³ÿãîÀq¿¿ðŸ1ž4[§xŠõvëµÏÅG\ú4Š[·µ/À…ø¹Gqß0œŽá)nDk O4¢>÷ôú£•àƒ?¼Nñ«ÛÂõöGüÓŸþôŠqÏç¾;Àÿb¸ú‘ôÚïs÷TtÃ0Îʶ“!þp<â‡|Ī ÿb&Š+âÍ Î§«ÄMÆ%ë9ä³ux;ÌÞìݯ“;G?Œâk §íd‹øŸ®,Ƨ•ø1²}ø4\ñ¬KñцðŸîrþj\Þ‹‡ÛïËeøpi[·¿ï­9÷ìÝ=a´Ž‡=ÛH&ˆGQ\™]_.ÆUæ€úîaD9ÞßÊÉ¢•Æ€7¿­“?R†â»ô3l÷B2@|åzΈÿ¿ñ7hxîµø§/¬ø›+:Moëí¦êV÷«(NÖÞÔ„áähÄϦøq›â³†§™_ãwoÅY§¾€U?íÝþG=òî¨ÄÏÞcÑ#Ç|+uþ±u‰6Sâº}Ç—œw ¾`xš§Åã-kНïj›}\úÇÅU×èW,2è‘“¼«ÔáäPÄã(žÍÐd5ž®`ÃóVüêµøÆëñóWÔ°k¸¿ª^¹dE¯œ¦(?)â|¸ÙÌßüéBaË—ŒŸ¬mó1Žôš3âZÉ8ˆÓ‘îûÞ~Ç$EJN)Mñº˜‹pĸñYÆ­eKA~O· .½ôÒK!Ž+OÅmg¢\ƒq­ÜOÅQü Ʋ¼4Éi"E!¾Åïãr!¬ø†‚\?6U\•á/9~â+¿È”x7oºRÄQü(Å5ú/¹Žíq²VqE0¼SÜiø,ãÎñ©âáaŽkoÅ­G x­n»Æœxåwø³ (Žâ1^?%1\×€ïæ÷óZ G)©ß.¸§ân’5÷wÂ!W5 .—áŽï\Œ/ù=·Dý*Š¿Ymß<¢.ž/CñÃ9Þ‰-ñö7Pœ¤xÃø¬â.Çg xýîï:k/ã:"þcæÒô©áÞŽÇS\Šc¸ûA3]ÇñÐýªgÍxòÅSÜâ¸+¹0N)ñ]·×Ö³Šÿn ÖÝﵿÛäÇ1jq«â^ŽÇÜÃmry~ùÇÅW>k†Z(~ ãšÂ¾ä8Š“ Å ñ†ñEÅm¹—â†ÖµáãßèþíV1nN‹;÷p|§½_¼ gï¶u‹Ô Š­xãBqâ­x<ÃkÅ奸ø)²Å;ʧ¿fü«¯âsŽëGWqmx@Üñ ªK°…âg-Æ“—ãBñó0ÑðJq_ćKóÓâ~1¯Šñáõ—B¿#®Ýv~ñG|þ4”ë<7[(~âb<%ãíBøÅåð´WTÄ Þ¬kaY{¸â¿[/oûמŒ¿4;¬®zJ»ŒRüåøJÂu(~ãëW½« IùmóN Éñ؆ßÿëÁY„ßñÁzuÊ¿ž{Òlìø,㊠ø^ˆ×[ª¿yÖmÕ×{Çê6/¬WçŸ<Œ«x|Ã× îÁüÅÅøàqñ—#ûÔx½N½jêÊ@qÄkÇÿ*:o5Nƒâå1 xŠjü©ý©¿Ó´,§‰ìÓLßgíex^Šß·).ýãÁ³è›²>ÝñO7†??¯ã%9½oJycêæÔxØ–nÎñr¹!ižüAñRJñ$†?¦ÅUü6||Üw4ÝÅøñ{†ké£?,.)âʶ âg.ÇX(^ã W¼g\þG©Üëm}îÖ¥k±1Àxˆ+‘á™)~SáÓ©ññhŠ¿¡®oû¥îøPñs–ãÂ+¿ãê÷]¸n¹»U;bnýÝñFñìÜw*ÃÓ ©û+>)Æ«¼äŸn ªBü6-Å·2ÞHÌ÷ÄŒëœSãųSGŒ+Œñ猪÷ógŽË¢[›È8mäø6´¯á9*þR`¤¿õ·þVÓâÿq]‹ßb1¾î5ˆOßèx?ÃVüãÅwS‡Œ+°¯÷~Œ|ñªðùÐa\ŸO5Nç‚â½Ó]1Þ,ÿŽøŒ{Íy¯PœV²ïõ7Zš¸»ái†ÔCï_øÄô˜Œ¯/Çýÿ´ÜŒk‹áãô-(^$ã£AöxŒ+æŠïzÊñË(Þ0Mñ—,Ǩ¾±9€ø¼ã ¯6“©~£0Æé‰çýIý.'f\q—‰01¾g þ¿Ê=š~Å[Æï5ùK/¥r|ënÉ_çø¨T·o0SÍ5|äè‘õ°gÅÃ6ˆ¹l-Î[´£âq§Æc/AñýZGã¶4&]úÓcÏBñãQ¿;“q퀸¹ «ÅqË‚óún¾ûu÷&qwÄV<¬cApFÔsROÃxô•žbyÛ~× ÚRcôì·[ÛËÛ¯¯ÿ‘Lñ½¦Æ»'¼>½.nLJyÀøÏïéþ{î;Þ?˜qaŠ—4bªþY±Áxi,Æ“*ã{Œ¤ß< /Zñ5Œ7oE:Æ÷xl|-Þ¹!zµf­B¼Éü]ƒ®ªøù:3ºç½ºk“ß[ôj<ÁC—(žÁŸ-WQüwÍë$ã[×~Š/B^).ñ;ã³_î#9šñƒjñÓõftÏG8‰ñÄËÈY¥~dsù)GP<6ãëמˆwKÒäTüÓ#Ågo?Ðñ°åéô ¼7y9}j<±âãù(~ÛÅñßq«ã¶ûm¢®xŠw”[¯~ëŸ{)^ß |¤cü*û½ˆZœÄs<ú˜z’b™õmù!þSÕä‹(n0®—’2>v¼^祸c¹›,ˆÿs×CfühÅzü@¥:®f_tëP{^ŠŒ«ý<ðq$â?Õœhs5ÅãÇ›cƒnгóK ŧcëêÕˆsU›™§ËáÝÉêŸTã[WÒby¢x×;ð9¥øOéï|8^àóâáŠïʸ¹ °ù…(êŸN ÷®ø§ˆ¢¸DœZœ¤`<Ïb\r¨ãøaˆ?8^ÞѤù(þ’oëÕfÃS ©,¿¿o“ â(…â'`\·8Œ7Ô&RŸ>fËçx âµâ•ãP<]1.Ÿ®Qq¶QOêxçóôØUfjxÖ¥¸DgEqÞÁ5nÔøVÅkÈ•xH]´ŠÃ类w¾3½ã ߬x\Æ5ߌۓ㜅²â÷,Až‰âbRœZüåx4ÅÉÓ¼P?XñÉ‚¥w¾sÆ•K-žnL]sE^{=)ÎêÚ ñ ò@ÄPœ ¹#ç½Ëx<ÅG#ô±çƒ?¬7Ôž&™ãJRŒÿnfŸ}£ŒõœŽ%Ý‘ñßþ˜ïF~ŠKÅ)NÓÙe<}VñtŽK™(žp›þ›k±ú7~£†W§Fš»w-yÛeH]‹Œç2-þ&Å8ŠŸCñXO›ž?OÀ¸}Œ¶“âÇÏ­xÂnÅïˆß·³7˜ß+yó¨²þܲÛMÇ-pkŸùVÊemÛQŠŸ³Ï¢'>æm×t™ú¦Õ¿C _ëð¨ÑvvD|YñDŽ4iú1õÿfßÅ튘߻& ÿã¸1õ¶wíø¢s §“øŠó™¬U|TAoVO|o«ñH|òY(žîœ³|OUŒë¿Ù¯ ŸS|éãʸMññ-´33>6¼£jA4£Dˆ‡)žy9GñØŒùơ⩠KÜ´×þé3Ÿ2{V|2ôÁŠu? ãÕSœf”ñPÅã3ÑñõŠ'dÜ–;èYgmÃ~(¾¯áÆ5<ù̦xƒÏ¡øi07~¨â4¢dˆ+þó/VW¤b<9ã­áÊñ†Ð—|Í켺wE./Iq>ÿkÝf°òF|ôI‹Ï;a)¬xürü±È1/Åc.T·–âù—¦ã+%ßÝqM–§ËKñ}Ÿn:â€{žr|û˜úa#{6¤D\Kˆ[]Ž×•MIÖqŠÇc\ó¥ø¶Šü°!õj¥[¯øâ{(n™…c#7?ãºme\´¡*¾Œ¸]ñ¨åøCð~ô£#´ïÿù­ßêxDÅS2®©âk'Èu¤âÕ?壸2ã[gÏmO¬‚xI=0ÔB9k¯ÐVÜ\»ëõùR”GGÜc õŸw0®xˆ´I¹*à s|µâ–¦¥ˆ{¿,–â«?NñšñHŠß¿Ü{ßûÞÈåqœ8Š#ìÉ?¬¸ôãFêÚhG;+þÎõŠG*Ç Ã;È{ÃC_«¸õF2êŽêƒÇÌ슯UßëañÑ#ã•âí°º‡â™º6¼Š§ãºÉãø28ŠŸ~ ý0ÅïÞ7¹c+·þïð¡íŽøý47㊀øG'yÀn(âøJÅ¥ßùßI7¤>¶\r0¾~˜½–¹ŠWתš-X—ÿȤz~€]ÿgx帷â‹Ãx(Žâ0žHñÝÍÕg)È×¥PÏMñÍå¸ÍðFòoýÖ5ޝSüa¸…ñèŠw–¿äR| ãÚó‘3Sñê’lVª"^Ý< ïjý½ï VüM¯îÅQÆ“(n>W¯Ýí8yLÄýçœâ›Êq·áSÆ=_£¸ÄïŒ'{Úl*y¼Z|"x"Ò5˜¯kqÝê‰ñpÅïó½öÈk=ºn~ŒÓ[”©8ý|ÖŠGÁ4Yw_Ÿ|ª*¾¡Ÿ3|ª¸ŸãSÅe‰­·•ãé)©âiJóú«Þ«o=æÃÛ«¸.ƃÿÞïÕÅýO:Ä‚gÜ5ã‘ÞU÷DV_•û/Z'é_R|%ãšGÜ¢¸ãšKouo¹ˆO¨¸ñ8›)ÑÊõGÍ]ï´jÜŠWŠËCñÁò¶»âNÆç—Á9¤ÏôôÅ)NüoQuèõñGfŽ®Ï/Zá^-#ÅWª/nW|Ùñ‘ɳʾ7ãñžßIqã¡Ps´¬*Ë?â ¿;îªÆÈ'ž‰‘Ö (.Dz§Býnª‘z<ºîå8ŸnFЇ—ãZDÜÅø‚ã!Š;lßGqÅ\¡>AWŠ%ë#¼ï}/Æ?â˸šç¯!¯×ȼ)¹7g#§¯ŽùÐ?–Äãó{º¸~y¾çSÍPñÀrÜÃp§âÇuNÅ7´l¥®ÅåìÍjñÊñè{Õ(>Ëx÷ …áVü&Q±Åc<è*ªñ^u ŸWg@må¥`‹§â>Œ”ãòBÜ­øœãÛ0^ŒâFñ]—°±GÓg¾sâwÇ«)ñŇë_§ÂÉ™§v[~wã¦ßŠ7š!çÃÜ~¼suü÷-Ç= ŸUÜíxdÅ“1ñîvÁK’BÜÕ¶Bï#çhºz=‹qá_ZqÎÄŠ¥¸/ÆÚ2oqœO)Ê'½ñŸ÷‹b ¦{0nw<â‡)®í]_3g«øñŠñÉ®/õÙb4Å…ÝUqm›Ro–¼ÉUŽ“Ý÷U|¹Wâ Š[®x"ÆkugW«¿)`Zü{ÇŒŸö×òÚ€M ÈžXq>ÂHˆ{jl)ÅÃ>©ã?ÎGX„âKއîÁøÔñŠïÁ¸íxñÈì§x@5>E|2²n?›¬ðë¿üîK¼Š³(îø"=j>Ü™ÇËP|nX]ˆ/+>q<âI—…ð|_¾ö WôŒ‡)nw\+÷R¼sܾ[Å£3.Å^Ø–NqÏ‹maVÕ†?÷T|øµË?š¬ô>+‹×¯Ÿù߃q%ÙºUÜÛÿàÜAñpÆcî«xíxÁ“3.ÛÙâñ[±bmºê?Ô©eÂÝŠ·Ç“Úï6_%(ã1_By})î×cè_U©²þ÷à¸ÿûûνŠñÑìøJý¯/@q9$ÍTñ°—åVü F¬SãýuË.OÆê0ˆâ?CŸ¼WòcTT;^^;ÎÇš¶ߤ¸Ö¤øÃñtŠGaÜEx¶Š‡¾*y n-Çg–¶ipÊEG³Q¼gü¢ýòúÒˆŒkÍTzèS1Þ!ŽãÉ_«x5õñÑõ Rü[S*¾•qÍžë¼xð‹rLOŸa\)¿0ãÊð+m+áèÇ“3®=N4µ2Χ˜™âÍ)ÔýhŠG.Æçÿ¨xÅÃ_Óýœ/Ä-s㎵mz3Žâä$Š_õ~ÌçÇ–â(®Î%¯ž¬+ŽãY*¾ñœ_ËøãMøIÍžæÓÞqÇ:u/ſ׾¸M±§{€Ïó¿ûaŽÛ¯ Y¾ˆ¾#þ±roŒøŒã\ÀÛW¼±|GÄ+¾†ñ‡àì<˜Cq­êjä…¸}ºfGÔÅîg¼zÛqõv÷™þ±ïˆw‘ñ}þ•EqÊqÏ©o ŸW<]›Õވ׃êÖ½^|·2¾ýhqz¿Ò:®n‡{DýÚRÜö(x³:½yÔ¬]×6Þf°I ëÞŽR/[ñßѦ©q„Ï3ž§â«_•‚ÔÏd+Æ7nÚ¨×^«æàèPœz|E¤ÿþß×Uâ÷Kîÿ½Ç渑â¶›nýÛûom;¾ññî­¸ÊU|Ë ·¡àsЧl”J½]›§â³KÔ« afßú.¼öÚÃñÇ?€ůâ¸b~7ü®¸V¿Ù7^"nü¾õÆ››ñý‡Ô·)ˆxlÅWïý21ÜÁxâ©Ý q«âÆÕÕàÍïµåøc‰[ Å« 8ŠS³ßkðÿ¾Eq£ðžùý°ÆG;Ü]ñ–«¸uJg-â?©]ËðMŒoz]žŠ×{²ö¿“ŽñœgDQë=Ré[+~x»Ò úQüòŠKoûª1u+âSÆ•¾cÔþˆû1.Y~)ј:µ8/ž‚<´ÿGmZÅ•K“`DýÜŠ+²áo·0®~ñZoÄr¼ñK®Šo}M~Åøtª\‰¦Æ©ÅQÇ×"^+®¬>üË7D1Ü]Œ÷Éñq1¾GSÔˆ—ûi3׊·¸Œ÷ˆ¿vü]<µ89Àqm­Å•]CV<œñj·hï¡8Å8ŠSÌ‹gªøÙ.«à3§Þ¹ó£f¥+>f\5ãûìx]Œo}ú95ã‘o7s +ÆõÞÙr<èýˆ®8o|iŽ÷Åxµ¼MÙý4'»°r¥ì­¸Î¦xµù¯kiñŸÜãí÷œ¸Eñúçõf\ßëËxˆ Y)Έ:9N>­aÜ¢8 !Ý}‰×Swëä¯x(âÑ7»ì×ÃTèeÄïh÷¶±»á†â2!¨ŸcɆxÇxc÷Ïo ™‹O×ò€úÒsâÇ5 ¿×➈GW¼cifTâm-¾™ñºÇ ­Ýïàõ·>bö@üÃâÇõt0AñÞð¨ŒgªxϸŠ!܇ñÃ7D6€ë?ü‡ñˆŠSÓe’Ç¥¿ý·­ŠøÃ”â×üt"© ¨øaû§/ îÍxfX즸ÜýÂÌã±ûÜoþ;–âíÔx¥ù‘Ã¥÷wô×Wsüø##Çe þaφqm6<"ãR®ŠwŒ+£ÓGóa\3å°Sñáµã‘W»¼­R¼ÙN’®š>“Ì8^udâ¦ãŽâE+>1<šâ÷¶“ç€ú"ã9 ¾k1>«¸ñ â½æ1¯—¸Ýÿ¡jCëô™ÄÃò¿ÝEÓ2żÃR>éjÅ-ˆ;}мú³™–â=ã*EpÆ#½ðÙ¯âR\Š¿7ÂÁf4ƒê}ANCŸIŨ¿ÉŠ8óâG|&óoZ%p¼Ú[õ7Ó“qýË6^Ž?^Öãf«xø²ž ,Æ£*®%Æ«¦·Œx,Å»»«ú>K-W?AgG}Y5:Å?<§¸ŽjºØÇÑèma<  —ŠOïw;n.Qnÿ`¦êvƳŸÝSñÅb¼Z,>OWÊZ\¯5~×/ñ1ª(N‚ähøøp–êºÔG¡™§Í6¥û)þày2¾®Ñ f|oÅkÆUŽáKŒï‚ø@ñ®Ÿc<žâfù-Û±Œʼn‡f@=ƒÏaûÎ/³ˆOvp³ Ý{î2¼úÝLÔ»ãQTŽá9(Þã5£ãÅmšS<㺠§+@qøñØÅ!ˆË±Ä-ŽâÕp»â­Õ®ßùéœ{;¾TNU§ÔŠÏ¾ÕûÕ+Þ¨÷KÔ•Nñö9ñn~ÆQœÄa\~=í+æÈ#ßßfàx,ÅÍaõÅg|ÿiÆñlq?Äß®AVŠGz5óŠ?~ê»âjo«q¹§øM­âêªq §—%¡WŠZ¼¿eü?™y» ÿ_¿ÿû¿oVæƒUèÞ{½Ì1¾Iñªññù½_þýzòc|ÅëŸÚP¼ù¥ÁóâJö¤Y­x»Â­>£´]óFPœ¬/ǵ­]ܯÁ/yðt‹ÿù^×uüû¿¨x“^ñ é“CH=oÖ¯­Fü1ØþÓû/p“1ñ=7+þïïQxs=ö£O¯øÌmt3¤~w{xP»óY3ã0”MŠ›„ZÑkÅ9!ÅÉÆãí¢~'üË#Å}¿pkt)ÞIÞþšÖþ`üÏþÌxnl­ãG*>Wˆ¯A<ƒ>õö«Z0¾žפF·þ^3ŠùªÚ\(Žâd ãR$ÅÄ›ÛëÉÚmÐúl%a75®ã¿oü‚¥÷6¼Rüîøm‹â!3ã‘7è^P<¤®Îý€ÒôêR;¢>Q¼jÓ2ü½ï¦¸m4¤cœžÅI0ãŠt¸øqëZšœóR¬7 o[6(® ñG9¾—âq÷R\!…øã=þÚ×ÚdD~Œï1-^/Éx(.ËͶ{U[¤iñæ[½öšÌÎN^ŒÇŸÂ¡K%­¶­ã›ÖÕ†÷[9Ü«q–ªxÕ…êÿýÙhâj ߦøñ½÷|ÈìQ‰û´µZðGk˜ÚMq-uñjÎ_V|‚xDÅ ÇE1Žâd-#íB7­üuÞâ•áU¿¤újJñ%ÂW+Þ~bÅ«j\ €7‚¨xNµxs6©íš[R|Ãuª©â¯™Ãw:“âòþM¥ùˆÉ¥ÊñºךVÔ~Güc^9î/¶.ûþ?Ö¸-#nQ|f=zŸ?‹Á¸ˆMŒk_ÄïHk©?TqÛBOs,iûÝm¥xý;3Šoº×–«o‡Ó/1€§ì¾)¼Eý—ÿÒôö¾€t_‘®ñÚlÓp›âíú7ÆÛ‡ïJ¸âãR¼ù¤N{ªüŸÅP¼6Ü[ñê[兩ºB[ÖÔ¯Msˆâ¶ª÷0Å«‰´ÉsfÆ×/lîö²mñ̰ÔnO—9œN·€â$\ñGÝÝýŸˆßíþòPñ¡á³Åxg'w­"ˆqÙÿ‘Aôk¿ökÃJ|µâ-➊KŸùÌg63î¹k[My£³Íëk®S‹Ë2”špÿU-þâ}5® nÅ1|ªx󜸘Gq²]ñÆòPÄ¿<@ü1þ±q£»ÆßÌœKïò-Òcb\ýsâúù; ³Š?Ÿ(þ/wPüaøvÅCïÿZ»Ÿú×fsL[³Í"uJ³Hý 7Ùf®ÍŠŽg½ëWëtËo'ኇ0>D¼Uü6eÜZ™«ö¾Iÿ{ îUŒ«ÞÉí;¿ó;ë^vIñ_‹¢x‡¸ã5â[C¼Sük‹‚ºFÝGñ]^\{Ž™fGÌÍÚ"¼,+Óµâ·K+Îê¶²?¾ã?‡Ç@ú ƈ/(þ15ô…:Їã5àßÙüsȸMñã;(Þ"~g|GÅßîa÷Ñ¥¸­çÕa‹ÛªRü šu>Ö|ø âõä¸1«FG€âdâ+_©øhн™ã ã–çÇ+¾Í _V|âÕgä¡xø&Æ•PñcÇÓßíB¨ŸWü¦¨OˆË…x³—ÜM7Ž(Eq²ŽqãêëW?^¾ÈøtÞœÖØõsá¿þëËŠg=ª^®Ÿ2¾Eñvíùòº¶C`<«Ö&[!¾Ã+Ô­+Åç¶jYŠÛ—Ã×¥¸^íÆJPœ^^}9îÙ2¢)þø{ãÊTãÂïñ(Æ› òúíŠ+ÊxzÀº¶Œ#îÏx^Mͦø>#SÍ´¸–*S â¯I·«± ]ÿ9qIÞ*nyìÖ q¿õ™ srSoø¯{ã&çVÅûb|Óu­@ŃoOÜNý"ëRü KßKÑÆÓ]ßeü|™’ÝŸqúLbe\ß3º¬¥ïùžñ¯MfÅ{Æ×*þ1ZdÃxø”ñ׊um›× Åß.ˆøXñz¡Èw}W 8=_¸_PÚát›âX¨ÎÞm$-ãªÈî稆W1¯÷â_6ƒøæþî××)îb\û<+. âû*^íãVœâãêv#ý®Œ/îúò…*ZDDÜÆø¼ák@¸³ WžÝîø ïŠÄøÜ³àÕ‘f»0>ßÝÔnË@ÅQœlm2–¦cjílù—Ó)~GÆ5Qü÷äƒøŠ×¢áá³ã±ïÏϽŸ4€ïŠ¥øìÚðfÖԊϯlkÝ~mtBq£X¿îR<ãâ0®1â]1¾·âÄZÍN¬Îu雩øx3˜2ZV§x„b\󿧈Šk4(Žâ$eE®)ãNÁ£*þ-Ÿ7ön«¯‹q#žHñºÂýLH´Óúô…ÝJS|§uê‡]oz­Pß ¸Jîe·½z'KŠ«B¼V\³Šof¼Eüòå¸ZÇ[ÄŠk~iÛ^ŠßB_1;ÑñßUq:1^ïóR ¬V<ýî8 õŠ“”—WÅö迌â;ÝDiPŠ?ÆÔÿ¿³âSÄzáÁkÜtaÄwRß…ñùmÚª|OÅåÿ»iÇ)6~u'ÁdAñí;¿ÅûëÛD¼‘<ñøŠ¯4ü(Æ•ÙSf¾ç~×.ëÛšûÅÄŸü^[ÿ°¸.=-~‘Ér\ ûòãmÖ!N->ìã~o”•Š×ŒË—qµÒ‚øgÖG¿³û znˆû FU|ùO¤dÜwïÕ~›‚ Ô<–Ðèbß—œšñÎòMãé—_ßÖ¼Û›ÿ‘Š?ì–k<ý3%1®ü6|ñl×ÚQñvL=É%§OÎmädU<ù vtë¬è%I*Åg•®Bü[„ãÓj»HýÞÿˆcL]ú³úøGÉûsH:¶â{3žŸâ ¬Å÷ÙØ`<úÉ™Ÿ¬«Å Š“<ï'É}êò)â8>)Ççw(þ#N4.Hn³;â¡»¸m=%Ç Ôå]Œïv¤À£}<êååxƒø'ýÅQœd¦xÐb7«âߢþI•Ëž“2r©¸_µQ|òãÈåøå÷mDq’—â!£ëöbü¦ßþíß®nÚÿ½â›îŸUq9ß8ñýÏñz:ÃQ€Jñ{|ëæ0Äm_UÇq ÅI±Š»ÆÔ{]±åÊkÛ„ñÙý6‚?@ñõŒëk(PÜÏ‚Eqï©„ 9ªC¿;Añèˆ;Ÿ"þç¬ÈÍQu_Å—¶ûP¨â1®l?¹'¾Lpc1>øš!SI£8)TñÇÖmZT\^årÍ·w\C¹ëÔÿæ1”>WŒï¢øŒçw®¸¥©¿õ«¯Ê1'5T< ã#Þ?r¦RõZñÂÚ(N2SücÅåBü‚ŒwÃê2 7uoîP\ë×ÒÚôA3®|?²Û½+^Ç&yÆÓNPœì­¸ï“ãz¿æÿíñK2.sy›­+®%÷}&9q7ãzݱ¿zÃöëuV1®@ÁeA<ŸRüÈŽ·cü!ù¼¹a±NŠUœŽÿñ â¦â~ÅUnÝÁf3Ûaù¾/í~[­¸j¢-€¿nÒœ6.á”âËŒO&±7ýÍrwËWDjqrbÅ5V|ZŠ_žñªüÎHs«jýn¾Þ²âÆÕ•Ú“_{}Þñ…º¼~iÚP„çw"icêIoÆ[ãét¡(NŠT\> ÛÞ_Es¥øPñ?×EyK0˜[_§¸Låƒx7ºþø—Àû,þ5g”Ùç—#ãÞŠ/Oê¿®zUº¹B37QœœHñÁ¯ô„*þç¢Çýt×0®)ÏŠÁŠøÏ cs¼Ã}Öð¬×ÁÓ‹ÞŒoQü“jÿ¿]~çÉuÍÛD2gÜØ–Õ$|Èør-Ί‹ø…þVÅkÉ_} ã÷—ñs?·ä¸¿¦¹‘ôÏujÜ[q-"þÉO6G™Í¬‰‡§B烹,ã¶b¼|dø’âÉñûߥUí[Žkº ýõ­Ñd,ýƒƇŽwà~+W âõ}ÒÁßßd\NÆÝóâ¯úoçZO 6•ó²µøM–õèï—4A<@ñûWEñØÀ„*®Š¿>˜ÿ`ã?×ÏËøµrÏáÕ˜Œ›¾*F-nCœqH%'PÜ6¤þ~{©×_ƒ†µJ”ç̸ÁnÅ?8ŠUñVr•‰ø-‹uÚ^Œ¯|2פ%ˆã\мW$CÄ-Ïšù(>¿íËŸ×_‚†|„âú¶.Qÿལ^Òxú-‡Í3ŒÏ)î¹u<}4rO"òÌKDÜOqˬãRÅ#w^ŒÇE|ƒâ…!®,:Þ!ã²1®øèq¡8Š“!žHñ÷£xŠÏØçi³ÿ ŸâÅUâ’&+ã¯Ú—à ×Vè“]^\ãö$¦Î¼±d·R\óf|á<‡ñÝ—‰xBÅu>ÄêÈo>ËøHqy X0[«8Ws í é®Õ/9y1®Ù£I5OGñ#ŠñØŠ¿žBñ,?|$À“qü¶CH‡_?€q¹o=Š“Ã ·ï¤.ë:uYïÖCw†»½ñÙ¨¸")n)Ç·)®\/£<¾½ƒq…3î8Š£8É¡½|ySä<ÿdQñã}á­éCæâBÚχ)þzÅ[qeúæfñȸ›ñ®p÷“ËŠ¿ê½õ¬@ÅIŽŠßëxù!nR×£ÿL¸Ð#CãHºõ;ã7­YߦÂ*ñ<—ñö…µ¥µ÷Ë”â+•âÚÎVq>š‹(nà‰ø¨—u·ñ_áã‰øAÿ?Mô]Ô ž×–'PÜŠøÅóm M†½Ûj½oßR¼ì÷êû¬Ü!¥ß=¿âãÊvo“Aøû½BsŠv5vˆOÿ¶ÎòèÓâ+w(žuçŸÏk“ [ÆõjsT™O)îϸF߃KGÉ‘ˆ'¯½ ï÷%Æ“(n >P|˜cKq»â4†õŒ7Õ¸–üÍÁâí¿T¶¿º–ñáz¥¸.I¢8‰uÁ+þ~·âKE¶Ï0:Œ§ù Š*ðØÏ™­Eܪ8Maùb6,vŒªÏoOSýÅñ¦é.À­ŒËºuŒ&µ¸.ºó›"þ)BªËëï*Ôq½ßÉx(Ñ ¾?âCÅ%GAgÏâk§)ø\Ïr3î uªxϸÛnçqæ­ú•Þ£» ±ñŠ“(måïÞÎøÄñT†‚øI/ ~9âOŒbS<Êfüà£mÀÊó ^rk£EñÊñú² äcüÛ¦âAøài¶á&ëÝW™>evYÄרs{!^'xT]¶òø†¿_<1íÃþ g”ª·#¾Jqå1åõ2l њܖJñ˜u·üÆÜ¯Œ8óâ$jßÑêx°í•8ˆ—«ø–R||¤Í T ûB´¥sЃ—Ïßž(~'© 8‰ðq›ŠWãêò[ßðVq>àH CAˆ'Q¼š%_uº¸Jx·3{‘rγÆ&ÅõªcW¡›Uñ 3®U‚ÎÅç÷/ʵ+âã‘Ú…tl)^åÊñâ%´üæ~¬Cê ŠÅ¸V êæà>±i Û_^ë¦ý¿øÅYqYŠ÷Û€+ÎǯoàM¢xÈV.Ò•µBqb^ ±ÆÓßKñÖoÚs”Ʋ÷€úñAÕ¢8ŸÿJ$f53î(Åå×y™¯•Oůù9K‰ÿЬãÚ ñÛü쉢x¢õâ£Þ>DqtAætï¹Ûû%¾â¯nÕf{®a1.½Êõ}hcâÍ?îZÕ†³ÜŠÿ]}èCsŽïµ>ýþÙþeÅ-ŒGP×ðÔêu>ö }²‚ÔC‡Ôí#ê ÷ÜšŒ"ÊØ’}aõbŽ·wø‡¾ ø ãÚoeÛXuJòˆï«xØuu-æ÷¢\ŒGR|üœÙàsv^«Õ60Ö߬–ß7¤9§âBqRCÜŽ©GE<Æ›Ý)l¥9í{ 1?Äx„u §¯TœÏ:â¡ǹã‹]ñn×7»ãš,éiVÀ vŽ;9h(NF·ÿÁŸù,âµâwÇSüQ…÷–Q?¾N=¹Ÿ(£—!¸F]8ŠïÕ5hÑ^Ë_ÕÃûGÀ ŒƒP“åfCÙsäRÓ“Ë~Þ^ˆ;ßEñúÿ,ˆylÆ•ä ”Šð÷½ï}“Züþÿž[°ò!¯®Áç¦Æ_]˜µ^1šÞ£bnÅîÙgµR˽–^Aý¡NÐqÓô/‡x°iòBÜ9¨®†Ó«q)^ý!>ûÀ‘ºâIªøÿáCñäÆËx°îSŽß‹q>áÃt¯ªkâí_ê ñ™©qùŒ(nûÏQG¹ï:hûd‹â=âNÆ•ñÆoSäÓ­Û)Èz*y+ç`ñ‡áã2_í¸ã|’לÁ²»²ºVû3ËÛä1Їn»9Ùuèò€bœÆO6(n"îSßoû¶nË/NßÚ«{*ñ×ÄÇŠ7µy=̾€8ŸY"äÞÀÍŬV—âíâ´¡ÖjÎD5·Ø<ªÇ5Fß¶‚ý¬îÑüI4Å­ŒkGÅ›‹Å7ä»S"nW\â_ˆïóÉ;vŸH¢¥¸ùð·êïÔŒ§Ù¿›ì7£¡oÇ&ÿeöޝM-NΧ¸–0ndÅÛçÎÜÛ´’5Šßß¹;Ù ƒx­xÝdì#ê­ãÎJœÏ5-ãjeŒSŒËoeš×ëu†VO'Íý®ükÜQœ”ÒHôØ/Ýq[ež“â݃*4{Æ+Â;¸•â=âïkf`¥xóŒ§Ãxó‰8ÄÕ6ÄŒ‡zf*îx^N뺾¼æ ~YÓcPóp|wÅ—6j­˜Çñå|Óâ|ß÷}_û¤Y-öû¦±3Î'W›âu­+û!gZ?-.­~NÌXå6í—{ã™5W}wŠ”2ûœV+Îsår<Ôðšñ½ŸEÜ܆ãÏ<Ëq¥WüûzÄßgXîã8_Ä[õY;,Ç#Cï6oÑòK³]§’ñM¥énÆ?¿ò¼ñã ^ÍD+ Ï qçX;”¯S<Ö´xeøƒq»Ü#ÇQü(ÆÕò=ž!W?⢸ú÷Ú®}rÏ-s¬`ðõœŠß~­÷ßV¹vϸO|>öpóS|élSbe<±â¯wŠßV0Îç¶c1ÞŠ(ÍZë÷´ø’âæ ¤²®8ïŽQén3^]Vüók ò¼Ëq.Šø‡¼sÀ´ø¶§Í‰…ñäŠwŒ¿ï}ÁŒó©¥øÜý6o±ü5u{¨cÝ7˼âÝš4¹V£7ÀiP“/*¾r)c:¹ˆW^ƒxQŠSŽ»—öQÜñ¡â|f;2î1}mù"? (MGÀ­ç˜Ë8­¬_Ì69¨\¾¤ЇC®ñcì(N C\+Kñ’‡q‹âRjÄ_oW·y*>`œlGƵâkŒ7kQñn"\Æ­€4œ”_ž·+Š+ñf5Êû ÄãŠlx£xâÕé(JYŠÓ nþ{¬­ýÒƒñÚ°®n~ŽÛ¿;îeøãéóY¶ …þQÚ÷ÿP縼 ¡¡Ûo'ÇëYò˜†WŠß¦xuè¸P|_Æ#+nãöÙóùOF~ŠûЬϛб/+-› ÿP=ª®³ΨºMñú È¦—â"þú ÄëCS@|WÆû ›‹+Šâ“cÇGŒÏ(®Ùf æ)ËæC{%žŠ?ÊqÞp·vúŠZ½#^+þ¾÷­aœ^qOÆïÍ*~[u°·û´m…*nõY£RÜ_ñœkqrqÅï>_Áp·4‚¯D·Ûd|•âïãDÒ}OU‹ßê#Gb~yäNÅ?ïªÄe(®låä: þŠû þþs„½Õ‡ˆ£x$_Êe<™âázUqßh…(þyûrúî1¶)ô(NNËøYGòÝJñ×W¨¨x!¯Ù,“(>X¤~“¹9[<Â¦Ž‡+^¢ËV®+£5z)Sñ3!Ίõ¾ ¼žXq]Fñò^¨^­v4«øä|²­ˆkvaQñÏ÷Ô»¶WO“7•{×âûßûgѪ¨x΢øÙGñ}¿)«ÕmdB®w/½ò©§ÕˆÏ(>VŸS¼ßµ/¿g§Íi¢'(Žâë×8Ç*ÎÍŽµÞ¾Ï.K³ªêÕÅ;ÇëEóKÏ“gÔü¸H<ÅO‡8Œ›õØWÆ‰åøš‰ñÔu‚Fq±ˆb~™#ϽœÒN‡»~^}þ8Çu®vErbÅOkøW¬9XñÂ>œÒë×¹)Òûó­Õm‘ñeÅGŽÏÞ±èóŸÏd!ñèÃ/‹8Š×-à+ÅuغÊë½ oKƒgÇ'G†ëÐ÷ù {°â2Â8Š“¤å8Š_ñ×eÅw»‘?·5\a¯@_­¸Ï½G\ÅÛ#RhXä<Œ£8Å8ŠŸwDnâx[‚«ÿ…£|ñbÜg^<ìf$£J¹ˆgs½$â(VŒ¯]ºãet¶ƒÂ¼Åx¤Z|ÝfîG·D®«?¥â0¢xµ} ãUI“ã|';¾táóPøKÖçc3®C‹h«ÅQ< ãj†ÙÃKò ãE·(-B®Ý^Hð}‡>™qÿ"Z)žñs"ŽâŠký”ùšb¼Ì¦ø¥yɵÏû幓ܫµøŠUçÍÖ­G<ú¨“4)‚â(ž ã_SŒs4é¡’;ÏÿŒ³7LûEOùUâ—c¼0ËZ6iôËÁ¯[ÁÜ’LGñs_“KËÔÇ›»­P\(^"æijrÛ€Â.’!âÅû=صi…Û Ñ$uÞöÅ5F1^d)žkËu3Þf£â7?‘å6„}–tk¶Ø ©yë§Ø_í^ÞpoôÑ‘j›V¸iq+ؤ—¡g@}‹â_‰±#LslšnyºújÚNŠ5øMÿŒFßåéæ½„LÅ­w[|ÁþSjqB1Žâ3.o¿»)P? èuÕ;ºÕG“WN7[ÃèÖ>ÈÝÓoÞØœ_{_Ñ›>„zzb¸“ñÅ× ÁWÓmt’ºŠëÀóBuàç»ÃwrŠq/FñVr?]9%”ÛyuÅ KØ´°ÂMž?lý'XævõÂPŒ£xLÄý#þpÜ{~œOç|#£É ¿Ýn3åÿ”qÛ5W¥~ÉzžŠ—&99Å8Чx=AMqÆãŠjeé ÷úöãj}ÕÓŒAÏÊg¦¸Nå8lQÜ‹q›âíùâØºèÊ,ËÕ°öÜŠÝñ@÷„Šó#Èx¹Ê–“¾·+Þ8¾T’ó˸ÝêÃ1®µŒÿŸÍxü>qh[‹áªÙSñz\½:Ž\ηâi8*þƒúÙŸýÙ8Å8Ér—âGwØÓ%pᎃ Úßl'àuÔ7&×Ì,ù½yÓ=ñ³3¾Iq/ÆùŒŠ.È­ˆn‘&;­KǼŒ#2î^ëÖŽâ(¾¤xÍøB1ΧT²ã– 6ƒŠÒ<èlÛnªg›?òjãJ?Fñ)ãáù+N£ÙÌø6Åëb|ñ„”tu-àÒýt#ù¶‹}‘hd¯bÜ0<{Åi3ûã3Š?_T\`{–’|·O2`Ûñárú5I9ý@„lR|`xîŒs]¯x]‹Ï3.}œêT–gý­¤8'²í‘ß:®(>uf䛾©ÅiÇÑo>üŠß¿ìÇ?Žâ—n‘«:Ûø —IYhªwþŠ3H‰ñÊïæßÖ®ns<3®šp¿¶ÜZ…øçµÅަ8í.Z1>ôÜFù²â–b¼Ü¢8ŸÞù[áà<ò5Šo`Üg#˜½wŽn ŠÃøˆqGñVæ5ŠWÕ¸97óq3(~9ÄŸ4Õôýßl /#¾¥W¤?C½K(ÆA¼<Å{Çå©xÕWÜî·}DÏïìˆ÷Câ5ãçŽ=þNrÆ£ý!'ã žâ_‘©ócÉÛÊwuÛÍF7Š_¶ >ãJdÃqŸ£CŸlTiª¸f—±MŒwÕšó‹oòÄH;¼¾°+ŠQñ‡ãñÓ#þG½ÝMŽ¿SñÙNMŸýìgùOR[³´xíŠ3‰D²b<¯‚œËaWÅ;ÆmŠ?¯ÿxÌu?Á(¬âKBëIñŒ£8ÉLñ|ЧAü+î¹ïÅãk·?JüY?q!¾ ´N xÈà!‘ŸW<Ç™1«¸ñ„÷Î3îD|“â7Gq'dÅópœ‹!n)>w^ÙqÙŸߦø ůˆ¸üÔW<õÞmÔ$$*ãˈgá8ÍþÅð±1«\¥øòĸÂz»Jq?³âòSüDŸ÷O‚ì$­âÕ‚uøi÷T¼{€ÜVŠ{,oóïÂë¢>‹âe·Ãå•m^‹çPŒßb…û_ÿ-Ÿ¬dÜSñƒ%§¥øþà¬â‘ŠñÎp?o%^+®rjqíú5Ć $m-~ì–n4îŒ7æÅ—voóWü³ŸEñÒ*ïUŠÏLË÷´ƒ~Àîhü$½â‡1Î'ñ(Š/3¾Fq/AðÇèù9ù-OŸ±13Å£×óaSäÔåÄ—ñ@ÄQüêŠ×O§5Š?þ-F1./«Éu«ÕB—§âOt¼b‘kqíú}É…GñK"¾VñöÒ¶ÿÙÆQü|í­2q\›Ÿ*~xA®Œ¾ AqGñŠ›‡ˆJòíCê(^âOdûÖVÄ-_áƒÊ´f’šñBGñ£—m|QqïRÜTÆ3opœ—4[¡øQ帲üRÆQÄ×2îXÂIñ¡á(ž{)>Yx.Û¯oQ?Vñx“ò4f’šqGñ­ˆoU|d8ŠgÝÜ&w½Z}ù0³e’óQü¦ÿªHÓ˜Éækn–p¡8Š­¸P¼œîÄB­ßAÇ’fQŒÿ×¥Çâ¶*N#'QŒ…}«Û.‰ø.ŠË§}އÓQ<ëJ<Àlû¾/^›¾_ŒKi÷n+©‘sAfìxõü&Š£¸×ÃeIŸÔ៻]dÜÚžlÍÌÇ›Ÿâ1+­1 Å3ý`"*~ ã¥6£ô¯;µâÒ—¾ô¥•Šk±®›"þYÑiä\Ä`¼ÅÛ Ô¨cIæåx1Å8ФøÃðŠq+äZ­¸p&Å/PŒ»ŸדÌ/¤ (·ó"Q¯ê¡PÆ8ÚŒuŒâ â­äVÅޏ“pÏ»O‚¸ËñìWŒ½Ì™"{8þM+¢}-çJˆ¸—â2·¬kÕ¤øŒá(žoÿ¡ÍkÛ¬Ž/íý¦#âïYÎwf\m§p|â{®ÓØŽP\cÅ'¹[ñ¹ÎK ~á:|¨s¯œžäÆøfÁÿðs_ª)Æ ÊkYQGñ’_d¼ª#¾4ÍÀqçòõÛ:Ä?Kya#«O#{›q Æ›óT\ëþʽ7„ç®x×AC/µ/Cqجâ÷Þ":ãÕ¤à—¬ñP|~wYÅù¬3U<>ã¾›Ø$º”X¬âr|â(žÇ¸~è‡~h•ãš/Ä¿ô¥eÅ?.ïÑtù Žâ9"^ïÖò$Aº¡=9‰âãk8BìŽoCÅsø4¨ÉǵñãS—vËfm[qˆ?Ic¸ï¹¦Åís¦^t•QгMCq×e$Åwcœöµˆxå¸-óŒ7ñ›÷P\k¶kCñì’JñfT]O΢x3B6P½€¹q–¹•ʸTã4//Åñмy f"¹{F|Aq¿¹(^ â)ãñÛqÍb…mµé(sF¼„¹q®¼2—ž?ߨø>ŒÓÀV0¾Èz›Áoú îPܳ¿q_=î^Äö‡X)ÞÐØÏ‹'ø!¸^.ÏøñçEã´ÕŠ/ÿ®w½KÍV«KˆI«Gq?»âM-®AŽ·$ ãÄË(ƹ0ÞUâ5áâ^AqGñYÇÇ£é„$iiÏkÅ…â×R¼áû] ÝÝ¿ù3® ˆ³qˆŸ^ñÛhu!Iž¿â\QïÕgƒâþŸŠƒøÉ—Ísç& ¬ '+N)~"Å}Gq¿’⛾»fW^/–ªøs¡ø¥O¡xÈGÄ©¤ ëHòÞ­ÜM}ð¿ ý¦´?‚â(ª¸'ãÚ‚øŒâ|Ð(ž§ãë+âc^6WÒÕ.¦Å¯Äøœâ~ŒkÕƒâ(â98®]þ %5ÉXñvJñ3*îŸÖâ(âåMo¡XŸˆŠ7z{“ÊqJñò_P\aŠ¯Ù¡r7Äi;§BÎÝq?›â>Œk‹á;*NÓÙP}æˆx²Ùñ„-å°FHëGñi%þíÓ€xŒ/(îÁ¸V¦ï\‹“u€gJx™À\ø»“Ý_[Š£x‘Š/!îÁø6Åã!ÎÊ¡‚?ÉnQ?m5Nã&»).Ä—ÞÇ­¾ièY)îF|»âVÆùüQü´ŽÓ¸É^Š{w\±ôŸAÅQœauçÝÉQq ¾¸ÌM^°âšCܦ¸PÆa§ÈÁˆ¿-0óÃêlÏV®â÷]‚¾ˆ£ø•§uó†å©øœã¢/WñÄÇŠ¯ù…â(žHñ[­›ì¡¸V(îv\^¬âšO)¾îS+N[ØÛ”ó2Žâ”Û(Ãq1˜ž-㋊ÿâ/z+¾Z_ ÃQ< ã(NP<†ã(ž±â¿¨Mˆ÷ŒoÒWŽâ)8Cq‚â1—Çžé¼ý™(þx¼ßsyú@ñŸ`]ŽÓŽj#gU<×û&B²Vܲó •x®Œß™Öø©25’ËñFñí!ÇßWŠŸ·Gq‚⿱yÇiÕ¹(®~{ô*K€WÙ:šNPÅ ‰‹øÅ-¥øãWQ<[Å Æ}joSñÿñ?*ÅEÇTpëÐcä Œ£89•âÏ÷Uœf‡âˆ?¿;c8¨øc*ƒbÅIvWæAŠÛ–¨£x¾Œ?FÔµñÿ¡Ãxé½Å¡8Š“ò?›TŠ×_J(ž­â›JqŠñ3Üó?aD)Hù—ò󊻟WœwÿhÅ}Ö²Í)ÎGXróx‚â(NΦ¸¢)Þ~!Ï“q5+ÍqEÔ ©óŒXñŒ£8Š_®ÕŸ^ñ؈£x¾ŠoÈÃñê+ð¢8û¾ 8ˆç£øúR¼Jÿ xW‰ó¤Ù)8â0Žâ(NNRŠ,7nÄyf¹2¾UñÆrÞaGñ+)N§{)þ¶¨YÞ€•Q¶â|~0ŽâÔâ$ŵ¯á(~$ã(NPŹ9—â‘çTÒ¬GqrnƱPŠ'.ÄQ|¯¸r\ çDqGqrÊRÜÇpß±¬9¤'bÅ Š'GÅw,Çï䚆‹Rœ 8Š“S)âgþ”+t ÄߊÃ8Œ£8¹„➈£øÎŠÿbû8x®?ú£?ˆ£8Š£8ÉVq¿ã«·iû£?š2ÎçãWR\q¿—ÉWq?›âµácÆùüPœRœZœä£¸´ç#f(^ãâÆùø`ÅQœœRq?—â Žâ(Žâ${ÄŸƒ8Œƒ8Š£8Š“‹+â§+Æâ0âQçú!ù*®åSÌ@¼PÆAÅQœZœœ\q黿{Áñêqe/Nq8Œ£8µ8ÉWqE2ü»—¿·_/ŽñÁ>1|z(â(NN©øw÷2ãñâÿEžGq¨8!y"Þ)~w|nDÄËcÄaÅQœ\¥¯Ëq{A^ÍŠó®¬8ŸŠƒ8Š“ó+îpü>œN;.Zq>>GñŠs‘Š+¾â•ã ~6ÆùüPÅ©ÅÉEŸ.sc4½tÅùüPÜÑ:9+~D[æú!¥)>rÄKgœÏÅýo¿æQ˜gÚR¹€H2ÅŸ§R|À8M¸pÅùQÜðÁ—Þ]r'×+ÆS)nÌŽÓ‚ gœŃ?Fò\›*—I¨¸R)Þ—ã´à²çóCq·à~ßB(NH"ÅŸ'T¼eœ\2â¬i@q—á»ü¥#Žâ¤TÅë½ÜhÀ#Žá(ÁpW9.'$oÅ…âe+Îg‡âQ ·›Øíù6W.$’PñŒk¾§—Ê8ŠÇ2Üömyœ=ãæÊ•D"¾]ñÙu (Wq>:f¸eH]±7œÉù=¦™‘R§ñË8ŸÝEÚ…vÃRIϺ½r1‘í%šâ3ˆ7m·TÅ1œBß«;„ü Š{C+#—â ãä ÕfÿÙó FÚÃðAùªx›éÀwŽ«ŽŒxœÆyK 9äûÜ«¾;ƒâ7¿7.’d]ŠWO›ñ¦B‚õ+ñ›Þóž÷,CNIò.Å)Ç !ë:£”Úûèáø{„â¤tÅaœÆß­[LSôcfBqr$â(N9Âpã‘¶ò_`œî‘ 8!äL†Ë\¿©?¾ëŠ“ÃGqBÈQÿQ¶â ãBqRp)ã„Õ½RÙ›¯ÞïHªb\(Nv/Åßö6'„”ËxýŽæ‡ÔéIªRümoƒqBŠGQÜùÜ8}#qBŒg{šÙCq¡8AñßPÚ!—W¼Þ‹Î9®N7Aâµ´d³â—-Ź> 9Žñl®?=vbEq²g%ÎÚ6BHáŠçÓïT{¿¸ž§{$(Nñ|oO·yÚÝ#É_qZ)!d[÷æø^©*^;>:#…þ‘dÏ8”\EÞƒW~DÏø{4^§ÕܧBÒ8>=óLYÞKŠ¿g‡rþ+MNÄéŠÓ·rÙËJ¹ã£}iPœìˆ8ŠBJQ<ÓÕb€=ƒ8Š“Ã—¹¿[¾BޝÅsYÛ¦Vl¡8ÉWñvÃU qBÈAýÖ“n'´öÒ,z£Fñöũٴí†â$/Åóºû%„\ñöœñîÀÒ<¯vZmä–Ûp'(N!G*>Ìñ]Óøq¹ Gq±á5AqBŠÇAü=Íi3š‘DS¼-ÉQœR*ãy!þžÅ—COJ¢"Žâ„§ø"ãô¤$VË{®qßçÅëe¼s„_‹8}(‰‹xÀ¼xýÈ8-’ãy)¾üjèCILÅÔW'„äÇx†kÛPœì‚øs)LñfËš !$ÆÅŠ“l×­;Ѭú'„à¥%1n,5w¨ŒBJ¸% WEüQŽ?wˆB#„'ù¶¡Á ·8µx}Vo.!„ 8I[‰«ù_ǹfÁ{W=Æçåø¯°ñ!„ 8I\Š7ÿó¼f\‡Ô+ë‡ÐåW~Å !ÅIÚ6ÔÎŒw+ÕW3^Õá¿Òá„‚â$}1®þÏ-Oœ2Îh:!„ 8Ù«UŒßêsÍÌGΚ¬ZàFË$„úJ²S+R³F½7|D9ï!„Ä—˜Î•Äj…m-n+Çig„‚â$Ó¨f›±¾­1¼Åœ7‰B2» ¤c¼~Úìy»¶í±ÈMíR·ŠsÞ$BÌû^BPœäåx3¦^Þÿ5¶s£×"Ç Š“¬;¥ òçæ·®GqBAq’5Þ¬r«än~­.Ï߆ã„‚â$sÇëùq5ˆ7ÿ^oæ†ã„‚â$ośм_¶þ¼ß“Ç !ÅI抷›¨Êœ/å¬qžn'„ 8¹n{jønÔ‡µxåx}¤!ÅÉE!ïŠqu³Ê8n¼€z¼:V«žÂõL.ب›¸µ‹ÔßVŽã{_¡'„ *=IѨŒ ò†òáãF±žo=ÎÅAÉT:*’¨W»Œ=ù·>® B·äÒ’· ÷œÓæ!ÅIIE¹q6)qBŠ“BërB!(NŠtœæF!(NJ®Çio„‚â„BAqB!Å áR"„ºB!„ 8!\L„:B!„ 8!羜¸ž!(N!„'„BPœB!(N!„ÐéB!(N!„'„ Š·€B§CW!„ÐçB!(N!„'„ë‰Bèu!„'„p-Bèy!„‚â„BAqB!Å !„‚â„BAqB|9­œ‚â„ì¸Àœ‚â„BAqBÖVÕ¢áBŠ“2§ÝBŠB!(N!„'„BŠ“5Ðv9!„'¥ Žá„‚â¤HÁy!Å €Bвá N!(Nh”„B‡IÈñmòQ S£BŠ“Âi³u:cí„‚â¤0Áõîw¿»ªÃœBPœ”%¸Q€ÓZ !ÅI~W5øñnDBГܛbëwe8sá„‚â$ÿ–øn âª-çý!„'y6B5ÿ^ã­feo!„ 8ÉðÚéÇ¿½{8’Þ6Q'„'yÞx=œ ç!„'¥´Á~, !HÆÏNʪÆ'„Ó0 Áï{å%°t–äèËo¸š–I8¬èF.ë8}%ÉGqÞ B¼G{3”sAêÒ'9´Ýõ‹Ú˜'äоàKP(NȾ÷üÃ)Ä ¡‹Gq>bRR£ïñÂv«ä¨ÛJZßøÝ(æmT»@ö²Ÿ–ÑäÌ…é áÔää(±&7“Eþ$a?¶ûwVÝUOÞÆ½n»TþG‡â¤DÄÇÝæ»u£"ûþn{Êk‹µ¨<$ö$³¿‘iÞ@iîc¼Ü\>¿ô¯ƒN“ÒãŒîÙÑ›ìMø»SäÛç…—ß›Žó¤®ÄÔí°Ç‡fýÔý 'Ù½± O-#dÿºH^”vc¬ Y§£÷÷1{úEG/ ñŒJô´ß”N”ìÚÍ‹”!t²wìšœ·?% +ho;Å|+Cnò*ÚK9UÇCJvêjÞ­éªtÞrHÉB¦þª":ÉW¾â?êy$§%;õžãžÃÉ÷’}¾f8»Ï•s̛ӓ’}:ÏQýƒádOøú‹ÔëïÙócwrÍ÷û(QœÛvÿ²6²kËëgLWÉ%5½w(ɩŠñmlq²—àÎÆÓüˆÕw(NÈ\ƒ£'»•àEÖø1%yyÓät¦äÄßÍ3fä%xÅü¸Š¼¼vzR²s;YÞ†çä„%øÆ<“Õë… IÿIŽªÅ1œœ¸_Í8†gNyv]=(9Dñ~#‡ñ&‹4IÒ—Ö>3/™?‡µh Ï}{~‡ Òe’„ðô—&W ÝÈ ßÒ&ܹ#â¥;>¸«ÌïÑ4zP’p|S·EÇ»?DS$.Μ3”*…ßË2sX—ëÑ´ã×´Óu’„Ûº0çÚ#'%‹v™Ùeª üÔ¼ÿÌ ='I8ÚÚ³]”êíYiŒÄÝTª62ZG¡ü»y¿ì:Š“rË( ã‹}”¨ÅÉü,wó(oÛo•ñHµ<~br'Gw½æܬg—-3NS¼8ßž˜ImŠ2ߪáû¤£ì(N ì~ÝCêM=²Ü]éÆÜxaŸ{”¦^‹#xÙ‹ëI)%9½&‰WˆobÁ3þD'h¯<òcµÜçêÇœ’ÅIî3NKŒôÎo)›ÏÎÙÉ©ðŒé—‘ÛÒœeûx üB’ï9}'InxÓ§Éïæ•š|˼Øk¸ö”ìŽá6{ 1ÃÝוWn5 DdèñKbžNtzLiÖìóí“Þ^õ -rËìÑUØÆçûúá•å¸ÞmÝøˆ·Ñ£ŠNŸI"ømD]QŒS‹¯yó'Føm=Щ{lË'Á[NÆ¢£89pçoãõSD¼±~`ßì»Ü.®ŒFï]GÕ1œx•/(NqÅ¡„s´Ü{U_¡S²5û†iô?zn8âd¦,Gq’‡ëK“ÞÁïèp“Þk¹Ò € w&†£8Y,É…âäЩq-Ùøèø3þ Ý`p¼HÄùÄÈÚÛ??<þ׃¨͆*à᳤”ñt>E²~&ÅÏ8r=,Ǻ?òÑ=„eÛyL ¶_…F §é8!i §Ã<çžpka–¶é³:’qØSôÈøM’§£øéXOý]ŒÿY,m›±H=ìC¥c#„RÅO]‹ý•¡Æk¿ï»—Žkr¿4JœINˆ£øùúô­_¡®y|)­ÔRœõ^¼úBub Áp?OÞ¼òDç^`µ_P¡30í:x áK/gÝÉVWgœ.‹!¾¡Ç@ÊÀáè]¿ï\¦Õ±ýíù¿ÙWHƒ[‹Á<¸Fã+ñÖÅŸ§ 'ÄQðJµ¸ç~`lu‰æ»6G>BHìîîŠóâô¦”æûNàðYB’ötW«ÅùØ)ÍãS Û„cû¹ë¬Q§ŸEójó–Brëå.ô¤ÝðÅ5g\œã…?/N× æâiCBÈÙº¶KíúB_M“×ÀoÞB”¤8Ÿ÷åÛ;~B ¼LÅé¹É»ñ›rjÊu^Åé½ !„P–—ººÏ–BÈ?e-â„B®QŠO‚â„BÈ l/øyq>GB!€¾T¦³FB)Ruå½ë ;uB!³¬ßò'SB!^åyX²qØ !„\Pñ¨7ì„BH1ŠÏ¢ÎÄ:!„RŽâ;êó£ý|¸„BP|Ô}gåùø!„ ø1ß !„B'„BŠB!(N!„'„BŠB!Å !„'„BŠB!Å !„'„BŠB!Å !„‚â„BŠB!Å !„‚â„BŠB!Å !„‚â„BAqB!Å !„‚â„BAqB!Å !„RFþ%5àlöiÏIEND®B`‚rgl/inst/textures/refmap.png0000644000176200001440000004162614100762640015667 0ustar liggesusers‰PNG  IHDR,bÕr•gAMA± üaCMIDATxÚí½}Œl[v¶~kïSÕÝ÷¾a2 6 q……$"Š@ åC‘@"ùEQþA‘¢HAùPPÀ‘I€(B–ljÛ(±VH˜±H;€• ä|xæÍ›±#EvÆ3ïÝw»»ÎÙkå}ΩSU{WŸU·êvÕíõë§==u»OŸ³ÏÞ¿½¾þøŸÿYÀJD`k<ä˜+@UÉqAHb|ÁÑçìqêýË>ŇãRà„åp8œ°‡Ã Ëáp8a9‡–Ãáp8a9ާü»ßÿ^ñDÊñ/Ö8,kÜÓ©ã8Ì¿ÈYÝ[Ãæ<ëõ¼fÓþ=Öºr Ëáp¸Jèp8NX‡Ã Ëáp8œ°‡Ã Ëáp8a9— Aúo||”‘N8Vã°ªHB§¬‡unõª<.ì"¡Lß¼Ñ%,Ç*gùø&ŽNX‡ÃmX‡Ãá„åp8œ°‡Ã Ëáp8œ°‡ÖC¿ÀÌ̦ãC±ðHð¥àp¸„åp8NX‡Ã Ëáp8œ°‡Ã Ëáp8a9Ç›AXr±£Ãá¸`à?øþ/™~A5”`G‚‚8~¢Q’á:'Tž[/Dz+!„µõöX!‡ÇºëîäèEŽpÖp8žœJèp8NX‡Ãá„åp8œ°‡Ã Ëáp8œ°Ç凕ûíèn_‹‰3ÒpÒË‹”#TÏ-.æR`]WÖ¸$ëuŽuÿþÞ]Âr8NX‡Ãá„õ´to/Í|Ôy³Îçc•Ìö÷î„åp8œ°.a¹„å––Ãáp‘°,õ¤ tN%ì"ÒÌÑ8?>úèã Gü‰O¿oª*•·1 Ñ«ŒP-~Óu„L¼Å™æX!ÐéHI·>É#8œ´Î—>>…±VÏŽaÛ_ø?h+àô8¥;P'Dªªƒ@²\ ø3«ŽWC- šÙf•r–GŽ‹Ù_|éà-éާftw¸„åp¸„å–Ãáp Ë%,‡Ã%,‡Ãá8cⳆ54ç$sdOéQÂÊ×¥”Š×·U/ìRúÖ9Îsýk½¹Jèp8žœ°‡«„oŠJ("éîp¸„åp8.aUªå*>VS+¬Æõ‹i&òÔ6ê…8CN½~\Âr8—£šêOA­õk^“B;ûþ×WÛõ}ôÑÇÓŽòÓ_œ_j`¢Â¿‡ÐCOo²6Þÿ ¯ïã8æz"¯ÿïFæ“Þÿ±®¤‘)‰¬$ £²’@.w]áO~ú‹v«QAz !TtÚàrìD­þÑÉ…næ“Þÿ±®´yND4_&P‚\ôºÂŸúÁ÷ŽBXµé„å„u‰„u)™*Æû¹pÂ:àíŠïF‡Ãñ8Ö÷þ_4þŠ˜N—°\ºD ëb Æç…\´Ìáa ÇÓ‘OäÒ5$üÇÿå{Æ_±=°KX.a]¢„u)µv›Ú“³a9ŽK=G.^Fü¾ÿÊ&aYݽ)yê°KR/1=5Ú+yÉ«Ïÿ£IÐþÂ'¸Ë‘°þë/˜~¡÷Qct—°ÞlœÚ¦ãP# ºd*¦P¬s³åáOÿ°-¬A’íÁDø"6†ã<ß‹«„GU Å8zñ„e¬uÂr¸„ubÂ2dž\|jÎò#F£{²ÍqÂËÈçx\¸„5C¼Ñ_~jŽZþóþ}ŽíqRø Ÿà½ÐüÿjT`ºÈÿc"Xþ{‘õãk3ÕðÜñ<¯ÿúÎùÇßoæ²Ù)ÿ;íÍàÏüÈ—íæ¤4•FÓRå0äõ†„ÌEQ¬„#BG©·e.ÒÓˆtÖh¹×«ñeÚ‹§§­€âé+ž•mÎJC|Ðér²uRYÿµòSVþÌÿ¢ñndú„3žÓ6¡R¹`h¬6²ƒë”õ†Œ×?3§•nŸxŸ•mNZ?Gxä#Ùˆå Â2Ü¿YÂÂPfx‹°êã8„¥U"ã£làê‰wH6üÖìËŸa1óI ëÜÌXǺŸ½Fñù¯ Ç2UÂÒÙ kÔþì~åÕ KU‹°Taúµ“äM%¬S\€§‡uZ²±Õ19ë8„U¿ÿzŠšîöGß?l¢_3aÕ è¤/†O\oˆ"¬320ŸšOÌËÈm¬_Gm뇎C Ç RK˜[yî/|ù° ÿšUÂúýàÄ/ÆÂ)‡Ô²]ß*ÑœZ¥:/ ëôAF'&,=Èè~„W|$ÂRk2¶™îî/¼o|°2aíÐ#ÖÞ>‚„u,Â=µ—çÜ‹ù´4Á‡ìÆrhÍx|4ÉñÄúiUBûý[mX¼>—æŒÃ³í‚‡°Õ¹]ß~?ç9­kGíyÀZÕW«`­\Ç6ïéļ~LóöŸý7_*FµÐ1J5‰ª2"¶ X{OòÓª„uÉKަž–VŽsýǪ´ V“Dc½O¦ò Õ½½¶¸0æx”x±J_Îê„ZGD𯶯£•xÆ×БÒtÿ)¥âýWß×Àè…qÜÓïGyjwt<9! ÐISmØvÙ³ž‹ã9…éâ†NÛ½ã(ž\ìý÷"Þü·öçüK5IdêQiÌì4/ÒÝ.AOx%[¨¬[‰Êã yœëËVUï/©õ×u„ –U›‘цØbwOïõ³ÚÕÙnµçsÿÕyûþ¿Xö¦”Š„%©÷Jœ9aYUÅ#qÊ©#•«×?µJX»{k¤»é>a6º ‡“>爫ïѼ„Ge+Óü›—ðþòWj„5%‹ž°„$Ö†c i+a™Ož3 ­]ÿ‘6žZ#ÝM÷ ¢6„ÊöaúÚ‰æxÞØGòÑJ`ºF´]¾FXS‚Ø%,Ú UÕú‹7¦ÎÔŽN#a­xþ…Ö©7^åse>áÆ>€°˜ÉDX'Oµ1™&ŽÇ÷8)Möû‚-ÒýÓ?aQ …Uš“Ú°jkm*ñmJd¶Õ(aá BÑ×ýSKXu"Ó£\JX$¬òu €<Š Ë¬;UסQÂ"Ûû:=l÷ØtxüÀ_~ïÁ ذiP ÖX…Jë™÷>n2–ÕD¦zQpvyœ޶ëÓùV0KX6‚ A­f9Ûü4oG(wS!¬\À—MXÖ=Œú+ïÏŸP%î:]SX¶Ä«*(LfªaPbÑ%º¶Ùoʹþ‘ˆå„5¨0 RMÂ"PA z£ ͬWŪDÓ‚¶ÖÛ:Ž%Y¶m³šQ¼A®`Ô²ÅH(Fk,Ç7UâžêwY+sT±éž‰H¹x”÷/ €âþ*¯eU=S¨Wµ,jüÐ_ù’é}µDs0i"UQ…BAP&”ý}lÖ$Îm˜Plü„X2?L-)%P(J( )&TÝöæ¿0ÖÌVör¾„u¤‘+œ 1•³vð— b7êzeÙá0SÃ\‚ÓÒ©íöªWY ˜ÈJ‡&ÿÏ Ðe×-~øx¾„"D)‰(2I©H’qò3aa*ä“abƒàMæžžo | $…Ì–7x8yæF«-nˆM ˆˆpˆHL¯?"¹á-F²ÆY$>ˆ=l¢¼‰ËØX›¨'Äùןþ¡ñß3®”Ù6D¥ùN aI"Å¿bÓýÔÅ[2\ ÍzÉ슻?úW¿bIèEÓ¬ª¬}…ƒÄÊkÛ–2¥ ›ÔÚjÓn‰å¢Y¯v˜Pµ§ò˜ê;0G“½Œââõä[C .”¢Ñ-mSQÍÕ)$D[à+õ«a6ÝR Bšw÷°Uí:‰’iý[â6qØÂ¶ý¯ü·ŸýÅòÆ«©Tªª)SÁHX[­ç7ÉT[OâPË™·m[P-"‚HU :<Œ¶³@fçˆe[ßÙ£^¢·3y9ƒEe>€@Ùh# |XüÝìþ€’Ð&U½F4§—¾òûU²õ€?!aõ÷oºŸ¿ø×¾" Vš3æJcdÃh“SÁ¤˜ÆNÍâSÂÒÂb©{ ÷¸[òcoÝm6£>§ ˜O@ö” %›‚vXµƒW¶aÕ$¢dJ- kÓõ¬ù¬q«^?#ÖË*Õ“–AÞù  Ÿ²°’@fî/E”?§$¥ýXÝíU2 ¼/*û…óùA@LåëBùþ­ÖO|îý²/J š%MUž±xžªAUG%1Ó–&év$,Þñ®Wec¿œž½«,Š”HBª„”7ð!ÕŒ„eÕ2¬*ŒµZÔhä&µà¢9Ϋb£Ü÷-DÁDeÅÆÈ¶>éG’âþb $¿i`šÿó½Cmk§üfŠûýåçû°AR¼Nï~>9ãg¯‡ÿþóï——$ÝýÙͼ°7k”³Dd”³:í&×`¥lh'ˆ×Ÿç&±)TªZ SDEåù'€€"Ø"  ¥CÜð3 ¢>ÖŒ F‰Ãï#ÉX°mòm͆XóBšž—UBÅk¹¯ä±%Y½¦Ç‹zl–.æKL"å@ j“—d_Ö%*Îÿøƒó%8üÕ¿õÓÝÔ™yCI¬W#aõvtUˆ&RJ”H!HªP"VVF>‰ò %¡¢Ê0>ð4`U@`V–µ´§¡€T àÝS… Å­mýÜj3é 'ü†”:ë­Uú9>¤Ï;ÀæÚ hs<$æ_GéZîk"m~>T™ŽÔ7Ù”,ÁŒRçX .2U—®³õÍðÅV2•¶išâä@“Aà YSÖL'FU6¯]?2ï_SYRÃOþíÿËb!$ôí€Ïµ‹p4ë*E¤)K^Ù¬•ÿ'Æ8z¬sÁ5pôNNG­rÈg®ü7¨±9ä¢(²j41ÛÖcË­£aÏ #0'o‹Í¯¶>\S9káÔjdE0Ù°æ³U¾{Mí.[ÑfŠþdÌÆxñ–ì¹õ9HiBpŽD®ïkŸ[2·I RvŽU¡Ù1d‰Ô·õ4°I¬LÁâE|îç¾`÷vªØl”=ܰª²R{w™z{Û|zÛü4•š…HK¡=ÙK²Ýª‡ˆ‹.û@9œµ?IºTbh–uü×ì Š³ E@Z¹~5.LË6£Jä7‹Øbùj„Õu]…°‚°p˜ næóÒ›ÚT¨é9H‰¤ƒÎ&,HJ+°’òtmš»#Iâ¤]‰,«ÓÃæhc¤ùqL‚aúg›%,êýH³‚@‘-šþæÿö%“J‚ †ÂæÉ¿á«„¤)fâI”Þ„EćR³yÕëA/á´Ä;C! s¨d°a)­hÇH?ÞÏöÙFŠNæŠoA€r\[mǰ˜¿N˜¶Æ¥¤й´mÛž”°Š÷ÃZ­([%¬¿þ3_´œ¨’¥¢’£Ò7²”®b3Qªx—•úOBŸ¤X"¬ÔvÙ>5•ÂÝJ” ånjOЩÐÐI‰™×æê‰W¶d% '±œ¢ë:‹ÄÄ5£»•°ôþ³ŒÄJ)©EePc£Í=‘ˆ‚JQ%¬¡Ë.÷ ‹ˆ8)—n«ÎÒ0*8Yê—¡O›+q ©!LAZÉ­JXGêËY[oe·hÍ«ˆŸü©÷Lóžå„IÝ®q¬›ñûÑ V®Ë„UŸ#s{®Ê°àhæñûÚXNq¨­ë[ yŒJ ÑÞ’¾†ù)ë}“Ÿß¤-¨˜Ð¼8ÊAr´>’F/K2¼°RÑú)ì~>$ú›Rsl5ì(`i›Sq5¨æûÿñŸ|ß$â2 •ó²QsWà j0*ïQ CXбùÖ#XU•b®J˜Ÿ§#¬ýBVI+„-’¾÷ò¼jY›zꌟÛ$5e[œZ-µf²¨¨Û»Q {X*^ukü]Õ+g¬î“j ¬±öìuò—þ§/›T¡ltÜ%¬1wëH¦ß£ÚOÚ2"iñþÍ ý"›§ær:óŸ·^ƒ|ÏüIª(ve‚æ.he€Ï‰°l62%B´UÔ4•0&ªª…qØÖy=ÑÒzŸåÌÖšñà.•ÛUmˆL&¯+~âså&•œÊPÈVgŽcÒŒ*†2/,‚ÑÂ:R[*‰Tð;š å![ÒîóJ*'{ï ã8 $ñ.gm=ø8s˜^}Ãz0Ô~~n2-‡¦ØE¦V½ ‘_‹¯íöêþ1Õ5c. ܘLÅúq½œ³½–­¨EcPcÛ7Âgæ+¦_褵Ô]ªvU)»Q‰˜Ù$aÕî³¶ |ï ª9Yíüë8u¦œ\ËU¬T_°ªl•à˜ló_MÊ­ü¼Ù(‹zUÍQ¡«¶3…M[ï?«Sðà}ÕúhÕ0‹DliR£ÆIdJÞÆgö=›ˆb´õD2Äõˆ½«M0.ˆ…ÑfQCNÞ®<×\/ÕªF“Æ.ÑØ’«Çü6blRýj¬§S /¨¨œIrìîÌû·СŠÃ¼ä ¹œång¹\R.I¬ó)·Xª¸V0¨ZM¡Ú |Ñ~[EV|æg~Áv²!…°jV°lÏõÏL?o$,1©ŠƒJH²µÕ²IX 1åB‘”U°Ñ‹È¬„EŒýmë-€‹¾¾âîö]æ¤754UÑdªç€ù©9Y (ÚÝkÕ¹±ÚXm¹¥øÌÏüŸ[ “­í‡JöQ—ÎÖ„â‰g]ˆµ>j0éüÕBkû*”Η°ª„U¯âpÚb’ÔV¾F³1½ªS¥¦b€€ºÇkÛÁQ.\Y˜Ê)2‘C=¥fn*BR[Ný ˆ¥ÔŸêÁSU9©Swغdá³?m(‘,¹'†ÅèÄû– üÜ®M¦f µHÙ¨åø—¢-G¬æÅ`Æ"¥d‰ìçšd2öïstÆð-wº±œVÔLMòw­‘ôµF§CeÁíÍÝ„ eÉ+%©Eˆ{ÛñÌ|EíTf'c[»1 Q'6Ó„9óá³?mˆtš8Œ¸\ÙG5‰ƒ*Q(Õz=D¦2s¯ìåYh¾N.D1¥"…Ð%0ÏÚ%¥ª’‹ÍbU½÷¯ÍÂ&q×Rg‹«ŠWQŠ+´8ÿ¬“\Í1†Pm¯W²a•›2©ís¿BñóìÛßýÑùaO“¾Ÿs×§5¼Ÿù©/‹6S2,ľ Ñ1¼EÕ“YOêV¯t¬¥"I°ê6»xâ®×Û2ªó75ÝcŠí_ûÊÑ ûq{ªkÌrÁ˜y_{ÝÃÕÈcKri®7gùyÈüdW…ÈÔ†KDLÉ®µ6uÉÅ Vk„9)ø÷Ђ˫(ÙÜê)%KêŒBS±ÓráØGr2ôõ“ú9?Ü¿’ê‘âµÈoUK]³1yû•;~Ë+)hÝ®o¡(ß·2¶Ñ›×çÛ¸ ’%,Kà/”Kô±²r_*"b’&AdÐ|å\pü~—%»ñµª’G$“ñ~óí†Þ†l{ ¬ ùmšºÎÖ´¢Vƒ­¶a²uf«t)íôVÑiH*O«-f ºUlqßFêrãÏÞé¢c™ìŠZjs]霬L%¬&1R1Œ V ÎªÇÆ!À*šÄ”\mÊ@P¢”tO ÷v@²rJ$Äó½œIË™!U'[͆U\@qlÕ•Ã(6jIáU7@‹åª6Ž´¿ËÀö†Œ ÍTc­–©¬v¶NÎ(ר®<5ºÖæ}KJB<Û-µ\¹ªÍ#qðFo"% ŬYÆ:ŽÒˇ[/·jã„Ä­Ÿ·ÚÂjÉü™uv ã±FûlÉÅqc˜ßæ D1ç-Ì®6Q$î=ŸwRÎ샇(¥røª—ÜXq ŸýiKà¨æ—››ÖФ,:1O{êÈ«Í+Ót“)sU#ã£ÍëTé+?_ék*¶-Œ u†Hwµmg,m4~„µ6ó”„Š|bêÄ¥¸[P°xÿc5‹97ª´ó +†`‰´–Z=¬Z}+kéuÃù½7ú¦"×Öjl7ƒ´E[Ö8 j‡“–Ù(n “ʱsOT$*—©¨v4íŠ´Ó IH!¬q‚u/¡IÂxÌøgîÇõDôСų¶áeë¶Ùžò/P X—(: 4ûƒnצ¢CÖm(Æ8#³Õϰ¡ýù17—(UÂVŠ J¹º@/£íôdåDÊÂÙÎ! ÏY„¥Ü¶™¢7èæ¨¡ŠUçÛPcªÒAÉØóÃ>4'›ÂkäÕUÂZŠšÄB(!‡¶•›MXÿóϾo5^Ž]šsR`¼} K5aSbÚW¯ Ê*¼#aí›89NeËzœQ°”[QkA¸Ú Výy"™íõãD*0´ªç8£éf€èÚÜžMï ’ ¿á„¥@×þ aÕm@¹o¯Ái ¹}æì¤¶úVF}G‰‡Öçó®/"I óskŸ—sg¬·Í÷(›¶ì‡6‘*%w«ëùó÷—¬–&Õ¤ªk‡4rwl¶³?І¥ªc­Ü=p«uø–[—!»]pªÜ7¦6Ä1YkQ3CsØMÉ^-šŠ*F-;æ{-Ye£|ÊäÁ‡“SŸ7õ? T+O$Êc;ñéXËuM]¹ìh$ÞJ“Bcàý6\-HGéR¥€h"¬TQ!r?“uXViu+ä„$D˜Â2˜B¥è²|Ïýì{ÆÉq¨‹¨D脜mX“ö‹ÖØ?nnv~ÈÇö|Õ¯µ%ë&µÔiR¶}C¥³±½Å¼Žé„»šŠ'X‘”Ø–*Dª$}±Ff!0Gf¾¿k7ÝYýõ¥VÙ&¬®“R“ŽÜ˜vv9å^³ŸÝµ(ímÜ[vóC¯Rb’^îØtméëo¸Ð‰Ž—i™U1Ô¤QE4lºþçÿöÄpÜQÊq6ºoW)ƒE³4ö•¦ù&ÖÌ’9˜J¸ªñDjÛd S[á½ùAšʛTle^+R#¬Š¾I‹ÅB“ˆÈ7ǰQSk Ò¶­AvÓP»Úëú9·`¤$[r~¢¤†ÀQ†²Ï_ѵïZ£ßÑèž_%gO<0ÚX·Œm›¦qÿ¹-Œ€´3e”žúƳma,L˜_Ÿ‹†jó5ü­Ÿû‚Ñ 6F¸™Á:È\÷×!·¹‘'ÏV‘r˜¯Áü”‹—Í cWéŒ'ö\+o_kßV°P›¼Tœu½‰M3äv¿£'2‘Ɖ ÚâUBW)X3º“TreQµ…}°¢É]kQ "’z“‹ê”°¶2:ÆoRR€³á„Çê%µdéúX+à—_ÑÌT¤!iIæ>oÝÑY%¬ÿåï}Áb„FÎe[ŸçH¯nç8Ç­¬5" `ÖB[ÜZÃÚçµù 3aYB™2öO¿÷ J¨Õ¸:†MNÔáŽE»N:MªŒ!H¤“‚jcœ® A;(B`AR¢‰š’¦ü9“@iÀÙw Äã(m2›yÌ¢4+ò9% »¶Wª¶·šÊÖp3á‹uD«®s$§Ñj”’šM9Æl™¹À†8ÚAmw?ÆÍï4?åîgbéï§ÌaŒDtww—3ÅbŒÙ¾Ð®Òª‹_{yõòŽ_¼xùâÅ‹ÛÛÛÕjµ§åª‚:&ŠÔphš°hB± !ŸüäÇ›HWM³hBÉj‚Ü?{MwYNÏ$˜R꺮f‹éêK3—çÛË‹‚îÓŠchøŠÃ‚$¬ZjïRÛQ{/œ÷L¾¾ºZ,õåË_ QšFsÎOC™¿DsL5¡¤š:!!M ¢,C\*7÷wÝ×?xùÁ‡úþÁm§ M*šDHITH› Fkt×KQcŒ‹E³XÄÅ’›&pÐë›,ÌBDÌL©‘Ä*{ënH,„Dªš˜:P40¨&a憛€HÊ"VuÍ2h¾oÕlQaDw«U¿q†$-%¢ƒKBtÛ¶[ÁhYrÇ~ñÿ-ç”u]©ài—òßå@9À=ÜX­Vmá! ]îÉâ2r#Šn%«¶ ˆ…kÄÒ˜3˜XA¢Ô¶ÄÊPb e¹[aò4âî? §áyªªà¸|¶>&1½Å>qÙ,>q<Ë–S[" ¼4Ýç]{'Hù`Êl’9kHú]’ò¨’êèyÊ·\,Šï=„…(4I'Iº~Û$•ÈM!韴“ÔÞw·]ü¥ÿgµJ‹Õ}»jïS'ÙŽ&IZ*G7†"æU‘–‘o®âó›åó›ëç7W×W‹&¦€Œûé«I)eš(Sz®ˆ»#+kGÊÂ((kÈß'& a%šV¸»O÷/ÓËÛtÿ2­Zº¿íäz /±Y¤O}Ë[ÍRšˆt)%¨fûÜø~yLáT–”k>STSRã¸Q]Þ·ôá‡ÝW¿öá_¿}y‡—wKÑ«áõãž&)Ö¼™ó®pŠ €ÄA˜ÁAB˜˜ôí%3Q †F  Œwž¿U²F¡£hˆ!1:hKÚ‘$M-”@¡LH  ªÈÑXkÉQˆUI"Ò‰’¨#oa”›˜4M3•Ö;ôoüÿ{~’$‘Ü,9€BD}˜»Në+¬½BLYg¾J¸)w÷ú⣻ܾ¼½_ÝuJùn1} WËG9 “H¨ —!2#0HXÒ•Ýø”Ú ¼Ç¶5zgòÖÎiZ‰–„&Ó©¶]')%‘ ¡wï¾Ý0RžèP#’Dd¹\nºP×V/«²´©%ȘéÂâ,©B©f¢Ay™”RÛ­ºVº”Tö»í›xÓ)i—î»6Ýw÷]«v*WÍ¢SÉÒ1V©K«ö®£_ùÚ}×÷‹ 0ç[Ò¢ÓF‰ºÐˆ”&ÒĹf¦¬˜h°lâõÍòùõõÍÕõÕ2½ó®6Mjš&Æ8 ¶µr4 e.Ûn¤ÓlåA l¢ÖDñ‹[ºoqûQûâÅÝËíËÛUw.‘&r$`Z41Æî¿áêæZŸß<»ºZ4‹ÈL‰™¤ËÑ¥µN&íz¯TN‚PU!eð"i¼¿ÇWõöW~ùÃ_ýÚËÕ½&jWJq´÷Ô ÆYJ€hlçÀQ sÚ“i`a¦LU ‡L[Ê(Æ‹õY˜š&\-ùú&Þ\óÕ’*+’U•Ì–`e¤lŒ§ ¤’¨ëR×R+úâ×HÛ¦û6QÊÇZÊâÝÜÜŒö»¼›úéìïOÚEÓì~êÞ}+."–Ëæêz±X,bä^ΚÖöî7! DBZI·ºMw«ööÅýÞ~øõÛ>Z5q¡@ÛqÃ’Z‚ÆBÃŒ†*„¡°\4qb9“‰4]EŠL!„zm%„°Ge«F<§”§f<Æ»®k»ðá‡r“ \uiÕ®’h×µ…ºHŒûO}Óó¼Á‹E9’Te§šE_V,> …„†•’ÊØñ”Ñó÷룓v¥mÛvt‚UŠmB»Z­Ú6Sm®-YijÀ¤MR@µ¡¤­$ˆ&%Q+ç Ϥ $-‰" x²¸ß;–%÷U ÐgVEIÒ$$”BDäÀ¡ýÄ'šå5ÝÜÜ,—Ëñ¼ !ÔÂ>ºÞÆW°ÅŒ«4¿Ü®ëº~ùÿ»[IèîÒÝJÒŠ:a– #â:”˜„E¦À©»ûê³k¼õüÙ³g××7Ë««Åõ26 D! !a’ß ù D‰’’ uÊ÷÷z{¯_ÿúý¯~õå¬Úq¼ŠÍÕËU« lÏæó©ïoǦ̠˜­ã}2ïàï醦d£t¯ éºU/|0¦ï¥¬réJHSjúÖóåÇ>~ók>öü­gËE¦4¶Øèë•#ܶÒ´“»vµºïîïÛÕ}êD¿þµ’P×¥U'™°²£(g4!f•<[îÆÒØøÓ?øó{ûm|j|µ ›g×ÏŸß<{öìêzÑ4™?üðÉ+öÛ ôQ{Û­V·«»•ÈJÛ„´Jm¢˜úNÓÔÔ¶ÊÁr”°äޏíÝ"1rÃ,J¢”Å+Ù*Ƙy§Þ¥Ã@X’øö.0YjP…H×u"Ò%Æí;ÏÓr¡×××Ïž_ßÜÜ,1ßÒíímI+̦lIE$¥,ö (ß¾l%iJÚ¶)VJÒ I¸^‰JÛ­R—I'«·4ë ôå,†~Y·«8K¼9¢º')tè`—i. –µªš].@¶ûhnÞ§Ir=RU%Õ¾ÚŽ¿¾¼WWW‹Å"ŸCùà­× «zG‘¶m»®ë’~t—"„…"KP4¢"ô²¤¦D))+“€:j?ZF4Mˆ‘cঠ‹%ÇŸüÄLj2Uu¹åÚÒ îZ‘¤’’òÞ¾|Ù}ðbuK¢‹®‰ĸ½¡¬C·„GAÞ䥞má{g—¦-C•"«n48Õ´SÉE¯ËÂ~W¾Ž×©kS{«Ô6QŸ=o=[\_ó;o?ã œ[[Sé„¿úâv%ÚÝu·«öþþ¾m»Ô! ……Xµ/Ÿ£àllëž(­^ôQÅ÷~ú½ù†iЊÓGM”Åb±¼Z4MÈlàƒ>؈lÎ"iš»nµºk»$L ‡S „ö~5©.£ +r3l ’P"U¡$]GŒÀf©¦NU©¤ÿ%SmYzŒgàú‚¿Ù¤XT©w¬6±[ôè%¾lŸÝö×äueë¤M$UMIS§)§pqJªUÎÂWo­"–¦éT4QŽÓÉnoª¸½)ƸÕÊ}8À” Iu¤$’´ÓÎ{cÁÜš[º÷ÍVBAD£È]kŸFAJøˆ£ÄØYÕM"Z¿>Ä¢^º”Ïê­÷˜òéMQ¤Q*¬Šl¤éD„¨]‚ã˜K+ LMƒØð;o?£Ìh½{N˜ˆ” /C’4‰h—Tݶ«Vº×M¼!4íJîÛ; N´“Ç^ ÊŠ7k¼ðf iŸ8EÙÙ²XH)Œ %ÙOV¾iž‘¨èJ©u„6 µo?¿f¦&FfÎeѤíZ¢Û•®D¥M«ÔIêÍA„0!0Ge 2Ü3ïiÄ[0ºÿ©O¿_tê7Üì~êäîÒ¢ÞWH"°•{Vïâæúú^:íRR ùìÊ6‘QzbÍ­“TY±g)€•%¨&J £ïÊ3tèÉ Äx¨º‚t˜Ñ}ûeÐ;m‹j„EH wДízª:æ…-—‹M•p  V,õ³úäóž’z‡p ¢À 9“./tVHIÃÌgu>·»û®Ü8Ʊ;©*ñ Üq¶P%‘¬ZæªÝf Cþ\¥)D5å¢ cX<5ÍR³E&KaùÌ nq…ÚÑF&Ò¥¤)µÅZéPŠˆTJÑ$ù sî²@BJ™9©d·ÄÕÕÕpdi'Ñ®£U ÈŽA¥$¹Önˆ€Ê`Á•!蘈8¥«$É`fRUíT Ô€ ‘D)Q+mŒ£fG3zHšd«'1â¤fñÀ\Ù¿ÌcÓ ž–r*ÙÈpû2âÞœOIµUY)u‘ Ðξ\n*©RÓäæ#}™Æ¬Þ­V«œb¥DLxàã$µ\ÂiæÖ:Àøû~è—Š +u•2„•”5äú=Ù²!ƒÑŽÀÊ‚þd¾]Ýçmã"p£JÙzзï3ׯRîAq<]úÂ[D£|›) ßDD1ן~™bmÇ1·Ëßç/Ì!G6Õ«\n”¸ Œl¯ÓAAY'ÙðÂcl5Q `j5Y6ê³óeH›ÄÂë:ŸJ¡H„48QÂØé¤H(TyÊå÷Æl釘“Hn*¹É¶¤ñô›zZ‹.S®®ÑAYÖ;°÷iŽÉ°ÓLƒ¤©ÓŽQ EXP í´Ó®ÒZ}-] k˜º’‰”¯1Q檚¤SÕÖ”Ú”’®$†åÑ$½iZ×1JS/I»13ƒ ,DHC ]'w«Žˆ›f±\.V«»ù¹·LÒµ÷c¶ÉyRRy”¹6UÅ £¾j*÷Í$(š¡^bJ`e&†vÝ*¯ë¯ª :•1„5ÿ¢ˆéb±è4;²$~!„ÈAV Z0Iµw÷Ùp1ú1³êŠïýô{–ZÔ¹šBv¨*TúNp¡¡ßTdÕŸ½“7²?ÖFÁÁ†Ý›·SúÊÉÕDDÑÔªÛôeN`·ßV§¼tPFžTé4ÄïᎸèçÜ"‚µÍhöý›„V" Ø×C`‹h†Ðšz T;FÚ%–¡@m"LªhNö”°t_Cá­™ 4®°7­„C™ÏfâAöÄ(ÐLhKïʨB–Ñ7Ë–‹é_ýO_A¤/Î0J~뇖ÙZ&–ý¬ÝÕ©Œîz€7MC©» Q©¤fsÙ˜·IœŽ=òCæ×ÛÏ2oœÜ|A4«õMZ­ñ]í4~p~†œA.{Øsó¨‡>¬%feø£¶ÒÞ»®*z ·îGyè ó€ÆÚËl;>qF,úÊñÏÿ¡ï¥s‚ˆœÕý Kâóöam˜úx šMÏÏm>ñûþ…ÿ’ âüˆr:'ÀÍÛSùmøª„¥¶ö_ç6Ÿø½àß1µ–>õ¸›Lû¸£­¯â#±•––E+4¨`5Ö’çñOÿþËfƒ8ñ8£Êâk+íÎöŒä–ÖY³Õ¦í í'+Õ#ÿä?÷Ç.œ Î@+½·Ý†å6¬Ç7¸ FX5‚x¬±F øžæ_ŸŸ½ýÆJ?ÄGEÔø[®º„uþBÖöºegµïª} ¿û÷üQ—°Ž)aA|Þžàxn*U-¹‹ ²%aýÎïù#m«ªM´õúÇÛðrÂ0ÖËs©äó¹ŸÜ"ãÕ¯“kâÏÿùb»³G×Ö«î±öy¿ÿã¿û»qý˜„}R’ʽÇcm°s“8Ž'aá"ŒîÕ÷ø;¾û_¾h[Uí:õ&DzUÕmXçä~¬°š[úÜÜäµû¯¹ù­a.ç.p<Ö±öÙ¶õÛ׿xÑͱNÈ£I dÃz¬1%½ ¥&AÔî¿Øäâ€urfóp4ÖcI¦ø­¿ã^t€¨õ„/'®êà`÷WzÞcí;;aýÖß{rGª°æ_ÒsóïŠÚîsßÏÏïš#8«ð»Ó}ÏÙŸ?Ö˜M÷™[Œî~ž½3¯þwm¬”{¬í£Sï;óø›¿ëŸ:©Þlmi3¶fÛNxy$½_,t¥ëª>úxú1wÙžýó`å‹°F.ß'~Ó?ü{N¨÷m%0Í@гJ=k HÏésœƒª»G$x ­5aÙ^ÀJX–ªÇ.a9ÎWÂR¾x ë×}Çw_a=¨µF»KX޳–°.„³ªÖ·ÿúßåÖÞ™³ý]—°ç+aY»Ÿ„õm¿îwº„u,¶r Ëq Ö1>õí¿ý"àQ%— æ 'ÐG&ˆó{‚‹–/†°oã]ö†wõ‘U0'¬£øÖoûm§}ÁÆýR‹2}¼'.a9Þ ‹/^Âú–_û:a½©lå„å„uæœe&¬oþÔo¹Âr•ÐUBW ]%Ä7}ë?â„å„åpº ÂúÆoù®S[¸ámX¸à=ï*¡«„›âÀ…Û°NJXc­“0Sä¬GÚx—ÍV.a¹„5W…y$ Î.a}óoò´ÿNMZ¡K4Žó–øN-a–°.dcëDòs‰Æá߃§}ÞO~Ówº„uDÂr ËqÞÖ…Ö7|ãotÂrÂr8a]a}â“¿ÁUBW ®^aýCßðNXNX'¬Ë ¬â×»Jè*¡ÃUB',—°—°Žú¼ûø·û[w ËáÖEû+w8#Q¾ûk¾ÍgÁUB‡«„—¡:a¹Jèp•ðbëýZë.a9\ÂrÂr Ëáp 먄õö»Ÿò·î–Ã%¬‹ ,žlË3YO7ªe$&!ù裌DÃÞ9ÕþÅÛï~+‘ñ™Œ¬L(ëiFM‚ dOx?>úx‰c@,}N“ñ4ýíw¿ù¼ÊÓjT""ôsv8³lgO«¿õÎ7=)ÂRU',‡ãT¶3'¬#KXÚùjs8N&a¶ï!ž¿ó çEX'–~”’¯6‡ãdÖiÃ,ža¹„åpœXÂ:%a={û.a9Ž‹°¼ZƒÃḢ|ööÇÏK²¶¶¯D–_zÃKOñqUë$Æ…ï—°ÇåHX7o}ì¢%¬ù"^Œç$>Ñ yášÁ]ç„õÄËUBW ° »÷úù»MXµ©.¡¸„åxº–}¿8a9a¹„åx$ ëâ ëêù[çEXrœ\Ùðì–ã)KXÆýraÉ)ï_™ˆÎdä\ŠN::ŽS³Éà$#žÝ¼«0|1±éçM_ƒ`¡DØ.~n\ÞLIçM_;·y{jó<<×Ü]YÛïµÏnÞ=+‘õÔ/Ø Ë Ë ë”„Å'ÝOŽ°ìººÛ’Žù6¦p”ý~4ÂzSOH',‡ãõKXæë?5Âr ë0Æq\ÕïMg«„urÂ:õDŸú»„å„å„u>–ÕÔóäË%¬á$߀çu Ëáp8œ°‡–Ãáp8a9',‡ÃápÂr8Ž#”ˆdþHtÈhý+>>Êã›eãûÅ¡ëçD÷snóyéÏûFf̉„`a¼þc DšžøMJ¶ÿN}ý“ÞÏÎç¹=ïÙíÓÆ¢P'ÈeˆšJÞØÕáØè¼ÂR݆åp8Üèîp8NX‡Ã Ëáp8œ°‡Ã Ëáp<5 ZÜ–B Ö Z -àp8\Âr8NX‡Ãá„åp8¯†ÿàvl[(A3IEND®B`‚rgl/inst/textures/worldsmall.png0000644000176200001440000001607714100762640016577 0ustar liggesusers‰PNG  IHDRËäÀQÿ"gAMA± üahPLTEvÑÁ|̯|ÌË}ÈŸ}ÏÞ}ÓÝ~ÅÐÈߨ»€Éµ€ØÏÞàãà‚ÌÙ‚ÐÛ‚áäƒßÙ†ãΉÔÉŠÄåŠÈžŠÖÝ‹ÃތׯŒÚގѵө‘ÝÀ–àǙę߾šÏ©šÕï›ÙðœÏñŸÅæŸË“ŸÕóŸØ¬¢¼é¢Óž¨ËìªÄ“ªÚ¬¬Äé¬Ë’­Ò›®Èñ³Óúµ¹íµÇõ¹ÇúºÁê¼´â¼ÀŒ¾Ñü¾Þ«Áݣ¿ÂÜžÄјÅÒÅÓ¢ÆÍ“ÈÃöÉÈþËÃùËǖηìÐÄòÓ´‡Ô´’×¬ØØÇ˜ÙµŠÚÅÿÛØܷ•ÜÈ•Ýբ߯›ß·ëàÀðá¯ØãÈœå­Õå¿ôè˩ꭼ즾ì©Ôì®À챿ìÈõí­¨í¯Êí¹¬í¹áí¼ëí¾çîªÌï®Çﴼﺲð¾­ô²×ôȨô̬õ¯Ïõ¾ðõ˦ö¿©ù÷úÀÛüÅÂý¾²ÿ¾çÿÁæÿÿÿÕ™‡¯‚IDATxÚí‹{ÅuÆ_[ÔˆÇØÄ7šB‚¥å)® i±€Ç·šaš@C G…HŠ€ý÷;÷ûÌÎìÎìî'íI,äOŸõíÎoÞsΜ¹,ºÕ‹am‚•åj+ËÕV–«­,W–«­,§ºjm+Âe°„c±K„g'OfýÓ•åt÷lCÔNž¤ôNzfƒœ,ûí í;˜˜¢hñ½ˆ™ìrÍ Þ¤î²£Ä:Œý’¼×ÃÇR0ä°lçjQdo;9ÌÊAú.Úý übõw²Ÿ>`- ˜ ›ºUãõþ“C y·ôâ Úñ°°”×Oqioã´ßžCc@žÌn5ò¶ ÌŒ€®u˜mOm~',9ZQFÆ3Dޤr±Èo[ŠR_辩u΄möqDQ3š^:g‘Pº† Ë?MãmQÛ‘¸AÈû.¨0ÖǾ ¼ÛÜ1̾0éšPâ”ó³­ª!:Á‘Ð`ĈH‡.'È2Rƒ7.á¶oZßu²63¸c«Ò½+3Óèw:åB‹f‘æsq¢ng|¸ö²vù¤ÇÛ °ZÐØ·f|lŸ ‰=|z<;O¼´Fü^ÉrL©Æ–{<÷é‹h‹rà8+PÒ“ñ%­Gé`í¼>rõå7„z(Å%eÕ=•Ä1lF»'Âj†§­:´Er?ÐÞûû2sï¤ÔD‘|é]Õi½úª!P9Êâ?ñê°±|ªç4$6‡$å!®ú¥BƒLvì€eÈ8ëþ5Ä(¹g—¦þXheùn/äž r 屆ºœ¼› ¼I¡$_´ÈöGXâ7X5þ®?‡v~tCY²pé¼ìÒ饊›~_I©“; œY’)›SÏË š0U59-ŒÎk´Íšî¬ò¸7Å4 •üè6¯Z*ö›»É ’QT¿ø"ÕYÃK)Lá‚'ÂÙÅ&ñÃ×~#nfÓûÔ„B˜l÷dÁÏ”rØËÆAŽª6’øšs¤cÐàkÐqÆ_¹ã™Œå~ ß¨«ó‹72Y¦f“½ùÇ™*´¤ð²[| %.àkjŠ%\W†}5xØOûiŠ;Ëø¥øn83ÍÒ™Z¶f}ox*t mÆT‰ ©÷× Y:ޤ‡Ƨ;•ƒ©é*¤3)c]Á“Ö­›„ˆŸî9+gAá´2¤( aòv€= Ù$ƒ(©dæFÒAìEßê"`$?nvæÂŒŒ«ÿ Y$µ(UÄ„U™Ù0öðÔîã…,ýD(©L‘׆&è+þÄV^r˜Y#Å ¦(Ù+VÀÜÍ…ÚÂÜK 2rD(QW©œÒMûÏL2tG‰µ_Hç ©™ÏZ0‘‡|HœB´+Sæef®‘5›Fµ.É¡N]A8¦[:ìA“^à©S~I S%ñØß’êRQ¶F$²¹Í=gþ¹ÎxÍS§ºê¯UÉkr”JrK䥌ñ’@I9Qg<~Z+öÀ“ ®lHˆ%dë÷²Ìß.5jx¢ê ™Îx˜‹õCf`GÄ´…¶á²4Ö¤ä°,Â!½_½%ÅrìòeàÛoùâ ­Lö+ÿ‰ùïo¥aa(õ²†ÌD›`ÔP<ßË"šá p“}mßB8Y™ÿ(’„e7ËÀjè¸kO2ì§ŽIÀ¸½èriF„™¬øaœ‡eÿ9Å^è¿+”T˜¿¦Z±àA÷ ÌÐ:ùX‰è2w–-oÎf|;êfЉRUªøh°œN˜¸)J÷~Mâà !¢dVhèzá˜EC–ԜɀÕÌÒ4IfmYÊO¹y“üÿæÍÀªÌƒƒ(ÌË>Zµ6“ŒKhmÇjOÙŒ®Å’ßñ#5&ð;b‚'Zq¼2³gÄaò­ ½¶2Ëèîõ¤¥4io"}i?j³„ù;´È›½æ $0á¯N/AYs/í ÓGwD£§7a|5ü²-ƒ ùÁm†˜Ò–œ¦Q@!¨‰Y²ÙÐ.¾jyfµÓíl] c(ÿýËÛo¿]'G”ó&|œ²_Á¯•OÇòF¶õm¨†òê*¤?ËŸþT<%ÙQ’Ì =“`‘í†(ó`Hª° ßÈý—­`š<-’ìÉ­µ¯ÍÒåc=F¾~÷Íok–¼ä·ïèÅÆãæ“6ñ¤cf¤‰ÒÚ\6dyÓd,í]$ÚE79z@ä$9LBó;TÁ4æÄÜj1G¨ÃÁ.JYJÒ¨¸â" Çe3±¤ïK/͵bF[‘§§ËÇx4Ö4#[žÍŒ2§¤Š@ô+ y³´Ž‹QvJߌ,oØËûØË¯¨3V;é´‡þÁ¤Í¤`~ôÑGá³´Jr&­B™©‡3Jò€•†T™äâE sù,oÀð§&⪞õ½÷ÞCèˆXÂÓR’K“^îŠäÙœôËqÆò…(KåeNrL¸UB¼v77ËAùOã_ñ7j&Ê>–ü64Ê,–À-bãXvίs³d‘gî` ¥Í’Áìù Ƭ"Lž÷(–wïú0…—ŒûØ —¥(øáK›·nEY²¸bÃÔ›ÀÐ"OAz*ol>›`é§Y‹¦)KÆ’ÒtI¾öpÖ xŒõöv'eißC"^J”&Ìmíö6þ X¢ÊÉA–:<˜Ï9C½íögl–„¦C’Ξ=«Ä‰?›„an{,; èg…½¢ Oã—ÔØžéf%è¾ W &Œ×¬¥SÿT]xæŒÇRJS‘ä,%M%¦ãb£žVöUO3˜öj”Œ&F=–]Ee†YêÇ-×ò±gB,Lƒ¤dÉq†X†ÒŸ<–†ÿ4P2˜Å½¶ê›1X>L1:3±Ö¯EX²H“4ažõXz0ÁAº6ÓÌÉŒåÓ¼PÉõ¡ºð"Ÿ ›ŸÜ„?k/kD–wm”˳a– &Ò(m–ÖØŸ³|`±D3ÇØüAö¬Öî–f-ÜîHy\Ö•`ùZ„¥‡òÏ"¹Þfó_¸JÌÏaƒ,ÝC¤Ë¬;<rЯ£K´¢iOO£vÎeԎ¹/Ë4Ë"Ž_¥®r˜ñc]ƒ¢”“ü»Ì ”i¥ìíX6U'ŠW_ÍzÞàI‚{1IR–{âÄ Þꔡ@™úìJ~ÓW –¿tÝ,6ËÇÚ÷ö*eùÈ#=8 Yš[ØïÝ»§ã®™ùØ(sXRŒè%™bɯí„ÉY:°7”¥ìªôÖ5“ïî1˜w¬#Ë0Kæe¯^Í ©XÆžÁ1=–ÔÇŽhÌËRï^NM ž<¡¿Ùb |øá‡ ¦U¨ëCIa"‹d‚¥ Èÿpÿþ}f_ÚÞn0Z“æË/ûj±4`2”&^Ã)ËayÂ~DrJ8ó±ûnˆeß$ÑòY²|ÙŸ¸”ÇŒ¹,àW¼Ž$P~(QvJ ¦ÏR ÁˆœÏRVGÐÛºÊ2„²ZÉ«› ¦ñŒŒa¸æÿ‡˜H| @þ°P"Zõ!$yÀ4hÝs#ˆ‡Kô>Âò݃|ÄI±ìBZ½þ+ÆòZ•ʃÉq²Xù—S: v!w}ÉŒ,;%yÍd9ÎËþ‰Â”,ŸžÂtYv$m˜Jîh{Xêƒ~ŽðøòRÓä^¯RÒœ“¥Œ‚¥óÚ¸ˆÉûI„%AI…yçNË}(£ƒ~ŽÈø2}*Íë¯#ºAHž^\ãå¢1» –nÄ|bÜžÚ¿üÅ`Éõ¯RX¥8á:Ù\ˆhöÓ¥XÚµ„’§<….ˆ¥%M<ñÄ£_,ÁÒXÑ”dÇP¾b¡¼c$³LdK Þ˜ˆ¯3Äuã‘êƒr®X1?dÍRÓc‰O>þoxˆ’ôNòä(9K«ª§æ¡a†Êþ¼'c’€psš•üîë×Q²¨?ËY”.y$š–°ü„Ø`–‘Z@Éaâ¶6‰ ¦Z¢ÅRV ®»îT–×Ú`@Yîì0aR–¨¼ X±¤vû¶CSÚïß[$Èd¹» Éz‘-Ê:Çm,N—æ5&ÌE0ñ³ŸÙ( Ì&F02ËYöùX <:ª߯”Œ±U”[ ­·:³N¸$,!YŠ›'ßÖ[=k k=–ä5—%º±º”4aŸ±E^Ûµk{¨£K,D–²•w8LõÝju7ÖhÿJŒôeéé]%–»ê8-Á‘ïY»·c>–Þüȳ€f¹´š³BŒdœ% •œ%¾GW%™J…"¹ £Ž0&’ôï3j¸&ÏøÛ³Ät/в¢—å(©‡õY²) Å]–BˆjºÄei”ªº’LÏ«Q̲ÞÇaù,^õõËÔÚF(Ydy[[!YÖ Ò¦œ1=¬|YˆgGÖ.*9Là%bTœ–;¬ÃÖÊ€”%ð"‡Yw3KHa ”»ò1 <ìš[ßäø4ó)¦#o2^¥Ï2’Ìb(™2Ó*,©*C²|ñEú‡Ã¬{zƒ¢¦Ã'ÿ»RR"ÅÞ…ùV#óÍ(HÌ[2Q&XZ¡sì³áˆ’±äÖ⤈)Ý,Okw­ãóÍhêÞ)Jžy˜@k]¾TIJNVë—|l–ŒfåÆÀ®UÐ!Îë£S#àãõÎcQÐäÙjö–£L7³aÞN²|1›eö<1vá¯è€ûôYM“°¤4åA#ðƒb!KL³åèÈ&,aV(h»0N&ŸKB³³s¡Ø:“%䱃PŽ•&þJ I–¨Ì²sŸùçÐù­„™á–1&ˆ²Ë¿Š–-æè jb=še…½˜©tÖ>«AG,€YS–Èd)€šãËNvˆ{×OöÓqžö-ÌaZÛb}*•áchýq01,M˜Ë_›0Ûúh9 z<8„&̉Ϥ6{_÷[·Y$Íщ¬!LÍ’˜1Èœ û³]éá ÿà6äjý·Ð†åKÖŒ×t,EÈ„`)Ä ´¾ñ2ôNH‘K¿Ôº^ Y>N íQš,•45K}²ÛÄMk[ÂÌ㧯-aˆæãy0k£ü5S¦bù5èö›ê 0ξ(”œ;‰… L\aö¬Ê̹š6Ë7ÔîÉæ€-f"Êm•nLÐ,ÅóñtЬp€¦¥JnéX,ٛߚ¦eÉ-é ¶JaZÔ¹pÂe™¦Ù†¥Ž–Kà­ö,ùç*– mÙ#Yë$ÞÅò±=~¶n¸„Eò "L å[Ô0suu¹•1i9$2·8äÞ•¦É2³¤š•úXšä´P6fi£0a„Î<–YÛ« „ ËÅÖb™pi6KúÊÇ©0)I5!5K‡¤ÄÙËÒY’{l=&9Ñ’efE\Ï=÷{ø³4Óž)\l%¥¸ÕÓ[FJb牟̆,Lnʇ¦„%"(5Ó\˜æZ…Î+»NÎò]3÷Afƒ5Ë'™I–6Êæ,ûHª¬6Ræ³…©U̼\ b Ÿå5¸™QÞúõ•å"YÚ0ûîy ‹gylüQÇÌóP±ÄFEËúó«"¥ÍhXK›ã†i«ÍQ™[Džz Ò¥ÆâȆJ¿ƒäLv-˜%°HÌ2nÉQf•sÚ°\EiWúy/«ûBg>«ƒµ`ö&±Oµ>"l Ë• Å2½7Z£\Æa•<.¬,ÃMÓ#J”fJSÀ\Q·š!ÊÅøXBR¦>+Ê¡(—ÃRèr™(yUX:ËeÀÄFÐÄ"N™H„ËÕÉìqXËå`祠ÜÈÔgYe¥èò]l¢*—Ä c¹:ØÍÏÏØøÇàž#µÚ&úXËó›•É. æ&œñ¢Ë’%³Ù­[m±bÀltÌ=°%%Õ%;Va.¾MptwèXnú€}e¹ÞÃÚ+ËÕÇ®,W[YÖVn4˵,{X« .±ò<$,W’‡„¥,Ì®(7%“äùàI3Ï옣nËk€E:W`Øñ\(³óçÏg| 6‚%º‚̬—¨g€õõlËÅI2$ÒÒÃᥙfr[ÔO)±”-¡èmévû»ÎbYRŠÔÅÏ #Ús, º=ô ½Z}Ùõ¤î Yc9ÇÖ ÏOh  XHPâMR¦Ž4£‰¥YNK2)QLˆ«§åÏ[ùâÈÏ3î¹a“ÎC2¯§ai£ Ì;¾¯FÄœª…g%é7j…»trꌛú#Ö–s·ð„$+êP´lñ…=ÞàWÒ¥pDP¢ò>/tµ©Æ$UÔ=ª$ËX¢Z*Y¸ÂÊ1s\;”e«¼¾¿øXT/]YfVC&ɬW9f)ÊtÙ´¡ åè¾õhbÔñ2³V`4qãѶ½:^že!u<îQK~3ÃÝÖ“ u:ÏBòg <ÒGÔÁF£JŸ‰JÆ–ëåz –qaÏPÏÔ^¡:ß8Ûd˜X\A ÞïQ§WÏÇÎ8©³â+”çœó°6èò™fïVl×Úk(V›–åÚ+ËÕV–«­,W[Y!û'RöªûüúIEND®B`‚rgl/inst/textures/nightfire.png0000644000176200001440000014045114100762640016370 0ustar liggesusers‰PNG  IHDRÓ?1ÀðIDATxÚìýé³$Y–†íÞëoɽ–îªê™®^3ìCv€Pi"@“D‰4£$$£‰ÒWý ú$3‰”ÉLˉ’™D™(#$ Ã03˜­{zfºº»ºª»kɬ¬\Þ‹»ß{Ïчëáñ^DæË¬¬êžQ»y=óòŒçÏÃýž{ÏùßùüïýÏÿ¯0lˆ›MwžGµõ1­Íl÷uLáò†`4ú…ñf¼ó:¶ó:4¾êÖýïÞòž?»u 6þ޼ó<€íþ¼áîÏãîç“ ö|_|곟7ËOýÌU¾¯áîó¨²ó½_éšW¸‡Ý¢õîOÇ'î{n{>ÿ¢ `ß ½(Ø÷>m@¤nÛ÷ól°ýÔžËþ»ÿ³ÿtÏ…vÏ:4º™«î¼ûmØ6Ú= ÷<²g4xF~êK½ŠèS `¼©ÂsÀ¾Ï¼(¸Ês~þAÿâ `û3Ÿ²ì¾ Ú÷|xóµ¶ i§ì Ïj O3W1Ы€Žèøü³ÀþãüÜ3ñ Qù™†î^—øYM€tç«ß7è÷®¯³õù÷?ú¿ìè´û1ànØ÷ù=hãEl¯$´ç~p÷ƒxFHŸuFÜ7 ÷À¾ÏçütØþ¼=£<ýx|Ï{¿ï¾Alôc2€=ßS'ß­cÛ»¼( Æ=°Çe}1f~šÑËþ1À¾½oæ~<ŸÕöÞÓ?ó¢ ÀžH ‹lf·AâçúÞ=p÷ hMõW1!|ªˆÈS};â=+À³»@ÏfºÛRÒg2€”ÒS `|~ÿõŸnûóÅÀ¾ëì»æö÷ÙÀøï~êÀ²{æÚõy´ñÔýt@cÞp?£Ø3Æšá…Àx€>«ìÜ?5€§ìŽþÿÉÿ ‡ÍÌp³mŽUu}Ì€Η[A2ÄÍmm®¢qô;›¿¥ëÏ—¿;>.·x!XŸ¿Þº¦=môï}Á~׆­À ëÿ]#r¹“õùr È£ßEÛl8¾Èæw‘l׆£ëì¼3c}ƶ®³'°ÖF2~ÎIwÁ³!?Ïê÷?1x}Ê ÏÝF‚6„ãñùüÎÙú*żvŽÚñ?]Úöîl=ä/oãÓÓ6¦+mã¿>¾}·´o{òË~òg®hþt»Ò¦{Ÿþƒÿñÿñ©+ÀøüxØœ§òy¸la`yÏàÐ×7­*㥊`¼bŒC‰õ篲)^^,3tAûÙ}3sÃx†ÞÚ€vÎÖV€Ñ«ÁÝ—Ùsñ1=uØçísc²é~bW€ñøÙë&‘í\6paR'‚Ëç/Àæ g ÒòÖ£½ìôv¤7ÜåMÁ®/ƒ;Ï#ÀS]Ž aÀUV€§ÍÄ=:4 n-Çj–vh°Ñ]ÞÌ’î]œŸºlÝ­^6€}ƒ~¯‘ì¡xl¡Ÿ©ðU `˜p÷Œl>3š ÿíÿÑÿþ©0Þv"n‚Ý-¿yÏu„ð*†7Îì¶r|Æàƒà}ÑŒLw¸šYAG}ôl»Îï3U¸ŠŒ,LvFÀûòû‚ã}TËé'Ö¶fô=+ÆØåÞúü'1€Ñ@V€ Àü¢rì˜öü]%ÚO#ÁÎóôì.Ð3@™ø.9PÝm)› ŸÏ9?ÕbÖç6€í%f·ìË?l1RGF´'óâO¬ìîbt•9æi÷¾¦á>sÜ>Þ õç×¶CDH€deŸßFl€Ë‚VˆðÉ@ÐSwB]i0He}†åpÛ7Cä=+Û¾ž4î×Ç`7ÇXrOÜ÷mðDåê×13Ðû§³]Dƒ~ã¿ù?øßí¶ŒÑ cæÑ õúPü*"d"î]ôòŸd%"–‚-nP!?C ±I†ˆ…„?˜õ©³ËSá* ô8ÔèøYù*CÛ'ÊÖÇj0øÖXbÍ2—Y³ B媦ª)g3˪ªP¡¤YÕû¨jïV)˜Y*ŸÕ¬ãÈšw®ÏŠ2ÁNª…m‘ó¶\ =ô<Ó}ÏT÷ÌŠ;ó ư+¥`¨Ï˜ðâ}òî‰fðþôìÉV/340¼ðÅ. ÝÏ.òû†ÉóòÊ£}Ç4LL:´A–†ÕàÙ¶~mgúƒÝÙˆõÒt[ Áþhs’‡ƒ«=a£-GmG&û&cݹÃþôiiÄ ûC­gùO=×±ûnð¿þüo÷¼á§¯ý8c "1Þœ'[¯¨FDÄeàÚð ë韈˜Öy}¼Y"ÈÐhŒ÷oŽuwFyŽÓºì¡Uë>2¢î µtõÇOûb³}±Á'[öÌdûÁc¼J¶èÉ™ÎËÊ…ôíå .?ÛF","Ì,ÃVŽ™‘™®¼ï¾Hty“þ·ú›Ø¿ªŒ^†íÌ”ÃÕ`ÙO5ûû ¸v5¼mtrϯà)ÛïßÿOÖ˜èh¦yÛ+­§ç>ܼ´”3e(¨ÑÀhðëϳlp§áoYa€®i—cã„l£IO£¯Œ >Ƴì8$ÈýÜf–Sù'4³˜»õ±æ~^×aË%00³”Ë,žÖŸéÁ¡K+À°2”@wæywp¬ú”tÁV€ígòl•e¸Ç±¡½+=9;yÉbž-XÑ‹¹Ø:¿9þ»ÿÞ¼{ ïuh4Xi§°àØv¹@%îψ£Ë°AUÊù@À°;£üìAðn"nbQÈinjÒ´vŠž`ªšûóHü¿dƒa<Åö¹:OýO0€í¤Ò³€î‹cvB휘t_ˆmø¬°µ=Ô3z1KáÓ(_{Ø—4"(ÇÅfúcb`A$SñsðÓÛ‰`íM•?M#°Æ̰o™.ö…­Ÿ¨0êNÍò®ýdzÑ击ÎõÅ`ßïîý»ûßýßìÌìò%frïœPqTŠkDkÞ£[ŸOê½74¸@×eúV¹á:ÿÔ3 ÊïrŸs 5O®[vqŠÆÐðD™Qn /<²œ³šâºQè}³T0"í1ôœ-ÅÁÿÉ9æ¤  j1éh+પfSÕØ»F› 8Zí)¹äqFYG®ÎvÜr‘ktÙ¥¹J €{ô— öÔ ØnW‡iwʸäusÜ]Hdˆ ü¬(Ðî¹fo yƒ|Öâë«'½×ðH9·=ŽaäKìžn‰ iǽ»òÄɨ$›Ñˆi'Ú¿Èn&þ1Ì17·¯$àê.ЋÕùŒ6{†ùü™W ÃOùîéêËÊ'7ƒ­!B6ª üæÞ½ÖŠ š„ýR0ÚYhðÅaä¬ãà²_ÍË—þ'²ÐæÊ¼ù_b"X‡HˆCÜÒíx°9W(‚Ùù0² ÏOºé®Ý~\1íôøÜwpÅüÀÎØàBN`óSx|f Áñø „ïø*£_„ÊOÙÆõ·3 ë?JëŸr ûrÕØå¯ÿ¬/û®ÀŸúôÿ<1Àî™ ž#yüL«+™BÙÁps hVA *åwÇAð¾ŸW³û–LpŸÃc$!"!$G(HŽ˜…„Ð19&!tÌ^Ø 9F/´Ù™ƒ“§î^¸ß™¼#ôLžûG蘸üQ&¦Í ðšo7‚w‰Æ!ûx•³'ÄÄ;ƒ`(aIy/Û¯†Ê{ÞÈpldŠ÷ý‰'£´s7#ÓK{!ÀØÅÝŒÀôŠ{I&ì¸Î§°\€h/Tµë×`ú|îÑÿä à e»ûfú}Y‘q&—Ÿšá~w;¾{ÓÀýô;3¾û˜°W©ÞzŒ—P¸ç]Ÿ‘–übfúg…€ì…ÏôW\]éê¿ÜÀ'¥O#@7KÁ5·qíæ:!г“בë(@t°ÿx¿àzßÊ8ÆûaœšØ†üñb*m4ܯ”øC}þ¡Œž_~îÿ l°Ðq`°™/úÅ{žçfI@Ý €µÒò^€/åë å~œÞ”HïlXŸA[çјöì¼Ù·yÿ0ŒÝiG½iìòïLh$×;3Hëó£I×ø`Ï9C¸?Vû>#)š§ÅQ9xåy»wBlskýèIJ—‡S^êhßOù¼ ¤½¾ìØûûUÜa ýWy!+ÀåG‡íßù_í¤<ôïxózûcfè3d}€ ;DbFF"fF&¦1) ‘…ˆ…H€ˆ„™ ˆDH§Â113€ºÁÃAâ>-%¥ö‰‰Ô2!23}ˆ2ìcêúy¦¤ƒ—Œˆ\ðø¬– 5CV552ÓœSÎ9›!åœcîÁþœsÁø Ù!¦¬j)éûÙrÎ} YÎ9eSÕ.mè–“åœs.x?æœMMMÕ,çR{°¡|fSÝ_C¼þ>›¯kiÄÚŠg hbZÆN+•á¡:ØŠL=å ÕÔ H¶êŒ/ˆp©îÀ-âñݬÃ| X„J&°P'ÐZ„a¡`Ø%ïšPm™oO¯¼³`‹®âšÙøx=÷n«µ·R×€Cj©Ü÷xžÃ}q?]BйRºÚ~\¯S°HcD"£‚å¯wÆÝûP¤HX¾g˜þ°ŸG5œ+ƒ ÝzÖö RKe µBäÞ,`8®cU±ÐœkÛÉÁÇ^½•.Ûô»x 4DàÑSEB£~éƒrp5ÞaG¯½Ë»ŽÖ»¡Ù…ôÜsCøüy€m_ 7o¥yûpŒ«ú²—BF[× ›!ާÿÃeú‡ò³TŸ žúÎÆ\#GL›Ë b1!D¢1Eb‹áóä²Ïg ä=Ùü”ðþê!Œeÿ Ñ©[/6a[?Åíðs.__a»A™î'VÛ6“´ÏI½ïöÐï>qüÉÈè°2º:Dý¸ËuÀ[ù @DÌÌòdŠþ>”‰/]¶¿x™á¯Ž÷?õê¡ÞgšÀõjöt¿O;SûLÄ¡'Ú£í|ìO—ƒB4¸ù©¸sâÖ`4tl„¬oê ¸® A™‘™=³#òÌŽÉ‹¬ÿW˜„ñâ.(ŒŽÑ:B/å·È 1#‰e÷¯aŸ Ù_¼PôdÜU‚³}°ò3½¦+¢ëÙ´Pß‹¿Î¥‹ÇX*CÈ”° ûÃqáóîHôûzþîÿJŸÅØùa[/ý‡/-ÃuÒìF™pǾwZ¡çN%<9ðTnú>‚Оu÷æDJB`ü íÖ†À±ó´3õ»X`ä§ý/ĺ ø\ö$?“ /¸\Ô)Ûæu¿¸éß?;dö™ó[¿¬0âöB ë‚TØ£[v•ÌÀ¥:H‘HÁJn@ˆaàê’†ØS8BOÚÆ\F">Â,ÿÛ3þ7?í®/}Ö¡¿Ï ^l`ÿP×µK]¦B\ç}‡J# Îô–P5ëýIÊ…éíIîûÎE ì—çö=z&ÿg{¢Â!zy’¼ÔÕyrk¿sÄ]½,@½E]ë%öœjîsjcÅv8þ­uy'mkm°§]Ž>ìÁû?ñó Að3yAÏN抺ڰ_/àOýl­O,f„+ÆÊ;!¼òùO˜Ø‚ùÆ,óË/x“#ËÖÃÔå³:ã×?Çïo}1/¾÷ÀˆŠÈ= •šf6Aã°2êÀ’'ìEI¨OPõ¼ .Î=÷ËB9aïÙoLÂ$´+çKn˜ N®¸Ô'†™ñB-ü´œYë÷¯å*žêOŽ},û\„/7AÛ—ŒÏã%¹ÈÚÅ9&32#ìWBDÏä„‘K¾$Ë€VPÑ’Ø*hr¿#˜šfffÂ"”LspÎÌB@d`Æ…á‹ýwDË`¹/%Ë ²^ÐxÜzV[¸íæOŒáñx¦ç°ž­ð'žû/1äÖgl\2v u°µ.ï¶·ZV=Ó?ÀÈÅÂb­ýl7¬ûãú„=˜‡íœû_8cñ3p‰/e²aè*w­ïŸöè·ì™®ÿä4îY0ðyFWŽèY¹hC&‹†“ÏŸض„aDlÊâk–4Yù)–A|ôB)´ Ñöïk(¼£Íç{&E>Ê•™ð"¿uM—xB6ãÓúŸ¨üï’îS «z»÷¹ ^ •'Vòë}ËMÚ‹ èè¦>{??d»üÇA{Ü ‘‹§Š€hWì¸t´ö™[~?Ltõ`’¸¥ºKtwÆâpû¡k˽Ài¥ ¨^(þä4ϼ^¥×ï3ÏŽ;uZi+=L#Dn+?ð¬×Q¨Ñ Úž¾\vp lúäy€ ©ZzŒIöÜÿ´”‚cAB)#†ByØòG;£•]¬P$JPQ&þÑñ6¿ÇUl;¼£OÞòè™+žß7ÐT Öó+`ñòÐ ¸×å6&àa5 S+÷<ê-Ðf³ÔA‘í½ˆAýûÒ"€O@“Öé…õõi?ÆúÌ.ÐUjbž#°Gß×Pl4g5@/ E{5(®ÒzlÍ9½Ð\ žXòû¢\ '¯Ïí=Õ!ÞnɃ Çvëíà³/5O£2]ýZvÕ“Ï·<ñô™àчO˜ØL¢4^l-C2fÝþëZ|Ì`³KÔü ;Ž5LÇÜFÀ²J +=o-÷c~¿Â~ ¦O>ú?¥ x;/­6̲F°y, ˆd[õ[OÌžTá4¢ýŒ–ØŸL´qöwMB*ëL¿¬±ìO=Þ®ˆËýìyp ²µ=n§ FLÒK“‘틉×^)lÔ" a/2ËŸ{”¥{`Éh++7ˆýÛhÃžã¾ÆÂG¶ñüõMýƒEìÁ€¶°³õKÑòi‡ñôtgÛáï00¿ Ütè§ç!G†àEÜšÂ7%£\Ø6²³‘æßÞ{>±ÁEú¿m3ðtà¹*¢"*à“bcFªî6€mz9²•Ÿ ” ÈJóÄRx¡ÃÔB´ÈÙ @ETCŒªIÍúT¯™Èªj½ÜNFä"@ÝcÀCy ³”bw"2Ë1™0˜jÎL°–q@äû¨6-+X.Ì–2è™HJFQ˜ÀIŸ Âþ¸0PK‚1A¹0ÕµÙæÝ¬ vû^(]ÆL7ºa×—x3)\ÜM“©©¡•ƒõ>Ôm¨%ƒ å{D½d¸Ë8Æò^h3.ŠÆ=˜‚¨¢iy^B ¤h™Àxq™ éŸ3a.¸Dhm2ØÊ"ÛPmdZò =ûÙ2 !2—ì4"À a fy0’ªB7 ¾ “•LEqžøI.]ªþÁ§±±·´ñ„³¦¤oŸ¯£ €!à®ÌÀz%±CBýÌ/ ¢´ÑÖ<°QÞQ‡+e=IŽñ€åóá_ðylàÛÓ¥7°û½ìw¬íBF¶ŸÝw°`Š Œõ¼ŽZê?.V݃Ò&ý²i˜Px+4ôfܪPé£)‡B’mg`+ÿ°)èÁ^Ça š‹}OþÂôoÏøÔH¹ûÅàÇu‡°/8þ$>ñfÅÇ]ô®˜–ßz€ŸmÉîÕr°%|DRm(Cا`±/L{ÊNF`HÅf¶À¥Aƒ¬'0d$Šr¡ Ɉ¥ij¿“O+ð|ñ Ç›¹DÅ!za)Ø‚c"Еoï… Á‹>[K¸âû%`ÖN @sÑAïs‹z\‚·µB©˜¥Rpy¹²­Ðõz^0î?“<À'ÒºZ`÷ñæ=IêyW€ | ¸ çóÄ{1Ĭ±&ÊexÒ@ŠJ$Г µ¦¶qÊ/Ìî`E[©Dã꣱>ïŽC~`à¾\a°¢’¡ïåk leØçï _ ú 랤Ûs C0°Æ¯ÎEyNˆúE1þŸið}òÇø)¹@;*ЇÄõõ1ºfË*£qÿÓŒI×»míÔçªH{z\O{FEë.õuÉ›÷þ‰«èÎXÏÓVõ¹\ ]Ìdx±1ÀPu5~†. âKð¶!íÜqS)¶´JÏlï…1Á<È“1›Pá˜À&VàסCÏÚë|¾¹ÿyV€Ïª{"Þ²™… gíEÃ>OŽ›ÊLø4°ÿ?Œ+ãN§ÌÖ%ýÐÉ¡Çø7BŸFý/íȃX“P¡m ùM Dhý:À4,#èSÉïœø?ƒHà 9uÖöSå ì«øé´?´)Š·RD? ômp6<¼] 8L˜©´#áR‰OåR„… ?¼úM‡èCD¿Ò ðLÙ§æmj«aà}ª£Üäð¯ ôâbÛ@ŸÃ ØpnÆÓÿÈ*ö­\*õJ>úI}ð¬OúöÎO_×ÑS€F ôìï…öxÄ8æ®+̬¤é²]ˆm,ÜòID\¶•zÅì±j1  ï ´@¼ð?Øã)ŒH­veúŽ?bð”gó¤ ç~¡ü ôüKßfÌÅ‹TPÓWmóÀ Ø‚v¡€{j3­%9 ýÛrÁø±°€6➤;vTÁ\ö!“0Ê öз“Šóƒƒ–Ç•ºD‘}BÊ`ZˆKLF¨,›Æ¬I¡Ô ;ß Q³AîÃJ @Ï75P€l– Þ|•¢°¾®Ñ P°—^e€¦TjL *üb{h"ô0F¿R #ÄÒt@†£1ÀZèB–Àú{ìûv £’æ\ÒˆZzP•Ïf° šA3ä¾”³`_ƒQŠúb ¢ ¶Þ·ÊRJ¡ X2-/±O5¨© ã±LÓ$$2ÈÒš@Ó·+õTê8ŒÑ„H˜3ô%ºDX4ó¤ÌÙEJCÐ xÇ l^@؆}«C8 Ç »ãè¹ ÜyŠžSí,8óbŽÕ3:2…¬-ÐTA4›¦¡zˆÐ@ UM³iVÕdšu»! j.$9Ñ0‘*îë.£ÄìO·¾'L‚C®wí Ƕ¸|á.ÐfZTB€KüÄO6áa‹~ÕÅç[[vö]Øn³²á}lëÿ ®Î(œìuMúæ5CÕDÉþºLCœJ% |)\î€ ?b¼g4dŽ¡ *ABÈTšÊ˜a±ÐþU aÑMÚJj iôŸ´ì;ÿ‰rdŒ`ü‰¨w¬ë¿±D+͘ÆÅÖ;â±^‡’Ⱦ8ØLeÝ|dpÓ`ãôwÄ}«JµÚPæŠeUå5ç×¶»­áEIF†uZG²[±º™ii¢8ê¹Ý·~t~-º?A@üc¼?2ÛPQÝ „ ÂJ–aïnóPF¢@046b bÔÄ ‘dÞ?XÅ¥<@iv¸þ×>z&!RþEw±÷ï‡ÀãRÅÒ†Ó~Õ÷µ©+—™þ„,ŸDwÿÅ®˜ àr[—¢½ÓK-@éAÈkeRD^—Å÷0!"(C©gíž³m ÿ>ã‹Ôç}áÒn»5[KqÍZŸG"Þ¸æº ñz)†ÜPAi­]›ªK²1Ò3žþsßOm»AÆ%/è'å}ï¬ ø±üõ?JøýFx˜lhy¹.³^»õ£â;XOü=žƒhD™xˆn”“È¡gA_Üuo÷Î"yÛ¹³­N’° j3 G`Åõ/0öSèù 0n©C˸—[Å¡?@©Ã‡þ|/Ê Eˆs˜õ±'úCfTľO™zž¦Jáíru6Éí]ú·CK‡^-ˆúÎõ#ü£'Dâfâ‡õ"Pք튎ÁÓ)‚¦[Ó?f@ÚY’g?Ýž†×ÿaü2q”#Ùà5ük€¨ô‡, ¬-‘ÉBØÌªgT‚Þÿ¾müù}ÙÊ ×¿ÌqGì{\ÚS2"ð6¿d£þ4Y±rÿåz€ ,üÕþh]/±î½Ðwûãþ®K¤[c–¡Ìˆ…^Oj¦}[´¡Ÿa¯UUÚo"#*‘ ƒÆ?ƒfïÈ;rÁ£mZÓ^RR¢¾Kð;aÇ脜° 0¡‚"î{aV35ÍVTÿ‹rQéçE$|¨U)!ªålªš²BùßlLU•>mvçO·/x0¶Óme™u L™}OlÜVº/Ù¶A°¤T~çïRÆ¥¥¦Qwì Ô|)Zö^c6]é̹’µÖ%04íïÓlP8ZWn%¼Ê¿l-ÂV†^|£µŸn?Yp'Žu­K€}A Œ˜×ºÜ6È´­-ŠR4–Þ0=s㽟'¯A{òó¥}«k˘07Ø€" ™ŽôT Çðkßµr#%h4”ÏÆÜóõHÖò“¡£þtø#»\v/7¥àBiì`¢Í#@ÀAZ° \ëÂÝïáQé ?Ƥ—w*"sp±…€€>ƒ]2C‹DàM/;«Û­,ËÜ¿ÕÁz/ ”Š)¬­ÉŸnè Æ2#aç>µÕ#,·Å™ÐúU¢'ÀA¡mx%“ÉÀõÐO£MÀÅ}Í¡Àí"2¡Uý­öº‹6äž×©ºžS=F­ˆH¯EBGÞÎZº|Çô_B3ZǦ?]þHZÂÙíõ?­K«/J¬n˳múÁ @Ÿ´*©_.YdèiÌ%¯Œ¶¯GÉFϺ¨¯å‚‹µõŠ@Ñ_‹¡ošð•”l}¯í•n€€°¸@ÚGÄûV€ŸÆ¤]  ò©¶Å[rûëé‹ú®î(½å@QtC”¾µ ¡þNßlØFŒ†í}_çÅߣj'Ý(ÔoÛÀ¦ÃMÉo¾È6:ë•/4&iÏ×ݽ?Û6$ÙG CÄKxú löúãßì ?/WL\M½à9Ÿÿ“û-¬Ïo¦vÜè?oOÿ0à÷3ô É³n\7Bu,—„ƒ1¨€ ôA…zó¨±ÑŸƒ ÓÖz3 ç #dÂŒCö­°[ÙÖÉ¥Ú/3ýåzÖ`¹ í{Ã:L€¼Þ #¨PÆÇe?Ú‡¸fÒåmüZͲZ6ËfI-•ãáLVKfi8“TÓ_#ý—µtà'8 k›%¶Ôä («å Ùzÿœ ˆm9ƒ*d…\ŠFtø_5Ø<óqÖÎö††˜²ZÒœrNš¢¦h)™eè«Ê ìÓC™ }ÌÊ }Š ª¼÷¾oc¹|Þ!Ci¨ì eá̤ÌIH…Õ3TB‡5CPƒ:É"™©%\y—[QrBÎÀÉ(d!àâ7)pÙkN9çÔ§2©£È"cbÊH‘(M=×BŽP¥ç’’­UW2›’eÊÊÉ ¦<ìe|j_ó"©Cƒ›¥àòô¿£7Ì&´cœýûck CÑž!‚™é¨áŠíÉDÚSfég¬Ø¥÷Iß·¿*þÇE¥Y  !hqc]*4Ae*…Aʘ…Œ) )SJ‚êPeW˜°a7êµUÊDÞgmûðw¨ú%,Õ®}cž’BÔ!å< ®¦ ŠÖ7VÚôö$&ʶúú=[±õå ƒk÷ÌoýÒš®ø"‡Ô3ÿñŽþ§?›÷ˆ»ò‹Œ Jƒ +zR…Ö Ek­ö9^~E˜™E˜™„P¹ü,}bQØDTXY”%—ca•QCž¢ÎH}`êCè“\hfÊsßžÕ¹ü¹^O—ú$…Žš¤èæŽj±6M÷² è'e*ýÄŒ÷üI€„õÅìIqϦ%¼)Gm1 S(ÂâH;ÇNЗ¢G!áÞ#rŒN̉:Q'æ$;N"™%;Gè‘#à"€E}CîSoFlÄ=î98•CÙ:bîÕ©”Ø--Å’VÃùòÙ6în9TŸîÍ<áîÜ/Lü†/`ÆúC4ñJKÁøa>yEñFû!.¹^ƒ­f=˜ ÈH 8èùô„"qž#çØ9òEëSÐ z)<þ" ª^Ì9 ’+§Þkpœ ™°y"G(ŽLHq¿ÚØÐ. õˆ¥èP×ígÍ!x† èªC”¡³ØP®Ãè¿À1š&}Ú+€½x¾æÏ?öž«)òg V¡:¿ÃZ[­”T+‚09¡à8xvBÞ±^Ì‹ÇæØ™8¶²2FÇ&lŽÕqrœ=™Cs¤‚*¤Õ¡ ÷„jÄC3bFÊ4ÂIGõÄ*B&Œ®W &D$-µl#È`J7+Œ¢ü+À“c€±Ûj/týÿ·`­eòbézãžIVšY`åkT­P'‡~Æ`ŽÉ3yAïH›gt¢ÂI8 gÇ*˜=›cÒ¢åæØ<ƒ#slŽÁ±9TGæ0;ʲ€:Èúóëf0ŒÀE½ïüÕ'æJ¼Öàp¨B¸&TFF!qਓ Ú%ÛßJüdÆ?]^lÇ"ðYzAãZŠ'ßð¾Ï\ó‹lMÿW/ífýu4£ÿ%$A"qŽDP8‡Îcp<ž²§ì(Ì“€SSÞApäzÁâý{GÁIôN,ˆU¼ÓÊi¬ò¼VNƒWï´ö¼¯^̳:Rt{J+áÂÃ(ÏÃÊÄjPèd½^ª©Ù64* l†ÿÝOϤ'`Ÿ*ZrE åÇÂÓ¾ðGöuJ¾ÊÄÿcl2rÁ‘†@„YP„Ä0:GepG•`Å‚³‰Ã‰ÇÚcåÁ‹9^(8¶AÐ œ3çÌ;sœëu…UÀ*€÷x•ƒ*@pTΜ¨ôEôeÌö¥DE ˜MÁr!UYýeè+d@µõÐS0…œ!g+Ã)ç”sJ)嬪ZäÄ_  ´^ž•»²/L|V(ý3³'TÓ=á»<ùüºäÞ<9h{Ž€F ZÃAL,ÈŒ,è„DP„¡®Ü´òÓà§A*Á X W´ÐÙg¢Â AåBuÙCe!`QŠ.®‘0ôM#˜{îÃúk11 ‰V$|Ð,”J.8ÈE‡ÜŠdh9[Κ³ål9å4lW™4iŸŸs5Âúä¢GeG;õXŠm]zm¯†:¼¶éA¶Îà•º5íÇ⥹?¥Fmàx–G´n—`k`yM`¶â,Èîë&hf}³ë•úJ#¾õü±á©åýÝT”õ3† a8(^mTµ‡BòÞ:`ÔÏ=Åê3©Páxš°1cå9x…à™‰™J·Ø¢b[ðJRÁì0{ˆ;‡ÇÄ‚X`ðÒS¦MÐ<•̱2©u²”6ÀCA°ôz륪Ŭ°ÁTÑÔ=Ä~Ü“g5Î Q1u†Ñ°ËÜeކƒ¦R¶"Od:èß—¿(‰˜’j.c…žÀYzöðR Ô0fè’æ ÑAQ³iî£5Ó~*q˜ õ}š× :FŠdExÑz)B ADF D*ª›l½ü&Eÿ’+2"`. 'LM­ü ±cöb}‡–ÂáqÂD¦¦¹$^H+Gµ·ÚëDòÄéƒCϳ@•çʻʇªò( ]Añä‚w. ;qÂ$DBV9¨Dk§µË/V·fþz%‡ž‚%§™5aލ iKšH²1R%4 ràhÂ@ÅÚ£wJÔ4šVh‘I½ç:1æLܦ&j“-kQWfôB^Ñ%ãUÆE´Fi‘aí¬³³H‹È‹È«HM23¤œsO½.EèëcUrà…ãš„¸¿ L).ÃMW™á  Óõ‡×"-† 5šÖÅAž}sa°õ_|Ñ~]tólPÏOð…b…ëãáKÁº°i÷škýÔÞÿ¼0ñ]X`<%ŽGê })ÒzíJ JAmáÓ#1£ôòʨ…Ñ0yTGê <ž¦˜BVHŠYA‡ ààÆ¨wê½VN+—j‰Z­@ËÉ"["K‰0äRàË`hEë!† \q«L¸W‹(Žfމ¢r̳´‰p2ІÉ(eŒ™ºLmƘ)Z©¬¡V¡Uì#P—Ñe˜°ÝMìÂ1}’‘b{à‹}ÜÆ’šVÜÏ_$žŠ9~z±À0 ¨ÏÔ–"¸Ë ÏЪi}¦øN:®‰¹ô tσ²«ÅT=µ‘{–K¤Øâ‹OÄýz®äk9)Äær@NØ9vÌ"$BŽQ˜˜/öX·Á²½³àrZ›V6©s]ëd¢@)'¤Ò™tÆPhF†”ŠNI_û⃅@UE¡"qå1*„¨“6ù6ú¶«š®ZµuÓVm MrM–&ó"Ú"Ù*Ù*Y“´M³v ]Ì]Ê1iLZB…Br¸ðœŸ ±Ÿ!{­¯>¼ž”ô½À8ØGCøL²{ïá3ÈT<)¦d¢Kb{÷gh6QºíŠ#/ì=yOÞ‘÷<{ÏÞKp.8ñN*/•/ì…„û:w,,³ízÕJ r<ñ\œ¬N‚Õ2²­õ…`2Ì@†ƒÄ9¢ äMu\°ªED‘8štYšÄ«–›ŽW-/ž¯hÑʼs‹NŸwxÞÚYgg­®ºÔ&m“uY›˜Û¨]Ö¤6&àà6Z“|zæ ý¶‡Û/‘Àú«\˜ÉìRµãåÔæZ›x=G–Ù´Ì‘%´×¾8Ë®áÜ Ãqmcq¥ BK{ö'ƒÂ´Îôazi¶5Z£†H¸0ÙkQØ…µîòô¿¯ bû‘ÚºLks< Ðò>³cbÇ䄜/?{J³TÁUCà*P\l x‚—ÚIðT9©z!_j\Dhè}ˆÅ…"aÇ„*ǵ_Ü1Ç€D…Ùmè¼¥ÓO;8ël‘lÙ¥&Y›¡Íc©ýíSƛ֪Fã®5àrLã)gëwœ¿Ð£ëYiŒWþw:?jc ÞOûS`0–NZÿUƒ¿î¹7{ö´îî®P=g…Å1{f'<—I=xqŽ«àªàêÊyÞƒ÷†Ñï=y/ÁKðR9©œó"^H˜˜@ EŽ }NJâØ¹Ïtè=9î)jkȤ4´`”D `h­¸i ³iÁ†(ŲjhM›œW]jº¼ìlÑåó6Ÿ.ñtI§K:]áY‹çœuvÖÙ²Ó&Â*C— F51¤=‚Ê{ ŸqÛQ—~â†é¾s¶+,¥Í²°Aal'è3Q.ª¥t¶¸þã5ÊÖÌð¥t{qX Œéö·¡Ñ˜þ¹½<õE0@pÇA88žBIfyžª u`çÀ;tÄÁð½ g,^N@ɺυw"Â\8•…7!^©# ±²ÄBB@g(FR"NCîüö5èÙ(e.)Åœ“j¶Þ•%UTÅ)BlµmrÛhjS\ÅØÄtÞày ç+O—¶²ÒzÏ>‚Ôž«Àu ÚÓ¤’:¸à9¸ïRpì¤x8HDB}o{.È)3õ®ŽôUi%û¶Qà5mH(Q—0&è"$Z@28dì=‚Sp ’@tÈaðÖ…9a/"–U-#’g!c4òžÄ!{¢ÀPØ£Ž” j!Ì2ÃÐý†`¨Þ…¶é~™x·ýÙ̸ÿžæ‡csªÆ¯.¥ žkØÓ[éÒ˜9EùÒ™-ì%°'¬?ÅÄtûÒ—óºû·Ý•Y[Â;¥ka$Ѓ—†þz(†Ê…àB¸ª¨ª¨ \U\WU®`;ÁIpâ —DÌBìÙ ”¤Ô’AR0 …¾O.¡©r1!,%î‚JÔ!f’@È °r@$À€F Àf}“lD$Ç"ÄÂÌÌj ¬$§ “YVLŠ9AŠš:‹­ÅF¨ñÐ9hås„AӘܳæüñ•±œõØî½O*¼§¡T¹¨õUCÄFŒÌ啳ˆ!(®A ÑPu›íxaÅ_£ìæìͰ۶€u {`²œ Ða5ƒfÓÜ'HM¯H*TòÍÄŸ¡,*6x±=ÑôB(œ·Ãâ1ص¡‡‡Cˆˆ¼ùÙÃíeý,ëêÈÛYg_J²–EØ9ì©Ëž| ÊsàØ :&AðBÂ,Ü#;ŽEH¹‹¹‰¹‹©Í9*`†Ò¢¯Q^ßv)§ïÁ;ŸÅ5™W‰›äÚäRr9Ó  «*€à‘¨¯H+}ŒFù'ELÌ™zo *¨‚I Yš[:·<Ç<ØZyîÅ@ÑC"í,Å1´3Ò^·õBÚ?ÿõ4ÊwÍg¸4B#rÎUUB‘¾j{BÚ[ËhEæ(Ú—Â|æ‚ñŒõ~·gçͶUŒÿ¬ m›¿ :²·r;—ï¤G{¶Ã5Ûè#òx§~ôÃVÿãíÇ6zü›ßǦ/POI¦zA/Ì‚,eFBÐwF?³8vBBĈ˜Õ²AÌ–ráQ bšƒËW¸W:4YÉè¢I4é²[¶¸èhÑʲq]ã»FRôÖÐò´‚\ðq¯Í5Hq(@HÄÆ’}°PÑt³š&Mk¬ƒMª\U± iVé,à,àA ƒ‰Ÿ Œùg¼oÜtìÿ" JDÞûbÞû¾ßÞ¨„–i‚õ|Ã"`;IAcÞõè|†§çv—8 ÏC|P¼L_t ¬çÈ5— F 5£w²n»eÍè§(„ q0îF–£ˆZrôDÆ\hÆÆŒÒþ–ô=XŒˆxû …-,%ÅKÌ}Â{cÀåÅlu2k:Xu¼liÙÒrÅ‹•[.e¹rÍ*´mÕ5¡k+M3MSM3Mõ0î¡÷ˆ€ ˆª¹àj‘8±3ç1»vŽݵcw|Ì7o¸×ý­þÖ 9>pÇþÚÌÎü£éÑl2«\í¥øj—w­ ¶é'ó¤b‰L¨N48ž˜ÑÒ%ÉlÉ &FD¨%A4TÒ[@Eõmˆ£¯fíÄåAK‹\ËÐóÅ3–¢PS´Ä–P#iGÚ‘&3íYÌj Z\ ÔlåŒ]&ÍmdÆçú‰\KG´¾'¬9zسÿ×äOêéÍ`aÉÏ÷E³aF²"ûÁ Äʤ©÷ð9Pï)‘!YQÁ'  Bb%JDiÐ"Ìÿ@Á¾ðUǰ‚™õÈIÏ 1"…âÃ:Ïâ3°+º ’’±‚KࣹBU Õ²ó‹ÎŸwrÞÉ<¹Ut«èWÑ71´]Õ¥*¥`ÙcvE:̃’¡I˜3¨’¹h’Ôˆˆ…IØ<Ãጎfr8åã)Ý:¢;GöÒ‘¾|d7êöFÝ^¯óÍ:Ýœ¦›u{Í·‡Òm¼u™¡OI‚"1›Òʲuí®yí¥$?Éuü‹ÿýÿäÖõëŽí¥;·“Ñ·Þú^¾M6ñAsiÛ¶ªª”’ˆApNœ ªæÌ¥E+ -—Köˆúq€`5#3ˆ3)”¢6ÓãƒÃà¼Zn—˺ò×®;‘Ê ÆÅ$ø:°g BÁ‘g°Œt|8…´ª ÄÒA-šJ˜1õ›ª®@mµZQ˜ˆs1%q"Þ¯–K>˜©!Åd"‡òP],[·j[$Ÿ²AÓu€4?_¬V+çýªiK¢1eËŠ§ ˆ9Ŧ‰)%³tºlI¼Ú¥¸lÏAÒ\W³s\ul’@›Ô ¨#iÛÔeP’Uâœm¹Zä…ˆ_{íóßûî÷ÈjöUg]=Co~áµï}ïí¦I“É{ê¹¢ia1¡u+/ÄB 9§–™*/ÌH`šr^s Á11‘YÎuPÏDš#AŠ]‹h•w*,D˜s¦clW1vRˆnòÔsMb«6]«Ñqߺæ&Uñ1Ú‚X¡K-¦Ì´É„SË“.R²l:5\´mÓ&#çcV“ºé¨é0›NfÁTS§g§‹•y‘£OÚ&ƒzþøt±êøáãôpY%™µ ˘Xü*åÄ•TÓI·JYM|"ÎÄF„„Û®•”$êÍÇšs]ü›ÿð?þüË/½üÒ M¹ËöÍ·ÞÑ0[u&šsf*⺮-a  apŽ™RŠ`IÄ•i©ª*Sdf0p–½gfÔ..ONuÝ*TîæñM&j›åùùyåäÆõ7nß¹}»ÂÎ;!O‚Ÿç„—1OkÁ¸šz#Ìf†D³ƒ£Gg«ªªƒ"ÒëIð>@Û¥ÁœšfÕz2‰©33§Vú¥ ¦‹&`STè’ªa—²qÛu̲X­VË&™Æ˜b‚Œ3SÕ³¦&iÓ¥]̊˘-G]&±U³ªÂ4EÈI'(Ù´Í ä.ÆÎ¢¢q8i1ekÚeŽ¡N_yé¥ï¼õ]Íu–1Oký“?÷Æapï|ÿ‡'gídrPx€–ºÉQkJÞ1 jŠNÐ,Eç„Á¬®+Õ,R &3Ö•#4È9v€–ºPƒˆjvN1ç¼NDªª/Œ5LˆÑCtªG>,?ºy®Õ•tùˆùÄQ‹b­[dhQ£uŠ0±ZuÔÉtÕv ¶ZuYˆ(gÀJbr±Ã¬QµaÊ.GìšVæKçNÚU 6¹ÿ0Þ?£†¦K ËdÚÙ²ëdšyr¤qÕt™¥ï57 ”sStP‡ŸùÂç?|PUÿÞø¿þâ^ÿ¹¯|ù?|·éô­wÞ¯Žo><]‚™æ\âcçÌs0@ƶY©æàœsr0"B³ZV³é,ç<Μó¦c4C"ò^sÛ.Ïç'?üÑ»óùéáÁôÖ;f:?;?=y$Ì׎_ÿük_ÿÚWïܘ9'ز®=;'¥fS[{q^ŒyÞD_MŽº®ƒ¬Ì¦–3’9–ÀÈÎ¥ÉIN ‰Äû®m‘ šË]ÛB°^SÅGÍj¸l»6fCÊbÊ€®MÑ–ÍÊ »”Û¶K1·Q¬¤°M›®[¶™B½hc7ï (+Æ6FvÕbÙšÑ篧®iS—5Ç”ÚÎR@ÿ ….i×59u)ÅÏ¿zçæÍ›ï¾óÎ|a§«e5áëòwÿÚ¿ÒžŸ~ÿû?ºÿ¸DBK±02@ЉWϤšc×Ì*ïæ‹3GÈ„ªZU•j†ÒᔈкåÁbêb³BÊ9EÄ”¢ˆQ÷ëð;€ P"h!¯‚¥ã‰³®9ªäp*±ieÓ1Ï;'Ô&u”V”ÇŒÙ7-/˜ólÙ$3[µ]iU‘Bošbw Œ>¸©æó®¥Igt²ZNŽ®#Ïî~|öñiÓð¬£i¦ðàÑéÉ<žEn°f '§gF $Ô½î.b@c4ÍñÚáÁ+/ßþÊ—¿ø{¿ûºòøoüÃÿåßxíKo~ñ­·¾Ý)Ü{4?¸ùÒ;ïÝuÞ«{ïCm×>~üØÔ|çç§]×ÖÞ;'G‡ˆ0?;}åÚñÑѱ™½ôÒËN<}øá‡˜QaµZœž=:;{üþû?\,ç³éäpv„ ‹ÅâìôÄ1/¯¾úê/þÂÏùÍ/x†:„Iå&^50{G;„ì½ïrvÓ£G‹–œËÅõkÇŽèìì´mVšR]W׎kvNÊ àœkÚf¾XL§Óéd’c'ˆ±YZ3TDá.vÄ>æœbV@nÛØ$h»SŠI]ŒMÛÅ.­V5[Îf±K ”ý²IMkʨm\SíîýGjö§¾ò3еŒÐ¤6¡[®ºv™5Óƒ,˦UMÍjÙ4‹×?ÿê­[·ÎÎNÞ¿ûød>¿sûð‹Ÿ»þ—éçãbñ½ïðÑÉêã‡gÀÅ˜É “ƒŽÁÌrNÝl6}åå;Ëå¼]-sLmÛ2S×µ)'c&ç¤]¶fÖ¶«fµÔ¢KE`mÛ8×@JÉ9W×uðÁC]*d‰"êê°§ÍK7Xht¨ÓÚyŠ©›kj  upyÂÇvZ;Ì´\åó¥ÞÏÓå*À²íÑ€bŒì}]±ãàÑ$â”sJÙMªè>öõÁõ“EAŽnÜQ Þ¸ŒMc>‡ëRþðGw3ÖßûÑ£Nf—pzræ½K)» œ@ c'üÒí[_zó ¯¼tçÿýŸÿ?gÓÿö¿÷¿xõ•—®}ðþ%¢Ì®ÝþÝo¿}píØ D$ïœ_,æ<Èf“éôôô$µ­÷ÁÀt~zú…—î|åÍ/×u}tt|çÎKªöÍo~SÌ›¦m=zøèñÇ‹ÅÙ|qSç„؉ӜVË…÷’»8ÕoþìÏþìÏ~Á LfצNðp69:˜Î8ƒv"ìÍW¿þ»ßþ/~ù_¼÷þ×ÞøÜ_ùKÿ•W_~é½÷~ôî;ïÌfÓŸyãŸý™7$.ý`·ïÜùàÃÞy÷¯~õ+_þÂ뢘BlA1·ÆÉ`Õ¬–«2ûœ¯ÎÎFÔt1fY¬Ú.FjCŒ1u]Œ1 jBͦ‰3»&é¢Í+u)%z~~JL÷OÏ¿õÖÛæ¿ðóoޜܸ֯ÕZ>éâɼiOºÜÚcg‹eNÝb~6ŸŸß¹}óÎí›Î»ïþàƒùjùæÏ¼üçñË_}íV%ô·?úè¤ûÞÞËš-gÕ|~v‚ŸÕ“à]àlš„Ð{1M¿ð  ,øá÷ïÞ[,1vóù¼ëZµ,ÂUU™…¬¹]-–ËBPMQ5·m»^º® !L&“àC€ ³QfXÝ<≋ž2æìWÞ[N©[.çóÕr®)M¦ÇS~åæôÎuÏÖAÎMÓ­ô~º6o"­ÚF³a×¥ÉtòÆë/·ç«¸X@\Va—ýáá­wJ ‡7n&s­y ‹6žžŸNföñYwÚ9t'×o¾öÏ~ãÛQß¾wÛöÆÑ,wMJÖ¡D•œ-³ÐÍ×^~éÎ^ÿ\NÝÿãÿþ›M&øWÿÁxóÆ5D:?_ ú‰Tß~ûƒ7ÌÐyW…Ê{zvúñǃaU׋Õ"u-3j=©Au9Ÿ¿r4ýk対üò+mÛ}åË_=?_üÞïýÞùùòí=|ôàüü¤ë$(ApjÒ¤®™)um]…Õji9]¿~ýðÚ¡ Ì®LªƒÉäå—ï¼úÒ­×nN½p=™¶Yÿå·Þú/~ù×~ë­ï{8ôÕ/é¥Û7›¦ùîwÞšL&Ÿõ•×_û|°XVçÝk¯¿öÎ;ï¾õÝïüâÿãõÏýâ^¾=å¨Ixy• (>~|r¾XܼyóðèøýîªALùÁYszz–’Þº}{2=Hj)eÕ,@^°ôBä¤Sëï?>Ô1dy>{ü¸Ý»wïÿ³ßþ.ëŸÿcŸÿc¯½þÇ¿ü•Öà»÷îž,£ž+uô€èÑãG]l?z°\Îg“úæÍë“Éäû÷ÄØ~íg?÷oýÍ훵£o¾u÷îãöÞëbìVË®ë|üQnZ×U7ê¶m¦õíÛ7ïÝýàOý©?1›NÞzëÛß{ë;óù¼iWççç‹ÅyÎÙ9®'³jrMU»fµj¨ ¨šRÛ51vÎ9DÈYËqÁ‰÷V ‹Æîæ1íÍ;ï|÷÷b—n^¿>N?~|~v¶œ/‹EŽ)Þ8t_ÿâ+_óåvñ5w]\´ú@oÎ;5³UÓ¦”I\ŒéÚëöOÿüG?zÿч@;'J®ž4)Lo}ùõƒ¤ËãëLJ7^ùáOϺ‡g§.૯L¾óƒÞýð´2›á‹?÷å'-¿óáÃYåÞ|íe]-º.v*ùÖäq‘ñg~æãÙþè£ÿå¯þ‹þåÿæÿðèèˆÅ-›ÖȵɚlŸq5ìó“ÉääääÁƒH )ÅÂçf&!ÍmÓUò×ÿÊ_ýÚ×¾–’Þ¸qãG?úàñãÇ?úчïÞûøñãÇóù¹YîbSbhÕ¬I'“‰ˆä®«+o¦íjÅBÄ.¥Xw|p Œup/ݹó¹Wî|õµ;‡ÓÃãkg«öŸþÚoýÓ_ÿ»§ Iu­–Ô5BP×õÙé‰e ÁM'“ipn@nß¹óá½»?xðÚ«¯ü­?÷Çÿkã/ß>ðÖ.™ø¬…G+;ê=¼÷þ{ï¾ûîk¯½výÆ­o¿õV—"¾÷áƒï?Èo~éK/½ôʺùLn^;<:˜²ÈýG&‡×ÿàíwÞ~¸ôä^::šŸž´1½ýÁ‡ÿä×þe$û;¿ô•?ý³_üÅ/}õþÉé7ôÕqˆÕ„ºÅÝîµmsÿÞÝ[&ͦ1åÓªéÍWnþÿößýÚk·>xôÛ¿÷ƒ·ïždáÅr¹8?]­Vóó3"*Žþ›×V‹ó›7o|ùÍ/|ó›¿óÕ¯|ùÚµão}ë[ïýðGËåJ-­–«Ç'cŒÞ»ƒƒÃ££;fÐum×® g$˱[5‹œ“s®Á)¥!ÑC^8°L˜ ¹sÝÿ¿þKÝ}÷Ýï¿—SFÄ“³³³óùªmb—ŒSòؾùú­_üꞢ€jÊ«hï-'‹&›Ù²i ø*ª¾üòËâîƒï¿³úøþae1.¨ª?|Ð&šþkî«×oÔÓãÙdvó¿üßúÞÛ<<{ôÆî¼ñêì›o}ÿ­|Ô¶øòíWßüÊÏÿúï|÷÷?>?;}ý¥›¿ôǾ¤‹³”rT·T¿2ÿÃEŠ)}ík_ÉšÞùþ÷>º÷a³\"!¡†i媀^–]szv"‚MÓ4ͪm›¶mTsÙÁrÓ4}r$F3K)ÅÍ,«Þýø£³å¼šÕ?úàƒßë÷Oççïß}ïüüÑùüqW∳v1¶)E‘’pÓ¢‡‚«'˜‘¬Kñ|±xtzúуï¾÷Þïç;¿õÍßýÇÿì×þË_ûí_ýÍoþʯþƯýËߺwÿ8ßtÝÇO£Ñ2Áû÷>î;Ãȩ‹Õ»w?~÷îƒwî~ü·~÷»ïþàîÃE¢ïþèî7ÿàíEg&!*5ŠËlgž4éw?þƒ·ø«¿õ»¿ñÍ?øÍßûƒ_ù—¿ù+¿öÿü7~ë›ßúÖo}ãw~çßøÎw¿ûÍßûÖïýþïû­·ÞúîwÞ¿ÿ㓳UJ*œŸÃãóÓw?øàƒï?:ŸŸ¯ÚhÐ*´€Jþøæ­Ùµk@üðôô´Y®r&ïëéLÈ’å&vs°6§f¹8ýðýw—ËóÕâüôÑÃåbN÷Þÿðý½÷ö÷¾³XœÏONN>|t?¥fµ:?={øàÑG÷?¾{÷îû|´Z-?ºï»ß}ëíïçíïçñÉÃùâ¬ëµÔuMÙcìrêL#BFÈ!$ÐH J eTИºUÛÎÛö¤iÏÚnÑvM»Š1Ùdvô¯þù¿üÒçÞxºþàþyó~ô£‡+<~Éf×ï-âwÞðo½ûÛßy÷N¿÷ÁãÜ;½ûpùxÞ~ôøôÞ£G«Ø}xÿnlN5×gtc /ñK‡|ç@nº£×¦Y\¾ûý·îÝ}ovP{OøwÿƒÿH¼r]†EÓ51/Vm×%àÙjÙ âd29<ú¨íÚ.eaRÍ9E±”Ñ ÕîܹýÅŸ}óÏþÙ?û½ï}ÿŸÿó_õÞ?xðàl¹(]Ìc[`53 !XÎV 9aabIšsÖ”¢æÄDLä9«‚÷Þ!â½6À-H4š„º ŽÙ çc×åÍŒYœ÷ì¤K1ådžøÍ›³óoÿõ¿ó—þÕZ ˆ~øÑé?ùµoÜ}|Þ¶óóùé·¿ýí[·nMªúÃ?<;; Þ7óÅr±4„I=»yç¶8?ͦӃFá×>÷Ê›?÷µ/ݾyóßúÝ—?÷ÚÿëÿûåÛ?|éæí×oÞ¹6=øükoü£ö/~ë{ßóÓÉ?øúOág_¿që{ïýð?ÿõј¼TßùÂWÎòÉïýÁï.—‹åâÜ,W^bêÎÎÎÏ­rL¯ÏþõåOþ…_üú·¾õû¿ñ­ï¿²Â)ûàO= !0¡÷>uÍùÙ™€jNGG/¿tçý~ôÒ­)Æý自v0;œÎêóóóùü|µZ!Út:côÓª6ËËå‹tšr²¬j“@©™×¤×&þÖñᬪ˜¹ÍöÞÇmµË‰‘Ù9ï«Zœ»yûÖÉýû_þÜËo¼||íhòö{wë÷øöý½ÿÆ_ÿë/¾÷‡Ëþ³ÿì—¿ûö{ŠéÍ7?ÇqõxÞ4Yb'•;<8:]å~ø±ó7îÿ¥?ñõ›×.VËVÙüÓ·~¸Rýú׿þÑG÷¾ùÍßY.¯¾úêd2Á¿õïÿCöUF‰Š«.ǬmcÌ`“Ū1³ªªf³™©ž6«6™ s1fÎ]W€…ª²ÃÙák¯½ö•¯|õîÝ{¿ó;ß äó³³.. ¢,âRŠëì:³äœ@J¥s¨=±äîEˆˆS§ ™,#2g HœBÎÍXHsêbŒš’ifqŽ˜£¦”²!x¦cæ?ÿ§á¯ý…?wûÚATûÎ>ü'¿úÛ— ¶móá‡3ÂÉÉã®íê Y­–K@¬ê‰²s“éÁd6[(¿òÒí›G³/þÌko¼ñù?xëÛ7ï¼ò+¿ößþè¬vÕ+ׯ¿|ëö—¾üs¿ü¿ùï½ Bÿ­ÿê_øÒëäþàoÿæ÷¿×fº^]íÚ&?zç·›fµ\œª¦à$¦n~¾œ[˜Tõq?ñÅ×ÿÌ×ß|÷w¿ûÞÇ;€}ðg'¼÷ê½Ï];ŸÏµkrJ³ÙôöÍÞ¿qí0Çx÷îÝ®Ku=™Í&]×­šE³jl2™bƺªÀòr9ϱ­‚SÍ‹Å9¨M§ÓbDÔ¶­ª²á’¨f>žºë‡ÓWoÝûð‡m‚¬ÉWþ£û÷¨b…\„D [-èQ“°Q2Œ)Ä”36³sž„#`Z.~æÎíkyùåk>xü½=¾ûñâk?÷³¿ôþäGî®ýÍßüîÇæ†éÆYex²h¸”º@zxxØ>x<×åé­™ÿ“_zãZ nµšÌ®Ÿ·øÃO~ÿÞãÎà7ÞxðàÁ~ئîõ×^ŸÌð/ýýÿ6úJ)´ÊmÎE«Ð²šM—‹&¥ìœTUsÊ9ÏK`bfSM) a×µ9FD¨¦f·oß¾uëÎr¹zçwSL)FÔÆ@EÄû06€œ,ç\ À²–EÑEUc¡‰¸´ô ê:XÍÏb³bÊׯ‰‰7æ6QJ‰ DØ´€ìIsÄØ‰‹sÌ9礎…Þ¹~ô _{ós¯ÜŠªßÿ£o¼õn$—-¡æ¦iªàS×åœ -8Áå²kô¡:9?cqU˜Ô³ÙœÂµÃƒÚÑË·¯}á Ÿ÷?˜_{ë{ïžoVÝÙìµÏ}þç~îO|ó;oû‡ïµÙþ¿ø§nxá6¾{÷½wÝ_E=ƒ;Óã¬?¾/¥n~~ªš‚pÊÝb±j,IÖ›µÿòk/=~øàQ«ÙO  8YžÏgËÉ9§).Ëf¹èº¦òr||Ôµ«º»Ó³“że–ÃÃåÛ®%‚*Ô¹í‚÷ Ú´‹ÜµUí ¬íZM±Ô‚u]ç½O)©*3ªžxÃÀÄ”n߸qëhvúøÁªé­ž„G§¢v@F‚À`˜Ûå’³NÅ¡aJIÍ¥®5"’óÀHdÏÎ*t/_»†qþÒK×çMûèÜÎW6©ò¿üÚÙùéªÑ{׆–s3áê|•Œ=X¢´œNkpÕ*éÉɹ‡ø…Û×f`vxýñyûö>|Ð%C::::›Ÿ¯šFÁ>ÿÚk‡‡‡ø‹ó_'_'ô­Q&"F$BÀ£Õªëº®$ƒcŒÞûù|ÁÞ3¨ÆÔ bÓ¬R×h¨¬mÛëׯ;rÖ““Óår)Ĥ tÎUÕ¤8?åçjÕ–â!Ì)1"1÷„3Ýðã ÌŸž¤f^9¬B`ô%´ cNd&Â)FДsÖœ05LDÌÄ”UcNÀ"'íj~ýèàèpÊÞŸwùñ² ³Ãùb‰ Œ¤9åÔ)´èNå.*¢s~±\Kð¡šLWÕa<¦ÕA%7nß¿_êÉÃǧV­–«i¨îܺý…7¿|÷þÙ‡OÛ”¿þú&±|Þœß;{¼è’wä'Ú>^5sÓ¼˜ŸjN̨9¶mgêÙ±¶ê-ÞœúØ®² rpˆÞ±ãv¹a͉™,¥¶kšù²m!¨'•cB2K)Æîôd¡ªGG‡u]!AJ ¼÷ír%BhÚu«Ûª ŽÑÌR×– ¸¼ñ¾³Á<+'«rvh2­&Óàk/¡ ÷Þ7P$;_œƒóÌ 56-Æì‚«–ͪËYœóäUADœ¯RÎf˜Ul»ŠýñdWç³™K1U‡zr|í0¥´lÒj§³#\ÌÏjªæR¨ØÌây`úûÏR»¼9«'žŽf³®‹ç«ö|Õ­rç²jÓ¥”Ý~éÎd:Á/þ™_DW'q&'ì˜ÉßlÚc§jˆ¨š«ª^,—™iŽ‘™ÚfÕu-™2Řâáá¡)¦”sÖóóó<Æ9a1€ºçrfPÕùªI)¨gI©¸\àŠBQ;ë¹¥ˆH©9?Å'µkÚ†EÐ$9&óÌmׂªjB3Ô„…f)%C`q•LÎç§T“½ÔG\M\5Y®¢©Âj9w Þ ƒiLñü\³ ³d5Et"¾šäÃkĤÍ\¬«*^,À®‰‘üÌTE$„êðøf›¨‰”=† ¢çírÕu±ŸÁ‚.—sÍ‘ÐJ¥ƒó¥ÎêÓÖr •—éŒÜ„YrìˆÀrF*åÉ9µ]+‚ãɤÒU3œœ.cì&“ZDT3"ˆHÓtŒf–5ŘÚàœóÌ€)u×(aRÃV)+¥NÅb NÚ¸D‚|Ö”rW²lÌ„ŽS—5f6¬ëzÞ,;Ë, ™‹ïR25ÈšUs¨œ&ìÐ’s¥<;¹ŠæÂHÚ.fÕji›Ž–r50ŒKÔ•ú/rìfµŸT2©«ùü<©…–m#"çóeoЄ“ƒç=~î믓ŸD®uŠ,LžI„ÍßL e,di»Ä—@SáØ¶)']2²÷!¥”Rf–Åb!,˜`ÊìCðD¢ª9ƒ©.›6¥„`"¢9aÑ1#,ú™¥¨¹hߘ¥e«]㪚W«vÆœÏ) Wì+òÁ€DdHØ÷CÄ4¬˜rLI‚ï4«ZuxÀ>ĬÄuÎ4Åfå2˜ZL”´WI0 lJ,Bž¦Æº¹cȪHÜæÆ!bê’9–Ë„À{€ÔÅsrF ]ì’ëòœŠ@j²&45È $ Š/Bº2mLBM8 ¾¯h!›—*¶˜cl³FGXU^s2S&Z.cÛétê½éë™±M™J=¦œ£c!a²‘Ù@$U%´lÖ(àÙéù£ë¬Ôuíéùýà÷¾Tº’0#!‹+ -@[ë:ÈÀD,"²sj¨jÙÌê]£ˆâE¼7eR®xIà€‚ª’î°Ànч)›Ij!å&Â*BÛvངʥÔ1*31ÓjµBijó…!’8ï‘_ÿêKä'-U 8f$'ÆD J)ÅÊšs±‹Y­\ÏLsì‚s)E4FhÏ'¡*YR3qMÓ˜™Õ¤H(ℽ™ådjÚÅœR0"005-2Êzî8 f4ŦËÊ„QsJè ©Ҝє…5v½¼: Ö6`öÈS'"í<›rUw ygJ1r84‘0“f0&„„„d€Ù¬¬×HDÎ7.@…ªÝ4– ƪiØ(TÞ›¨jÌçL^šóƒÉôäô´m;fñ1Æc=q±KÀ,Î93ìK·2¤”À !öSMÕ´A„RìlFÌPu‚ –5å΀#@g¬j5sNPE$¥È= iz¬¥Þ¿ °)€@Z6‰k³…ɤiV¥`) PŽí´®ºÕT½ç*„fÑ1$5ÎÉŧ삛8ÊqÙ®æÞyò²8?ìX˜¢¡# „LL½^Æó¨i¦¹0Z'âSêRJÞ‘ö`̘Ûô³DU>[ú£Ê TcNmŠìÕœÓB\ðJ´\*s ãMU%ç콋1( !¢*€9%³Ìf š­àª1¦œSyõ!Ç’blVÑÁ&ÓjµXN¥f“ù}ï=1–掦 -Fóâ<‹‚eT7sà Ë-%»”RB`&"@&Ì /Ó¬`)5‚êP2c¬«C0GLóÅCó9Q˜ÑyÛV–!T>$åå*^« ªêNS—bÎÑ41©0úú0ÆÔt!Í‹z6 uBÀ¯ÿâWÔ0E Îj"Þûðp‘Å3mÛ6„*¥Øu]“`¯ê JDUp“ª¦Üxq«¦9y|–4Of‡MÓt1有h2™0;°¬Sî¥aŠÌÄqN«¶m¼÷€³Š¸ªª›Õ²].§“Iʳƒ£UÛ>zøØUUŽ© A¼sΉpÓ4Ù”E®¿òÒrµêº.›¦”Ä9"Ò”aÙíz2U3ï}×u]×ÎêºY®ççLdf0©kﲜ…ªªêºn¹\Àd2]víáÁ!Z>;;0&)­Iêàêºnc¬'õÉÙ¼i;f7©§ÌÁÀæÍ’˜Ôrì:qáàðp~zc;™L„ išzl¹\Џ¦éB]ÅØ©¶•÷ˆÔvIÁUÁ#bj[3cUMm眬›ÏVu躖Û¦5S'âœH)ÆcÊÀ„Œ^˜›å‚ ÍòááaÎÙ —ÐT§Ó©wlªó³ùªí¹>˜5MS klW‹s™LÛ®õ‡]ÛĶSKÞ‡v‘Bð³Ù¬‹Ý¢Y :"&‹ Ù€œÏªf˜ÁL1H ®‹†Q•‰¼ÈAífõŒÙÅØ-Wç]×r¨fÑPB•¢9˼OÙ–«F ·m㫲‶msppЙdÕcÎ9ÔÞ‡]×á—î+}? @CN @Ìί"ŠóªZQ)¥®ëbJÈÎúŠ|%0ðÂUðÐuÁ»¨y>_fÕÉì ë:3Š˜ºU•ˆêº¶^w)©©nèÖ)¥¶mTW]×VUU ™¹ªª¦ir'“)‹´)=zôØ™ùðð¸ª*SmÚv:›v]D¦Éd2½~¸X,W«UÎy±\8çP³.N9¥º®§ÓéÁÁ™YÓ4¹]-ÎÎTÕ;wÿþ}Ç2NCmÛÎçóÂY.—«Õ êºnšf6›™Ùùùy©uè“âÄ©™89_ÌsÎ$|ꉪ®–­x— bŒ,îà`ÖÌç«fNDªIU뺀ժa7麦”5Ï¢ÑV«Öˆ}Œ©c@D³¬]×±lŠïB]×(“-3³sŽ™KhcL9£ä MS'Äy6›¥¨€–L+œcÈ];_vÉÌW5˜LªŠ,Çî¤MM×2ÁtZXŽxÎÏsÓé4¦¸l—ÄÄBÈDFmÍLœ9[ a€„k0J)ain E¬fÓªª©íV«ÕªÈ¥±ølAħs9«÷^5¯–+",h)f(pÖtvÐ¥”clsΓi-ÂÖu5]jbjSî’f….åU—«V3¤˜SÌš-'-rަ0®¯$d3‹1·mÛvm›¢²ˆsˆœ<­½"ÃÄ\FIÁ7¥¨”ÕµˆTUUÌ@Ä9‚¯ëjZU“êà뺞rÑD¤ÃÃ#bgÄóe3™ÖÓ ©§³óùêÑãÓ>~xïþÇdEªÑP;Í]N]ŠmšM§Þû£££ÃÃÃÞÕu]UU5›ñdr|ëÖìúuò¡šÎªé¬ž”¹Ó [!„P4œs¥¼½ÔR×u]×5‹Ëfì\V0$qA|@–*ç\ùØ$Tu]OªÚ9?N3ëºdC_zD(ÄË‚AOê™÷¡”#–ÆXVÔ8˜]áëoÔ^‰ÆÕßÌÂ,%¡2ÈÙˆ8çb°œ½¯¼÷ÞUž³÷¾U]×e9‘º®«ºr"¥pt(Æé¤žTUå<#1R7 aRùIUUÞ{'ÎK]Uuå몚VÕÁtœ³sâó^‚÷EÇÅ;®ƒN&U¨Cð"„H€\ŠÊÉ¥F©cÆ"ë“•q›Ô’B6Kª%ð6¤.å¤fHI­íR›b›r›b—RÓÅeÓ­ÚHMÔ.[—4er†¢@YQÁŠNÖº&hšÚ*°/ÿÚu±¸ŒE qÝŸ~­À²®/R€P®Yþ½¤ÜSJÎyïªàëꪚ8 ¥û±°íõ7^{ýõÏ¿þÆç_{ãl¾ŠYoܸý¹Ï¿Ö´‘Ä’Í—«6e$ ÷ï=xøàÑùÉ|9_Å6u«Ø®ºfÕ”{(tßG=xð üid\=Yvwõ'çêÉ4„PLe2™Ìf³Ùl6™LnÞ¼yppP†þd³MY¼;_‰¸Š}ÅR! ¯ ©?3# ]ë¨P£JU>ô=ìÄ!r¡×é,C¹×%â¾Ò]˜l[î¦wf–V2 "âƒ@1lï}ùXY1Š©—”‡ÆHe«ªJˆRL«ÕÊ9 NˆÐrZ-ç]lRŠ©ëœgD0S2.Ò,,L΋# #V>TÎ{ïƒóÁ»JhVûiðµwuªà™ØûŒ”ºÊØG£ L£å¨EÇ’i2KVú¶ ©AVCâœ5¥”b韗SÊmÛµm›Rê›Ï(ºŒŽ}E®&çÉCÊ€É@‘rÁDˆJUF÷&>0;$ñÄ.v9™¥”ˆÅ‘ëgeEÈ»cŽ1w] ¶ˆ|íÚõà'ÞWÎ@ª  ˆ¼jºU›66m<8ºÆ>,›öÁ£Ç“ÙìúÍ[³Ã£l³ÖÓéÍÛw^ùÜçÚ¶³dŽ]&7®Ý¸~íÆõ£ëÇ‡× ¼s^.—kx·ªkr¾žøP/W­ó•«'F&“©÷•Ƙëz:›Îf‡u=½qãÖÑѵò¿G³Ùád2«ªÉ“xvÁW“j2“Pa% â¼÷Œdf¨V…)etÎOê)—‘-âKÑ:‡P¥¤9!_9 el;çE\W"މ…œcï%”ÇÞ» Γxd$† $ì‚ó!xï}Ä {/Îû*8G$®—_afvE#@UKMÌÂRTDg³Ãƒ+ X!+d--üŠò­¥˜º6ŮȀeT#3&Tõ޽“"m] 3b\åÅ3U^‚c'Œ¸‘¦öFÎÈ%(-¾ ²ZH´¾ õŠq,ì<‰cç³i/|„1iÌ9›!3y ìY‚¡;rûšˆûZAæ2sŒ—Ú-…u¢ÁÂ9„pppè½/<Ï7i„Ÿ•ù©$ÆKÉEI¹—ß=>¾Bí¤"t½qFÍÀ‡G³Ã£éìpzp4=8xíµ7~þþø_úËõöK/ß¼}çÆ­Û.T7oß¹~óv¨'óeCTz9Âôà`2ÖÓi=™àÁÁÁd2ñÞO§Óº®€ˆ«zrxp$>øPÍg³L1ñ ¾WE™Â×säÁÁÁ7Žg³YUUÎyEt¾–PMg‡³Ãcb§Vêõ©¬Î9äAË2X „JØ•Çé½/2VD|%"LÌ,EÎVØ1‹÷Y„e°"kë¼÷½¦¹÷!Tëé­ˆÖ«ß–©7ô"¸ï/œÅ5M·¼wDL1AÖ‚ñ3ób±ˆ1:–I]“c LÂ8T³i= !8v¦QS«¹´æÔ´KŽ]ðމ² #zGZ;vBh*%8Vµò‚X¼ˆ/]‘Ä„ŒI 3‚1#õJmÄÌNÄO¦³PÕÞWjØ÷ù`avªfŠLB…7¿üóD‚ìF3DrׯUUDÊî½  µ2>äÀ1;ƪªëÉôôôôáɉ)´±E²œû8¬D$1FSuÈ:œ?<<,‰÷£££Øv«Õª¬¹P)ˆù|5¯'S‰1¥¬M캫0yõs¯N&ÓE³Ì9þµ×ªºncwòèÑj>…ÒCTÔ¾rÎm×äØÞ¹}ëøø¸´’],)%@ª¦–-¥Ô¬Vˆx0}ôÑG©m§žN?*Ázñ‰‹%O&“µ“ÀÌ1Æår9Ÿ/>xp2„I5βêG÷?š/uîNoß¾™’žÍç<*RâMÓˆ°5ÍŠ眂O©5ínݺÆD‹ù26É€ 1¦DÞ»;"´œ»ØšÆu°[üÌB!®g«ãqå¹ð»LSJiVW±ëŠÖõZ¿Ï9Aµœº¶mkïŒ\FÌ ]ÛL*ÁœÚ” MsÒ-8!´;Èx¾X ‘™ù©(#¡‹¨AL‰Ø•”?˜ö]Û­šfµZÕum«¦KB=Aâ¶í°ëRÔl@H„ˆ«Õª¨Zyï³æf¹Àœu6›‰HoÌìäôÌÈÅœcìrNj«ÊO§SÂaúgñmÒ”!)±\TQ$Ú^p팒HŒ €BU‡ªö.ˆ‘hÞÒÖ,WË9÷N0båe5899aD*YñcàÅg‡‡u]7«n>Ÿïí·ßþþÛ§ggH´jšº®_~å•×¾ð…—?ÿêÍ—ïÞ¸VΤR®¼ソuëÖ;w^}õÕ7ÞxãÕW_N§U¹‹ÍjÕ¬V“ª>žL¦;T+h¥p×uggg]×9玎ŽJXÌÌ€h†â=‘TU]Õ5"e3@ôÞ• xÏÌnpÍEŠ[šu­2»¾0³;:<šL¦Îùâü !•+qmÙiÐ+—]o‰xoäG™p“øQïÍ~‰^~å·RJ“ɤ•0ƒÙ+/½|ëúÍÙlBðLµÈ$¸IðdJ¥‰lì\Q%2ÏìY<±'&„Ú‡Y]UΓZ߉„Ê@š3ôÃ.GÖ$ ®H˜B΂PðzÑ+.jxEzÉy$GäC5W‰TŹ+ÃÉ!‰øàk¼ýs¿¤ªdâ²²Sã'躒Uökô&çìœSUM)kò̽ˆ*\¿qã+_ùŠÞûèþéÙYLéôô¬kçkEXfNkì_ËzÕ›ÖÁÁA>o\»ifåÝ–ˆBÀÁ|±À.F N9?|øøÞGÂÁÁÁÛ·r΀xûöí/~ùKmÛ²žÅ‹×cŒmçó/þìÏ\¿~}¹\>zôˆ™½÷=>xôˆÑ^½>ûÂë¯Ïß{ÿý?ühz03ƒ³óóâî§W«eÖT÷B¨²ñÉÉãÙĽöú+GüðìÑ9‰S³˜2˜r‰| ,kÎIHמPa2§”J“/V­âºˆÈ¤®*OR(ŸÂmÛ0bÛ¶Ä‚Ë1©%AòÞYÖ¬QUc³b©”)%»~tÄh/Ý:~ãs¯œÜ»÷áãÇ!¦43£®ë€?~ €U=E¤År‰ÈVU5"¶]œLgm×b]M®¯–«U×ä óå2iQìô–’óÅçléÁÓ.éìè냵m[œØ²¯–K‡>x_ (q.§ÔŘ³fà”{4ÆVDJw¼ñÕ?€ÄÄÅ”‘œĘcŒ]Öe ï3Y©H¼*¾ñÆÚ˜Ìð|1× óùùÃ÷ˆ{ö±L}µm,¨|ù&•¯½÷eB-k"Ng“ÉaݵWm+â2Àl6»~óvLéäääƒ{.—K"Þ¾s'¥xp}VWU#"Nê:¥SÒ”Óùù­›7sgggyPþšŸÏ›yK¥)ƒš³w¾ëºÅüüáã‹ùjµšÍf¥DŒq±X×ùÚµkUUÍçóây?xøèÞ£¹sÞUÁ9§ wïÝ{|rB ¯\›¾úÊ+GG×>úøþïß “‘š¶s®BÄ»år‘sò^ĉˆ‹‰NÏNfµûÜç_žNêfÕžŸ,BUŸœÅ”@•!gbdDódÃqYµéÚ’ ‘âï9禓š1 QÓ4ŽIU ¬i$sŽÛUÂLJ)EPSK`99?æ”!ÅîhZߺ~pt0}ôñ½¦Yšæ¡©FÓ  •÷ˆ|v~ŽÈ>Ôj¸X. 0uˆ rV«'uÛE$®êúøà°Y¶«¶Í€M³±sÎy‹¡ª|¨ Ýé|ñÞ÷Ú¤Ç7n`}ðñÇËå²DeÅQïÚ.'ôâËë@Ä”SŠ)gEqšU-«j×5fæšÍêz~~„&5i^ÌÏ&Ÿ{åå¯~ùKdz養]sòøáãGæ‹sÕäדJ;ÇÓY}íÚµò°ÊdY,Ó97«ë:øÊ;ï˜ÀãlR];:ºqãÆíÛ·ŽŽJ˜>ëÇÅ €Û4M×u)%",ÊÌBÀh9E4e4Fdâ®mÛ¶e$f̬֘®ª*ÔNzß‘¼¯¦“™ÈN<‹ÀfÕUÕ¤ªÂd2cvccLšAÄ×õt2–ÔDñ}KÞÝ9§ EÉbÐ{îqN&‡ÈE…‘ˆK¿Fµœ3„J{vAâ.×õd6:çB¨ÚÕªm–Nø`69˜ÖÓ:L«*8a„ÊKíÝálz8›Në0 !8_Æäd9 #0‚zæ"B]|³êjªêÃÙôúáÁõk×nܸæzš¨½QF#MFÀB.¸j6=dö†³µ1¯Ú®icÓŦK1¦Ü#ÉÞWµƤ Xˆ~È= )EÀ5ìcc±ì’Ê"ËõV×53¯VÍb±899Y,Ë岸åÙñݲU>”Ë–…e¹\žŸŸŸŸŸÏçóÕjµ\.OOOïÝ»÷àÁƒÓÓ“¦Y©j3?ϱµœRlfuõƒïÿŸýò/ÿú¯þóùé‰cºyí4iîŽg³I•cûàã?¸òèãÓGÎ?|üàþÉ×g')Ŷm Ôy–²f"$¦2²å.u«®iÛ&¦n2™O&“â —zÎb 9çÂù+1F/ìˆÍÌ;©«PWá`6[G;ëTÀt2u®ÐŹwÎWU]æHqNXT-¥ä} U+|‘'M)§”ÌÀI/î]¦’’µ`f0s~eoËÓ.›… ÛÂù=Òµvzûæ#)kîuì›Õj1_œœœH¨}]ûz&“0©Bí\(»÷UJÚ4ÝjÕ¶mç›å¦YžŸŸÎçg1vˆà„”Á¡òÂ_~ó‹ŸÿÜ+<øÝo~ã¿ýÛ?¾ÿ£{±ë òþƵk3ç"§dm‹´\æÕ*­V±ëÊH-syÁC«ºv•°gt„ âY!7±Y¶K3ð¾šNf³CçBÁ×B¨‰¤¤)r¶’²hš®m:ÇÈd šÑ$øƒÉä`:=<8`æSJ©ƒ‰½÷f˜³š!‹¸2G™¡©1 §”'“Ùd2qš­T[ ¥Üu±k»œ×Ío sÌ뽪&ÅiÚ“v17m\®Dq.d.@:“ó,"r4;!´«Â-·œsN¹,tËår¹\N§S3K)2‘¥”SŒm·Z,çggm³UBlVËÕbÞuM»Z6Ëe»\vÍ2¶­göBŽÉ 1™†cÓvm—º˜SÒåª=oºyÏ›vÕųóÅÇNÞÿð£'ó¤È'çËÅÙBcâ'Õı#CP@èU™“YTÅ"'ï|I ÍÌØ…ZB`ؼý•?ª ‘V]Ì€H®Hd–)ªLãŽ/šòšCb)já]?ºžÁYÍTœä¤N86çLXü‚E–Å‹[C 1Æâ‹‡àoÞ84°åbyv~V&Èãããë×®MŠóU]­šÖ9{ÕºêÑüìÁƒõdòáÝ»¡®Bf‡uUånQ×uŒ±PÚ¶53K)QY” aº®‰1¦”„ bŒírc$eç|Y4ʇËïžžž6MS¼©â@žŸŸw]ªPdõ€4mÛ¥H·ŽÛØj†Åj™³Å”D\¨'‹eQÚj‹‚1,ËåJ´ TUòÆë¯×õä£îÇl'§§MÛ¦ØÀâüTUëàf³k‡ÕZñ:ÆXàã¦mÃlÖvÝr¹,™¬òBð/߸溮ƶmƒs)¥à˜ÖÞgÍr…h–s´¬±kØU€ÜeM'º@6­duþ`R'”SÛvvPWÁ«æv5O)9W¥l9£¡,—-^;>T͈´X­²š8¯èš6wf€î|ÙF ¼»áMM›.Ÿ7isFi’6m7«jB¬BU°“¾ÞƒÝƒykCoÏ’*L×¥‚e3S]W‹åya^á«_ÿs>„B•瑼ŨjP²‚lp´¾G–š™Æn0(LOñ¡îrvM×:ñç9Å‹*)°2ÖÇ]øŠ/!"UCÎñŒ%?_U•(#R]O`~¾¸~ëÖáÁþÞw¿³\.®ß¸ÑÆnÙ¬Ì ÔÕµ£Ãƒ …EWÄÐú‰û.¦’(ÁÉjµJ9¦¦mRJhà½ïÚ¶ë:í²®”š¦)({1`¢ÿ_{ïÖ#I–œ‰Ùåœã™YY}.9Å…$î.¹Ü‹I€í‹ýã…z =´ W»âh©fÏô¥²2#Üýœcfz°ãYU•ÝU==œtÕÙ™‘ÇnŸ}ö9¾äwßoÑ~¿w‰Š©šº8iUE€ˆf¢Ò0 c.¢ŠHâT(g—ì%fžòpss3 ‡qf솀?ÿÙOéîë×¥Ú~˜ÆéPrÐq˜òÀH»mÿÙ'WLèù̲ŸSU-v1%/Üýk­50½èc—¢Héb*yìûŽû¾C’˜L4.¥”i¬µJÍÈ©Š¥ŽÃ¤vlÛ>l©ô]ìR$Âh·ë»È9çqx=åS7M¢ÆÌik±ï"B"„×÷ûqšˆâ1©ŠÆüú0U#ä”bÜÈ`h¹â!‹r ÕØzFô@×õÃ0LÓH÷І´08–3V‹Î[¾€È©øcÄŸÿÓÿÚ)àw÷ûÐõÈŽ‰Tq™eG»­D•šMU¥â¼ƒ+ uݦëºíõÕþ0Æ÷‡CŠ)Q‡ƒ;òeÐŽ™‡Ã¡eS„WWWR…˜6ý&&0ÀcÛÕÌÊ4iEt»Ûaàív7Œ#rØ]] ¹¢¡ÝÝÝeru úÉÍußwSÎSâÀˆXEysíëcqØßÞ¼Øï÷SΡ#O`Ûo< ´–ºßïæŒc,SÉRewµ Ηî»iœbS—¡~$ò}Kˆx¸¿K1v›]ÎùîþÁ÷¨aß Þ.Æ_ßß]__ãX*†È) 3\_ï´Ú0deæa8Ô);Sý°¿WÕMŸþàó⻯!Ä¡äë›["zØïÇqz}ÿ0å‰Xjßwf²é:“ºÝõx»ÝTèbØnúˆK‡R2C1£©Ê˜§Û›Û cŒ2|C`¾¶Ka·íl8< ÕišBìÇ¡ªaŠ›\4Æ®Šö}ˆS©xwwÿ0 äi*"ÈñaÌb€RŒ6¾ÌqT㸫*†®Û„’Ä/n_<¼¾ß?` çU "2/逦¨¨¥LàÓ²„øó¿üW"Rj-b“÷Á ’ªä\Ö W¸C50õi&QÕÈÉlájwSk-µH­!ˆ¶Ùn»Ý·wT†u¼ì¤Ûlúyÿîv»¥'¦m&AUýöÕ«_õ›oïï®o?Ùì¶Û톈~ò“ÏïïïíÅõ5”<å\jŸýñ/aÌSJMè²è•"òÝÝ«¿û»¿óWèïkÎ9SŸëáaï)ÐÕZ©ÖÚ÷=‡£§i¼s1 ÌEd‡@f¦bhfSqUB⬬Ö8þNçÝS¼ÙlÌt¿èºÎªä\D„dY"r÷®®w/®{×óÉã¸é"3×Z¦qÉ1¦Ín×ow¯îî‡,¯ï^¿¾+eä€ÎëÐZcäM×w·‹B×Å.ÖÂh @hW½¦‡[ŠzÊZ‹ÔbZS µe±©ÖZŠH…Û—Ÿ©X©*Õ’“1sQ,U§\§ª“îD¡H •æœûMTTˆŠA c1Åž±ï¹Öæã@XÆ<ò”¥öÛ¶–Å0¥Ôö•(B[òhfØöÿƒ?ÿo[½¯@1€"€•ÊDN_£ÖmÈDÕÇ5Sµ.ö‹xf,"ªÂXÕÄ©)ÇÝX}Ú8&}}í“M-Â9úÇ}>¾ŒŒÙ¸m­D‹}ê7›Ø¥_ý_t}c€·×Ó41ãv³\§)W­JÔ]m0†©dDÞX25©bª]ŒLôúîõ¯¿ü²K]ŠÑS¾£Š†Ã´?àaöÓ49JÛ @*Æäà¯ü¸åIm½Ê{iç!É›H‹´™Z¢¥A¾ÙlTõp8¸<‰ë%s¹oôÔëáá¯o®n®6WW;f.ÓÈhD¤RÇqHd!…~sÝmv‡išŠÞÝï_ßß+ˆÙ¬P 5ƸéRŒ˜(2G²ÈDh ƨ·;‹‘ýþl6›œó8޵”[²Zk­¦õÅ‹)ÙL‰ "ŠH)"b„AÄD´ 5T?ô¢TÕJÕªuã%·™ÅÈm&•HÀ („jQÅØ c—HêæC&“©æC™²M±›÷Qkr‚ÁqáÉ¢ÎÏÿÓÿ²*ˆˆ(0³¢[ Ê”}6ª”rl m{tF©Š01Îë¹b·uŒÉ¹(sÍ`&£Î3^’úµíw®ºu}}íÄL¿q÷F†‡7*ŠÁQl%è6›ª’k©"/_~Â̪RJI“ (p°\r)UŘb—ú«ÝX²ˆF‹%—qJÎWÛï¾þúëÈÄÄVJ1ŠÔýþpxxÐûý4Ž9g?ÐK]¿ðmŸnžfUÛøÿrM µ€UÕ s-„L€\­¤ÅAx3ËK—q¥NUM`‹ø)dæ››ëÝÕæjÛ‡jžJ)Œ&"µL».„Ôõ›-ÇN²èÃÃðúaLSžÆq¨y2©!r 1QcP4ÝnzcyyÍ!¿÷ÝnwÜz%YU]„¢±JU \˜«X-ªjÓXUADEm˜DT§">z53=f$ëû~Yì)ZÐÐ p`16€HšR4B•,y¨µàQ­í& !̨>]4€Û?ý—â”fC"Z ÀJ Ìþ†×¨H­’‹ˆÄÀ =—åˆt̽fR •éÁ¹G1FWš_™™3Ì®¨ÓNiôœ{¡7v]gËÂ3fŠÌ)F}·1³\¦qUëf³‰‰M ¦’KQ3 ´½Ú]ݾȵL¹L“H.ã8Ö\vÛ-ÃðúÕ]´–ßûKÊ9OÓyª¥æœEäááa1ŸíL)MÓähümìÈžr0>„€U&3ðÉú"Ì_¨ˆ-ÑoÍØiHÕ㛟©’ú–¶Ö\Ÿ£èÕv×{æcRsÎjf*eÓ‡.õ±ëÙˆªØÃa< c6Í9áæÉDˆ!ú0€úžY©Û>!0ÊnÛtk̬ëú8„ÈLy}3˜B)T‰Ã·UDQÄTMª™¡—^³’,ˆ†ˆ#›¸­Å®ë|¢ÀƱø¢/„`ȈmbÕ"uR©ø€¶€/&ò p²¶ôx«¯þø/@|,Ï–¼¨mÍäõ_Tö¾T^D"1 ŽÖxqËfOÒ-Ó~a¬-OÅU!Àyf Ìê9€zÿ­e& Û†@¢n»Ù]_mú1µ)Ã0ä<îv»¨–b¥ÖZ§Mwsû¢ˆL¥L¹mµ.&&rÉ7_~©Ò€Üê<”õ)ùÇæ½¤c PÍ­ÚÉë°€¿)fsÍÌS * ©×Û]ÍÄÌ3 ç'/Ê4¾/YrY¯Oõ@±ÝnRSòéEh'Î"C×÷‚(U5§i?äûiQQ­&ÕÙb AÅ#| „m³)ZäbÖ†œ<˜OÓTJéwW¾? vÛM­¥@11Tñ@¦ˆ` uVë ¿D!ÀÁáò6rÒ Aƒe!Bm …HÍ&PQUP¡‘¶ž€04·Puµ=rv¿ø§`^,#/Ð…¸hÂ,9.‚Ùø@m6ÌÀ“ˆˆ8(Àü‘‡ãJPªy¨µ,äñÃ[ñ‹<ëõgòÞÿ=MÓòïHì›X áêæz*e˜Æœó§/>A€*eš¦ZK×uˆZJ"*bÃÍ‹»ë«jª”z¢6ê‘80‘ª–œ¿ýâ‹’³Û¤§¹}ßÓæêÊ3Ÿ[X @²0QáááÁk.‚õ¼ë'fÊ€UuÍ/Wä3Ó•\¤Ÿø¶[¤íÏ\íl)ºÜÃ…Ó‘RâÌ™ME„@CâíŽ)×,âY†izu˜Üå hP€#ˆ7€E¥ò¼,/öQßR-ô]K2Àb R‹™2…B¶7ô_è©¶£ÈÄÑ™þLÀ6ÚZ“ËOÜTŽ9‘›îW¥d&uÔªdž‹ðAt1€¹Q‹† çS «ŸÿyÓ Aö•5 läeëÒ¨rÀR"3b)…±­¡>"ûn9D„&ÙIuî×—¿ëÓ¥ ª¸ñýr¿Ôˆz§^b×)´“q8 1@Z Tk-E¥ 0rŒ/_¾L}WMcL›ë[BJˆh»ÙtdSÊýëq8x¾—svf †í.Äà-¤¾ïݤV+æ\çE/‡>—ºÁžõù¦q^7ïÛ§QTEe²•¼¹ùøÑaX€ϲZ(!„B dfR2"v)"´Œnð>溯`󦿀¤VÛð]ÓÞê‘Z¨éh¡aƒCbŒ.˜c !yòá@DP©¥dTc& iÙ–¬ªˆN¸€€e6f † Û¼ÝühˆÕ’¯¤%ÐŽ)…@ÂdaÊ9ÎyZ}T0Lªó&3s0Ä*mõûãèúáàZT.æÊtnËAô+Gè9Œãæƒûóšëåã0´êš¸ ÀTS[yÔuzÙ–4WUeÊ­FÈR AÍ\í°ë:frÙŸZk©“ˆ˜ˆ Qˆ91Ýl¶ýæºÉn!Þ¾xЕ¢¬7û%þ´9`3M1Ĩª  µÔ`m®÷Õ«Wk lÊÅ¡3çN»,3¯ ÀT¡@Ìt©ð“ºô—­ïvË=ô;Ó~X‹Ëìu!T)5g"ìûžÑ¶Û™`ž£Y)܉Çv‘”¢J©®y¼$oV[º„ļÐãýO—RLªãrLH)ÅZ²™F"s¯`1FgЀÈÄL T€žY©oMQßîýt¿ßC•Ïwýn³i„¶”œðüíÝnwý¦wγçµÖÍ3•»›×w÷Ó4¥\ŒØLÓ;æ]Ä'9ØJveɦq?ob©¥¥L]äå9¨ÄLfæðPHÑÄÜ?æ"n$sÈaÂ"0ô‘_ì:&œÆqЄäƒx#úsúÌÅùŸÈÌm3»„°Î$Ûë!—ÿÑ?÷Ï•c› @fI‡%õ…®¿ÃVÅ zÐÕDyž¦;14ñÕkžT,‹V›èÈ)ˆ—Zðˆ®X“=0 AЉcô1Ô¹¸¦”J™öûýýݘ]]_ßÞÞ2óTÊ4M5×2JŒ10ƒAŠ1…øÍ×_ÀŸýü§WÛ­+8mÿÃßþí]ÎÛ««—/_68±”2-©ËápXÞË”Ër£<¹ªš@ÕEG­æ™®bëC¿þ÷’r0³ÀÒgXRÄf¦ª •‘R 1†Í¶wi‰>Æ6ÑV˨xÿP¦S@3_¦<â``¨ˆ ¯fi©.¾^:†&_ìÚ mÜ9q4kýîõPZ520•¢ª„€ªZoÞÇë ‘ƒ€BB#Ômâ«]Çi¬´1àiʇÈÌ~ÿ 4 .ÐuÝbb0gX¶Ð·ˆo~ñç"H!1˜ bl¥ Ñ‚6 bˆ±ß¼œçç –fÆfl‡³ÀhˆPku¾ôršU*ž^v»Ýbk,%„óà9F df%Ž!&©BÈe<ì÷_þÝ—)Æ—Ÿ|òù'Ÿ:2ëÇf:P Ì1DB‡ÿð7¿B³ÿêÏÿìúꪥ["^õþßÿîß}ýpàooo—OÝáQR\“ùs]€3Ï–KDŠ˜ªzu¨†®‰»D€5𴶝¤Û]BöiúãGJ‘ M]ÐJU#¤)Ef“]ßKÍ=¾½?ìC­%¸Ø·ºZ©†ç²—DÍGo˜ˆpõzfTÜú ž"yÆhŒhFI]dT+3› šAÖVö©ª010`"·1£;0 Cg!£HßÅM˜0牻«ZaÊ~ÈȬfUM§,3Fc›~ç÷Õ ²¬À„“"øgÿXD8ÆXÕ$ŠP—ŽlJi†2#Çmƒ{ j.ˆH„†u¿¤@ Å"CJÑâFRoY“¬a©Å"½0óµ C±ï€Z  Ý¦G¦\‹¤H›š{{h†¡äŒˆ}ß_mwÞQò8YÈSFÀMß3ÑáaÿWõWã~ÿ¯þÅ_¾¼¹Q5€¦t4MÓ_|Q1†Á‹žœó0  Ç|}ÁmTµTYÏ@û9ö;^k͵u\@ ͬÔaí–àÜuLBÔÈZ@^v=k¡@ 2Ưnnb[i•·]&ªb"w÷‡)gU Œ ª®¦L€À.Þm ùxúׯ‰k£®¸¢AÁ¨"UŠˆ0£™ª‰T#43EÓÈcˆLÛ>ºF«¥¸#/–ŠkI#)¡¥MJí6WSÖáìÇJ̆ Vj-°@ŠýlVÍÿì1ÒÎ}€?ü³jBp!DTÕjX9´Î®·â®Wu‰ä“Ë€„uZ `=ˆyæãà±Çb‘ê±òM˜s­¸°!ükØô@ˆÂ fý¦'æ\Šu‰8P[I RJ)4?m 1¥DÖ@?Ž›ñ0¨H`îRg"ý×ýÍW_ýwÿù¿øäö…¿†‡‡ûÃa‘RêfûâÕÝëiš‡ƒÄq‡aP…G«WJxÌËçÎdt*¥VBST03ÈrLÖàQ4hõ†(j5=ÕœÕR0ô¤ R™¹‹û !€Ö< ‰Ùä*"  Ðþ¢¨V­ª¡ˆ™¯ÙàÜk3GçŒÝ©1 V U­j•ÁÔPÀ¸c@#Ô8îRL!ì6aÖGÆ·¦Þ8á ϘµÖ‚ÌÔjí6›q”à ¹2+¨@5¨ht]²Ps9!­k€ã˜×õý# !ÄÔ©ªˆH5¨àz^èQžˆêx˜Ã8˜èÉŠ®°ðG൯ûòÍfCD¥äÀ4“ºŽý/Ç(–Û<ÌJÌ–‚"¢2r`Š˜Õ SBDò©¾àϦ>LÌÌ)ÆH!ÅÖÞq>†áp¨µnR×uݯþæWwß~ýßÿÿÙçŸ|âüÓ/¿üÒ5@»ÔwéjFUÝï÷÷÷÷"2 Ã0 EmmKc(Ä#}-È#"µê˜s)¢`njè…ç›5À# ¦¹¦P&˜ôVå©2Ì€ˆn)²˜I-yð”™ifDšzÖ™K."S‘"j€Ò&³KÁ7^›TD$Züߨþ§šKL ¤!Ű!„€H¨».¦9ê6QÕGÇ(p§ RAÍöS5D „©ŒŠ51¦šGH€A¨ª‰Bf8ÕV-ÛŒ©_ntXÄxó³? ©ë:QƒZ«¨eà0Ó<ÍõáI›p†©˜ˆ‰3‹Ñ { \/Èw­ÝÜÜ4ÆbžÀt1€uÆ¿Ážm7­›&²f„@(¦è²1!6@Ù·›ÄbÓ4ÅSŒ‰‰Mg³}Õa_¿º{ýúµ«ü}óÕ× õ¿ù‹ô“Ï>ñ±ÚW¯^ùÉŽ!FØ‚¡Ï»—”; ‡¼2Ï‹|2x»»ZçýËûʹzªñ,I=)ެ+ÔV½”G±ƒj6ìq…ε L‰ €@½'e*HÅ”Aª”1‚ÄÈL„˜˜C`©)†®K1FUsÞÓ8 Îj¹ˆT±i˜üª@G,€ˆ„èŒ3¡Ù"L!``"‘¥.¤‚úr<h} !1#ƒö±ªƒCH¥b­* ‡ HæU0X–Z Ð ¤L“T‰ÈVªVif ÞãÕ1ò1x6Þœ×õÏÿ „˜ú¾5Gתh5 ©M×;tàƒT½Øõ† Ä…q"„/¥üáþáõõµw…JžÖM±%úäÓÛ^< ýá`"’" ÓXjA¢M¿åÔ·†â~ÿÀÌ}Ÿú¾ïúHDd`¢ÞuÖR«è`0åüõWß|õÕWfc|ýp¸¾ÚþÅ/úŸ¶™¡ª.ÄRJ-µç#›Ù7ß|ãµÐáp8ì÷YMŽ& Ó4 Ã0å|ssë ¨™ÞÉf&"71O9Wç(yUH]Ôjt4ŽkX‰zx dz ¦i:"HØZXFh¦Õ}GÕÂÌ ¢uÚv‰ SIKîSÁu¬¦MŸ¶ÛM1†ñþáá0ŽÌa*2N¥–\Ça‰FÞ™s äcB‹ŒM”8anª‹1”rH1ö›®OI‹qCyˆ 1 aIX|3‹`©&b÷ûˆFHÃ(UıŒC΢cºR@AS¨fZsY"À ƒšš àRMív»HÀ›?ù狚—ÚšPHˆ¾bÎÙ*µV­¢Ógb5±+ØQDíà“å<Ο;A­}߇ÛÛ[×òRÒ M3[úÍþwúGŸ:'mW§œS#¢®ë8„˜bñ‹/¿µ*EUÁJ>ÿü³ZsEdÛõ^Ž Äü믾ù?þÏÿ«ˆÞ~òYH}Œñþð¶sÕØ@- 1#vº”"‡»»;­27€¬ÖZ³Tï¢<ì÷f6æLÆ]ê!ç¬fˆPEJ)SKf®Us)ã˜K­˜úänaþxŽÁ´©õÈ¡òÿ+RKçZË ¦ÿ.ôZ«šÌ°ŠPT-…RL!0bôM%e”Z40Mo»þŦ“‡‡ûׯï^ܾ‘Z³ªÃàÃñfºÝnuš¦qTp“ânÓm#ªŒÑ”Iõåg·jmh ˆqx½/ˆ9 D樂ªPM+‹€EQ‡,Ã4M%q2³Øõ¢ZUÔ°ª˜b)‚HˆÁsô¨›?[èôH4I¦àÃõååË—]×}ñÅ]×áÕŸüËErÊ(Û“µVS±2-§OpÇèê³ã'¨5!3!‚Šlº~†/^ܾ¼íº.†ˆ1vÎŽ^7ýtÁLsp.3ûMXR&?!âÐïnu…3zÈ2³ÛÛ«*ÅÛûÞâFuˆ0t÷ûÃÿô?ÿ/Åà§¿øeuHÝÆS¤ˆj.l@€ͤÔífƒ€Ldj>¤j­ƒ Hš= U§‰$¦Ô¹b­µª¨ÊÃp_Š„jÕRÊ4–RŠ€Ë4,ÔCGÛÒbk!n‘:§ß&RLMÀ,XP¸káI²ª¦àZ9ÇÀÁê(5Šk"j—¨ï»Û.¢9§a¼ÚnD«I•ª .«¥”ÞU¥Ð¦ýc"a͉$±"MìûµLkpÚ½žÔ€£YaQT%1¨4VµlT^òPu˜j.Ò!Ç”®®®Šë€5d˜¦"¶Ðø—¤ã&ÊVˆ½ßZ_½zBÀë_þ³cW q ëá•…Ž«ªh‹=!P3j† µWk׈*šbÊyº¾¾¹½}‘RB³MÀgó̬և…Rá¡Ö3œm Kåî¿â Œ¯óåË—^c ÃðâÅu­…ˆv›ëÛ´IõØű”ý?üC‘?ýÿ“ëÛ—jPêƒ10 #ªIPe‘û»»«ÝÕí‹»í¶mJEê4M¥VU݃ªãˆBc5­µá0 ¹f¾{¸«µÆØùœÔ4M¾Š"vÑL_¿~í ðnVEÜ–à°bŒ"€š:ÙǪ̀1œùâo†PÌ qH]ˆš;’–ɤºTFM‰7}º‰ ¦Á¦™ÌÚÄŸ“D˜‘ˆ¾}õõv»Ýn{fF#- %¡tÁ6'æÉ²Í@c2µÁBEUœ&%¬fÙF1( è˯^gƒ\A"áÍõÍÍíí8Ž_󊈣ƒ®Î>V iÄ; ¢P«Ì2MóÙ@TN _Ò!¼þå?[°ö5ýpÍM_£ÚNƒCd ¡s~s¨ ®OÀŒícóR²VÙív»Ý6Æ›£¢ÉÏ«ÍcÛd¸Ðà@óh3èáo ý»kÝ ·¥Y±‡†áàâ?ŸöÎ Ç*ðêþþýßþ÷©êOÿø—ÛÝ 1Œ¦­ÃZsq¯¬U¨Ö»o¿Ýl6/®®¯®®Ø¥P‘e™µsQ ’Uõa¿G!0ð¶W}ýúu.%uñ0µÖ”zŸ“š¦©dA„‰~ýë_o6¯1üÔª ûÒQ8o‡…°ÔVk1ß*i¶ ‘™IµUPMëÅÌ"QêBd‘‚“©˜T"K‘…QR ›.í"[-!ÐvÛ#š¨V0ûöÛo‰ÈÑé®÷…K*µZ-ÊVÖŽm`ÓÇ. ¨ª¢ j¾EJ•LAJ‘* ˆ’ªÚ(£f…jøÕ«} 5èˆ_¼xqu}ýúþþË/CCè˜Qt|Öj­(¤´ñmF<6ÄQ}µ#Þ™­µâõ/þâ,ê¼æ¦¿"†Ô#4AÖÝîš9Ä™Y`¡éZíÈyŸ˜€aÓo8pЉˆT$’ðlZWWWsÓ8˜ëcz÷w™bÃÞËn3sŒÒ‘®*QãŸÀõõõn·‹1~õõ·Í>ýÌQHïöÜ ¾~8üêoÿö«o^wÛÝv÷‚Bì7=¡xã£3¡­r•Ã~OD ¶Ûl]¥šÛ[ŒqªÅ ˜ûûû€±ÖZ¼ˆ‡»»»©ä#€©J×mTµdDZV5L„n¸¹G(%/4òã¬ÑË!ôK 4 h ·~úâªK ‘Dl²ÓUT%L]„©c­µÖ±ªjbŒ‰ Ñúú>m˜ê4h×Eóµ­döÕ—_·_ ó8åq·ía0±%’>â¦O] ›.ˆª(Š¡Ÿø1×,"HU-1… Í`”I”ŠA5>äªÉûv»]ŒÝ7ß~û›¯¾!æ‡À” 3«jSÕ®Û.iüñ<1Ïà…Üõõu)¯~þçës¿X𛾶Ðm‘(ÀÕîÆ•,Cväö@ð p«fæRê®Bågšˆ¤–›>à¬Xæš›)¥XtrXšî;§Ñ2ZIwßþ-aãùõ]ÿGôG»«Ý8Lc®¥SëB4Q4µ¯÷ùï~ý›ÿ7¿Jýö§?ÿcºÙl6V§Vë›rbZUT•EÊ”ÍlØ’§ãP³t)mûMJ©Î²W¯^õ±Ï¹äZàá°xxó„}ß™YßoT­d™¦©V0Šlfž-(uJ±J–¦uÃ]ׇœsÚ¸“Ø8 MLÍôÓÛݦï™CÉVЍ€¨ši ˜:d]ÐÊ4My0KL© Lˆh} }ŸŠ”,RŒѵÒÀ¦×¯}÷û_9,R¶›‚õ‘;Æ5Ût12'6U-J¢8eÍbc±"RAÔ ˆ©sï¹(±jV ‹¢b0äj`@Qˆ9~ûêîõý»þ‹H E¤TÑÔPÁ#\«ªj ÀÎèñØ^JÙn·¥¼þù?Y7b–TdÍÊÄ®Éi7«]+Ó›e‰Âú$_Á¬¥µU—)Ç™O_nzÓaöû}h‹ÁºãápÏ|¤`,Û¸n¯®b3’°ÝngÃ@«÷p$,êË—Ÿ¤‡Q”ª4Ž»gäµÖ*òå«Ã¿ÿþæ7_}}uóâg¿øeˆi*%p”<‚™€ šO»3@©>ösö‰ww5uª9pýñ¥/ß|óÍv»†aª…™Çiš¦i˜ÆRÊn·3ÓÍf£jµª§@@‘k-^;wÈo…TmM߻ꖴq3±&Ó$]”«ÝŽ9•¬LI¥š*±ª¤©£ÀÚ÷¬ Ã> 1†M‰ÐRŠ›¾Ó2²Ïr× Ôú.€e\üd×¥®K!2˜Œ‡;DaT6a’H–ˆ˜±U³¢X5<Œ¥*g11ꈀƒ)‰‚(ˆ‘(ŠA1¥ P|ºCì†qÊ¥( O]NEq¡T-¥•´R'Yèâ¢V嘵ÊÄÇ•®~öß4€6µø† ÅÏ`KàK1¦ˆ‘ÌÔD‹ª¡/ñ !¸§73©9ZÓ‡‡o¯Îr¹q¿¿'ÂEä¾ëºÍfÓuÝÍ‹›”š¤n×um ƒùª§…é‹6¼Pyýz1¶ÖrnôUä×ßÜýÕ¿ý·ã8ö›ÝËO?»¾~á@ W%0B"pùy‘2Ž)%&òª ”bUtðÞ­ú7€è7ß|suu= ÃX23;á~˜Æa8lwSØn·fPJ¦\JA 4Í0è~¿_6vÐb›Íæîî.çcƇ%ÄÈ>]¦uúöêê:pÊ“îv7R¹VQAÂh )@JÄ\7ÛZöûûé`h#oûÞû¸©‹}ßO‡‡MßCÍ™´ÆF®Z^‡qÁ‡¿óO>½ÍZ&«…Y*!0Úu ªZŠòý¡T HÍöÓ!V$EU5ìÜŠÁ8•¢–‹¨š‰ àf»UC1“Å‚!! ‡kÕRj–0,Ns¡6ªØ$Æ–é®c­»ùƒïºV­oä´¶#Œ˜ƒÏž1“Ë›™/ÙDÃZOFøŽ³Å2‚É"ä½ ¿+i>në(P5Y¤'m <5ÀÊ¾È Á¶>,/EUÇi`&§‰ªˆÊh.d»¨Å ĨB˜ŠUH¨E&3“&Œgf(Më7¸ؘ‹ª§ò¢îy]ó xžüjPAŅż6€©ÚøüOÞiGŒ‘B‚¶–Mçéc0bk”q6ŸCŽ.C真ã2ç`KQëþ¯­éŒi=3kÅÐÄ ¨/^¾LÓ”s®“!’O«,yƼÝmo^¼Øl·æb”¦¥Öáõ+©µŒÓv»ýÉO>ó)…Zj‡É·‰•¢úˆ”Ù0 D|Á£¯Îµ*ZŪ”)›H  fæ(!¨¶b:EðUôMµŠª†Ï!ôËJæ#GMÍ—š¹b’OlU0cœ˜˜)"ß9¤fhÈŠVÍDeTË‘1¥¤‚ã8¢Aß÷&@„‘˜ˆª  !‚2ù&8E0Tó^P­µ,l¯.’‚öŸ7 &`(¢,ÄXU“su@Ô•|NºF—°ìƒí††³Ð¢Ï‘ú†Uô€ÜlÀC0³*K_k¥'UÏÏZ¼—<Šm0Qdž«^àËyÑšïuæ´|G@ h ïÑÏaæÐõ‹,thdâë­ïsó\±Ço~ózÉí–¦)„Ø…cß…1±L¥LÓðú«ß¤‡/^7¢AÉ%Y¨¥:£3viaYò¤¦Þ‚ð­ ·u*b¥ZU­«Š—\ ênYUÁç+TUÈu>Œf€RELUS×]H6KX‘ä,ÄšsöeJ¾îÜL4‚’×f¤Ê,¤€Þ!r0­U&Ôê›MJ)hc4"b@ ,&`¨hÆ-Rƒê zß–ÞÚ*fÚ'ö%LêÈ9‚!@ECßOŠ]òß (‘Î\)EÐ6RBû¾¢®ZzhضS‹oÆFgÙ‰û÷ù +uÉÖ¬DÇ‹ÎÀö³_¼óПüBë‡YGÃú ¢¦Ð ÿÀCs—míä\.nŽnì$NØrƒi†˜¯60¿±œó\Gâ>„è,ïVÎ ;:óBJAÆâ“\²íúùæêzö(Zj®0áb.ÝŤ «Ž‡AU}r;Dv}$,ʈ®Â¢"Š¢*ž̓^ÍÅyª»¨€šÆ”–á÷Ó(.ˆÜzV8¥s®µÌ[›[‚@UZã-ׇs+4eE³œG­ÙZ×™¢ˆ×uÙ;´jÈWFaZ8º«jÝžÑ?ÏÉ Á, Ú| )FSl½xFSP0s0Ë C*ºÀñ 8^ÿIpî;bð€gJíôB-‹\úWËlÆ™ìæ} `¥  BH„m­ùÌC§÷6DKÛŒúÏãÚ0K]rýãŽ&D ýë…cER §€O—¯7F6õElŸ®SÒ‰”ªtvΕ/@®g~Þ€ã|þq]KzR\ŽˆC`¤`´bŒ¬ŒÜ%Œ!v‰B´rT«Rcp­î(„b,ELm¬kõ‡åæxKHkVU°¦£RE²;ë8<Ò›,GL‰a½=‡¸ÑÀè¬ÁÐjݼW8ÿ9ÎÓøÌð•—`ä sÁZEÓQ´£!P\îê,ØŒ†!òì W³Ñ'x]ršz¶F%=° Ï?ö/þà^ùÄÓëQÍa½8 m¹43œåÀÉfðNX½zÀáLJàÉB£C¯†ë¨bd2&J‡”©ßõ6o‚Í9Ï’}˜6‘ (`V3AS)u\¤ ÁÚyüFLŠˆ h­UKÕµœ¨FW9kë÷rj 'ƒÅÄÖŸã%;'Í‚fÔ‚ Zl4u$›%  6„ÞÎ8S €ë?4€ÙY°Õyx`ÃwÀÉ;{ª¬#Àé3Ébs`' ˆ§À‘ÑŠËÈå:òxx=í·Mhp4Ž"s ÈÜo70—ïyÊMÔ lwµAĀ̀$jd.•×°š—°ÅœÓaµªê´2€“%m¹€€9"ô†¬5F]1sá‡.7Ü–ÞËú#XÀzœÃ>€Û» À¿Õ @Ú §´šH‹ò}¯žå‚“‡$;Ÿ¡œ‘‘ü.ÐÝüä|h¸”£­geV÷¶Îíí¥ f r!÷R{G×ùԌ֌Xzá ТX dܺ?€FN7óÄg±Ûó¼2—pôMfÜç‘)‚*>)EHï4€“÷þ àQ0« mï¼!b«ï{¬ÄDO{FGúê4GT?ɾÌÀ÷t- ‹z½™¥äCÛ‘9¤äD´@l%þÐhÕª³À_m ‚Ú €µ¬_gÓ~Ã΢moI.8¸Vc¼Y3ÂG14ÿ†Q0@4CPÂæÇOR”“HÅ ¿[öL4óGÂUsÃôüë9©gV¿ñB»déúóó/”.å^— @fWሹš^8è úNX׆p¶ £¬Ž1ñÌ`v¹,$Â@sÜF¢y†’#ù’8UÔÀb¢7Û+`Bb&J€o€Sb–H¥xw÷‘¼yæÞn—j€“"ø_ËθÿGà’=9Xo;8…ÏyŒQj‰16Qㆽù<  sZF‹n¡*Ÿ2Γ÷1€DüN89?ð=®SKX=l>ñƒiòwÞŠ ¸Ú7¶B'tÔX&•Ö-½GŸG8żW«œ/ÚÎÂsDºtøÖd26nžfvM]Å)0óŒÿøtIž™R@Šq»‰}¿¹ÚÅ®§yðÅéF‹¨)“ˆx €«æ‹ÿüI ªïðòüöÑyZÛÈÚ£¯ƒá¥p´<â%ÎîªJÐ4@‰|<Õ;P„0sc Q3¨^Ê —£AD‹táTd-|Œü€ç#ä…b/¤ˆ ç3zOÜ~Ó.{„–%:Gߌgs§·D•÷ùù·º¨Vá"™ùšpÙU4Eó¯þ0'ý¢©Ö¢µÔ\$O ×z¤Ò<§ÂôF ÷]_óëzÓÍ!Ð,¸¢‡†¤„†$ˆŠ(Ô¾Î"XL@-9…chÍÓÇ÷ íã¿ÇuxÄEy5¶pÜÆÁß3laÆCÕ¼rîùùbE_ÏílXgÅàÚ370ÎT‹°ðº ¨Ö‚LÈ#3§Ôm61u÷Ë3»ØÆ¼äDDköu¼ëpÖs¿O8ÍÑõƒDdzRr±Ž'ãàzÜöÀDÈ'î}/" #­÷ê,¹ÿlÀƒõ;€S]ø‡§5ÀÚ‹¯û?ß#œ¤'æúoÿy/ ‰&Ò*ÇøˆÏ>Ž`>Š ÎDTÓ ¦`âu—–¿9Ýmš¦a÷ûœ'ÒX6—­ ÓõðÚ’»¨õcŒ«X·n€03pÆléÄñ·""ÙŽ` \¸oøCF€· 1K¥«@˲±õ=‚Ö*4—ÄšËÍÞî¡·Ü­^nܼ™ëŸÜ¥uÇq)>f²ìу¶Ïyf×1Hs´„fˆ‰sè·7ØMÚðîLàCUEU]G;]Ürì¼G¸TæF}§??…ÒñÂÇËïŒëœ„12’‘R"p%.ßìtýÆ:Iƒ…óQмcŠ…–Õ +õi8IûW5Þ%ßïNÎáÓÌ…Þj-<¯Lù‚ûkxZÄ£3 …˜{áXé N³J]Z»·ŠæZÇìÛÚøåŒzAì±G°ã¥—ú# öÔP°rÿØ„›x F €Øˆ•Ș½mÓKJ Ël‹\€hßãeÚG‰?¼Õ…³!´—…¾ð¹µÈô§èlppíL `õ,Úc+¶é=PR[ú£Òúó& èú†p–·ðb@IÓGIÌHc‡Ä®çuÚ¤+‹Go+[çpvá…«¼=œbóðA"À¥“BßÖV¨'4$Ep÷oLF ÄBà©¿“¨ HVŸËºÁ'ÇUuK/ Õ @:ŽJ®Ê¥wÀß9|÷>À[óZŸÜ·Çý¢6C¿~ 6ÐøÑÃå%?ˆ Î<¼E|¦0Ç>O«C—cj<-zÄÖNDôRÁ¬ÖÈ%zÿSòÆ·›®Šú³€ü\ÍS‚vöÑ»ž>à$,ƒ^D]–0ñÆ 9ïÑÖHâŸ&!«d¤€LP‹IEU¬ñÊ…ÚòFQÛ„FÐì}óW£s!Ï×Ýh¨Gûô-¢òÔºÿšÎ)°!P jG{Dä|»‡~jxL⤯òàÔ³2"2ZSžõ½¿ÄÆè#FàB{¾@–ÕUÄí)ZhϢΘG5+Etž}<’CÉ ˜UOÞ.ÝŸ.µjNSÛK^ðû8éóÀžÊÂï÷WoÄ.]—PŽß ÜO½·gï'Ý¿:¢F纥؆÷U EMª¸@¹V1oªo¨¨ªúêú·DÎYP8¯]C|‚ä¬W ¬oÐúœœ÷FX{kS]çšfjõXTاØ;=Ç¥ êÎ0ƒ¶g#ÀyÏj²ï{E€÷Z:­.õ4Ïó¾¼Hå¦+ˆÆàõ€× „DƒbÅ çPS&qò/µ*˜*Ì2R~ð(¬y†0¯6zw¸äk~ sVwæûΚ¿G ð½&ÖïeIŽé’û‡ß™ ßÚnÂùü6ÑWåô®Àºç°ˆþÖ¢b j¢6÷Z' ªŠ˜ø`)´Ó?g>ð[ˆ—dQÖ MøŸBåoüüâ,×Ð2žf·‹žïÂTZäój 'ƒä+n}Ó™™GõçEü¹ãiÇ×ÝâÅ7ËŠ§¸Ž<Äx ¾€ä\Ì_ßãµæÜg="=ÎRˆÈùZË_wQá6ÀF„ LÝß#l1a`$"Th=ï êÒÛ] x™-‰åœç—‡UÅý¥!©Á¼Ë??ÛÕuàú^ÉÓî­]xúp¶d?ˆ·zZÓºmÑüûñúü#….ùþÕ÷aÞ¾I>Zi¾ E¬ŠÕªULüQÛCÚC­ÊüP/yA›Ö^ãK5·Ú|åo‡-õ½"ÀéÍ=«€|VÎäâHÒYø¼<Æš.x<•ãW3 †ß¹¸Nº×ônDâcG€“ç$>—I‚ÏQ,²õǺ„ˆùž4ç/1z[@f§f}£~E9–1k\g%Á9p»ͳ"­è2„õŠj¼Å½Ð¶&Ò™ éÆœ‹x = [ (­NÀ˜5Ê„:ãñàrnMˆá©0C­ À7FœAu.Ôð‘ €Ïg§Êj‹ª6¢.+H935ÍĈ ˆïÆ,RœèfRjë׈ïøz£x•`³6qÓóœq÷ýˆÜ!ôsEËË\¢\˜Y£@rš\è#}à-´|Ó³˜Œïâ[ðìw"HßãÏÚ¯À§üèqˆÍu…éÜ+ñ 1¨fY$W«Jb(J¢¨MUƒTÈÔu6XL¡©D­¾Êé=:~µ·¼þ[|ÀFØwÿþû Í\j;áÛ®¶ÏxÝ Ç'^ߢýí»«›Àoœ³iy´?Ö²ò“ÔÈŽú÷þïòz>/ÿcÁdgLŽÒ@ˆ¬†*PÍë,@GxÚ:  ¥ŠõÇqàKC<ê¶û‚ :w³ìÜ[Ð ¢âæö'ï×Y¤Ùbôrè·7n+éyLOô…ÎâÖëÿUõ-5óqÿÀÉV[ôê–‹’VS1Ô›×&ÕàD¾bý:ÉŽnâ}¼žÍŽ Ïçý¾EèÜg,rv¡Ã±EúÆë9àyhéÜ+t]\òºšó<²á‹ 9T\¿~¨v¾£ß¶÷Âcù†ÇlÖþÔçyêõD‡ûá àýoúÛóûEuùð.—Laåûñ÷!¼¹>úíðÛâèÿ Ž¦ñù;sÜ÷› ¹ó]Ò äp.×GXýü¥ç9Íq/è¾Óy~<.ëÔMUµíG7Y¿þK9âEžÉÞùwÁŽ?óÔç¹T#]ÂÅùl pQeúB °žØz¤l÷Aêû‹Ò…>ÀåšäügG?6'õCÕ!¿Iÿóõ´èûp*>vqö¡.Tð¥Þ‹â2ŠÏGáÙþÞ"ï‘~àsLx6€8,Ü 5“ù¡;¸<¶¬3û—:ø¬èìð<éñ²J}ãaÏGÿ÷7ü½Ç¶ß£¦z6€ßÛ[Sù”—ûœÿ<ÀãZ– ?fÓ£ÂJ‰x¥æ¬çE¦‹úôD Ú„@ATuÎ~G>2¼œRž!e^vöωv/>yÚ/èÓ´&Þ½ðDÿ‡øìü€Òy¾Ú[ÉÌoÆšÅí˜ÎÜÁSõéÓsò´S²šûƒ÷(¾ßâƒøÌË98^=§]b!½U«ëœ„ê_?|Ÿ¿øñG<ù±²Ö3“Ç-ÜœÜû=pµØìGíí;¤î—îÏS+„çè·W°þ×óÇÿ|ÑïÕ»Åß!wøäñ„g{þ­NŸççŸüç‡ÉÝŸk€ßEçý{u={úçà¹x¾~¿"ÀóY}¾?Âà}ò³§æîDçwo]âµ_úùïsÎ<5šÉwöAï©UúÎý£ø€Ñþãè'Ö ô잃ÀsøE¼0AdOûùä¥~|ài(ÍsxŽÏîÿùú݉—l’øBcßžf×GmÏ?Ïo/\ðÄx¡Ð÷ÐtzŽ¿³àÙó=ߊrýè àCé=÷ž¯çàùz¾>t pÑ’ì|vQâò=r÷÷ÙŠþ¡rÁ§æ©*P|Œ€ó½žó#Ô?¶¼ÿ9<_Ï×ïZø!½ÂéÕž#Àsx¾ž¯çð.Ë~ªùØÑã9¬zX3þƒ}Øýûȇµ5#i»ó46k$`  f €îR©Udd†îü¾sî½á•U]"«ºªÛoyGGefE†8ß½G|ç;~Ç^ºÒõm]Aú¤+@ºÒ• ]éJ®t¥HWºR¤+])Ò•®éJW €t¥+@ºÒ• ]éJ®t¥HWºR¤+])Ò•®éJW €t¥+@ºÒ• ]éJ®t¥HWºR¤+])Ò•®éJW €t¥+@ºÒ• ]éJ®t¥HWºR¤+]¯4b{¥+]é ®t½ÔË?“xˆ(¶»¾/_á—ðÅx4Š¢QÄ¿úüƒðÆçÇÉ_®_á?ŒÝwôKɧëé—íü2ùküSO÷^øÞø§Î0}>þ#>Üð‡ÍkÐçïß·ïÃø ñ}óß ?/%]¯F1¯0öߘQy£‘†Ñ`Ã(Šñ±>Ý “Íd‚ Žð5¬HO¡8æ3Šðñ ~·¾³H߸Wöiãø'xjÓ·ò-ÆÜ›¢pœ¸ç»_ãÛW«‡)¿ëõ"}êxž¼@¼6cå‚~ù)¾QÿÈ_ðUÜd²~.dsúS^Š‚W0ýAä #l`¼ðÉ…!¯þ`Ôíô»Ý>Î|Ò?€ñgsø“ôhˆxþˆfØÄa(ç†Àà›àÂ÷Õ:íÙ!Р!,·Õ>h•òTý‘@¶cìòtõ6Èð™û²ñ¹œ_,d |1À+Ý;½a³Óovòâ>æ¶úpw;`8Åbàø&ÍŸ ÄAìù‘8J4™‘gO/¸ß—û‰Ø×½[¶^Òfü¯zæÎe£÷å;«v_÷/Òœ îi˜5ÐÃÉ7?¹#Œonä'4þO‘åHŠ™ w ƒ—ÍzÙ .›E>ŸÍå³ùîúòc)(^&¨9À„OÚõæáQ Ö °Ãç …b¡Xô½Œœƒ 0‡a€s^V$K~{ vLA” ˆ=ƒM@îÓFÕêaÅæ'ž(p¯[œvpÄÎA|9ËbÏü/éлpÁw‡÷|¢v¤Þ'¦ïÜ| Ì’—!0k±oìûøNŒQ.—-ò…|®2Sœ™)ÍÌàn€+›Mð’¶:ò¼ýƒãíÝ£­£L¶Àm+_˜©`Íd²ù~oØã5è÷ú½^æžae“ô ãz˜ÇõÝ‹ÇIâ1›xZ¾YÀ<Á »ÞËÚ«õÍmp;ãeß<)8oa8 q«{?ÕŸ\‘]øA¬QZ¿[¾O.ŠÂÑßÅ–_ÂR*ÎÍ–çfgfgKå¾’)äó²SË}©°³{tcïþÆÁ‚€|¡ *Üú~ˆhxFüìG#õ…Ífë™DˆM!YÄqÆÍ°'€ƒƒ‹ŽýIÅÃɦYl¾(±Ç ¾KÓL.I´˜Ÿ¶ÏÙþ¸}Þ¡ÚujŠ+ @Eºžyü3Šä? ’å‡Ò@A4 ±EäyLfJÅ|±”+—rÀÀ\µXÁ;š-˜FHm÷e®­ƒÛw·oßÝõãÊ劰ÿ™r¥\.—Jy\0öÁp4Æn¯Óét»~¾pm³¹Æj¤&‡[H÷Ú` II„ V¦€4RŽO€üiŒ4EË ›Î¸5ýqV3•ÈÀ>P4ŒûÃ!þ„aà²Ca&ÄÔô¹˜#²y, &Š"ñ÷èFà™PÛ$rYy©º²T]˜Ÿ™­fg‹ù\&µÝ—Øþÿåæ··°s@¡\ž)—èÍ⟛­‡ݶÛÝ–¬<*—“R6`[!Œwl‚{(ø#Äú3’Õ4èÎÁ±N¼º4žºMê‡ãé¶K C £ßð0\>6Ž'`O :@ÀH‘ŰäµàEÞ8¹«·ØYÿÈå¿øÓ¬¡à´Œ––ªË‹ÕÅù™…ùâÂB¹\d\Œí#˜òÑî陵Õç €- @ò'Èá(Â-”f*3óó³sóÕB1Ǽ‡ïÁêöú¸°‡Á]BÚ[h_Í{œˆ÷¬Óû‰B•q~ôÐ}3Â䂾ýçz˜Äú6Î¥ñì.¬ÆxæyL¤øãØ=›qíaâ‘;fûŽ"9j|ãöð¡8 ‘Þ…û'I^ú€rÊ›5u“‚@$„r9 Gh¦œ›Ÿ+ÎÍg+¥j¥\­”ˆƒÀtvÈÆ6cĦëì3¸¿±ÿ…Àó³ŸE4ÏF¡<3³¸8?¿8W.c·÷ry)…Ñp!çÍûÙœË%zc“‹Ç5¨‰°À~Åcæ—Ôš®ÐN`Œó‹&6øxÒG÷]r|%c_[{°åj‡S›Pè?´@lÀ’0Ä^("0"bbŒÿñp£Äyz¾ñ·Eò!Μ—ss…jµ¸4?³º²°º<_ÄÛœõ³ Λ‰ìS£?Kh øò6°íy¹ð‰d‘ñÇ9°°0?¿ (xy`!@i8›39”¼ØnønsòuÛ6y“9ßÇ„» ÿª…Fv£÷ ×@kd.y'ÎÅwürݪÝþîkÈ‘tüq”Y¾†f`½q­L©vŸäFJcp„|-"2RÕîC~lëßÑH"i ÄòÔgІaw8ìùqX*gK¥ |¡ókËçWq”K…r)/EåSöwÀ˜×ê?žÏ”àqV;|ygëöí(ÊИ¢€Ù{|~v¶:‹¨­„ŠŽ‡]û^éÐ^YA?;™s?Ží†+W¸¿ú± ±˜¹”Ìå9‡&’Xã\?pÆàÛQlwhÏšL´›¢&R#GN2ßxqâ|R·È}Ée9c?Ъ²dv¸ãâÊø,öáá ,ÃX¤V²Á„À?î÷û<"R+$Lð¶ ½QØÏdàbà­­.®­,.-Î..Ì-,TáRæ28 ü‡¹@.>J$ÓõÌ#^ë›Ìݹ»3 ý‘ìvCæ|@È FJ´P€Ë"„ßëµ[m\-sxÄ¡n‡‘IJêˆûb(²Ëë}qaiý#ÙÉ"Z[ûHÜ(Ql†ÖÄÛŒ©dÙ4”ˆ>mš_~:b°ªÓ1Žw'Þ ÁO©$˜#j$…Ú ?CŠº¨þÁ>¹r ]IáÊÃUd6€ ü oB— [Ä€Hè÷%Rxßú=` {Ãa‰µ•e¸@ çÏ-_8¿zþü*ª%)–=ôòKÃýÔ:³ØØ:¼so÷îÝ]˜¾žõàÀ„=¹,+Ëâ>ív³Ñ:i4¨ùDqÈ[1Lø6¿žñÍ– ûµR„ø¨žFÌyš·!©F]p€^‰ I>2˜HükD(ð0°®¼I­ÙëÓ#Ç™|IRÁÀ•!5ÒJ¸eüß9ÞŽ™|ÈʩЮ¥Žd_Y0Ág‡Â#Aœà& ÆŽ=W—6+iDà¿y‡š«TÇë ßIœÑÈÔ¹$£êq¡00]@&ŠÐ´;a$ ”ÉIPÀ•7+ŠlD@ è…Ã>¯ÐüÛA™d¡üêÊâ¹Õåµµed‡Î­.ÍÏW§b€8ö¦È|©õŸM¸·¾÷ÅíÍ/¾Üv Fؽ³%ÙÓðIíN³Ù Íï !¸°]™â‰‹ä p™òš"óÛÆÕ4Ÿ ’•pÚ—&L왚]5(pû{ä*Ú¨˜ú°M);Óìûr:eM¬møvãG4=9zZ=ý5U¬H€/:§ÈÆ6ÞÐ’GR¥Ù¼9 ò=¾Epx°ñƒSÞí¶põû_ò9À¾P.Á¼zçí×o½ýú¥‹¼Dg†7ÖoM·ÿ³L¡èÃbï¬ôT¡ßMgí6{/{$±ÐK‘^dF‰¨!ºB³Ú®­*ÛnËÈdlGóIpcÖ¿°z&+m[YÍk†RÕå¡|Žä¬P¨c<§0œ€l­ÖÖŤT?ˆn_¼”ATBlǽn[ =¤¸$(Â#!Œ³ñ;½÷ÝÞ¿~ýªd>µáÆKôÄ)%@1b€ÃI°ÞÉ’¨„ü$îa¿Õj6ÛÀ Ù\^¯ÚÿóƒœÏR¦õ|°¹ãûÙZ¢*eЫKÕj¾Z-°¨‹qñ7‹¿rҪכµZƒ IºáƆ£þœ¦,461¢+Jè–o <+%-ùiär³€EŒe,ÜÊ¿WO‘y t…”î£Ð¥­@ÒüI|,Héïõœ®îïãû‡4;ÅðXý“ÆÑI£Þí4‡R@ºˆ]”Y|ÂÈ…ßû^ý†öUÒÏ´-ié®ÿ¼²@ B¨ ¤1€"|¹¢¨`}@£Áà„{¦9m’gb?GwC›c}~Ž@6_!푘)gffàù ¼ñQÅžß­ÕêûûµƒýC@GìŸ ñ¨z#ê­h?®Ó*ñ'€I¡J0à2›ê+gZ¾•»|bÌà˜á-ˆyò¿óøHäs7æAÁ.g9M°ïµœeCõ½,ÏF‘«h" ÞB{X³I$ …€«Ýnôº-\(¥ãW!õ3¥F¼{ë­wßyóÆk׿f«ssU8úY¥ ˆçÉZض֟Aû;n $hJEüIô™jžà’:P ›<ýݬ¤4•)@[ äôGkq>ë¯V+`}!––p:†¯ ¢“cüÙÛÛÛÙÞÙÙÙÖVÜ „ã¼84ÞЮtZ¤ÁŒ"Ü·^N&c"ެ­`™lyÀå$.y˰•·|a’ØÔwVOÀP`(xžIÚ:ÈQÀ_.t 6‘ÐV”R “]YÈ#7šõvë[ nY C$ôxD„8@o¾võµ×®]½|áÂÚ… ç±qPd Àª‘®³€bàÞºÒ¡²Øþ‹0ºê@ '€ÔC3ô de³…¬ËìgršÞAŠpßQñ— v³…H¢}T«ìÀþwwvqÛ¥ÝwP6GÓ‡ë1Îõ!Ñ`׬å3³%Ãf=Ó ¯ú ‹#”“ç›@EºP¿L«33UØlŽ9ÚB 1,“ …š]µðÕÿ dzx¨™Ïþ€’B*æ³€¼6QíöI›t’z³QG:ÈÔ†ÙƒÏòð…ókϯ^¾|ñõׯ߼ycaaVO dS ÐYÇ– :åI6•Uxl fZFÒ  ‚3ô£u£ÔE§"—ë’]òáÔ–¨V ¨ì „Í ’߇µÚáááîîîöÖæÖÖþr4Õú$‘±l4 MÄé’ JòÇ-c±&F\š}7<)„Ešò•g2Æ•ÖthÖ&jP|v}^€èl¥Š«Š> 4BŠe `axQäÊÂ|Zî°Û¿§ßˆ„FdqxG"¶çK2G]óä¸Ö8©uéó-È¥Jˆ$Ô†±ýðÁ­Þwuu)š¤¥F–ˆMGØ!¬ÿË;»6 ÷Qð‘I;]DÁ ìàJæÉfyI”›¾–¶XÛ¢gÍ:re&_™A0Õ_Úé´·¶67·6××ïß»{ûÞ½Û`1´n7°kJ‘hhÄå” )Mñª2.8†éölÔ3‰PÏäÐBµ°‡2ªm…3ŠÏÿQƒ@²\­‚ù=‡«"·å™ªTuËJ`h 9Yh*RöL2Pfl Ô&ËŽbL¢]eÌðH¦L+ÎCÀqý Õ¤/„ÔЬ)j…º *b?üôãOðñŋ罴%òáëlÄ)u»È¥É¹˜â‹ŸP@IHؾ^Iÿg¬kÎââi4U †q¯v:ƒf³S¯Ÿò8>>FaÆN‹,bð% €AH¶ òñC††ž\1cD^1/tWy¤Ö¨jg¾-â ùSòmà]ð•Ÿ}ÔGÈø“ž ¢r·Ó"ËÉq]΢£z„¿“8*'à~Ã7“¾¯Ð•Ã’¥1}#t°Üé¬ Š„F› ;iö5+ñRV‘iª‰–ɇ£¾&ÓÁ]^89WýM×sÀD``?Ôd Õ÷LuÕÎ"Ý cÕGs»­¥sú6ê©õ¼n/nw†ÍVIÏ#FvÜn·Yf1ìãä•rïÇ¡JDlÔÙQé‘M¡#FEöFïó¯úuŠ(-”ãçEíE,žñ%Ñ‚‡âåëåë<ÊKöº<܈ú1€§wt|Ì' tºí>ù’ &WÆ–..ÏÚø<` %ÐpB9{Œ¤Ñ~ÝÁ” †g"€™à1œ"cÜcØ2“ž†y?ENðÁíkîr¼ ½Nô€nÔé [@£¥'vYÀ@´àü[ ¿HZÁÆ­3»g" I¨Æ•É EEBÜÁ9à~¡–,ÑûeËð|€­û梢í›û<=„àD^ZŸj/ÍÁõ«u€ž@èÉS5´Û9ÒhD™¡L/åòF.&3ÌÄÊ>p™sÀŠ22—HVŒÁÏ1€!l v{1€4}#‰ëÏû”‡`jœiAªþ1i„ð~ËñI]%/sÌ›KV…1pQã`éa§ˆä Žˆ€¦tÖëû_~ùûÛ···»u| /èÞ?|ân»©4h=+!?/„2M«ª!‰ù WOKY1¬˜˜P¶L»AAÁ3ª'ܹ¥G—a¬ÍÛR &#¯×g‰ …‹Ùrué Š#ÍTËváñð¥ybØY¡mùÂX0LQ‰]|ö°¦‘Â3Ñt/Ãï:©×NŽA/o’\X÷µUu1;@òçƒ÷ÞC|åò%æÈª®bê}%Øs•àÝAðš2sýòÑ/ÀI} ¦9°P’tŸ©0ÍB:Ì)¸}û‹;w~¿··urB#è´Ýná5c²‹ K‹ó¨¨µØ6í8+Å\ÜÆ–•6¦?ŒÙiNþ‡Î“x+dõèn _gDR¤J i‘W!0 Sˆ¤ø/#üÕKÔñ­X˜ó0²Š@’—Ô6N*g~àÄ(²òœx\²4(A°PhG(àlÁË?9'GpÕiÃ'Ø ïݺõÞ{ï\½ryiiÜ+oJò(]g%¸ñdp'@æAä(¯KE‰¼pËI–*­[þ;ÀþÞöICSMä±)R\?€ éÒE$—––ôx±…+ä ¬/âT;U D)ÊÚ°¢Ì6©Ã}é÷,`´ÚðÃØ¬ˆx‡F–¯‘þ7•`B!¼Œ”Ã*€j܃%¶ÑÆÉG@©xRúM@N‰dx4è\Ëh| ééùÑìlåÝwÞ~ç·®]½²¶¶‚ {‰®€€§;”Í!—÷­Ä@ZK%€&7³#éPØ"´¦;³ªé¢A0N. œä°RGÖ£U²ëÇk‡õ×ëõáFú±€@õúk7^íµë7®^»zõêµ+噢&ÄÒõ /(& »9Ér¾ùØ"éê6Nïß¿sÿþ—¨·ZdÅ ÷­YàÌ,ÌÏ}þùOþðóÏÞ~ëM1¥`Üó;·»©[CŒšVdT©Z‘§ó;TÑíèèd{{gkkw}cûÞ½­û÷7Q·¨ùCg&öñÚ(‘]¢9rÈ+Í9˜&8"@¹›9Ë…Ö6ϼ€'€§ÊH‹Õjµý££¤¡„Ú•V íkWÀ ºqãÚëÀÁÍ×ð\R¼ˆ:@bPêS@ëAân"DuZ²ÂiöðT Ê˜ª"ê Y}!Èmü§ç?üG÷L Á˜¿r©éŽÃŠg«3p¬oܸúî»oÿûßûüóÏ?üàƒ«W®ÌAÒ¿ »uœ^¯ë£·¢5²eb—öÇ U“ –L‘iŽ ÏÏ898¡ ÝNR«“†lŒ€<éw±ã{¤ë 4ðøÔoƧ¬GT¬hary®×È@“þ?²J—±«¨98¹+e-çÔÛ0óšÆð½©"´*|«J¤*Œ*Ún„u(ÞŸË‚£znmå:ð<®Ï?ÿìÃ?¸rå2dðfмZ‹YþàžOB :“¡}1¶ußÅ ªÿeÇHój÷™ ÷=|Ù—ÔPšz1'ÀSTÏBN=7’QÍMLY4ÓòXA`T1Í„Ýûï<ò&f¯šÎe ]óœ_T^˜Ÿ]Y^ºpþÜÕ«W.\¸°ŠÖôÅ…j•, <Û ûrÜp<‰:Û~Ma@9Û‰½ÀÚýËñ 4JQ‚…}0 Þ÷i!ìëÀÄ0Ü©ýÇŒr­êZÄ7»{âMýK3+ÒŸ°íVÌ0«$,RÉ·g÷*œ £ö0ûŽÕ¤í›êÑ@¨bvnv"UPi›ß_T_vnìÛØQÀN¯Î5›k”TÕRAø$üQj,ð–lùwò]†oGž‘RM þå;¤M×xöêÜOXÞ´ë:Þþ ¹Âæ 7£¥€L}Μø>þEŽËoÙê0¡j=G@’d0@x YÇ€rÆ4Alj’Ã2”%šP'²¯Õx¦_Ù64»Ã$vílžW H ýë@ü•1q|j´JúÇœX’.÷ ¹@êÆÏå@;%’¤–Œ7ÅŽÚ3äàgу.ìdÔŽáÜÇBÂê Mx>FlkdÙ.*ð|'S”P²sHL^®¶í=:ôJ×Ù ¡­|šõšIvS‚›Þƒ±r<ž Ç*â©QîÎÖâ*ƒ6²¼°œ…ò;r°ü¹ù9Ĭ|L`@{lbÖÓ¡ÂI DÉa16)äzš'½ÿ‰iNãûVØÂKÿ:&¶Á'=´¡VhjÚÿò"3~iÅ¢$ 0OTÐ!VT‰·‚  ç²‰%úø˜ÔÌŠ¦T´Ü pZ<½ý[Tyq”ZÿKLØö85þ¨@Í~S±QzvÛ«LHÜù‚_RVÒ£EpMG.¯}mNëж>+{ÙfHàÇ=‰'?éµ®‰"ùö220cœÄiè… ‘ññŸÀôíÞ+—É’ƒ?ž¯*W‘ôÔœœÜb_lók¬®—Ï ïÚÖ¢oûT<Å`À|}ܤ'€SY·žNBÈGÒ»êüÛ8®Dµ¬5Ò¸‘vý›É˜2—Á¾céúÆžæ7 ¾è Ã*D†MÍ9S†ãÀdmm¶p.Pz|³ð°÷;>-ˆ´Üßdpwêéò‹â lRz4´á ]Ó°µ,å¾™žŸÄù¤ƒ„ãDKKûM`ÕÑý‰ËÖ‚'#G,©þOr ·é'N) /D½~<¾N‹†M?¸öOdøüSMz F ª©Y±Ùˆ‚‰ÑÂv WR'{~r9§|¤=T®pZ±:6>û›É8»×ޱdíËìþ£xä& ›Iñ(ɧPM‹tÆKèMX1r'Úé9zƒÿ8瀑sEãÑ/_ÇÇÈ»«šP6ÑÀ«ºç$Àâ 2Êóšœü w•ü \ÚgLý⓵þH§ò™)ônïwÙ;,0HŰ^ÚÀ àg© ²ìÒ¼yáIûAà&]+ ÇF¦ëÙA¨I'Aý¨zbCÎÇó„\.+Áh°—w8жw†PxG…­^¤j‚¼ WHz”ù&P_ZÍÄÔhAË%åRUDû8{›³ZùEmq <öÚã·&ªfÉ@X³:--åA¼X$H¿þ£|$— 7ÓµMQý£ eÔS’´07ÒËwìI73ÏP$_à¡ïdniÂC¶¹°ÃÓ‹Da"¶Âÿp†J¥‚ #3/ºÊÓ¤bøqâ˃Í<¢È´p›TðAà&r¨±ìhOë Ûy8eýº$Qkºj–®—ÈJ˜‘YÚë›iI¨«ÿëœ|( y_Ëv'ìË-“0aÝïÅxEØÎ;„¦?œiêP12Ì¿ØN¨wl?Q4ÊxjýØ ØÛŒvQ‹ŒÂ‘©Ú"7íu[D#ý¿®(+k‰Ùézpi9ûßúLœq•Ÿ$ˆ%1zLóDDIÏŽy|ÁÝ\ay°H'DåÈ?,0×£4@Æóà yTlàš Õ(˜| Îy§|£¼ :×oDdä[2P1e{˜C£ +RÀC"a 1ÔUÇ ë*ý˜3ÒŸàe=’s¸{Þ’#";¿=Ù,`ZÁ|Yä»*é›4R?_CÒÛo¯?€zŠÊ ¦ŸÛ?Êà G`†°ÊÁ~ êÀCÀø3tWȨ TÖEÇ#û¢½-R\…„ €¬4: sé~8 èÁ"g ÇãBöIìŸHãà—: 4AðòÌ.Ç;5¡é?¸lºÄ³µÒóüe0°7 ñœéŠ3?T~§éƒ#}ßÙY" Gµ¶6¼ÿ¡è؉ëB SÏ9D>H¥÷â<™Ekº@/± äZâd¤œ¢›°6ƒed ߌ ýÔ ªÎaX D© GBa•JŽÏØÜ¥^ÅÜ2ö ^ åƒz°ýa×¹ÒŽO%¥Zpï¢lÿº÷£¤«3º%¢Å à‹óƒñÆØÂaçœà ë¯aˆfyPÒ¯BÒ£ðû‹e*YgTr}ú(áq2˜’`òNÈØ·#À…‘œ†&ó ÆBI˜S€<5öƒªœxäœ#Ÿ¦ëe€›“5Ö„òÉÉ)Ãö‚¿/œìúJ´0¿°8;·0S™/–f³¹räåàÙõöö;µn­Þ«pŸ q[;îÖ{G½ýZw÷°»Ç«³{ÐÞÙoní6¶÷š{m|÷?ß4[aƒ×ð¤É¿ÖOúõã^½Þ=ªwëÇpi  Ú£þ>¤GÂa†}ñèŠ,ÎÌäaµ¹Ýž}` 3ì}¼,ÔsÅô rå9ʉÙÒ"¤$V–ç€E Âí?G")ì5€=`À£Ú!!Á}J¢÷e4 ¡…„ÅâÂüÚêÊÚ¹58ˆH€¦&þj ž rîOd[þt´œâ=gtªLjqqÉŒ–©½0Pð‰1©x åVîxV\×3}“¾M±Ê,mG§ÖYb2LÂô£³ÂFB€—•+¯=¾¤+pòj˜c‰¡­ÃÚ1Æ·Öê˜ppp×¹TüÁøeB çge…Ÿ 1é†ù¡:!†ÚFÏ-$˜”/Á1jp`GÖP% éqhéȈ‡ª­L:Ú.}i>¼Œœ'—F&Ä`PdàÙLfd ξ ·éV™vuBš5ufË%ÜÌŒàB÷¬JŸsð¤ÇnÌPÆ+51û Á‰Ýp®@wèt1cT0&Hj–¥1ÎÇ=Ä.¨Ñb’R¡Ì«Teæž'ˆ–I êÜnwpÁƒâµ±uïîÝ{÷îîlm ¥´®LÌY*¦OU¸xñÂåK—0 ã£?øè£o¼v=kTèÒीnç2!¦(b_0NÈ{‘¾æ03»Q©gfÌû¦\Cz±Ä©óêO˜J.Õqf<­xz¤í6™P1õ˜¨Áô Tõ2FñŸÿ”qB/î÷#Ø:‡çuÁs>Ä…`WSXðÙd‚w'˜ŽúÐô<ÆÈ/-Í/--..Εï’=„ß•c¹ÊG"A€¤£†ïß_¿ï>ÖæÆúÆÆ:B?Eñ•n e}1æõ›o¼þÆ›ošëÒÅ ž¯Ó&ÓõÊÀVÈÌð[¦½Iù UŒV=¨bÆår$«þFŒ$åX$Ô%ž¡€¡(òpÉA£C˾D%Ñ}®Ã@^"ç/éxFÏ>#¼Æ^260> ÀP`Ø,F'Y½’ÑPã© Ë­47WAfK1·t^î ï)ƒc2šÄ‡ÛÓí¢Ñq€Û„ çgV¿ÓߨÛÛÙÛÛEˆ9ŸQ(J¨¬Ãúå1çÞïÝ>øà½wß½xé"f_©q¿t0#’ŽÝ˜TÀL€Pà¶æ´j ’HÌ7TJŽ`@FßÑÝ‘똲š—I{òÈEÖDy‡ ëÏ*<ÓV£|9ó+ÔÙ¬Þ3ÇÓÓÌÀö×@ ÷œÅ NOªîb#æ…vx98º¨ÌrŒž9bEÀünü¬YTiýs˜›Ä`¥$#Ñ0›ÏdÀ <·(ª×`ý¸˜BÂ$¦Œ‚Ä7@²ÝÎ#uð°8LàôüñÇŸ|òƒï|ç;s²ÀƒHû•(lÅ 8þŠß°Š¶Ø•C€nŒH­Ð‘¡šY’¹È#¹$d^Å"âWOlCéQÊdŒ™Æ#ŠHîçlú^ˆ,P™P´o‘¿ƒ1¬0o á°ñW˜üHw*$Ü×wS¢xžWp™„”†Qu‘“z¹ñ/T ®Ò Òçî±oÞµfm÷k‡uF»Û;û{ûÀaí`oo®(нÿCvÆd³ò°¯¶¾vŽSPòãöÙçŸ~ò‰ë.JûE€í vNðÓÀÊ&ç8$8_ ‚”tŒê›p¤ç›è0PÝ‚%£C[“ ZÔwðà‚å ÒNBr T‚§Ö6VòµïV3Nž›)S:0h0|zÄ@·ÃÙBx ß#m¾ñ‡JD¡&m£Œ‘fdL‡âî,ž©žÙÅ¥9ŒnçÈ`PßÊEþ<¯¨‡ƒÏf£ƒèØß§ÉÓökG‡˜ƒ8ú¸qr¢Íøg:5A8Ü=¼Ê Î߸q“ð0¡ìÃ>Âh`'5™÷sÀis‚Ÿ’W‘±ñ¹žeA“)›@ÌŸ™ÏŒã hÜŠB;íÚH@1òÍqn»ðÅæÙT…-Ó—ÎZËÝwËÄŽ†ä¦©Òé͡΄ĭ˜|¤µ9” mNÒQ"ƒ%$¢Â@­Rx8+Ë‹Ë+ ‹‹ØøQ,ck¢L-ÎrrÏ“,»Ñ<&»á<ŸFnNiÓ£oQ ÙØÃOK68”x}ô˜R­€ðöƯ¿ÿþ¼wóÉ._>þBjý/LŠbØÛÕÙY“šˆ(A`.ŸCsCºã£Ø%o…æ©j ðë3±xVm×NõÒ®3#¾ ¿á\Oq.tŒ—' m[{¶cW$vE^eå™éOLðp¦±ö¯ ’aî(¨TJçÏ­ž?´<êÕh +¤t’°ƒÍ¾bO£±·»‡/<¼%x[À˜@â_?æßOŸ¨ì›ˆGh.˜âCHþ` ª”{W>úèƒO¹>ÁïÀùjxjÓ¯Dh ïÅËåYÂ4C H¨û±Ë”ó,"ÍrÙçgë]*7¡e6U¡¢04SxT:–Heª"=^Ì l©•iÝÐÔÖ§g ªoÒ½…½_º±Ê«« k«—TÊåy!>–h¢},õ¼âèÔjìpl7[Mþ¯Í’*@§czGú*p°à¡PÜXYY~íæ›7¯¿ýö[ï¼óέ[ïÈX>ç ©M=€õß¾»ÛïÃ¥Eçš²±á=¬n¬€!3Ø3`˜-Àêëeš‰Í‰=‡Â•¦¦”Ôe%|v-Zh¶DS–ÂQ˜¤ØñWD¶$M‹ãO0ódDØEkYòD¦/Ùó¦N#{¦Cu¶ w¡ååêòÒ P1’߆DJ‡…¨Õ0ߎN¹þ#8B}&’àñ?Ä¢ð0à|_ß50†ÿ„:uõêå?BÁëýëׯ_¼È¼§4Mfm웺@¯’'€€2ÀòecöäïÑngRšV‚}&öÅ?Gü2^`9i¤[º89SÓd"MªŽL ‰Æ¬`ÌL5Žœ¸‘ X \ÉKYQþaÑmì9¦žë\@Ò³½DMÚC*dQ$]ÇŒé[¡D&}~¨sIŒ{áâ¬s |^¼tD7Œ¤·bÑ~Bþ+µþ¯;ìÁOe)ÔîóÊgÈ£O¼0SbŸøLṻ|Ö¶“æo4;Çõ&P(Ðjoû€:]‘«§V¯¥*›z’àRî’A$e8©k!2Ý ž%Tñr)á†N ÎèSP Nka8 @QF<ƒSº…mð€õ»{»¸ØÝŒÔ6ìpBQIÁiDRÙïfšfPçz“ëuT¹®\¹ˆs@ÈÏyUýÒŽ÷o ¤P`S·5*fÕqËNÙ2H¿ Ó{33ÜÑ?é@á V;FÛÉþþQ¯§éD`·(·GRÒXuŠž4fZ‹È·©~3÷o¨ó”fHO#±4çÙá#3„س½9±ð€Ôòʳˆš9Ã<†4ãFà®õz­ƒƒ½ûw{ŽjÈÀèy º#ü‰¨å6# ½³Pö©Tæ"Þ½~ýê¹µsçέ"ä5å<ßÑIðõ Nà˧@’ ”Ϭ Dm@@µ¢Ýâ8 @/ƒË IR@ÃTG˜jM°gv¶w··wÁËô4‘È»J¦±Œ3‹2ÂîwæŸ3û„JÍ_ áBÀÉ^¯œÌ¶е”¡ÅõIuLZ ù†À•å›§¼.0ëÚÝ&0pp° ÿ'ºk‡ûÀ=Ÿaúþ”³—*Z¥"’<çÖ`ék+ËKËäxê2ÅE>ñF@)Å´òx©õ¿,ˆ_< ˆýè Éëþ,`ÛálµH ¯RÂ4v|ô#(í´;=< H‡ûÛ[¤Íƒ8/Í"}‰f*ÒÆòAˆ„Ó%5ã»Gg=.l¾ˆa¥¯åÛ¢˜5‹Óì–dèä ÀþF)2 ÛvuÆ’Bw˨ݡv'Ȉ€×ïßNk{µÃ=º¹ñò„Ð&Ÿ_ mnîâÅó¯ß| ×åKpþÏ!ǯƒr2ÆÛùzF?¥x< €/ïî~yw§Ï&©ÑSœ €Âø`'—ýäUòðàúPg qË"Y‘å6lkww[@¥XM ¥Ñ%,Ÿ}.Lšh§¤@ûLÖ<êJež­ (ÌAãÌj8EÂ3å Ñ km|èH%ê¨ÒEEhå …éX§Û:„ ´qosã>îÕŽèî'NNµ ìU×VWW!æƒ0À €ŽìýÚИnô/)6¶¿¸»sûî¬_ò_Í¢„r^'>H:Â(,½îÔô+Êxé Ã_j Rô8ãA ”a\¨+m¬ßƒm!͵T—ÂEz_ I#ÍþxRN#2¤I' `Ð(±(R+"ÀÀ[~ ›EèâA'¡ãEV³=0½ù€¦ÉÃĚ⧨ßßk×j‡Û[ë;[GG'u0œ(ƒ•§(=««Kk«Ë—.®^¼¸º²´€ÔþºƒYõÒòVjý/7< €/ïíÞ¾·‡d·;zRHþ›(H.‘1%-ÒdB`úȬ—ŠYJ§[›÷77Ñ-{÷îÝ/ïÞùBQØh»¦’æC +µ‹Ò¾JºžM·Š®n!oP`ÿ@6ÿ»>T¦¡,„[tïBoP‹ÌÊù›ˆ…6jF÷©û–X§œ@ØcªM^µÝÝͽ­“c̆9n5Q1€~ ¤P®\¹tåòÅË—/\¿†ëüül…-ý©Å¿Àu6}Cv0zæés.ž›Š¡0BÔçôàöBŒƒ—X®;µZmíVaKbŸ­YØœI8Û4ÃIՉɿ‹ž¡ô!¶ìÊbÔ ÿÇàE 0ãñQ¨…'X›¸ÇXìLd™q€¬t¯æFµy`¤é&¡é©ø„ž o¥j2³…$"ìD8Í 8ÔY¬ííý½#«À‰“âuœZç+3+1èè+ª’§‰„Ú¯[³úÙlÑ }‹;Áx!4Î6*@"´a(2ÈBꇽ#Î*òT}VX1}ñxrZ`bý@::›x`—ŒÛÂü•)É8ªNB[??¿ˆ¿‚3¸"-Š‘±&£QávñëjðžT‹EÅŽÄ9­ïJ]£(]oE¶}Bô0Ž(`MÀPÚÙ>ØÛ«ý)^±ÀÏd¬õ?é“°¸9å 1¡I—É%Ô¹° ƒCÀ«IÂ<ŒUmW£^ín „¡™—ì$Üè ÈAðFQæÇÄNÎ4!b‰'fÂÔÙJZàb\-Çyj9BÉt¡v¾0ƒX ´Þhuë'ÐÁEwLhž¥fú œvŒ»ñÚ¥•ñ´›œ£°1ô€±&{PU€‡=¤îH§'RØù{2!=R&‚‰¦e>CÀÕkׯñºv@ž%U°ê‘÷gÚéN&›²© (XdGŒ…v“—™ÆÕ¡£Å,ÓPvw³7Çn¬kì¤É"ŠFp¼ˆÌ²€X¿`a (ÏTó…2^äx€f cZ'6}.°›ºôÄ©¹øEOJþ¶gvöŽïo®oÕ>®N'Ìd0Õ$÷4FË+„±Ð˜3¹“œf|`ÄuÓ¹º9ÉÍK.U –Õna,J£^?ØÝÙÄU;Ü=>><®ƒZ©ÀΰßÁÃóðòÁ™ÁBfHdUiÖ÷á,Á¬{l5«Å”6¡´!Ip£(‹ùF 4³­ JF0-àªV1‰£¬õÓ /ôRDÜÒ@ŠŽH þ\àC;…}^<¸”Ô-ØÑwzòH'=ÉÖet“¡êÇ ŽFRŒÃ2*økQç®>¦Ø‰ûLÓRñ Àö^ýþæáú&Ð;`×CRѦAU>–½»l§Âq²!F¹å´'Føp!Æ t0‘C…lç¨5h¨=«iУýfJùuRŽ¡h.@ýÝwo¡MöòåKyɶ².%ÜÆBú҂˨šn¸àéOŠ!3 \ Ìͨ¶‹ÛòÌ,vk-Ðoa, ‹ÌùfÆ¥#™ê+Éüw_'ÈË0wj_I¥` !f³JÎ0f ôçI¤ãp¤µOØË‰[êÉ¡F‡NP‹iËïK €C` €l®Ä[éi·žŠ-ɯ9e½‘ gdQh¬¢«ÀÜ|ž{žœnÆ©#ÙBÙÉ èõ·ïÝ¿]¯íw:˜Ñ Ã>hq4 ÂfÆG~ý§?ýìóŸ~öÖ[o&f«î•‘t€!ö8Ù*þ,K@ÇüþúæúúZ·Z`ð´»°lUª“RäS*@g{N<.ŒP…&¿°ƒ›JÐ÷#Ç—fL,MÁÒfO×HO}J¨ É6¨OÁô¸‘èÇŠúâ TU–g!ž¾²¼”Ôd_ÊÀÁfœ(ÄV!9 ÆåO\»bâÜž( D‰±ñ¾Qw/ªV‚"TZɘ64òá!ÞJ×Êò2ÚJÎQ­ä<‚„ÄW¯\¾~í*š oÞ¼ñú믽öÚ5ï×V—0e±(ÓyÙÉyØ&EÔ•I×$\0åª2)êóˆd'3°rÅÒå¨ 530@@4ÜqÁÂÁ-G´C Õ€šÒ /}Òäü¥ãFû³•ê;ûhŸG4Ò•9|£Ô¹I aËæuN4lQÌø©ï±áѹ/Ñ2•-STË5žö'GÇ«ÐÔÈyÕuëE3 mìEÂà] o¾~ó#ê,|pë·^»qýG Uò¤øëÔmÌþHæü9œt@:_§y€Ú6„vUè[„¾L†ÒÌ&õD\Tm××ÊU‹”ñÁ- !³shʃ±¯„Ûèeˆ[Œojì€EЏ &‘†"Å5ÀK #J.\þ¤<¥3A=Üô7øè ¶4GÖÁãàÏ.†»£:YðX€’ÌRǼñÆM(ëç£Þyû­›¯]ã¹¹ªž””óe&Àxîé(Ͼ~Ä{ÞW}ȱ`NÉÁÇO‹% gÏ¢ …21rHW¯]=/GÁ,9úhÖÉ “Îd~4öP¤æÂH¶•ÝUÓOzzx|w œÝH°ùl¨¡Ê4ó-–B yG„Qý¸¹½s€¨Z[jÇ_#T™AµûÕu2yOµ¨L"Ôœ ¡ ~²œÑ#M?›ÆIü@,Á)2æ}‘Çô€Ð)??ÝaB”òa´vnõêÕ+èKDþ Ã%àhè*ñ?”î^’#ìé']8öÙâXF§øé9€ó¡K´uðF[ج¡Skª”\Q ºÇPØI‰…Ãñ±8À ! u”f…^‚@w»q ÿÁ NÎ|[ÿ³Ÿb‹¡>G_ý/ñvøº*²s}‰«”ŠYt.Bœe*’œl6Kt)„ˆ:jZ4òMÅ#ö'|°1Ý•¢‹h‰Çðw޳¡€zBüW0œ¢±´RªE¾. pÜha€ÆîÞá €ö‚$=^ØÆmùŒ£Ñx ö“óßG£DUË;#²Š 0°¥¬@eÑg›+,s€û,&îB˜ ëH\âEpKæŒ=—ʲ¾× ½9À¾(¼&zJ±‘X´U0_Ÿ¤™æ$$í±dU'qÀ“R~« {{®R,`†2¤™ÙÁ3Ä 4ÔÕŽêEŒqƒMÔ³½4øºàªKj….ã¡ûºŸ?UÓúîWd÷íq`Ê ÂÏÁÚMI7úÙæãâd®ãì¼è5àVx8±„ž‘öš©ÐD,¥0ðcZT¼k›©Ùa\PúÞ6=äcbT£Fö¨Ì;+kxÛ?“ÂàkÀ8öÜL ãþëô§oöάöM† ™ù?­ÑÀ•#b­Ö>;žÕbè~„ŠP›“\(–Iû œÜà¥ÎÛˆ¸§mÃÍãÊ +V¨Š–f©T—Ô¿¨ð¬1,gô)p À«Ó¼PÄ0@æÜƒÌ7O ÔP8:F(3Iašú öiæîF"Dþå#Sœ¹¯®6$®É¯›¼馣ÈÌ5z6øS P¡ÌàË2›Ý«CE 0i.‡ü|rQ‰ÌhÀ(pð&Þ Ø=] Qk ÅÒ(FÔ ìû¦v-"ê4þ:] 1Èf<‚¤ó“<ÔâØsséÎÄ…´Ÿ3y@e ÁªÎ”0ä×"Äãæ0Þ½(S9˜r¨&+%+JêOoª–ñ4gĉÅ~9<é€Óþf•žS)—œ ¯ÏÈû‰°;#5a³ÙõãØÞÙcV”3ºÓõ5Å<⥎?µ»'Ùo‰Ê—) iîrœ0z<‘{Óqé—!‘oÏ0´ÐoaÀÒâhB(+A›¶ÿ Dã¶'©!` ³OÛàKK9‚9MåL½Ij÷d¥Œ‘.r£’%gh$ÍivhH^fˆpìå‰FÆÚÙÙ¿}ûæM¢¦ðÜìäa§o €q43iü’R ž?ÂŒýŒÍV'µž$½ñ©­Ö^p¦¢±Ê –Vˆÿ3Í K Ðõô‘ìÿ@kÀzÜÈægUù+cÁNQ0± ¨íÞÕ–5!œ¢a^ø:B ¤ ÉR³ØÝÿòÎýݽƒç ïiýÞ™rÌéDƒK’'ý`¥¹à 69æÚfNÏ.°aúRÊÃåâì,åÜ Õ^^^™ˆŠ»,PÈ\Chû!MyÄ>I76aý '‡¡BZ:F „˜¡À\s»B’£és ¿™Éb÷@bô@ËÉ áN ¼xHo—­™á£É|¿ç!ì3ÏfTN?'3^Ôšò‰ÍuºÉÇN\Ë<³¥s±'³±ÏÞÐ(}Xýl¥<7ÇPX[Ú#5 àpØ‘X(¢VB2õÜo22vy!…€¼¾¾[’,bG‘„Å-HB”=9öãõ(‹*–ï4ÔñÐɹ·G‚ÐæöîÁA êBYZjî {hƒŸ¼)ÀcìÁ2Vqø ËÍ¡8Ä×1£]cO–}Ô  MN€³›ÂŒ_¨4žx4±˜WÀ*ÒB°ð¡° Cy"Õ¥ &ˆ¨§&…œ¿¨›ž>Ga›¡±YñþsTìe2”“;Ìì&¾Ñ|‡)91 !ÚR;9â`k{wc±@M'Î'—îNÁÃS€aª§O¥õûVÇ+¶³«L6òJÿk.¯£¼lÀ%„·3J°yÙ!oB#tÊÊ£Ø Ð•4“ëv7ÙUO4?£çð¾S€}3ENA•q¨0HΗIt8J¸…­È(±€:í%òåX®¸d{Lt/Ýô‘ŒëÃ1O†ˆ 0Ñ \Q`ÛÁÔÇ)ˆ7wÀ¸·}o«¶¹rxÜ:¡˜QÓH~%\Ãc`Êô»‰u* ^Zœ<úa­¹½[ßÝÇ$ôÖa­ a´XAð ~ØÅpRëü[¤ Á¡§¸[§å›¹ˆ¾™Z!µOPraÖ˜B¶²e"Q…€ZØ¿½FãpcWî@ ¨Û=év›0nwÒ2Üôs«+?ùñüäÇ?zãæÍ³Já] —~öoçw_ÜÙ;8êc¤%ºC½•¡~”þÔFGy°wÃ}Á^OªÏ0tšZÆmò#°ºu¤¥"$’)€ÙÉ¥5Á0U¾ÞlÔ3¥Ñ¹›³+W+ókåÙ•òìr CmL-ÐÞòˆˆüì(›å Q¡Wª~µà¬wÖŽãK$.ÆYlòöœ¬ARþnŠÚè%tþ\/§HÑ™ÚX»û(Î7“Fî1J™k‹½@‹¦¯²(Rý ôý—ò}Ý"Yb2¥K„sD›Ê€£¬”Ei4j›› p× lŒµ*°6W——>ûÉ€7ßx#8»ˆXwmˆ…þö‹Ûút[Pêmq$™Œ¦RÄH¤„ ôP €JYgmÀ×1Ã*G†§};^¢qL¶LŠœbßX èP úˆ÷–׆‹¯ùko”+ '®1¾MÞ™ºoÿ 0”GeLœæ+™ÊT“ªÞ&‘0éÑ1M»ÅÝz¶Þ'¦ËŸúÖL×’Œ#YLõ(ãzB¤óì|!}>%övä‚f«„R{áýXõ­TÀË ¨¨„öÎ{œÓÙ§&$HËì `ø#±”:tZ1{Žsƒ+ýƒÿmöÿÃòÍOgò:Ê{¤¶8´×`|‰ENi˜ñÑ0Ö3õuýoÿýEç_6¿Ä|Ͷ¬¤_¤ÜAÂXÓ€ßó©|4Ä `Òå u[ýV£ß¶{„—<žÝ9ðLMGfþ®Àµ~;Ï×ÅOš qÉÐG¬Édù)?àÊÀêb˜®û[Ï¢§’Í ì]˜«ÌbpM6^°!önÆ– +2ÎëH^!rn{å°úx’nëâöÙÆjáa®¾öÇÁÇÿsñÊ÷1/ÖˆG"΂ß²/¿£W{ݶΣáP|ßâïgdŽÓGzS£éÀªãuî ïüMóo~~øó»Gw)FªÃTÆÂ8ñº‡D®ÅÃô5IW@™ÄÏ›<¯dñ¤‡͘ˆ^æ8øŒ²@ #1§¹t*ŽL‹àD ÅÀûêYŸþW¬ÉD§ŸP³±ÚY‡Â${¢O`} Çdô¸tÒ>¥‘„ˆ2n`À~1¸428l 3 cä´½bUT7 e´q/oü(óÉÿT>‹TM)ÁȆ’áhŒš?iµOÚ-Lœ9BPÐÀ­¹Soâ‹mhG Úì($=õ%y”lCµªÖƒƒ_ýò?ÝÿO¿Þýu‹£]{®HïŽë©O“]Û¹â­äÅ—ãÓ‡(0²Á}™Ô“H4}£O/™yðLׂŸ1\åùÒÏrðL0 Lk<šM¤|n'~ €1ˆÌAtnu2Ós¨XqkÙÝ) %`Há]í¡ñBK ï³N_šx Û2ÔU¹þàÌ]ÿ!àå3ÅJ¶‚`Ö Ya˜x«Þ:LÐÁÉñþq}¯^߯óVîïã‹ÇT ÆÏ”S0´ƒ„mIYÎv5»Í_nÿòßýÝ¿ûùÝŸ79oj¨Ù¡dÇ ÞðåEâW|Ý{ýBpÁè‚P è÷ÆÉ¥—< œ‰õ«ëÁšc໯:É›ŒE€îq'³^‰Ú˜ïX§‘¥^Æ ¶}A:ND¥Ç}Rø-Л^X-‚Ö‰¾h$²&Ïá³¢I²žc“˜&2{»e¤( {þÈfOû—¾}ô—ùòlvÆ›¹ì]^ôšG{H2ÔÐÓ€}ííÕvjzá>¿²{d0 N™oç{m2Áƒ‘¦#ÚÇ[cÂDì%)üC18s ¸ç G Žæmœ?¿††É<Ý.ñïE„ÔX9›f†jSØoµÒO<«ÈnüØOý`øáŸe×^Ï!Gù©÷)öþ_z¿üûõ¿‡eþéoË–/v´}²÷e{ãoÛ·ÿsã7Uûûÿ¸ÿßþÃÁ?ü¿¿ùû¿þvîüµÆ‹2»åüI9ÓÊ nÿÇŒ4xÀ¿£ìáƒfN°*$’'@òHÖ€[qK¿hRRCC‰2Úw‰ ø›}¸üœí°¿u.Û½RÌ,aRv`€ ŠÍE*­³­# 8/€ØzDZuÒ¥èo._¸ðÎÚ­O/|úîÜ»•Q¥‰g’6Õ`™±o2§. ô.C¬N?>ÕÁÎßE'ENÉ=«DXôÊÐQÏFB·öœM…ØŠZ;Œ†iÙºŒN5éë·œ *OcéɪVËwYWÍÿ(£BGa[Š¥÷<Â÷Dðd®Qqð¹st„ (“‘j˜p*Y$zê=iž$´[N·= ®|Ï¿ø^9õ¼ð¸?÷~¾~g]~MïÀô­Ö֬߼œÏÎå)­ÎñeWS©¢ä þE^ˆ$"\çÆšxÇUdE×Åŋ߻ô½OÎ}²’YÁ–/"¿ì>pÖ¯ÖT+6-H‰¢˜øý˜8u||—öqÌ+àrzddä‘çé8nN PåFr¶ Sš³aPЪ®ŽÞþÃüí»Þwñîxw¾¼ó%¢U½F·@BópÕ¯å½ó Ë“Ã0är¶R?×,lóš+°>ï]Ê»=lß…|‰c*Ë t/Ï/tù£_þñjaU£ZHÖ-<¶›×Tü@öb¶­Ašë[€©t#@[[~¨%ZÆ^ã_ aç8¡üMÒ\$G…†A²¹ìl#±àöH˦ŸÂ°Jª ä Áñ´5fÔ\¦}ä-Šâ`ôá?¯â,\ò–éÇ£ýâþ/˜æ—À—IÌ£Fç(.Þ,æge¦F9O¥ x;bè®f §òëÂ#Dé ÏÑl™|FÇ|‚9-x48)Ë2­R1€[Àà7~ðéÕO‹AÑ•ðîf3ÙÉÁµÉžÕ ÿÖ§£‰¶¿W¨ß 8[ëwS0â„PŠ|Ï÷'C[W/sÒ) *‘Àãd A¥'E-Ƥ¡íÿb %™îs\v¨"<ú9½ö€Lòšd ·öÀˆÞ•PÊ4o„•CJH ‡ Oüõå«+!˜}Ë{ õïwþ=’3L\bØZ¹ËîI\ño•JU!–¢/Œ:Y°~t `ô0hÙTp›Ã˜ô h ­Ãl¢"DÝÉN1¼!•ÓÖÕµ«òþŸ\_¾î 7›ËNölœb' ¼hbwz…z'ƒ³ÞûO9l[ˆÚÞOo]5åV®z ìýŒÉšø¦ÿý´@t§‡×áñBO6[”¯RÆ­ykxœ¿êþ”ÌÖKþùÊns8Ÿy¦\!«TüúúeN”áÄyNk…rÖ ´ƒJå Ž—“ ¤uXzç5èïb¼@»ÕA0PGU©Ù—Ÿ¾ÿÓ¾ýC%såscëOToü?õø¡ »o¬V2YˆSþŸPõPµï¦ÇÑ,8ÅÁ¬„ÔŽ|*ˆéJ\p[Od×+òÀWßžŸÓëR•Ws‰*3øVÓËåt¨L½Á©lP_ýTû4^è>¤ÑváÅùYÌe3"Çd(@O'Éû*$„þÐ-ûÝKæuƒ@øû ïm ÀkvX ®Î°Ÿÿc¹WÌ/Ì/-Í/.ã–ÇÀ<˜¨ø” - N¸PÍQ™éY… ÜÁ € {Ñmðà|1¼Wæ_Ás’¥P\Uy¼”ÆÓ>&\?ÆW¾5М€mé°s#ikòüØm“d†’êãÓÂû!ø4åšA‹IµR¨Tr•*ò*×Ú¨—A© ¡f %/ç€Ù•üà”Œi¢;>zÁ»žd#ææ+++ó(Àò½`bDŸT½=Ð2ÃÎ¥ÊxŽxh+ÙØÙ@) ¬ÃMèô–Ëo/-,c(j ‹ UW–­9\Ë‹s óx×*´Ö²t^–ÔW,‰3‰neN+Ó,Å&d°êº ú£œpž„¬‡N@aP² ÷uК;žL¸àUSzæ!yri¾Ãt¹h×Skm_Æ~*»æsdÎûª(+ÂÁŒU{¥j…Õ¼Z?0£È`8K± zÊ¿wçÀX„Ñsã³#IæÙF¨ø…lÿ €b¡0P-ç…ŽJ´3µ«çž7Š9\ 'ÀÅ[ÈØ5ŠüÏf´©-d%´iýñ syíl p¥æç+˜T¶¼TYY®®.‹KH7U«º_—ØEê0Pf,ÅÎâx–2Sõ•Q8Cô ¦&úU’Mn%1`O€¤nŸÿÑU93] )Žœé>ù¡‘»ƒ½)Ç Õy{3™±¦¹åíŒ#+ͨ™©ëÒ1ÂÀ‘0jT£ÜK !V0&¥G^ðbXÏcMÕáªÏVñ2uÄj¬¨J× åÃ9—+„¢ ±l[BJ³óå«%1A±Ag‰œÿª#`)§ÓÜMLîXæ~ç‹âQT è€o¼øõ(@eð‚ö0S€#FTךЪyp%O€'ψk ó¿t˜¡ ûÚÀÔ³Íaøk¨—(LåàñÓKŽÙè®× ƒN r¡v3l·qpãÒiB(j¢°ÙŠ_¡ñå)ÌÑÇ»ô\Ol–ð§‘ Âp1lÔxŽÌ}Jú_ç£esÞù7f¥€CQ)h®=Æ«Õ×4ƒ˜ãøDKp¿çz^¿õ»!9uh0éJdkÛq.c‡o+$KG¡06üP?i`Ìjòq¨ýƆ²`L†Sƒà‡ÎývžØ÷Z¡àbç~ŽdŒŠ„€2cÝ“-œ2½ÿ*™§ˆzRý Ú˜=ètä‚‘täO—Ò @ʾ¦íF;ñbíCp]Ázt|Moh€¢°¶ºrþüy8ñ°¿¤@à ÃË·…(Êg Ÿ‡ýSÒÚ 6ö¢·Ïõ<ÆÎsð 0©×zØÇÆÞHé0ðf`ß×8Xuש¥s{òüè¨sÎp„ž±e²\Þ7tE  ‡¹á<Òp‘Q@©F£~|Œ\ÜA½~ˆ; h—ÕêGGµÚÁÞÞÎÖÖæÆúýõõûv­» _ÞX_ßÜÚØÙÞØÝÅ”\°Ãj­fÜ2’+‘ÕÓ©u’|35Wªn™NÖ+ïi€ „š€èÆ)QÚˆžÀX/Ýš·å12ÉHå žàád¹ãúq½vtxx°µ‹wgwkcssc“oÅýõÍõu¼[Û[›»Û[{»Û{»‡{µCŒ 8¬£cò‡$ˆÂhSF™¾š¡¸ "ì"'Í&„D÷ö ñ‚íÊE­j¾~Ä ~Å×3é©õã]ß8üòÎÎí;»B qj‡ñd;œ'”02“Afyq£ò<Ç›ˆ'ºìÛ«¼Dü[ŠCá? žQYŸ4SŠ6¬Êç³ÍŠ.ÐÚêòg?ùÉgŸýøÍ7ß°cÈLÂþ¹.µ$0Ámž`{õßýîËßþîKŒ1’N”¤ý¿ø?¸zmžö?!é Âz\·ÁúD ,Ü=_*VYëå0½û;ET4'´â¢ï ò/íÐY¾±Ú¹ФCo8Ô]€â†RÏú×®]¹qýÚõëW×Ö×V— pñXšô²dÂq[ååÖ«ë½b*ßý!û•ْƆL¼Škó×>ûà³$é Õ78CñonÕîÜݽ{o¾(V o—ié«Ô@Ï‘¥×´ûA¢›·—€oÔÕy% $_: `ÒÃ'ˆeŒ;< ¸0Þô§?ý×Ûo½eÐ{#ïì %X¯7ÄôŠèð¨ñÿð{\ûû5ìô]N¦¸Õÿúýä†Hà„à>€ô¦}^ìåÝkÕo“È™Vs^˜ý¨ÜJÚËxÝ’ÞR©<ãûE‰Ì¯¼·#+C­B¾”ÉÄøÄñÂüc4ñ\¸xþÆõK7®]>·¶ì‹'ðô@Z·ñmÀHFúllÞ¹³}çÞîˆjI1Â`§©R3î®+@`9ÈÊ:_ÊíISŒšPùÅÂߊ>¶ÿ‘ìô‘äó˜dñ‡\?}çí·ÆÛ³ þÊ#ß`Æð°áiß¹}ÿö{;ßR«Ã§Á{0w±üÿÇgª§•/pž0 Ý/Oï elÚz”Ý-·¯b*¦?Âx:‡ÜÒÐ,ÁŸ|šp¿p”à‘B!½~”«©j±²ôö[¯¿õÖëW.DQ;xrô‹œ„ðí€lDÄÀÆæþí;[ÀåÂXv–¥¤l°¨ÏÚ”·ŒW(íBø¼$BãŠd°dÄòü1“bÜ8O+2·Aâ§/’èÒ›ÂaH1--.üìþðg?û÷ß~{аð ¦ÿXίzA˜ö;ÅÍVosk¾:o麯c ¸ñýóô¿|W‚Gˆ}A|€Ñèù‚ŠÉï¾{¸ÑóLý@;윴°éI×äM‚‚“x’™IhÛ ’åÊ¥ ¹RH-yàÔÁ*çf?üàÝ>xÿƵ+œ†fvŸ'€ýÁ·z¬oìݾ½yûÎb*D^ÐÊÔ· ÁïÉÉ :†àµ7e¹&£„_nFøþ¸9ƘÓXQkÜ:ì:tî¤VÖ$îå…èóöGüÇôÎ;o»ø™0uø p zÝÞààû~}}cë÷¿ýýï÷ö„÷ÿÉëßÿ³w€á©OØ °SÃ- ÿÿÿýÛf­™f73d-6Ô’Øê‹É¾à›D¤}Çôò±Þ­ÜÁöª ì0«~”çk=0øø{ßùÞ÷¾ûúÍh ÌeüÌc4PóðÌ-‘æ?†_" ˆ([þqã¤~§pÛ©GÓn5ºÐ새,~W´lzmʾ ;²ï.ø÷½¶Üº‹¬¦\$—ùºü<Ò(]™¦³Ð$F½ø™÷þ§)ôû:b5ð‡µiiiÒAhf·ÂÛ¥RBç=ÑE%ªN“©­¡Ä6ò¶à¢‘E³¤jÏŠ<°þUÞ"y[º¨àB1™)$:¢¿M)¬ŽÙˆ° µø´m×#Ű1momoll©û“}ô߈RÀ3ÀùÖ±*FLzBi ÙÀèZÌë9 px€ ¾Þ“ÅG˜¸×r¦ÌB@¯3˜°{\]‡Þø"¡Rt™;:¦Ž „¨!…c72ì #àø”¹§Ð"tÆ0 ÀòÒüòÊüâB•ã%gŠÕÅòu§ {q¯Ý‘œhw¼#ôŒÑ‹Ý;$ÈwÍ{âL_a€Æw¡fB0iÖ@ò“cc(Ô%À`{{c}£^¯ã ߈ºÖ‹¯ÄŽ‚Šþ€-F¯÷þNK>HLSĉI ¡2ê8ƒˆâÉÑ MÀ^}sñ[ƒÄ×yÑÐGz§š¿†šúpžÒ×›£V ÷á1HËÎsÐ|UO€|9;ÝDbÕ›V0TöÖ\}óªå}з."­a0ùÎèA¦Ü\ªD¤½îØ)äLn´ÚMmEñNsÝ›<ðÓÚg”àÉvDi…‰Œ¦¥Œ ÅM¹¹°TÑ Âç¸ðÕ9[ }ÒÙ—•.V|üùlnܦWN¯<. ŽÎæÅÅÇΚ³Íbª5ŠX9¥{Á J¢QmÐçùi>éQ J—‹ p‚© ?Ü Uíħ‡³Sž ìµÇ+`’,‡$&îð}Èë•G¹7ë.¼-xsä2’¦·Ž‚pZDŠ©ÖÞ“ó¤+¹9¨—c5j;;›¨±íìÃaÅ(™‡MŽùŠ@1þVÀ–dDUÔ’€ÓßE@­„ >Î ºÆIÚ…„GQ>¼\Ƙ;?òÉË`€?C è¥Í®q^û/«ÑÌe:óð„û#10¦Mò(£»Í63¹`lô㦆÷ÐqÅÑЫP´ß„_~>?¾ø” ¤``.¾“Px<#ÌB‰R±~²®aý ÝD!~G€ª0€v4B €‡ëyñ+×úõ<²@ôúÉ©¡<ÿåí»·oßEãÑ!zêÇšûÄ~£µJeÁMÊHÛ6>%ÕJÁ÷Æ·š ‘„pt„N‹.am2G30gèHmVë¸xÏuz$ÞP9Xù§áé|Mãëž7&Gx­Ñ8Еɨ^`˜xà¢oܸqýúuli_/tÁ©»ï~óF=SÉh#€µWG¬SïV› r˜i(“×6_Wïšõ—¢¯ìAfΛysîÒlÞË/x W¼+˜^1òFPÚÚóö@¨5Á(ÀÊÙ*O/•Ç"®}âÚºvû‡u€Ú‰JUC×è[Ù{<¼!ØøGQf[Yem£hÆ0Œ`ª9é·m[‘{äM Hú z„é.ô”ïìOúÜž oôêꚪ^À§nÉ´R8Üûçvý?Y ¦þá>O€N£ûFùfmPC–Fô‰Fs‰DA8Vî /^¨*®Àœù´”[¤wOçªwH>¿÷þþpx Ö3ÁDn2ÐÅ4$tE´Gy¥7–ßøôú§Ût¬wàM [è2œÂö¿mˆ Û=šÐgä$´/Qì[†Fh‡0¨n³ý<#ÓBœIL(mÄI…+_¶>€x I;šªŒ •V*ðƒ •S8“„O< åh˜¤ÿc  ÃÚQm{a;šáð`* ö€Ú ^ÐO®~ŽgÎf_¦L¡÷3£/Axo €È"ÆA:!ÚŠšWQ%Jr"dbHû¾9ô‹ Vª¨èé  ò ®% é" ‚xíSít·SH²AAkEóm@l‚0UõÒðT|[ŠÒƒ‚¤Õ/±tŸÉJ¢Ë*<8@;™|˜zöžÍî‹=A<;ˆÅƒ“<|ƒF3³1( d’0zUA„õÀ†þÙGÿ|i~É E¶Ê%cô¶ÇÙî9F.èiæ²7ø"»›íèñècÆ#"Çì ¾9Æ ÂJµ šlfìIWZxsùæoþеÉë-×S!ÀKP ëW g9)ÞHžè¤ÈÌC&?ÿÏY÷)ó§èKeÆzÀžïdÝEÖ?y’ÓCÿe# Mq!™ŸÇ"¤ˆÌ5kM3!æ˜z[›×âf2J8Ð9/FÒY‡»˜ 1ýÁãŽzÅs¡ÏJ…ÀvŽ‚ D@Šy¿\Š9?d?:ßqù¼Å g0¾^ÊEä¶ýP¿å®,äâäB2N/è{L]¿L^šøÎJ÷«—[ÄõAîƒwƒwß½}£uãÂþ…ÅõÅÒoKÑ¡1úéâÀÓ6õ_A‚h €w0A9*$'¶ûâImœ©á“þ‰3ýÇ8r3rèåɇÅÕ2å¤Ù0q©þ¡Š2¢Æ ³˜È@?£ª†Ÿ ]§Ù(ªT~è; 3'@ŽÑ .LÞm÷Û‘!üÎwòHj¼©â§ËÀ$% U”iÍ ã»&ÔÀnÞ±÷”‰Á÷¥Ê@¤x)\ õ‚˜›äœ{ïd‚¬éþå…0ÀY¿»ó`=-!ûœ\.¹‰3ÇDáúô22ÅÞçÞR³^1ëOðâ\ 7E³8,NŽ18]М¸v;£Éõ•8UåÓ©Ÿ?âÈ©äüx²¦UB÷ŸÐöZ ¾V €tMnÒz[ +ô¼GÖ ’Ñóä3Ë|ǽÞ^—rC¡}œIëS'€“z~4Ø5‘Ïé±£!xr†ù“°Á€ÕÂNÓ é:%P `0€äh{ÆÁyƒØâÝÚ]gý_y<"x˜ äN‘ÛÎ9ïËÈíO2WÊùý~¢øi ®i3M–lKƒ’ŽdÔC€9œœhaÉ!°ÑÜuÞ”½}ô!ðˆ0àÔq`ÌÉ¢õçÇÖŸ±-vOd¾Suk *Ü«éÛ¨™•–É,„ 㑺rÀø¤Æ 9ôÜ0nc$¼µþä´ê³}Vœ)žŸp”&äùÞc:1†€èYŠ‘-i¿Bbº)^ 4ž•–ÍÎs™Af,ˆ’8òEbà‹ã/”Š£Ë©¬ž=Ôú3&p¤óÇuâ}Kè°$0-ê¥H×C½]óá¼RÐô€é~L ò]¿{§~g`×c‘Òžâ³— ¬Z¿9e¾÷ØX3x |SÏf‡7bšé:- p†«Á*†&戰!~W`àNëN½]wêÂIµí3@`'ÏJ¯…íÑx¢†wßs¤&Óș癒 ]§'‚tòJ)WZ —çLŽ6¤Ñpú'Á¯Ž~%3UÇ"%g‹÷”<3tyÜEð„öï;çGsYé ®‡ž$íH‹íÅÜEäC•}© »Æ-ÉQ¾d[û[•òQuyœ‰/ÄöÔ<;}Ç"aôøäç„ø¤-ÆÙ\^c €t=4 Ðde)_ºà]MKo¨ ;-ô8ÝJO¼“_þJÆCqíQ€ œ9å\(Ú<ðñ2N gIS@̨JƒÓ @ºh³ùÅÒÅʨâ:Q¦Î5¦#ÿè—µ_¢£òAÙ6= žIQÆJP9O›€&ŠôÇŒÌô¼Çx¨h<‘Yã`….0<ÅiMÒûžz%Ÿ| €W8 P/Hdì 7K7½¡ÇÝWå@9/r)‘ʵ‚Ö/N~±ÛØE'nGÖ!ÁH·JaÁ¥•p;Í¡ƒ "¶kF• ×År*C*Åmj‚[ÜŠ:©ÎIéX•ê§^î…ŸyDäÇß>=Ô¯qE,ÒÌý¾³ŒÍãÍßt~c’‰ÒljIþØ‚e¯ ÎeÏݘ¹Q)V¦&¹;ÛTWÿa²ÅL»Úõ÷z×½õÁ:úÅ(Ëup|rp‚Öa4Lo]zë¾ûGŽ>¤·ø¥É¦øÛ…ÛÐrGL@6@*5Jçãónú¼’/ž±)Þ‘©’¼wç©É)^èŠEÇJwÇ$¾8úâN÷ަSLFE‹SIn‚$\ðÕs™sòfó³®´ìú ¬˜¤ïMõ¸XoDwe˜rw¶ûûþï©‘[oBÐáøðX¥YÐ-‰SèÖÕ[?ûøgÀÙ/º¹®JµˆFòÈõÔg›ÙÙál!oþÈÈ¿[ƒÉÉ“”ÜbÏ âL¨gËt_«ˆÖfצdŸºô–àk8ÔIzX¿>øõFocŽ¥lI NÔ_©ø•…`Eå™ÌL!(<ì€A…~8B3r>³’_QšÐ þë;è §~„íÇQ€íû7Lùýïÿ£OþQRÔw°…'ð[ï·íl[­ŸJ[¡NC/N²I.=ª~Q’rç ÏIꨳø ÙFU}ú¥¬VVÿŇÿ 6êm €Wié!Ä5µÛíßþîNûÎ)H ÁYOòË HiBLÚã@ÕªèÔF‡ }å"˜ÝBqá–w«ä•¾ð¾øÍþo Ôq ¨@ÅXÔS€´ÒC üðÿéþi’L 7f ¿Ýô›I¡E˜ÐzÜî#l öH‘x î°¢_²t«z¢ûÕ(ð•µÊÚ¿üÞ¿Lj6ªj] €WÉÒÊ®=YzÜ>¼ý»Æï8 Ovzcú99ës§€aŒ 3Y/p„dCÒä÷ÙùÓá\nQíq¦ŒUŽàøž6NŠaXwÈÑÂßúøO?ûS lœø)a¬_uÕˆJkU{uE=¡•ägN€Ó\3Í8©*’acÝR)²º¥ ЇáZuíÏðçªÖ¨‰„cë'—Q1ö*§A)Sº²r»þòü²²ô’v¯·Z±V~g-I¬‚Û¿ºóWÛÇÛNK49_Ãp¼ÕÂS»}ûÇK(Þ'ÓŸcNžøQz$'°.­\ú×ÿè_§øfbÀkŽ©#ÛõíæÎaûì8̵‚Ïéêu›¬J·6›(fØGÞ|q~¹º|iùÒÊüŠK¥kqÚmùùÄ2k²¦¾k´¨{½ÿøÛÿ¸YÛÔž$ 0'þ•|ªÞxÔ•wê 0>¾#m\)råÜ•ó'ÿFê`à•÷…\HôˆÜ­ã"Ž­5kµv­Þ©7{ÍnØ<3µ$>ÝWžÜ šSï¤ø†äF 9Ùž.6pÖŸl“w8•&éhŽ%á¬ßmÿÉCàA»w¦ï’•®„—Ädòþsž€gò€r÷ÓBØ7í(ÐQÒ/ +y8âqr²Ž³þ¤fɃã6’ÿ ³èA’™+_$ŸOòþs2'•{¨î~J…øFS‚Ôpbr¤ÀÔ ð N=Üf³'çÔsH~åù ùœ§0¬3ŒS|3Oƒ)$LYÿ£;E’#sN=’¼â¹tF惋ÝýÏm%Ÿêƒ+À· è–òsq$íæqìþÁ'óˆõœN€G¯§ä¯"¦&)=æ p†vóY)¾!¨xð¾³ïÔÐS¤+] -Ò· ])Ò•®éJW €t¥+@ºÒ• ]éJ®t¥HWºR¤+])Ò•®éJW €t¥+@ºÒ• ]éJ®t¥HWºR¤+])Ò•®éJW €t¥+@ºÒ• ]éJ®t½\ë¿‘W‚Œ)É=ÂIEND®B`‚rgl/inst/WebGL/0000755000176200001440000000000014100762640012753 5ustar liggesusersrgl/inst/WebGL/template.html0000644000176200001440000000047614100762640015463 0ustar liggesusers RGL model
%WebGL%

Drag mouse to rotate model. Use mouse wheel or middle button to zoom it.

Object written from rgl %rglVersion% by writeWebGL. rgl/inst/fonts/0000755000176200001440000000000014100762640013144 5ustar liggesusersrgl/inst/fonts/FreeSerif.ttf0000644000176200001440000355616414100762640015561 0ustar liggesusersFFTMD€µzÜXGDEFîö,…:GPOSŽÉ†Æø`GSUB, >äøú2"žÖÖÿþ""T¬¾¾ÿ„þaþbþ~þxþdþ7ÿ4jÿþìäúhà0ÿúàÿþÔìÿøÿü<0þòT„»ÿÙ_@öwÿÿ¡ÿÿwÆÿÿÆÿÿãÿýet w]ô*sÏZ"TD¿@ÿÿ;«UZUDâýøxÿÄþîÿ u€4Êñÿþ›êJKá\ÂHÉZVÖ'·L®T8Y‹W‹W§X¿[º[\ rTÄYŽWzZ½Z±S±T½Y†ÿìPQÅU„]¸\·\ÞV¤[¤^¥^¤^`¨X«ZŸY¦XŒ]£S¡MÝ8L©LL»L:IÛM¤O‚RðNìNLINÕNæNKM´MGL)LÖJÃH¿KÜLPMÎKM×MMNL LÛMåMâMëO KÁKÿKôMþMOMÿLÉM)JMËLM˜KÔLÑK“MÿÙC,(zJLÞL>LgPP¤LYÿѤL¤OðM£IœN¡MáNÑO¾N¾P¯M£P«PwÁÔ<>” $'>F%\ èÍ#\å?äF#v v &F+\\\{Í!F%”\ Í”v F%\ ÍF\v,'>F*Ív5v/Í>Í(ý°|¤üíýüíüãõ Œ!ˆ*EFFTFEFRF‰FîF1F²FFTFFFxFxF2FÃFF{FDFOFEF‚F+F±FgFgFXFXFŸFŸFxFOFFÿFEF1FxF/FQF½F=FƒFF1F1FúFõFÿgÒBÓÿ³þIþ[þIþ[þÿþÿV›IFFF–ÿ –ÿ·–ÿ‹ ÿŽ Vþ]ÿZþ»þ#ÿ þóÿ þºÃG8<8<g<§=¨<ÿåÿ<ƒ<`<«GÍ$ÅMÀP"MkMÞNáMËMÃMÓM×MJNÐM»LÃMÌMÑM®L¸&D1MDGÓLvMÒMMÈMöMÐLM¸M» MÌNÏKRÇMÔMÁMÆ!Ä! !u!Ã!Ä!Ä!¾!Ã!Ä!4Ã!Å!·!Á!À!¶!õ! !ÿÿ0!Â!s!Ä!ëÄ!å!Ä!å»!ô!FÇ!Ã!àžÅ!¢!GEE0  G öEV1211G8ö2d-k119111ý¥9q:+.Ô.)+Â;ÂMI.?>ý=SßkCÈ1;qG0‚RG1ö0¼1G-¼-ö0G--,G,Ù-G-G-1.‚1N‚öè$‚1(¼@¼@¼@ö¼@¼?ÙAN@7@¼>¼ý@¼¼¼ö¼ö$ÙAN7¼¼ý öö ¼  ÿÚöÿÚöÿÚ ÿÚ¼ÿÚ ÿÚ ÿÚÙ%Ù%Ù%"#Ù%Ù%öÙö;ö;ö;11ö:1Xö8ö;d11dG7k0Âà¼öˆ˜0Gk l*?á]*2‚?Ÿ%¼IöHÙH¼3Ÿ+¼6ö3¼6G/ß/6/G//G(G/¶ÿß*BÙAB*J¼A*N*Bà>ý>ŸQQˆ>Ù ˆ ´ Ù k Ù Ù q è öÿÜkÿÜT ö@k@¼7¼7¼Kà@ö4*NNö<G<ö;ðAdC "¼"¼" "­"Ùþ"Ù"Â&Â&Â&Â&Â&ýHÂ&Â&Ó0 0Ÿ0d%d0Ÿ4Ÿ0d%k+1+‚+Ù%Ù%öQ1+¼%ö˼¼%%ö4¼¼%ö˼¼%%ö4¼ Ó#Ÿ#Ÿ#dd#G' 3N#ˆ#*¼%1# ÿöÙÿöÙÿödŸÿöGÿ÷ ÿè1?ý?ý?1>à?ö11?ý?7?q?q?* ?4?c?‡FG6F‡8FüFGF‡8GFG6FG8FüFGF8Zö[G"Ó"G"áAdCö¼Iö¼I?Ÿ1ö*¼"ö&ö&ö&1 ö&öC1ö&‚1Ô.öé0G¦˜:˜: ; 0é0¼0Ÿ2d#‚L‚L‚2G¼OöQ‚OG2¼%ÙfÐHG6öC¼1ˆ%d2Gk0ä¿ ä ©' ™h¯ ý ôÒ¼˜ ô ûôÒ¼%›ô›ô›ô›¼ÒôÒôÒôÒôÒôc ¼c ¼c ¼c ¼c ¼, MÒ ôÒô Òô Òô Òô Òô MÿáM Ò"ôÒ"ôÒ"ôc c ÿïc ÿïc ÿïy  y  y  Ò ôÒ ôÒ ôÒ ôÒ"ôÒ"ôÒ"ôÒ"ô,ô,ô›M›M›M›M,*…3,*…3,*…3,*…',*…3c c cÿ÷cÿ÷Òô Òô Òô Òô Òô ÒôÒô°Ò°Ò°Ò°Ò°ÒÒ ôÒ ôÒôc ¼c ¼c ¼ô ÿýÒô¼%MÒ¼%'%Ò¼%Ò¼%'%Ò¼%Ò¼%Ò¼%Ò¼%'%Ò¼%Ò¼%c ¼¸ c ¼c ¼c ¼¸ c ¼c ¼MÿþðMÒ"ô'"IÒ"ôÒ"ô'"IÒ"ôÒ"ôÒ"ôÒ"ô'"IÒ"ôÒ"ôÒô 'I Òô Òô 'I Òô Òô ÒôÒô'IÒôK)K)K)K)K)K)K)K)ÒÿÿÒÿÿAAÿíA AÿúAÿíAÿäª)ª)ª)ª)ª)ª)y!y+°°°°ÿþyÿìyÿâèÿîèÿÐèÿäèÿÉèÿÄèÿ½ ! ! ÿò ÿá ÿñ ÿà ÿÙ ÿÙ,,¸3¸¸=¸¸¸ôôôôôôyÿûyÿû°ÿÕèÿé°ÿÕèÿìy èèèÿûµ)µ)µ)µ)µ)µ)µ)µ)°°èÿüèÿÞèÿüèÿ×èÿÊèÿËK)K)ª)ª) ; ;ôôµ)µ)K)K)K)K)K)K)K)K)°ÿÿ°ÿÿèÿíèÿÏèÿ÷èÿæèÿãèÿÚ\ÿì\ÿâËÿîËÿÐËÿäËÿÉËÿÄËÿ½µ)µ)µ)µ)µ)µ)µ)µ)““ËÿüËÿÞËÿüËÿ×ËÿÊËÿËK)K)K)K)K)K)K)ÒÒÒÒ°úÿ¬Lô¥ô]lÒÿÍÒÿÌyyµôvôuô] ÿæ ÿ× ÿí ÿè ÿÙ ÿèMM ôôôeôdô],,¸)¸)y0y/ |wôõ)µ)µ)µ)µ)yy(yyè!ôÁô¥M'M'ôôèèôMsMOMOMs¼+¼¼-¼+ô;ô:^(^(èoèS÷›cÜ ¸ ” ÕM?M0uš‚¼Dô¹5¹5:ÿ÷£EM+§ÿXXƒxD D ‚ôÅÿê,ÿû,9,,,ÿþ,ÿý,,ÿþ,2,2,2,ÿó,ÿû,9,,,,,ÿþ,ÿý,,ÿþ,2,2,2º7››, ô  Ò v °å"<c*#›ºè6ôÉ!—6ôô):® j ¡6 ºø&ÛžÒ"Rÿþÿ››oÔÒÛ õ!õ!—ÿùÒ"ÒŒ"f2#2-), 87¯‚;"¡îîÿûîîÿñîîÿûîîîîÿûîî$îMvŸûÒû$]ûÒ û $ c ›Òy ,B ô  6 ô  ¼ô Ä>ô.Ä>ô.Ä>ó-Ä>Ä>Ä>Ä>Ä>Ä>ñ;ñÿýÄ>ô.Ä>ó.E>EHE>ô-E>ô-ôÄ>Ä> Ä>â>â>â>â>’’- - «l«lÄ>Ä>óÝó-Ä>Ä>óÝó-Ä>H-Ä>Ä>H-Ä>H-Ä>Ä>Ä>Ä>Ä>Ä>&Ä>&Ä>&>>>>Ä>Ä>D D Ä>Ä>KÌlîK,K,ôdÉ$44·044·077É|>|>|>|C|C×>ñ>ñ>%ÿþ%ÿþ%ÿþ|U4ý>ý>ý>ý>@P@ÿëŽ>Ž>Ž>Ž> 7î7;7ÒVî7u>u>úHu>|>O>|>|8|8|86|8|>|>|8|>|>|>|8|8|>|>|3|>|>|>|>|>|>OQO>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>–4–4š>|3|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|4|4|4|4|4|4|4|4|4|4Ž>Ž>Ž>|4|4|4|4Ž>Ž>||||||||||=|=|=|=X>X>È>È>Ò>Ò>L>Æ>L>ÒÿÓÒÿÓLÿÓLÿÓ|>|>|>|>>>Æ>rlŽ>Ž>Ž>Ž>Ž>Ž>Ž>*úE×@u9Ò?0404|>|2|2|4|4Ž>Ž>Ž>|>|>|>¿4¿4|>|>|>|>|>|>|>|>|4|4|4|4|>|>|>|>|>|>|>|>úEètètèt 5¼#Ú>Ú>Ú>Ú>4%H®L® ’>’>II 7 7 7 7 7®Lô-##########yyy°y˜yyyyyyyyy°y°y˜y˜yyyyy°y°y˜y˜yyyyy°y°y˜y˜y˜y˜y˜y˜yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyhy°yhyhyyyy°yhyhyyyy°yhyhyyyyyyyyyyyyy°ùùùùùùùùùùùùùùùùù|ùù™ù#ù#|#|^|#|^#î#¬########ù#ù#ù#ù#ù#ù#ù#ù#0#7#7Ì7Ï"ù#ù#ù#øÀ#À#«#ô «#ô ô%V%î#î#%H€%H%CX2X2X2X2X2X2X2X2%C%H%H%H%" 8 77777¼3G07ŒÿþG7% %t%!õ#A#€#€$€À*%!€"%! a 5 ’ J Z ¸ ` 1 š I a ·r"¶#S"#¶#S"M7+7Ò7Ò7ŸBy<’2d]Î#Á#Î#Ô####²#%W!#¥##±#Î#ó"N$ú#ù#;ÿÿ¥$û#ø#÷#ò#î#(##A#´#######7##I#7#A#0#?#›#è#Ó#í#"#·####÷#Ã#Ä#ª#½#:#/###Ã!¯$¸#±#"#É##$i#ú#ú#÷#÷##Š##Ÿ#ˆ#ˆ"œ#œ$Ü# 8 "Ž#›#ø#ø#####################""#######~#ì#œ#ì#–#Ÿ# # #B#i#<#œ#œ#•#¢"£#Ï#s#D#D#c#c#¸#¸#j#j#ø#²#"a#"x"Ç#x"?#i$Ÿ#Ê#–"èfèPè8èèdè&è–èXèè¼è2è¼è2è¼è2è}èÕè>è«èYèèFè6èßèÂèwèªèXèƒèƒè™è™è/èCèaèŒèÇèÇèÁèÁèÿèùèLèLèfèfèwèwèmèmè‘è~è¹èqèqèDèDèíèíèŒèwèXècèOè‘è‘è‘è\è‹è‹èyèyèyè?èoèoè•è•è•èàè”ènèPè›è™èBèöè·èþèÀè³è*è èMè»èÐèˆè†èqèVèyùßèºèºèÅèzè&èðèËè€èºèkèÈèzèŒèŒèoèoèãèãèxèxè©è©èèè—è—èxèxèpèpè¿è¿èèèèèèèèè¤è¤ètètè*è*è~ètè…èxè1èvèvèvèºèºèºè¡è¡è¡èsèsèsèèèèwè èvèõèwèÉè}èÆèyè èÑèÐè?èxèíè¦èðè­è¨èkè°èsè€èÕèÆù­ù¨ùkù°úFèuôôô+ô ô ô"ôô8ôÿºMa23zôo[èÿÄ21€(€(€(€€€îÉîîÉîÉ®L€6€Ž€6€€1€îîÉî]#,, 8#5#¥3^'^0^0^=^/  ^0žržr4ÿô4ÿôî{î}DÿýDÿýRÿÿRÿÿjyjyIÿûIÿûƒ¼„0ÿê0ÿꀿE,6,,,6,3,,,XA -ÿêù•Œ¶~¶~%ÿü%ÿü{{4ÿô4ÿôœœ*ÿþ*ÿþî|î}>ÿý>ÿýìzî}XÿýXÿý½p}TÿýTÿýrrrrHÿÿHÿÿKÿÿKÿÿ·|·|XÿúXÿúµ|µ|‰ÿú‰ÿúµ‚µ‚77µ‚µ‚%ÿì%ÿì-ÿù&ÿùq‚?|¢ÿù&ÿöZ‚A|BÿïAÿö!€!€,ÿâ,ÿ⸂¸‚ŠÿâŠÿâõyõy>ÿñ>ÿñ„„ÎÿóÎÿó%%““‹y‹yCÿôCÿô¨n‚ ÿôÜÿîII¤zÔ{#uÿÙòQ耀€fFÇeKsM MZLLNKûGKKçE,KVKAI,K›@›@›@KKKKKKKFfO¢GƒK‰K£M®M(I(I(IKKKKKKšJšJšJKKKÑMÑMÑMKÑMÑMÑMÑMÑMÑMÑMKKKKKKKMM M³I¶IÃHÍM´M´M´M´M?M?M?M?MÆIÆIÆIãHðHðHðHNzLzLzLÐH<GÁHFFFKGKGKG´M´M´MGLGL}HGLGLDLGLñIñIñI)L)LûMýHHMoLoLoLÖJÖJÖJÖJÖJÖJÖJÖJÖJÖJÖJÖJ‚HóH/LxKxKxK'H¸M>M>MnM'JL1LÂLšJšJ×F×F×FÜLÜLâMíLÛPÛPÛPUMUM‘E‘E‘EÏM>P7P5PÌLäM'M:MTMTMTMÎKÎKæKAÕGÕGÕGnJnJnJMM×M×MÓH×M×M×M×M×M×M×M×M×M×MgKgKgKMMM‘H‘H‘H“LüJƒHƒHƒHOOONL™L™L™LQiIiIiIÇKÄMÇIÃKNLNLNL¬M¬M¬MøIñDL,LGGGH;HKKKÕIÕIÕIÖMLVHDHAG^H~M~M~M~M¥K¥K¥K L L LèGèGèGñH HØGØGØGØGèGèGèGèGèGèGèGïQïQïQ Y YÛMÛMÛMÛMÛMÛMÛMåMåMõMUHâMâMâMíKíM‚I‚I‚I‚IšI‚I‚I‚I‚I‚I‚I‚I J J JdJdJdJâMâMéK-MâMâMâMâMâMâMâMnGnGnG&J¬JùM$OHôGúGH#H™J™J™JÛHÛHÛHøHÛHÚIÚIÚII‚O‚O‚OíIíIíIûHôLôLôLýIDHËIýH‘F‘F‘F,I,I,I6MÅJÅJÅJpIpIpI M M M K K K K K K K K K K K K K K K N K K K K K K™H™H™H K K K K K K K K K KÁKÁKÁKÁKÁKÁKÁKÁKÁKÁKÁKÁKÁKÁKÁKÁKÁKÁKÁKÁKÁKNJNJNJÁKÁKÁKÁKÁKÁKÁKÁKÁKÁKÿKÿKMÿKÿKÿKÿKÿKÿKÿKÿKÿKÿKÿKÿKÿKÿKÿKÿKÿKÿKÿKÿKÿKÿKÿKÿKJJJÿKÿKÿKøH…JJ%J666þMþMúHþIþMþMþL¼I¼I¼IÓMIJIJIJ­I­I­I²P”E”E”EþMþMþMOO$OOOOOOOIOOOOOOOOOOOOOOOOOOOOOOOOOJ›J[KÉMÉMöJÉMÉMÉMÉMÉIÉ=ÉKÉMÉMÉMÉMÉMÉMÉMÉMÉMÉMÉMÉMÉMÉMÆMÆMÆMÉMÉMÉMÉMÉMÉMÉMÉMÉMÆMÆMÆMÉMÉMÉMËLËLÊHaIaIaIËLËLËLËLËLËLÊGÅIÔM]J]J]JŽI„JeJDJJMMMMMMM-H-H-HMMMMMMMMMM˜K˜K£M˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K˜K:T:T:TÔLÔLÞIëLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÈLÈLÈLÈLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLeMeMeMÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLÔLýJúJÞF¨KðLeKÎKÎKÎKÞMeJeJeJÑKÑKÑK)J)JFL6J6JMMMF9y¡(ž&MMMMMK%C D%KMFMMKBMMMMMMMMMM MMÿLÿLÿLÿLÿLÿ½þúþÏþ ÔÿöZ úiÿôÿòÞÿû\ÿþ'ÿñ¨ÿÿR=ÿÜ8‘>Ôo ÄYÈÿò2×Uÿô›ÿýdþú'ÿòìÿìgÿîC’DhþúUÿþñÿýÓÿètÿðÿôÿÿáÿïÌÿñÄÿóOÿñàÿñÎÿýÿñÿíóÿñ'ÿóÝÿþÞÁÿÿÿÿôþÿêh»ÿî ÿìÿñÿð ÿñûÿÎ éÿð£ÿú8¸ÿýøîõÿðîòÿöîÔÿöïÿó:ÿú”ÿõ:ÿúŒÿú|ÿðõÿúrÿñäL3äwä×ÿýÿñEÿö•ÿì•ýÿþþÿþÿþ÷ÿþ+\“““ÿ¶˜ÿÿWŸÿýq!:!„2ÃÿãÿÿÿÏ imee ²p²pŸÿ[ÂEüü'ÿý¡ÿýzÿï'ÿý$111EÞÿã#ÿòÃÿò#ÿòXÁ'I'Ïÿý'ÿþ'ÿþt66Ï6ÚÂp˜%%NÀÿôLÿôŸë êÿþ¬ pckÿý..B»ÿîÿö»ÿý&ÿüÿýõÿý—ÿýìÿñ<ÿý8>jÿýLUÈU;ÿýžÿýìÿñ%%Hÿù$ÿòððjÿþjÿþ;-@ÿòBÿòBÿò§ÿίéûÿÎÿÎûÿÎüšÿã·ÿæúæŒÿì@ÿì/ ÿìSÿþLÿô€)44ò4òò…zº”¤ 룗ÿþ?£U:ÿúä×ÿý˜ÿÿÄÿýOÿöžÿÏ Â'ÿýÝ ˆî'ÂÿòÅÿüÿñÈøûÿÎÿþú£¯ÿõsÿõÁ¬qOÿöOÿöóŒ©ÿÿ^ÿÿò舓C˜˜ê§ä¡ˆÿý?ÿý»ÿý;ÿýÖŒ ÀÔÿÿÿÿj.ñÿùÖÿΔÿÎÏÿΚÿÎÕ*Ëÿÿ…ÿÿÓNN¹F…ÿýCÿý…ÿý»ÿýÙÅWÿòm"ÿì¯:ÿúåä×ÿýɘÿÿÄÿýOÿö'ÿÿ*žÿÏ” ŸÂ'ÿýÝ ÞÁ'Àÿôc»ÿýìÏ®ûÿÎÓ £ ¤Õ»ÿý»ÿý>%ZM+[Mÿøþhžÿ¦þŽqÿµþ{»ÿ¹þýðþ15ÿEþwÂÿòþþ˜þáþf;ÿ–$ÿ+*ÿ–ý÷ýùýÞýïþf\Êþe:ôoÇ ô.·ÿæñÿýòÂÿòÂÿÄxÿÄet ]ô*sÏZ"TD@ÿÿ«;¿  M©)F S!ùŽŠAôEÞ:fùͳ@ì` ÇŸœµ;Jë¶ÃŸs91wUZU1¼þbþb â Æªª~ö357²¿ÇËÏÝîEauz~ŠŒ¡Î×áò†õù²¹¼ÀÃêô :KQikt~†˜¯ÌÔ°    5 9 E I M P ^ p ƒ Œ ¨ ° ² ¹ Ä È Î × Ý ã ú  ( 0 3 6 9 < B H M \ ^ p t ƒ Š • š œ Ÿ ¤ ª µ ¹ Â È Í ×   ( - 0 2   ( 9 C H M W a p ƒ … ‹ ‘ ” œ ž ¢ ¥ « ± » ½ Æ Ê Ô Ö Ù ß:[ÅõFHMVX]†ˆ®°µ¾ÅÎÖîFZ|")…‡›ùEMWY[]}´ÄÓÛïôþ  # & K q | Œ © ¬ ¯ ² Ý!!!! !$!(!.!3!9!!¨!®!·!Ý!à!â" """/"="K"W"Z"\"§"¯"¸"½"È"ñ## #####*#H#P#W#^#®$#$i%K%m%%•%¡%²%¶%¼%À%Æ%Ì%×%å%ê&&&& &#&&&(&*&,&c&f&q'' '''K'M'R'V'^'g'”'¯'¾00000”0™0›0üöAö¾öÃöÜøþûûû6û<û>ûAûDûNûYû}û‹û•ûÿýòýüþpþtþvþxþzþ|þþ’þÁþÅþîþüÿýÿÿ  ø&57P¹ÆÉÍÔî`tz~„ŒŽ£ÐÚðˆø±´»ÀÃÐð !AM`kt~†˜¯ÌÔ€      7 < G K P X ` … “ ª ² ¶ ¼ Ç Ë × Ü ß æ    * 2 5 8 < > G K Y ^ f r ‚ … Ž ’ ™ œ ž £ ¨ ® · ¾ Æ Ê ×     * 0 2     * > F J W ` f ‚ … ‰ ‘ ” ™ ž   ¤ § ­ ³ ½ À Ê Ï Ö Ø ß? ÐHJPXZ`ˆŠ°²¸ÀÈÐØð Ha  )„‡  HPY[]_€¶ÆÖÝòö   & 0 p t    ¬ ¯ ² Ý!!! !!"!&!*!0!5!S!!«!°!º!à!â"""%"4"@"M"Y"\"`"©"²"º"À"Ë##### #)#G#P#W#^#®$#$`%%P%€%”% %²%¶%¼%À%Æ%Ê%Ï%â%ç&& &&&"&&&(&*&,&.&e&i''' ')'M'O'V'X'a'v'˜'±00000A0™0›0¡ö9ö¾öÃöÙøæûûû*û8û>û@ûCûFûVûzûŠû’ûüýòýüþpþtþvþxþzþ|þþŒþ•þÅþÉþûÿýÿÿÿãÿÂÿÁÿ¿ÿ¹ÿ¸ÿ·ÿŸÿ’ÿ‘ÿÿŒÿ|ÿkÿQÿ?ÿ;ÿ8ÿ3ÿ2ÿ1ÿ0ÿ/ÿ-ÿÿÿÿÿ þhþgþfþcþaþUþPþ9þ+þ(þ'þ!þ þþþ þýùýèýÒý¶ý¯ýû´û³û²û±û°û¯û­û¬û«û©û¢û¡û‘ûûŽûŒû‹ûŠû‡û…ûƒûûyûuûtûrûhûdûbûaû`û_û^û\û[ûWûUûJûIûBûAú4ú3ú0ú/ú,ú+ú*ú'ú$ú!ú úúúúùåùäùãùâùáùßùÞùùù ù ù ùùùøûøóøïøÞøÝøÚøÕøÓøÏøÎøÍøÌøËøÊøÉøÈøÆøÃø¿ø¾ø½ø¸ø—ø“öOöEõ;õ:õ9õ8õ6õ5õ4õ2õ1õ0õ.õ-õ,õ*õ)õ'õ&õ%õ$õ#õ"õ õõõë•ë“ë’ë‘ëŽë‚ëëyë"ë ëëê¨ê¤êžêœêšê˜ê–ê•ê”ê“ê’êêêŽêŒê‹ê‰êˆê{êyêxêvêmêIêGêEê2ê0ê.ê,êéÞéÝéÚéÙéØé×éÖéÕéÔé»é«é©é¨é¦é¤é£é†é…éƒéé}é|é{ézéwévétéséqéoéaé[éWéNéIéDé(é!ééèÆèRèç€ç|çjçgç]çMçJçEçBç=ç:ç8ç.ç-ççç çççççççæÿæýænæmækæjæiæhæeædæbæTæQæPÞÞ Þ Þ ÝàÝÜÝÛÝÖšüûú×ÖÕÔÓÒË«Ÿ™3A8ÅÂÁÀ¿¾º°®«¨œœš RSTUVW   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a†‡‰‹“˜ž£¢¤¦¥§©«ª¬­¯®°±³µ´¶¸·¼»½¾ ˜rdei šx¡pk úvj ׈š £s Û Ügw ˆ – ”ð ®l|Ù¨ºcn ŸT Å Œm} œb‚…— Œ ” • ‘¹ Á: ± Ü ¦ §üý ™y ’ – „ŒƒŠ‘Ž•–”œ›óXhqdefzigY!yXXXX ìLà¨l˜ä0ø `x¤ÄX´4làHx x Ä $ L t ˜  Ä ( Ä ” xü|À¬xàD¼DÔX¨x¨ t¤Àì,Tð`Ä@œÔP°´ü¨ lì X À!L!¤" "l##$ $T$¸$Ô%<%€%%à&d'(' (0(X)()p**++8+H+ü,,`,”,ð-`-ˆ-ì.T.€.Ì//P/Ü0T0ô1œ22,2D2\2t2Œ2¤3P3ì44444L4d4|4”4¬5,5D5\5t5Œ5¤5¼5ð6t6Œ6¤6¼6Ô6ì7l7ü88,8D8\8t8Œ9`9ü::,:D:\:t:Œ:¤;;œ;´;Ì;ä;ü<<,<ˆ<ø==(=@=X=p=ô> >$><>T>l>„?H?`?x??¨?À?Ø?ð@@ @Ð@àApAˆA A¸AÐAèBBBœB´BÌBäBüCC,CDC\DEE4ELEÜFhF€F˜F°FÈFàFøGdGìHHDH\HtHŒH¤H¼HÔItIŒI¤I¼IÔJ`JÜJôK KxKÐKèLLL0LHL`LxMMˆM M¸MÐMèNNNÄOXOpOˆO O¸OÐOèPPP0PHQ QØQðRR”S$S<SÀT T„TœT´TÌTäTüUU,UDU\UtVVV¨VÀVØVðWW W8WPWhW€W˜WôXtY0Y@Y¼Z@Z¬[[€\\\¨]] ]´^0^@^À_<_¨`H`ÜaŒaÌb bÀc`c´d@dðedeàeðf€fôgœh0hÄiPiØj\jèjøklkèlHl¨mm”n n4n¤o$oÀp$p|pŒpèqDqÔrDr´s sœtt$t<ttt„tœt´tÌtätüuu,uDu\utuŒu¤u¼uÔuìvvv<v\v€vœvÀvÜwww0wHwdw„w w¸wÐx\yDy\ytyŒy¤y¼yÔyôzz,zDz¨zÀzØzð{{{Ä{Ü{ô|||,|D|T|l|„|œ|´|Ì|ä|ü}},}D}\}t}Œ}¤}¼}Ô}ì~~~4~L~d~|~”~¬d€$€¨4Ld|”¬Ää‚‚ ‚<‚T‚l‚Œ‚¨‚À‚؃xƒÄƒØ„P„d„Ø„ì…x††ˆ† †´‡d‡tˆˆð‰x‰ÔŠ€‹‹xŒ Œ¨Œ¼@ÐèŽ,ŽlŽìlÀDX‘‘À’H’Ø“<“L“ü””•(•<•P•Ø–D–¼——t—ä—ø˜¤™™p™ÐšTšhšÄšÜ›H›X›l›€›”œœtœðLÜžHž¸žÌŸ4ŸLŸ\ŸpŸø   ¤ ð¡|¡ø¢x£$£ø¤Ð¥h¥ü¦Ð§ ¨4¨¤©¨ªª¤«L«¸¬4¬”¬¤¬ì­4­|­À®®(®L®h®”®Ä®Ø¯ ¯@¯d¯„¯¬¯È¯ü°(°p°¨°ô±4±D±X±l±€±”±¨±Ä±Ø±ì²²H²\²p²„²°²ø³8³Œ³¼³Ð³ä³ø´D´t´¨´Ì´ðµ µTµ˜µ¼µÜ¶¶ ¶p¶À¶ì·8·€·À·Ô·è¸¸4¸¬¸Ð¸ô¹(¹\¹¬¹È¹äº º\ºtºº°ºÐ»»4»\»Ä»ø¼8¼`¼`¼`¼ ¼ ¼ü½,½x½À½ð¾¾L¾\¾ˆ¾ ¾¸¾Ü¾ô¿ ¿$¿<¿T¿l¿„¿”¿¤¿øÀ$À4ÀDÀTÀàÀðÁÁhÁxÁˆÂ €ÂÂäÂôØÄDÄTÅ0ŰÆ$ÇÇÇ0ÇHÇ`ÇxÈ È¬É$É´ÊHÊðËXËÔÌ̈ÍÍtÍÈάμÏDÏÀÐ`ÐÈÑ8Ñ Ò8ÒÀÓHÓôÔ Ô$Ô<ÔTÔlÔüÕ¨ÖTÖlÖ„Öô×¼ØtÙÙŒÚÚ˜ÛHÛÜÜtÝ$ÝÈÞTÞ¤Þ¼ßhààlàÔàäàôá ááÄâtâøã¼ä\ååˆåìæ\ççHçÈè8é8é¼êDê\êüëhëØìTì¼í íŒíôîLî¸ï€ðð˜ñ ñ ò<òÀótóðô\õ õ”ö(ö°÷$÷x÷äøHù4ù úú4úÐû4û üülüÈýTý´þ þ€ÿ(ÿ¬Œ$Ä<à\¸L¼0ÐlÌ<L\t„ Ð \ t Œ ¤  Ô X ð ¤ `|̈L(@Ô¼Hà@¬ü,Ð|¬Ì° 8 ´!!$!d!ˆ!¬"à#ˆ$T%%”&&œ'4'ˆ'Ð(0(ˆ)()¸*Ð+Ì,ˆ-L-ü.¤/T/ø0¬1X22¬383¼4H4Ì5€6(77È8\99X9¸9È:4:¸;4;à<|<ô=l=ð>t>ü?ˆ@@xAA¨BŒCHCXCpCˆDDDüEtEìF|GGHH”II˜JJ0JHJ`JxJJ J°JÈJàK@KTKlK„KœK´KÌKäLDLœL´LÌLäLüMM,M„MÜMôN N$N<NTNlN„NœN´NÌNäNüOO,O¤O´PPPôQlQàR„SSœT@TôUˆVVŒWWX$X|X¨XìYLYdY”YÀZ ZLZdZÌ[´\\”\ô]Œ]ü^Œ^ø_°``\`ÄaTaÀb„bäcDcÔd¤e,eÈfgDhhxi„j,jük°lLl„làm(m„mün\n¼nÔnìoooDoœppqq˜rr¬rüs\s¤süt upvv°ww˜xx”y,yôz€zè{X{È|(|| }8}€}Ä}ð~T~|~Ü~ø(€€€ŒxÄø‚h‚¤ƒƒ|„(„œ…8…´…܆0†¬‡d‡ìˆˆ‰,‰Š Š|Šì‹„Œ@xŽ Žìhä ‘ˆ’$’Ø“¤”h•€•ð–`—@—䘰™H™Øš¼› œ8œÐœž(ždžÄŸŸ|Ÿà ˜ ô¡|¢$¢ˆ¢Ì£8£\£”¤Œ¥œ¦T§<§ø©ª ««4«Ð«è­,®Œ¯\°(°¨±\²²¸´(´Äµ¤¶d··¤¸L¸ì¹lºº¼»„¼8¼¤¼¼½0½ä¾Œ¿¿|ÀÀ”À¬Á`Â8ÂPÂìÃhÄÄàÅÅ´ÅðÆhÆØÇDǬÈȘÈðÉ0ɘɰÊʨÊØÌHÍ,ÎΨÏXÐÐÌÑ”ÓÔdÕ ÕìÖÖlÖÐׄØ$ØÐÙ`ÚÚÔÛxÛüܤÝÝpÝäÞpÞðßœàládâ8ãã¸äLäøåÜæ|çXçÜèpééœêLê¨ëPì4ì´í´îXï ï„ïìð€ñ ñœñìò`ò¼óLóôô@ô¼õ8õ öö°÷\÷ðø„ù ù<ùÌú(úˆúüû˜ûüü8ü°ýý°þLÿ(ÿLÿìHðpä Ð4”l¨ @ ´ X  h à  € °  ´ èX´lø(@Xpˆ 0HÀ €„àtÀP¼,„|ôlÌ$xà0œ øP L|ðLœ´Ø $ l ” Ü!!T!„!Ô""|"ø#`#ä$l$´% %l&&ˆ&Ô'€'Ø((ˆ(È)<)Ø*Ü++ø,à./Œ0`0ü2p3(3ä56h7ì88°9|:;\<„<À>@? ?Ì@ÔA(AŒBBˆC(CðDØE¨F|GèHÜJJˆJøK`K¬LTM MàNìOOO4OlPPP QQ¼RlS0TPU(VpWX$X´YpZ(ZÈ[|\t\ì]¼^$^ô_°`8`Üa¬b<ccÄd8dØe f€g@gèh`hèiTiÌj\kk¼ll¨mm€n˜oàp˜qÜr|sœt„u8uävÈwàxŒyˆzÀ{x||€}}Ð~,~Øà€Ì¬‚ ‚xƒ(ƒð„¼…\…¤††¤‡‡x‡ðˆ ‰T‰ÀŠtŠà‹@‹ŒPŒà@ÜŽ,¼T¸‘ ‘Œ’’“,”•T–°—D—ˆ˜™Lš4šˆšð›H›´œ œÜpžžpŸŸ4Ÿˆ ¡¢l£´¤p¥T¦ä¦ä§ø©,ª$«h¬h­È®ð°Ä²€³<´0µH¶h¸\¹ˆº4»0¼,½X¾\¿DÀ(ÁlÂ4ÄÅHÆ<ÆüÇøÈàÉøË4Ì8ÍDÎ`ÏÏ„ÐÐhÐôÑlÑôÒPÒÀÓ\ÔÔÐÕ8ÕÐÖ„××¼Ø ØøÙ|Ú(ÚÜ۴܄݌Þ|ß|à´á€âlã@ãÐä|ååŒææ°çç€çäèHè¬éé¬êDêàëtììœí8í¬î`ï$ïàðˆñ8ñÄòxóóÀô$ôXô¼õõpõðöTöœ÷÷,÷èø4ø¼ùTúú„ú¸ûdüü<ü¬ýPýxýàþþˆþðÿ0ÿȈ@ìÌhX äˆ \ Ì X ä ¨  Èdôhä¼HØ\x$dÄL|œ8¨@øtÌœ4¼ p!!x!ô"˜#d#ä$Œ%<%Ü&T&Ð'¨(D(à)|**˜+H+Ä,¤-P.@.Ô/¤00Ø1d22t2ü3ì4l55ä6À7`7ð8¼9L9Ô:˜;p<<Ô=|>`>ð?¨@tAAÈB¤C´D¬E FÐHHøJ K(LMxN¬PQ`RlSÄTÈU´W(X YdZ¬[¬\Ø] ^”_ä`ta,aÄb˜cld4e$fPghiiäjÜk¤l|m|n˜oðq4rDs tävwxŒyÄzà{ì|ü~(X€¨‚ƒt„І0‡ˆ‰,Š”‹ì\ŽÐt’<”•ä—¸™lš ››àœŒlž<žÀŸ¸ Ü¢8£t¤Œ¥Ô§¨©hªX« ¬À­Ø®ð°±²t³¨µ(¶”¸¹ˆºÜ¼°¾P¿0ÀHÁpÂTÃTÄ4Å`ƤÈÉ<ʈ˸ÌXÍ0ÍìάÏxÐ<Ñ0Ò@ÓhÔ¼Ö×|ØÔÚ ÛŒÝdÞ,ßààÔáÜâðã¬ääåÌæäçüèÌéÈêÈë¤ìÈíôï ð@ñdò¼ôDõÌ÷øpùäû0üøüøþÐx4Ø¼ÜØÄÈ ä ¬ <   ¬¸pÌÌȘX¸$ˆ´Ä ø"Œ#,$%%¬&¸'(t)T*œ+ø-.//è1d2„3ä5\6„7°8ü:;l=>¸@˜BC¼EFÜH´IHJJÄK€L@LèMNO”PˆQˆRxSTØVWHX€Y Z¬[À](^h_L`ˆa8bcldÜf|gØi0jül8m°o@p<qXr„s¤tÄuøvÐxLy0z8{L|8}@~P€\‚‚øƒ¸„œ…t††ôˆˆøŠ0‹DŒ\˜<ôè‘à’¼“¤”„•x–€—˜™Tš¨›$›üœ°ž4žàŸŒ¡¢\£°¥¦0§À©`«¬¤®¯@°è²L³äµX·\¹ºÈ¼d½¸¿œÀÀÀäÁdÁ´ÂL¤ÃÃhÃÈÄ(ÄÜÅ Å”Æ@ÇLjÈ<ÉÉ É8ÉPÉhÉ€ɘɰÉÈÉàÉøÊÊ(Ê@ÊXÊpʈÊ ʸÊÐÊèËËË0ËHË`ËxË˨ËÀËØËðÌÌ Ì8ÌPÌhÌ€̘̰ÌÈÌàÌøÍÍ(Í@ÍXÍp͈Í ͸ÍÐÍèÎÎÎ0ÎHÎ`ÎxÎΨÎÀÎØÎðÏÏ Ï8ÏPÏhÏ€ϘϰÏÈÏàÏøÐÐ(Ð@ÐXÐpЈРиÐÐÐèÑÑÑ0ÑHÑ`ÑxÑѨÑÀÑØÑðÒÒ Ò8ÒPÒhÒ€Ò˜Ò°ÒÈÒàÒøÓÓ(Ó@ÓXÓpÓˆÓ Ó¸ÓÐÓèÔÔÔ0ÔHÔ`ÔxÔÔ¨ÔÀÔØÔðÕÕ Õ8ÕPÕhÕ€Õ˜Õ°ÕÈÕàÕøÖÖ(Ö@ÖXÖpÖˆÖ Ö¸ÖÐÖè×××0×H×`×x×ר×Àר×ðØØ Ø8ØPØhØ€ؘذØÈØàØøÙÙ(Ù@ÙXÙpو٠ٸÙÐÙèÚÚÚ0ÚHÚ`ÚxÚÚ¨ÚÀÚØÚðÛÛ Û8ÛPÛhÛ€Û˜Û°ÛÈÛàÛøÜÜ(Ü@ÜXÜp܈Ü ܸÜÐÜèÝÝÝ0ÝHÝ`ÝxÝݨÝÀÝØÝðÞÞ Þ8ÞPÞhÞ€Þ˜Þ°ÞÈÞàÞøßß(ß@ßXßp߈ß ߸ßÐßèààà0àHà`àxàà¨àÀàØàðáá á8áPáhá€á˜á°áÈáàáøââ(â@âXâpâˆâ â¸âÐâèããã0ãHã`ãxãã¬ãÈãääää8äTälä„äœä´äÌäääüåå,åHå`åxåå¨åÄåàåøææ(æ@æXæpæˆæ¤æÀæØæôç ç$ç<çTçlç„çœç´çÌçèèèè8èPèhè€è˜è°èÈèàèøéé,éDé`éxé”é°éÌéäéüêê,êDê\êtêŒê¤ê¼êÔêìëëë4ëLëdë|ë”ë¬ëÄëÜëôì ì$ì<ìTìlì„ìœì´ìÌìäìüíí,íDí\ítíŒí¤í¼íÔíìîîî4îLîdî|î”î¬îÄîÜîôï ï$ï<ïTïlï„ïœðTðøññÈñàñøòò(ò@òXòpòˆòœò¬òøó8ó¤ó¼ôHô`ôxôô¨ôÀôÜôøõõlõÄö@ö¤öð÷€ø ø$ø<øTøløˆø¤ùù|ùøú„úøû°üdü|ü”ü¬üÄüÜüôýý,ýHý¨þþ4þLÿÿ4ÿLÿdÿ€ÿœÿ¸ÿÔÿìddd|Œœ´ÌÜHŒÌˆüpôxP|”|´    Ð è  , x Ä d |  0 € Ð øHd„à<Tl„´Ì t¨t¤,@h€¤0DXl€”¨¼Ðäø  ä hðÄDÄÜäp” xì¸!!Ä"p##´$ˆ%@&,&¼'L((¼)°*D*Ð,D-H-ü.˜/H040à1\1¸1È1à2˜2¨2¸4$4Ä5$6<77¤8È9 ::€:ä;8;P;p;ˆ;¨;È;è<< <8H>X>ä?”@hA0A@BBôCCC$C4CDC\C|C”C¤C¼CÜDDD,DDDdDtD„D”D¤DÐDüEE$E`EœEÈEøF F F`F G GxG¸GøH H H\HpH¤HÀHÔHèI0I˜JJŒJÜKK8KhK˜KÀKèL,LpLÄMM<M`M„M¤MÄMèNN(NpN¸OO@O€OÀPP4PlPÈQ8Q”QÌRR<RtRÄSSTS˜SÜT TdT¨U<UÐVV$V\V´W0WhWÔX`XˆX´XôYlYÀZZxZÐ[,[„[Ð[ì\$\h\|\˜]@]Œ]¼]è^^^¼_L_l__È``,`p`”`À`øa4a bˆcàd˜eäf@fœfàgXgŒgÜhdhÜiiXi˜ièj<jPj¸kk„ll|mmˆn,n¨ooLoŒoàp<p˜pøqXq´rrTr”rØssPs¤sättLtŒtÌu(uˆuÈvvw$wpw¼xx|xðyhzz¤zä{${œ||h|¸}}t~~¸<¸ô€0€”€üDŒ‚‚|‚؃4ƒŒƒè„@„h„„Ä„ø……@…¨…ø†d†¸‡‡ŒˆhˆÄ‰‰X‰Œ‰ÔŠŠ<ŠPŠxŠœŠÀŠð‹$‹d‹ ‹äŒ,ŒxŒØ0h ŽŽlޏŽÜH€ °ÀìD¼‘,‘\‘Œ‘Ü’ ’`’È“0“˜””L”¤”è•,•„•Ü–(–x–°–è—`—Ô˜x™™|™Øš šhšè›lœœÈhÈž,ž˜ŸŸxŸè Œ ü¡ ¡@¡`¡€¡˜¢4¢„¢˜¢Ø£ £H£p£ä¤X¤Ð¥H¥¨¥È¥ø¦„§D¨4¨Ì© ªx« «ð¬À­|­˜­´­Ð­ì­ì­ì­ì­ì­ì­ì­ì­ì® ®,®L®l®Œ®¬®Ì®ì¯ ¯,¯L¯l¯Œ¯¬¯Ì¯ì°°<°h°”°¼°è±±<±d±Œ±¸±ä² ²8²d²Œ²°²Ü³³,³T³€³¬³Ð³ø´$´P´x´ ´Ì´øµ µPµ€µ°µà¶¶@¶p¶¤¶Ø· ·@·p· ·Ð¸¸0¸T¸|¸¨¸Ô¹¹4¹`¹¹¼¹èººHºtº¨ºØ»»H»x»¨»è¼¼L¼Œ¼À¼ð½0½x½¼¾¾<¾X¾t¾¾¬¾È¾ä¿¿¿8¿T¿p¿Œ¿¨¿Ä¿Ü¿ôÀÀ,ÀHÀdÀÀ¬ÀÈÀäÁÁ ÁTÁ °ÂàÃ$ÃhèÃèÄ8ÄxĤÄÐÄìÅÅÅ4ÅhÅ”żÅ䯯lÆèǔȜȬÉ(ÉDÉTÊʬÌDÍÐÏ ÑlÒÈÓ<ÔØÕ(ÕdÕÈ×לØ@ØpجØèÙ,ÙhÙ¬ÙðÚ<ÝÝÈÞxÞøßìà\àÌáââ¬ã<ãÈälåæDæÄç<çÜètéPêêüëŒìXìØíˆîØïtð¬óó¼õtö¸÷ŒøÜú´û ü8ýý|ýøþœþìÿ„ÿÐ0|Ð0È0$ܰ€\P 8 ø Ü @ àd ø´tØp´èд@„Àì@¤,°<ÄÔDÈ l¼H¸XÄ  ` Ä! !À"p"ä#€#À$$´%Œ&È'œ(à)Ü+Œ..ø00à22Ü45<67D8X8°8ä99L9|9È9ä:::p:À;,; ?@@d@øAÄB0BÔC„CôDœE<EØFLFôG°H0HÔIœJJÜK¤LXL M$MÌN$N˜O0O€P P°Q(QTQ€Q¨QÐRRlRR´RøS`S„S°SàTTHTT´TäU(UlU°UðV4VtV¼WWLWüXlXØYLYÄZ Z”[$[ \@\è]X]|]¼]ä^X^Ä^ì__P_Œ_¬_È_ø`(`X`„`´`ÜabLc°dteHeÔfdg\hPiÜkllÔn„oüqÄrTs$tDu¼vtwˆxœzz„{P|X}¸~ø€Œp‚ ƒÌ…L†0‡ˆˆˆ„‰`Š‹ ‹°ŒŒäŽèD‘À’`“Ì•x——虚,›@œ¨ôžxŸP ¡ˆ£\¥¦@§P¨ ©°ªÐ«¸¬´­Ð®è¯°°|±X²²ì´(´Øµø·,¸P¹Ü»»Ø»ð¼D¼T¼ð½¤¾@¾ô¿ðÀäÁèÂÜüĬŬÆøÈÉpÊ<Ë\ÌHÍŒÎLÏdÐ`Ñ´ÒdÓdÔ$Õ<Ö`×ÐØlÙ`Ú4ÛdÜXݤÞlß8à\á`â¼ãHä$äð唿\ç|çôèˆétê8êäëììÈídîXï$ï ðpñ òôTõøö¨÷Pøø°ù¬úûxüüäýäþÜÿ¤d4°”DLT4È   Ô ì   4 D ˜ ¨ ¸ È Ø è ø   ( t ´ h °Ìä„dœ¸ð(H|Ì8pŒÄä T¤Ø€¬h`x°Ðè0H`x¨ÀØð 8Ph€˜°Èàø(@XpìhÀÄxì `!! ""˜##¤#ð$<%X&@&ˆ&Ì&ø'X'€'à(@(¨(Ô))p)Ì**D*¬++\+¤,,Œ,ä-<-Ì.„.Ô/$/¤0P0˜0à1l2 2x2Ð3 3p3Ì4(4p4¸55\66¤7$7¤8|9T9ü:¤;<;Ô>€>ü?d?Ü@P@ÜA0AœB B¸CCD(DÀE@EÀFpG G¤H(H¸IHI¸J(JˆJèK$K`KÐL@L¤MMtMàNNXNÀO(O´PLP¸Q$Q¸R RŒSHS|S|TT´U°UÐVpVÔWÐXÜY”Zˆ[P[ä\¸]¤^t_¬abcDdte¨fähdjkldmäopdqðsLtÐvˆwœxÌz4{p}$~x€Ð‚ä„…|†€‡¸‰<Š‹Œ`”Žü¨‘¸“”|•Ø—™t›˜œôž„ \¡ø£,¤¦8§°¨äªT¬¬È­À®ˆ¯4¯ü°”±”²h³t´µ„¶$¶ü¸ ¹¹¸º¤»Ä¼Œ½¤¾ôÀpÁ˜¬ÃøÅ€Æ(ÆèÇðÈŒÉXÊ`Êô˼ÌÀ͸ÎàÐHÑÑðÒÈÓäÔÌÕÈ××ÔØÜÚÛÜ<Ý<Þ(ß0à,áhâÜäxååÐæXçèéêPëœììîïˆñPòdóœô¼õ´öèøHù”ûüXþÿðØà ð , t¼è@|@¤HtÜØ p!È#8$ü&è(¬*4,-Ü/T1 2ô3œ4x5 5ä6t7@808¬9h:L:à;¬<Œ= >x?¬AB´DEˆGLHDIpJäLLèMèO(P0QlRtS„TÈVHW(X`Y|ZÄ\D]€^ø`¬aÄbÈdexfÐhiœkhl¨n0oÔqTr¼tXv0wx,y€zH{({ô}~$L€¤ìƒœ„ІD‡ìˆ°‰´ŠðŒŒäð t‘¸’„“”Ô•ô–´—¬˜à™ø›LœØ¼žà (¡x£¤,¥ˆ§¨l©°«¬¤­Ð¯0°Ð²8³d´È¶h¶ø·´¸\¹ºº°»x¼„½X¾¾ô¿ÀœÁ< ÃÃÐÄðÅÀÆÌÈÉ Ê€˰ÌôÎ|Ï”ÐàÒpÓÈÔÄÖ ×|Ø ØØÙÌÚˆÛ€Ü<ÝhÞLßHà„áTâXãœä¬å@æ ç$çÀè¤éPê\ë,ìíîï€ðdñ¤òøó¨ô˜õ¬öˆ÷Ìøpù@úPûûàüèþþÜÿØ   ü , ” 0 ð Ü ¨ X P ä Ü ˜ d l ¨ 8    < ¤ 8 ü ” ˆ 4  8   , !4 "¤ #` $0 %@ %ä &¼ 'Ð (¤ )d *` +˜ , ,ð -è .À /Ô 1 1ì 2ø 4< 5P 6X 7¨ 9 9Ð :´ ;È <ì >, >ô @ AL BH Cd D” E¸ F Gx H¨ Ih Jl K  L` MT NŒ OD P4 Qd R\ Sˆ Tø Uì W X„ Y¤ Z [À ]$ ^ _ ` a b\ c¨ dÌ fT h ið kÀ lÐ n$ o´ pô r sP tÌ v w¼ xÈ yì {X |0 }H ~ˆ Ì €À ô ƒX „€ …Ü ‡t ˆ4 ‰ Š ‹8 Œ Ž$ ŽÐ ¤ P ‘d ’, “ ”, ”´ •| –h — —ä ˜ì š$ šÈ ›¤ œ° ˆ ž žô Ÿü  Ü ¡ð £L ¤< ¥\ ¦X §¬ © ªŒ «ü ­œ ¯d ±, ²$ ³T ´¼ µô ·L ¸¸ º »´ ½t ¿\ Á, Â@ Ãh ÄÌ ÅÈ Ç Èx ɰ ʬ ËÜ ÍP Έ Ïd Є ÑÌ Ò” Ó` Ô( Ô´ Õp Ö Öô ×ô Ù Ú ÛL ܰ Þ Þ° ß” à| áD áР☠㜠ät ål æx çp è¤ ê ë| ì ìà íè î¤ ïœ ðÀ ñx òh ó˜ ô| õ  ÷ ÷¤ øt ùˆ úX û` ü¨ ýH þ þ° ÿ@  ì  \ è ¸ ¬ ¤ ´ ¸ ” ´ ø  D à  0 ( 8 ˆ p Œ ô   @ ¨ ¼ " #Œ $œ & '€ (ì *4 +È -œ .Œ /¬ 0¬ 1ü 3\ 4Ð 6@ 7à 9¤ ;d = >x @( B C DT EÔ G Hx I” Jä Lx Ml N° P( Q€ S T° U¨ Vä XT Yt Z [ô ] ^¬ ` aŒ bˆ cÀ e0 f g@ hœ i| j€ k` l” mÐ o pt qÈ sD tð vœ x8 yˆ { |ì }ü T €Ü È ‚ð „X …` †œ ˆ ‰8 Š€ ‹Ø $ ŽÐ  ‘œ “X ”, •< –| —„ ˜€ ™ šè ›Ð œø ž\ Ÿ€   ¡à £l ¤l ¥¨ § ¨ © ª€ «¤ ¬l ­` ®˜ ¯´ ± ²œ ³´ µ ¶˜ ·ì ¹4 ºÀ ¼t ½„ ¾Ì ÀX Á„ Âô Ä´ Åd Æ4 Æð Ç  Èh Él Ê ÊÜ Ëì ̼ Í` ÎT Ït Ð| Ѽ Ó@ Ô4 Õd ÖÄ ØL Ú ÚÔ Ûð Ý Þd ߨ áL âì ä€ åT æx çÀ èÔ ê ëT ì¼ îH ïø ðä ñè ó( ô$ õ@ ö ÷h ø| ùÌ ú¤ û¼ ý ýä þð 8 8 h à x D è À Ô ( ¼ Ü , Œ  „ Œ 8 ¤ D Ü h € , Ì < ˜ è € Ð T ¨  Ä  ˜  Œ ¬ 8 ¬  ¨ @ Ü d ø  ˆ ä Ô œ h D  ´ !¬ "ä #Ð $¼ %Œ &4 &Ü '° (ˆ ) )Ô *h +( +ð ,À -H -à .¨ /\ 0 1 1Ð 2˜ 3\ 40 4Ø 5ˆ 6´ 7  8À :$ ;< < =p >€ ?ø A B$ Bì C´ D° E” F¨ GØ H  I° Jd K` L| MP N< OT P Q RX SÐ U¤ VÌ Wø Y\ [( \” ]Ä ^Ü `< aì cÈ e˜ f h4 j k¨ m n o¼ qŒ sX t| v w< xT yh z` {p |ô ~T \ €h ¸ ƒ4 ƒð … † ‡ ˆ` ‰P Št ‹¼ Œ€ Ü Žü ô ¸ ‘¼ ’è “Ì ”ð •Œ –  —œ ™ ™ä šÀ ›´ œ¬ ž ŸL  D ¡¬ ¢P £H ¤x ¥  ¦¼ §À ¨t ©4 ªD « ¬ ­T ® ®Ü ¯Ü ± ²` ³L ´d µˆ ¶¼ ·ð ¹ ºP »Œ ¼8 ½P ¾4 ¾Ð ¿| À` Á” ˆ ø Äœ Å„ ÆL Ç\ Èà ʈ ËÄ ÍP δ Ïä Ñ” Òœ ÓÌ Ôà Ö ×  ØÐ Ùô Û ÜÀ Þ ßÀ á áü ã< ä@ åd æì è éD ê¤ ë ìÔ íì ï( ð˜ ñ¨ óŒ õ öè ø ùL ú„ ü ýX þì   Ü ø p H h ° ì P h H h ô ˆ ¤ , 8 p Œ „ Ø  H   ! !Ü "ˆ #P $Œ & &à '¤ (| )œ *x + +ì ,¤ -„ .< / /Ô 1 1ô 2ð 3° 4œ 5  7 8h 9€ :ð <8 =Ì ?< A< C D` EŒ Fü HP I@ Jt K„ Lð N< Oœ Q R` Sà UD VØ XP Y˜ Z¸ \ ], ^l _ˆ al c4 dÀ f$ g gô i” k l° n, p q¸ s¼ uœ vø xl yÄ {d |à ~Ð € ‚„ „\ …@ †< ‡( ‡ø ‰ ‰ì ‹P Œ X Žx ä ‘H ’l “` ” ”Ô • –$ —( —Ô ˜¼ ™ø š¨ ›ø œÈ ¨ žH ž¼ Ÿp  d ¡ ¡° ¢X ¢Ø £œ ¤d ¤Ø ¥ ¦D ¦Ô §x ¨< © ©Ð ª «X ¬@ ¬Ô ­x ® ®È °, ±D ²l ³° ´ð µœ ¶$ ¶  · ·< ·ä ¸¨ ¹˜ º@ º¤ »H »Ì ¼$ ¼t ¼Ð ½ ½€ ½ü ¾” ¾ü ¿\ À À” Á ÁÌ Âd Âì Ô ÄH Äè Åh Åä Æp Ç| È< ÈÈ ÉÈ ÊH ʰ ÊÈ Êà Êø Ë Ë( Ë@ ËX Ëp ˈ Ë  ˸ ËÐ Ëè Ì Ì Ì0 ÌH Ì` Í ͸ Θ Ï| Ð( Ñd ÒT Ô Ôð ÕÔ Ö@ × ×œ Øh Ùt ÚX Û0 Ü€ ÝL ÞŒ ߀ àÈ â ã¤ ä” æl ç˜ èÀ é¬ ê€ ëp ìT íÈ ï ð ñœ ò¬ ô, õ¸ ÷ˆ ÷  ÷¸ ÷Ð ÷è ø øl øÔ!nš.±/<²í2±Ü<²í2±/<²í2²ü<²í23!%!!!MþÔ þõšýf!X‚ÿ÷í¤ 7#'.546322#"&4½ "5I, °l û #*P þ3 ..M¯K¤ #&54632#&54632+ ° ¯©#.w(©#.wð–##7##7#537#53733733#'#3×m:†!:!ktnv:…:ai&…†7ØØØØ7†7ÊÊÊÊ7†††,ÿ©É×$*046753#.'#5.'53.5654&4ZX"q0 F?(G4a`"?N-RGcO±g)ar,@N ?? (o@Aö,,C,KOWW‚OI7W-æR#2œþ÷`.9=ÿó¤ 5C2#"&5462>54&#"232673##"'#"&546"32654'.16.(3B6B‡+L)).J"þë&/)/E('þ0_4:'wV1E‡V0a!=f "s83:r)3G:^”þ«Li0!/hm $x&ýOr ]§K4_—¯I"U *ÿóî¤-8B654&'533267#"'#"&54?&54632>54&#"327&ëFU*I0:SA[0¯…¤ #&54632e ¯©#.w0ÿO0¤.54>7$8G6%%2M2! ,6226,±-P[€EHUO&$:]Y]†_<"ÿO¤'>54.')8G6%%2M2! ,62,B<¤-P[€EHUO&#<]Xy¢V/E °¤I46='5#"54>7'.5463254&5462>2#".'#"&Ö&1 $%Y' R23,!V %E"D'%2.R- #7 "`  WZ'7 2Xú 533##5#5ùBÛÛBÛÜÜBÜÜB8ÿsÃf#"&54632'654Ž  !".>2 R 3&-T82'Â3#'öö?Fÿõµd 72#"&546}!" !d" "ÿ÷ÿò¤#äDå¤ýN²ÿòܤ".5467632" 4&ú4R0 5+7Ob||eƒB0JaX+Xž*4Àš˜À˜þ½þÅ<¥oФ"57!5>54·6´$;þì8'Q[ý¨$/Å/Û¤>323267!57654&#" !)I.Nk€¨ï"! 7þz²‚N?4?Ý"A+"fKq†°+‰ ½Šz?N9I+ÿò°¤,7232654&'>54&#"'>32#"&546Q["7L6/M"16=1/GYREW*4#QKj ؤ %##5!53#ØfMþç:,Nðç@§§@½þCWþ© ÿò¶°(%4.#"54?3267+#"&5432326e/CS= mÑ &Ä*’Ž%9KE#8B+Y;PÂ5R- í Y Uuq;\8$ !%>c"ÿòÔ¬ "&547>7>32"32654&e{§7iUvž/0!VfumD/LB58G¡„Îw&#™qq`g‚Œ<;t…YR^gÿøÁ– ##"'7ÁÔAÆÙ)+ ;–ýrT3“8ÿò½¤$2#"&5467.54632'32654&'>54&#""ZAkZUk1QO-lRKa<\<,$F91=*B <3/=:sC[:M\\I3E=ED1DZP>3H,#F0AP=1*? 44=8+*Jÿêˤ#'>7#"&546322>=4#";rŸJLQcwYa|WN3dg01„, Cšz9p[e‡ž|e±9%"$ %'þ!68YiQÿõÀË 2#"&5462#"&546ˆ!" !!" !Ë" "þ™" "PÿsÛË#"&4632'6542#"&546¦ !".<4 R,!" !23&-T82Í" "ÿö%5% þüþ\¤ æBæH¿¿x‚!5!5þøþ‚BBÈBBÿö5-5¤þ\ü H¿¿HæBDÿøž¤*2#6?654&#"#"462#"&546æLl""%2%?-%:&0]L ¤UF$K/-@ZMA@UG2F& 0|Sý¿! tÿò)¤2>"327#"&54632#"&'#"&546327332654&4&#"326â~œ¤€Yk I[5›ÔÕ˜‹½nJ$36G%3qS EA'1P©)_ 0H…»‡‚¨0!Ä’Ì©|a(!HA/Z¢&þ .zKp ïoQ'.–¢%#5>54/!3#5>73%3Âÿ()þú.DÆ%).Ðùþ8çt+`u)5mëýÈ8ìQ–*5%#!5>54&'5! 2>54'&#32654&+"Q3dEþ²>"!?4="þÅ-B:T0ƒ_FMZV,´:9# 8¼7ª!3 ;´ :+\#øI?;CFÿòy¤46323273#&#"327#"&À@p !  7 m-LQ.vi.ŽU”¸EœÃ!!⺢ˆWAe=Bº­–%#!5>54&'5!24.#"3 ­6T‹Xþä9;[W9m,FrI>N-V\C, 6¼7)AYV6+OQ:%þ U–)7;2673!5>54&'5!#.+"32673#.+É!Hk\%-ýä7 7 6U‡ š@%  &>šP3Q©!5¼5!C& Þ'8è>" "–$%#.+!5>54&'5!#.+"32673ß (=‘!:þè9 7 6Uˆ ‘<) ç=#Ú6!#>±5!C& Þ#< ÿòŤ."326=4&'5!#".5463232673#.ˆ9X6" z6O9ÿ,@-ZbJ1Á–:q  `|)@VO(‹¡#¢8,Ë,0IzN™Æ!ÓN]¾–+!54&'5!!5>=!!5>54&'5!Ñ/:: 8þê:þÑ 8þê:::gÂ66þD5 "?ÃÎ5 "?±66;–74&'5!!5>s!@)?#$>þ×?"m¼7 7þD7!  ÿòr–723254&'5!#"&546; & ==XQ+8l BÏ77þŽ^g( "Ó–35!!563654&/!5>54&'5!7654&'"431¾éD2'þÏ *I9j :þæ; :=±Nƒ1¼úI"`8i»7#>±5!7Í¡H  V–%2>73!5>54&'5!3b2L* 0ýæ7 7;"7'%#®!5¼5!!5þ' _–$ ##5>54&'533!5>5¢ÿû$:ë>#!>ÆçÝÇ8 7þè; =ýÃ&þmL1/M–7þù 5þD5!#> ÿõÖ##5>5.#534&'53à þF$:ë>## «%;ëƒ3+ýò&þxL1/M¹#þQL/"ÿò°¤ !"&546324.#"32>c‡º¸·¹G+:71N- ,W<=Y-¿š—ÂÁœ—¾VHpD,*?VO)3bb<54&'5!2%3254&#" #:dB'#;þè98-TS2þ¬"®`eá06'¶7!!?±6&J:þü“MI"ÿN½¤-##"/.546 4&#"32>°%306!=€V ói/dƒ¸¸rs_2N. (BE&1M. K7`A6  OGz7" ˆ˜Ã•Œ§)?TM(XB)@UP“–%/2#!5>54&'5>54&#"%+NS2 Î%¡î8 :þë88»yqY^–#J5+ý4Å6 #>±5þÁMi"Ô[V?Q–#"#7!#.+!5>5þ6T949U6">þÜ> l.RªªS-þ7 !@ÿòÁ–%73267654&'53#"&54&'5!ÎKa8Z$:è> 5iM€{;<édg+$+]K1,Lþû;XO*}‚876ÿõ¹–#.'5!#654&'5¹%Þö'& .)—“ )– ;ýÏ%B%[þ®o0ÿõ¤–,# #.'53'.'5!654&'5¤(S:? šÁ''õ& k!"+ M„}&–'ߦ§þYF+ þˆR<" Fþ«S- À–4!563654/#5>?'.'5!7654&'5¸15/’À()þ×23_w4 ,é'*@mF=2.0U*q()–!:¶þî+LŒ”A OÁ g4 v;Š2 ¿–&!5>='.'5!#7654&'5¿'8+”$CþÎD!ƒ24" .”'–-BâÂ9!A®ÀI?Þâ U–%2>73!5#"#7!’. ý̵Ý3B! þP& ) °a,$!«ýŸXÿd+– #3#"3+ÓÓZ1ƒ2ý`4ÿ÷ÿò¤3# CåD¤ýN"ÿdõ– 3254+53#"Z-1VÓÓƒ, 4üÎ)¾–#3#\Dµ<µD)mþ“!ÿƒôÿµ!5!ôþ ô}2ûò¦#'&5432ò(š"ûa%ÿöºÌ+874>754#"#"&54632327#"&'#"&75327>%+GY/L*aGR> 'V<.;úZH%"' a&>''=S/AOQÃ!"'I, - ÿöÔ«$>32#"&54&#"576732654&#"™N.Ke‡cDE;'<©þÎ%0}\k’)þ—ü\S[m.ÿöœÌ!74632#"/.#"3267#"&ƒX?[" =KWD+>$ '&>!SkÕoˆ=*.aMVm*4 4 }ÿöë«*'5#"&5463254&#"567327#26=4&#"X0PSfzV63[8ð&3>(9DL @Cw`j•+œýÉ#+æ(5#53>32U 9{z =þü6RRP^-;DYt þÆ87: py#ÿ&ÖÌ/=L7467.54632;##"'"'#"&5467.32654&#"4.#"326I>2+aF((MS]? (N7B7TyGf-5JPBUh8Dey,#'9-#(6 :>/D_ '+)EV*:/8-D9(7'(% !(6+0=)2,HY1 ç«*#5>54&#"5767>32#5>=4#",Ø+ D/#D,{)Ô+K3Wñ45× þÐ-'ŸÇ4 3Æjý«"57#5>=4&2#"&46> ›1í40Š7þ66è!!*ÿºÿ&«"567#"&54632326542#"&46M-PLVS)52!Šþ7jp<>M{<!*ù«457677654&'53#"#53254./#5>54&#"W&‰Ì%S>™5!Ú Œê6o þ\z  9:Â&! »¸ 'â$«567#5>54&#"c<0ì/ oý«)(Ý#Ì?567>32632#5>=4&#"#5>=4#"#5>=4&#"HD>0=ü/ *Ùiþæ)ý$åÌ*567>32#5>=4#"#5>=4&#"J@3;#7?%Ð&I*$&Ô&ŽO0!OGå%"/Ña"þç+ø%ÿöÖÌ 2"&54632654&#"ú`|€¼}{!N?8@P?5AÌ€bhŒ‡egƒ¹k–`Ug‚Vÿ'ÖÌ,567632#"&'#5>54&#"32654&#" ?Q@PI^yY + 8ò,E#6CC8#C‰ MOx]m”/'Ô#<ö,gSWi,ÿ'èÍ$73#5>=#"&546323276=4#"h6 )ì5$DYFZ^6½>12$]@J© ýª  *¼Jx_l”Ü+PC "ÎdgOÌ#"&#"#5>=4&#"567>32(,2"3ð0PD%4j#:á+ &ú!\5)3ÿö\Ë1273#.#"#"&#"#5332654/.54632 2+"++l-'S:T   (&-4:@5M;!:¸ ˆC8&+@7%4L œ '!-!$B*6E ÿöC#327#"5#&54>7672ÿe 0HY5 2 þâ/+# L- 6+ t ÿößÂ#%'5#"&=4&'533276=4&'533ßN;++<7B$’*.*/ž"2S++G;ü#þº-"&ë%þ©#ÿòÝÂ#"'.'53654'5Ý€ x#Ä fc/Â2þ¿2/N$ ÿÿò¶Â/.'537654&'53"/#"'.'53_!Ë#TZ{ Š[p‡´c6P) .àÞ* þ¦1+ìð',V&þûßÂ2>54'533#5>54/3#5>?'.+53ø  (ž3S€#É[O(‘r^  Ï+.0)*xÄ" Œ{ ¥#Eÿ&ÛÂ)2654/&'53654#53#"&54632—>,u 'Î  sa0‡ š(O2 *2†|Oþ ý þhl\!¢Â%2>7!5#"#7!'. þ‡ Š- [þó "#‡•!7vþkdÿK^¨.=4&'>=4>7^XM#22#.7,4'&88&'4µ6T±4..4²,7  68¨>44>¨86 Cÿò…¤3CB²ýN‚ÿK|¨"25>=467.=4&'‚!*.#22#.7,4'&88&'4¨5%±4..4²,7  68¨>43?¨86 (ºö@23267#"&#"'>£2~#6"6#2~#6"6@D 0%D 0%ÿÿaÿ&ÌÕ 3#"5472#"&546 !54 l4Þ($*P : 5ÿvÀC"+7&5463273"&'3267#"'#7&#"©t],#/K& e ,@' &$;!1"Ps=K BeŒ|‡6þÝ ,89 ŠìC ]M6J ÿøê¤=H%#"&'#"&54632654'#53&54632"&'&#"3#32>322654&#"ê'D( =3*%2)lkjY8J,7-2 }yTA"2þe##3ˆ -2$##""* ¢-$!k5((4IB,]-##y+  %ÿê: Z&'7&547'76327'#"'"2654&b))b2`=BE8b0`''`0b9DA>`á?WWzUUl`;CE9b0`''`0b:CB=`2b))b§X?>YX@>XÿË–47#535'#53'.'537654&+533#3##5>5¾®®§_)*#óA vpÃ'5\’¦­­ 0ô2¶(L(­J*ÝÜ03¸(L(I5$%>Cÿò…¤33CBBBþìžþìFÿlª¤AM4654&#"+#"&5463232654.54632.54632#"4&#"326"$&/"‰YA38&OA:P"+(/6LL6B1 <(M>7ID‘&'…1)%&" ' *qJQ5C1;&9F:*$"*# =5:T03D2<(6D8*þÇ4w&2x( <n 2#"&54632#"&546BÚn((&ÿòÒ¤%12#&#"32673#"&54672 &546"32654&›"V^CHJB-8]+[ozJ‹ÅÆþâÈÉ’y«ªvu©¨FY[TS]'/L iUZoËÈÈ’È*²~{³³|zµŠ¤*4#"&54632327#"&'#"&54>754#"26=L =/i 0+('+$ 5&q   &`s ,&*ÀM*!È -7#"./7>7632#"./7>7632‡q O4A W (L³q O4A W (Là I-;Q ' 9^ I-;Q ' 9^l‚%5!5!ÔþJølÔBþêÿÿ'Â&ÿòÒ¤ (4@%".'##5>=4&'53232654#72#"&546"32654&õ )0 %¢% %±4?O9'%é+!$GÅÈÈÈvªªvs«§˜A c  ñ! 2*H O6]¨.+O¯Ë”ŒÇÈ‘É*´|{³²x€´ #BY!! 7þÉY69†W¤ 2#"&547"32654&ŒxST=:S+==*+>>¤S=323267#57654&#"2:I&.Vy %ýbQ+6 - -;/%D-U UkW2-F#¤%4&+5>54&#"'>32"5462326Ò?4+$?.-?5¬^dcn:9š:š:>86@\mbW6ý­5!üæ"?Ÿ?[_TFǵ6 2#"&546}!" !6" "4ÿ)73632#"'732654&#"b)# (.C:-'% ccA% '- 9ø¤#5>54#"57ø¿ %v&  7þ©Š0¤ 2#"&5463254&#"Ÿ@QXA?RU ,%G-$ '¤K;?UO<@Ok=QW9H(,!Ê -747'&5432#"'47'&5432#"í€K6  7( AfD À€K6  7( AfD *¢]A 6";XD ¢]A 6";XD%ÿòΤ #%##5#53#5# #5>54#"57Î7F´Ë/F‡³þ>1Åþ•¿ %v“9ZZ1 þþ³³ýN²þ‚  7þ©ÿòê¤3 # #5>54#"57>323267#57654&#"Xþ>1Åþ´¿ %v2:I&.Vy %ýbQ+6 ¤ýN²þ‚  7þ©  -;/%D-U UkW2-FÿòΤ 7%##5#53#5# 4&+5>54&#"'>32"5462326Î7F´Ë/F‡³þ>1Åþ„?5+$?/-?=Wo¦4%“9ZZ1 þþ³³ýN²þÖ,)%!3,0#'+#N:N2'%ÿ&xÔ(4>7332654&54632#"&2#"&546-8; %?-$;&0]ELl² ?-V>i;O?@UG2F& 0|SUY,! ÿÿÂz#\ÃÔ$ÿÿÂz#[¾Ô$ÿÿÂv#X¾Ô$ÿÿÂR#hÃÔ$ÿÿÂC#j¾Õ$ÿÿ“#f¹Ì$_–:=%.+;2673!57>=#3#5>7654&'5!#.+"32673%3ä$7‘1LQI+,þ-°@DÇ! õ )14ELWoG7ýöŸå7-î%0R¨!1˜5}!.ä 0)æ#>êF?ÿ)y¤7327#"'632#"'732654&#"'7.546323273#&#"-LQ.vi-U  (.C:-'% %}•À@p !  7 mRWAe=B4% '- YµˆœÃ!!⺢ÿÿ Uz#\ŒÔ(ÿÿ Uz#[ŒÔ(ÿÿ Uv#XŒÔ(ÿÿ UB#j‹Ô(ÿÿ;z#\Ô,ÿÿ=z#[Ô,ÿÿ Bv#XÔ,ÿÿ<C#jÕ,­–-#!5>=#5354&'5!24.#"3#3 ­6T‹Xþä9SS;[W9m*CwN’’>N-V\C, 6Î,Â7)AYV6'IT=)ã,íÿÿ ÿõÃR#hÃÔ1ÿÿ"ÿò°y#\ÄÓ2ÿÿ"ÿò°z#[ÃÔ2ÿÿ"ÿò°v#XÃÔ2ÿÿ"ÿò°R#hÃÔ2ÿÿ"ÿò°C#jÂÕ2&ñ 7'77''êÄ0ÄÅ0ÅÅ0ÅÄ0ýÄ0ÅÅ0ÄÅ0ÅÅ0"ÿ°°Þ!)7.5463273#"'# 32654 &#"—+¸XWH1X,¸‘[TO1×þÌObs;"B_9˜Â1k‚ D^:˜Á2tlþ54&'5!32%3254&#" #:dB(#;þè98<PxŒþ¬"®`g _06(47!!?±6#< bþü“MH ÿ÷Ô«3#"&546323254'&547654&#"#5>54>32¸hK+6@„ _0+'/‘&%I4N\9y#œRq) ‚Ê  vAJ:1ýÛ(r2LC$SE6?ÿÿ%ÿöº¦"\8Dÿÿ%ÿöº¦"[7Dÿÿ%ÿöº¢"X8Dÿÿ%ÿöº~"h6Dÿÿ%ÿöºk"j9ýDÿÿ%ÿöºÏ"f:D&ÿöxÌ5BI"&54632>32!3267#"'#"&546?54&#"'.=2673.#"(\DA4"3"LLþú  3+A$ '_?Q03@%3AEPV (– [:'8J=¦%(+(ˆ .>-VaJC,5UJI*=1-C!$?1%þ¾54!2-$3$éA;:ÿ)œÌ674632#"/.#"3267632#"'732654&#"'7.‚Y?[# =KWD+>$'V= (.C:-'$ &L[Ôo‰=*.aMVm*4 OI7% '- [ yÿÿÿö¨¦"\8Hÿÿÿö¨¦"[7Hÿÿÿö¨¢"X8Hÿÿÿö¨m"j7ÿHÿÿÿøý¦"\åóÿÿ#¦"[æóÿÿÿð'¢"Xåó  n (2#"&54632#"&546"57#5>=4&;²‰ ›1í4n((ä7þ66è!ÿö×®(#"&54632.''7&'7732654&#"×}c]}zZ$4& *,{!y>G*1A&_![Šþ N@9?P@5A~©…deˆ#7K-A@, 20…Çj˜aVfVÿÿå~"hTQÿÿÿöÖ¦"\TRÿÿÿöÖ¦"[TRÿÿÿöÖ¢"XTRÿÿÿöÖ}"hTÿRÿÿÿöÖk"jSýRÿö%!5!'2#"&5462#"&546þøü!" !!" !ÜBæ" "þa" "ÿÖ'"7&5463273#"'#3264&#"}`{a,09'Ab€_/.A% ¡#/8?ÞŸ%+5ANyfƒm}FzhŒ{ÞþÎ*b®Æ0$VFfÿÿ ÿöߦ"\?Xÿÿ ÿöߦ"[TXÿÿ ÿöߢ"XGXÿÿ ÿößm"j@ÿXÿÿÿ&Û¦"[T\ÿ'Ö«,567632#"&'#5>54&#"32654&#" ]4AOI^yY + 8ò, E#6CC8#CoþÖNx]m”/'ÀþÞö,gSWi,ÿÿÿ&Ûq"jd\ÿÿÂ#Z¾½$ÿÿ%ÿöº>"Z:åDÿÿÂ}#d¾å$ÿÿ%ÿöº¥"d: Dÿÿÿ[¢#g$%ÿ[¼Ì:G2327327#"&547&'#"&54>754#"#"&5465327>àR> +5;*6V<.;+GY/L*a†ZH%"' ÌOQÃ!$L, .++I''=S/Aþ¯‘!>, - ÿÿÿòyz#[ãÔ&ÿÿÿöœ¦"[LFÿÿÿòyv#XÖÔ&ÿÿÿöœ¢"XGFÿÿÿòyC#eÈÕ&ÿÿÿöœn"e6Fÿÿÿòyv#YÄÔ&ÿÿÿöœ¢"YLFÿÿ­w#YÃÕ'ÿöW«*>'5#"&5463254&#"567327#26=4&#"#"&54632'654X0PSfzV63[8ð&3>(9DLe  !".>2 R @Cw`j•+œýÉ#+æ((9DL>-" x"þc#4@Cw`j•+þÅæ("ZDåHÿÿ Ul#d~Ô(ÿÿÿö¨¥"dD Hÿÿ UC#eŒÕ(ÿÿÿö¨n"e8Hÿÿ ÿ[e–#gl(ÿ[¨Ì&,3267327#"&547#"&54632%3.#"a010G$6."+6;*5Weu\LT þÎÌ *.Z?[-09*G'1$L, .* xho‡[\ A2ÿÿ Uv#YŠÔ(ÿÿÿö¨£"Y:Hÿÿ ÿòÅu#XÖÓ*ÿÿÿ&Ö¢"XHJÿÿ ÿòÅk#dÃÓ*ÿÿÿ&Ö™"dTJÿÿ ÿòÅC#eÉÕ*ÿÿÿ&Ök"eDýJ þçŤ.B%4&'5!#".5463232673#.#"3265#"&54632'6549ÿ,@-ZbJ1Á–:q  `W9X6" z6O¥   !".>2 R÷8,Ë,0IzN™Æ!ÓN])@VO(‹¡#ã 3&-T82ÿ&Öà/=L`7467.54632;##"'"'#"&5467.32654&#"4.#"3267632#"&5467I>2+aF((MS]? (N7B7TyGf-5JPBUh8Dey,#'9-#(`   !".>2 R6 :>/D_ '+)EV*:/8-D9(7'(% !(6+0=)2,HY1v 3&-T82ÿÿ¾‡#XÂå+ÿÿ çz#XRØK¾–+/!5>=!!5>54&'5!!54&'5!!5f 8þê:þÑ 8þê:::/::þk/)þD5 "?ÃÎ5 "?±66==6š^^ «24#"#5>5#5354&#"57673#>32#5>5‡K3,Ø+pp D/ss#D,{)Ô+,j"ñ45†6 †6t-'ŸÇ4 3ÿÿKJ#hÌ,ÿÿÿä.r"hãôóÿÿ B#Z½,ÿÿÿí$>"Zâåóÿÿ;}#då,ÿÿÿü¥"dâ óÿ[–#!327#"&547#5>54&'5!; $+5;*6ø?"!@)?#$>.$L, .+ 8¼7 7þD7!ÿ[«#."57#"327#"&547#5>=4&2#"&46> ›1!++5;*6ƒ40Š7þ6*$L, .+6è!!*ÿÿ;C#eÿÿÕ,ýÌ"57#5>=4&> ›1í4Š7þ66è!ÿÿÿò¿–#-M,ÿÿÿ&Ø«#MLÿÿ ÿò~‡#X<å-ÿÿÿºÿ&2¯"Xð Üÿÿ"þíÓ–#TÒüâ.ÿÿþíù«#TXüâNêÌ8#"&#"#'&+#5>54&'533267>32Ó) %"26"Š}" ê66êC)0$˜+51 9b È '' ƒHF&ÿÿ V‹#[%å/ÿÿ&~#[ÿéØOÿÿ þíV–#Tpüâ/ÿÿþí«#TÿâüâO V¤/%2>73!5>54&'5!3#"&54632'654b2L* 0ýæ7 7;"7¯  !".>2 R'%#®!5¼5!!5þ' 3&-T82\«(567#5>54&#"#"&54632'654c<0ì/    !".>2 Roý«)(Ý#3 3&-T82ÿÿ Ñ–#y,/ÿÿŸ«#yê(O V–#%2>73!5>=5754&'5!73b2L* 0ýæ7 WW 7;"››7'%#®!5§212ä5!!5©Y1Yÿ«54&#"#5677#5>=5b c<MM0ì/NjÊ#þú5,5þÝ)(ç6,ÿÿ ÿõÃ|#[ÄÖ1ÿÿå§"[TQÿÿ ÿÖ#TÃüõ1ÿÿÿåÌ#TSüöQÿÿ ÿõÃt#YÂÒ1ÿÿå£"YTQÿÿâ"Q1T° ÿ&Ö.26=#5>5.#534&'53#"&54632þb$:ë>## «%;ë 4N)52¸>MCþxL1/M¹#þQL/3+ýýtf<ÿ&¨Ì02654#"#5>=4&#"567>32#"&54632$I*$&Ô&J@3;#7?VS)52¸>Maa"þç+ø%O0!OGþÊjp<ÿÿ"ÿò°#Z½2ÿÿÿöÖ>"ZTåRÿÿ"ÿò°}#dÂå2ÿÿÿöÖ¥"dT Rÿÿ"ÿò°z#iëÔ2ÿÿÿöÖ¨"iTRÿúuœ0=23!#.+"32673#.+;7>73!"#"&54>4&#"326V t+F =b3*hF9'4Š|/A&,þ¢‹ ›(?URƒ/4[ca\5/œC&ì%=ê;(õ8G¨³•O|K1ýçŒ72 “Ž˜/ÿö²Ì!+23267#"&'#"&54632>32%"3254&354&#"¤ 5'$;# 'R:.;C3[sqY.D&:)=^þC-@xg;‡ -"P*?J)(0QD,33,€dg‹"**"QfšIWÿ·px|*7ÿÿ“‹#[*å5ÿÿO§"[Uÿÿþí“–#Tªüâ5ÿÿþíOÌ#TÿÔüâUÿÿ“v#YªÔ5ÿÿO¢"YUÿÿ*ÿòë|#[pÖ6ÿÿ3ÿön¨"[1Vÿÿ*ÿòëv#XqÔ6ÿÿ%ÿö\£"XV*ÿ)ë¤G.#"+632#"'732654&#"'7.#"#'332654.546323273¼c<.:DOcXuU  (.C:-'$ $!O %bC7DB^]BgF*b ÏXT4)(H,5g>Mi3% '- XÔ[V?2/I47V9L_""Õ3ÿ)\ËJ273#.#"+632#"'732654&#"'7.#"#5332654/.54632 2+"++l-'S8  (.C:-'% ' 6   (&-4:@5M;!:¸ ˆC8&+@7%4L7% '- ] œ '!-!$B*6Eÿÿ*ÿòëw#YpÕ6ÿÿ'ÿö^¤"YVÿ)Q–0!632#"'732654&#"'7#5>5#"#7!#.+B (.C:-'% )> 6T949U6">A% '- c!@ô.RªªS-þ7  ÿ)C3632#"'732654&#"'7&5#&54>76723#327ª (.C:-'% &B5 2ee , 7% '- \m- 6+ t þâ/+# FÿÿQx#YŠÖ7 ÿö,¤/#"&546323#327#"5#&54>76723'654÷   !".R%e 0HY5 2R< 3&M< þâ/+# L- 6+ t82Q–#53#"#7!#.+3#!5>5þrr6T949U6rr">þÜ> :-.RªªS-þû-Í7 !@ ÿöC##535#&54>76723#3#327#"5F995 2eeee 0HY-b 6+ t b-/+# LÿÿÿòÁJ#hÂÌ8ÿÿ ÿößr"h/ôXÿÿÿòÁ#ZÁ½8ÿÿ ÿöß>"Z.åXÿÿÿòÁ}#dÁå8ÿÿ ÿöߥ"d. XÿÿÿòÁ§#fÁà8ÿÿ ÿößÏ"fBXÿÿÿòÁ|#iëÖ8ÿÿ ÿöߨ"iTXÿ[Á–473267654&'53327#"&547#"&54&'5!ÎKa8Z$:è> &;<+6;*34,~{;<édg+$+]K1,Lþû[[12,$L, -) ~876 ÿ[ôÂ0%327#"&5475#"&=4&'533276=4&'53;ß L+5;*++<7B$’*.*/ž"$7+$L, i++G;ü#þº-"&ë%þ©#ÿÿÿõ¤w#X.Õ:ÿÿÿò¶¤#XÑZÿÿ¿w#XÖÕ<ÿÿÿ&Û£"XW\ÿÿ¿C#jÒÕ<ÿÿ U{#[‹Õ=ÿÿ¢§"[8]ÿÿ UC#e‹Õ=ÿÿ¢k"e7ý]ÿÿ Uv#YŒÔ=ÿÿ¢¢"Y8]«".#"!5>5#53>32U 8 =þü6 P^-;DYþ287: py#ÿÿÿöÔ«,5354&#"57673#>32#"&532654&#"F C1N.Ke‡cDE;'<" x"˜%0}\k’)ÙÍü\S[m.ÿ˜Q–+8C%#!5>54&+"#"&543! 2>54'&#32654&+"Q3dEþ²>"9 $3<’ÿ4="þÅ-B:T0ƒ_FMZV,´:9# 8¼3#25)ª!3 ;´ :+\#øI?;CFÿÿ'`®#ÿöÿöÔ– +32654&#"7.+>32#"&54!™:'>DE;'<Ý  †N.Ke‡c#576732#!532654&á%=9 #&66!þ(ee:KqA( 3gFþ¾/#gÄ,> þÚ!BjHH þÓ&51<=%,-(YÿïÿöÔ«#>32#"&54&+57632654&#"”N.Ke‡cDE;'<«þÎ%0}\k’)IqCBþ¢ü\S[m.ÿòy¤"&#"#'332654.#"'>32*@p !  7 m-LQ.vi.ŽU”¸À!!⺢ˆWAe=Bº™œÃÿò&6*2327432#"&#"#&#"327#"&546k?r  ‚)52#7 m-LQ.vi.ŽU”¸À¤!!’<3$ûº¢ˆWAe=Bº™œÃÿö*:174632632#"&#"#"/.#"3267#"&ƒX1& x)52#" =KWD+>$ '&>!SkÕoˆ<3$3.aMVm*4 4 }ÿÿ­–’ÿœ­–34.#"3 #!5>54&+"#"&54;2@,FrI>m6T‹Xþä9/ $3<’ð[W9G+OQ:%þ)-V\C, 6¼1#25))AYV'`®&74>;#"#7!"3!"&7327&#"'<{VF¨~<%&;þºq‚{\L&##3J&¼!<>%s':þ9<&h^IX%-/ÿö÷– .726=4&#""#7!"327'5#"&546325û%4>(9DL ƒ.!“0PSfzV63**æ(=#"#5 $Aš ‡U6 7 7ýä-%\k4, š>& Ï9&Þ &C!5þD5!©Q3 ÷">èÿÿ%ÿò°¤éÿñä¾.4>3235##"&#"327'#".4>;5"&ž8,ˆi1Ro‡!/$Ši‹JEg,= &K4g^!7-¥ÌdO…! $?'Xm‡ a41600!Mÿ½ÿ4"–+23254&'5!#.+"32673#.+#"&546 & 7 6Uˆ ‘<)  (=‘XQ+8R B5!C& Þ#<è=#þ²^g( ÿ´ÿ&€«&>32#".#"3##"&546323265#5gP_-;9zzVS)52RÂqx#&%Yt þ^jp<;PÏ  ÿò06;%4&'5!#".546323265432#"&#"#.#"32659ÿ,@-ZbJ1Á–:q )52# `W9X6" z6O÷8,Ë,0IzN™Æ! ’<3$ìN])@VO(‹¡#ÿñƒ–%0#"&54>7&'5!7654'534'32ƒ1E‘9VH=I(À, %m{=ÐïX!.(Kƒ [ÀT(BGPM>!C3.¢¡'ýÏ({(6(2 ÿ÷Å«>#".6.#"#5>54&567363232>54.54632Å2X89D%%67,Ø,"i%9W2:*(.J#%%4g[8.IXYI.?ñ1"2×! þÒR/L\\L/Th,(#82ÿöF«%#"&54567327F+T<)OmD4!BLD;oýÛZ#K–5354&'5!3#!5>=r!@)?#rr$>þ×?":-Â7 7Â-Í7! 8Í"˜6".74#"7!5654.'!5>54&'5!7632"<;:Ìé*>þÏ8qh"8þæ;#7:"ô^P/h  5:Èú1% ƒd»6!%=±6 8ÍäXKù«8"&#"7654&'53#"#53254./#5>5>32A79‰Ì%S>™5!Ú Œê6P^-<DKYþÏz  9:Â&! »¸ 'ppy#«5673##5>=#5354&#"c<cc0ì/aa oþ¾-æ)(ã-Í#ÿöÊ /%#"./##4&'57&#"#54632732673ÊC:€U²yp2$$(" e[\ [e'ãþ²ÃS,MZ5*?5 E,>þ¿ % ÿö£–=%2654&'5!327'5#"'#"54/5!3274&'5!Y8W"0 3"YQ LH(a ]i4 5(4O5$4458É#"2þ[,"[9$ffØlD4þK:J¤8(3þ†ÿºÿ&Ö%4&'53##"&546323265.#538%;ë þF3N)52# «L/3+ýò&ýåtf<;Py#þÿ8åÌ*567>32#5>54#"#5>=4&#"J@3;#7?%Ð&I*$&Ô&ŽO0!OGþS%"/™a"þç+ø%ÿÿÿôÊ¡É"ÿòÄ24.#"32>4&54632#"&54632326>+:71N- ,W<=Y-d<lX¹”‡º¸?U3AHHpD,*?VO)3bb<54&#" &632>763274."2>þþè* .M,D´þÚ´´“D}-Ji$3-:þ@/WtW/.WvW.(£24:Y„”ÄÄ(Æ41 T'B/%þ¬9'86g_99_g67f_99_fÿ'Ì"3#5>54.#"#"&546326324.#"32>Û* E'_byx`w>MUv(þu;';; ;),8Ù+¬$93H`ŽŠda‡TT²þY&‘$KK/^>&QU6>Lÿ—– 43254&#"#"'!5>54&#"#"&54;2Ê"®`eT #:dB'#;þè96$3<’ï-TS2Oþü“MI‚06'¶7!!?±3#25)&Jÿ'Ö« 132654&#"7"&#"632#"&'#5>5>32ŸE#6CC8#Cš78@PI^yY + 8ò,P^-;Nö,gSWi,àKY¹Ox]m”/'Epy#ÿ“– .72654&#"723#!5>54&'5!ç\E6D,dbSzÎ%¡î8 :þë8!@)?#ä<(#7·ÞK/V"ý4T6 #>±7 7g*ÿòë¤/"#733263232673#.#"#"&54>54&73#&7 T:S'-l++"+2 9";M5@:4-&$  L4%7@+&8Cˆ E6*B$!-!' œ ÿÿ2•ÓÿB@«%#"&5#"&463232>324&"2@29If)>7672ÿe 3N)52 ,Y5 2 þâ/+# Btf<;P=- 7+ tÿ÷Q–!#.+!5>5#"#"&54‰Â9U6">þÜ> Ž!6<–ªS-þ7 !@ô&25)ÿôÿö^« "&#"3#327#"5#53>32479{z 0HYRRP^-;DKYt þâ/+# L- py#ÿ4Q–2>2#"&5#"#7!#.+Š (8+QX6T949U6¦  (g^s.RªªS-ý0Bÿò:P373267654&'532654&54632#"&54&'5!ÎKa8Z$:è'0<C6;#5iM€{;<édg+$+]K125)4<+Hþû;XO*}‚876 ÿö|1%'5#"&=4&'533276=4&'532654&546323ßN;++<7B$’*.*/ž$3<y"2S++G;ü#þº-"&ë%#25)v þÍ#ÿÿ!ÿóÉ— Ùê—Àÿñ°–#'&54&'5332>'.'.7>°¿‘ø!9ÀQ]O‘=. "0 $/'8+ Ižºþ87 þI^csÁ - 5Bj#š+!5>='&#"#"&546327654#53# 8”(?þÎ?&£A/,o42Y”EÛƒ(!&âÂ; ;¶ñ_ 30J6+Þâ!ÿ&‹Ë6#".#""&5463232654./&'53"7632‹ %= #28- / ?#r &Î  s<>s(W€F*þ¯# D#y!8Gö ýª¬( U– %2>73!5#53#"#7!3#’. ýÌ×Tt¾Ý3B! ÌaÄ& ) °+- ,$!«þà-þì¢Â%2>7!57#537#"#7!3#'. þ‡VtkŠ- [v_}y "#‡Å-£!7v²-¶ÿÿÿòð¤ñÿòð¤"327#"&54>3!#.+^BW5vi.ŽUXyD1‡ 5$“GJYDBe=Bx^&NA'Õ,A(ÿ/jÂ467'7!.+32632#"&W[•/#¦”WR20a(;EaƒMxä u#çuH2G<8*p.ÿ²Â3#"&54>54&#"'7#"#7!63232>32²AH=a-AA-(,Sм .V¸ 7L5LL54$ Š+>:*?'!*,È!а=5,D*&1#"("Û¤$%!5767#53654&#"'>323#3267Û7þz²7^uMB9=kWMh/a€¨ï$$‰‰ ½:2,73ANC?ZmhLDK,°%ÿòD–&%#"&'73264&+54&'5!#."#"32D…`Uƒ=eyMmmMZ"5¥(2 9\‰Î_xCDpcšc¦5!!+ ¥€ÿI”Ý$+#"&5463232654'.'"547327”&Ä+'zj4^ B7À8 nÑÖY UÙi{..!)!eH• çÿö{D+%#"&#"#5332654.=#&5476763#{W:M 6<#./BC/5 9,ee+l**w9H œCI&#-#'@)P 8Vt ..@5ÿ'ØÌ&3#5>54&567>324&#">Ø9be9$4ò**IGf5V2,'E\‡9>zfO"&1(Ô)€3L¾,>>*þÄ=¤ÿÿCÿò…¤_ÿÿCÿòM¤#_È_/ÿ”)f%##5#535#53533#3)ä2ääää2äää‚îî2’2îî2’ÿÿ‚ÿ÷í¤ÿÿ'v#?Ò'ÿÿt¢#@Ò'ÿÿÿö–«#@ôGÿÿ ÿòÕ–#-c/ÿÿ ÿ&%«#Mc/ÿÿÿ&Ø«#MOÿÿ ÿòD–#-Ò1ÿÿ ÿ&”«#MÒ1ÿÿÿ&¶«#MôQÿÿÂv#YÄÔ$ÿÿ%ÿöº¢"Y,Dÿÿ @v#YÿþÔ,ÿÿÿíÿþ$ "Yâþóþÿÿ"ÿò°v#Y¿Ô2ÿÿÿöÖ¢"YNRÿÿÿòÁr#YÖÐ8ÿÿ ÿöߢ"Y:XÿÿÿòÁ‘#ZÔ8#s!Ô8ÿÿ ÿößÑ"Z@x#sŽXÿÿÿòÁ£c[ý0I%Í#s!Ô8ÿÿ ÿöß"[Sn"j@XÿÿÿòÁÃcYí¦6ò3Z#s!Ô8ÿÿ ÿöß"Y@n"j@XÿÿÿòÁ¬#s!Ôc\ü÷1¦)+8ÿÿ ÿöß"\/n"j@Xÿÿÿö¡Ì HºÂÀÿÿÂB#s Ô$ÿÿ%ÿöºÑ"Z7x"j7Dÿÿ‘#ZÆ8"$e¾Ôÿÿ%ÿöºÑ"Z7x"De-ÿÿ_-#ZfÔˆÿÿ&ÿöxY#oö¨ ÿòŤ3232673#&#"326=#5354&'5!3##".546v>j ?œ?a7‡|)`EE!7ÿ0;;­F3`cH.Ǥ!Ó«7\m<§t,4$4,:1NRŽÁ ÿ&éÌ;GNR23263##"&#"3##".547#5367.54>7&5464&#"326.'!2ñ _1$ S_@ $ .N4E+’B8;&+2 #(]b¢51%&2'&#hO0$:þÃüÌ"'*2@S172,3> ( ,# .! )YJ]¾7k3NF;8þÝ +,8ÿÿ ÿòÅv#YÅÔ*ÿÿÿ&Ö¢"Y7Jÿÿ"Óv#Y¸Ô.ÿÿùv#YÔNÿÿ"ÿ[°¤#“22ÿÿÿ[ÖÌ#“ÒRÿÿ"ÿ[°-#“2"2Z¼Ôÿÿÿ[ÖY#“Ò"RZLÿÿÿòð‡#Y}åyÿÿÿ/j¢"Y 1ÿºÿ&$ 567#"&5463232654#'37M-PLVS)52·}>|"yzŠþ7jp<>M{<§§ggÿÿ'–#=Ò'ÿÿt–#]Ò'ÿÿÿö–«#]ôGÿÿ ÿòŤ*ÿÿÿ&Ö¦"[7Jÿò•–="57#"=!!5>54&'5!!54&'5!326=4& ›,O7ÄþÑ 8þê:::/:: &>7Š7ó'9@)×rÎ5 "?±66ÂÂ66þ˜*.Na!ÿÿ ÿõÃz#\çÔ1ÿÿå¦"\TQÿÿ“‡ÿÿ%ÿöºÏ§ÿÿ_z#[fÔˆÿÿ&ÿöx¦#[«¨ÿÿ"ÿ°°ÞšÿÿÿÖ¦"[UºÿÿÂz#zÅÔ$ÿÿÿöº¦#zkDÿÿÂl#|Ô$ÿÿ%ÿöº˜#|‡Dÿÿ Uz#zŸÔ(ÿÿÿö¨¦#zhHÿÿ Ul#|ËÔ(ÿÿÿö¨˜#|‡Hÿÿÿ³;z#zÔ,ÿÿÿ¹5¦#z óÿÿ;l#|MÔ,ÿÿÿü˜#|/óÿÿ"ÿò°z#zßÔ2ÿÿÿöÖ¦#znRÿÿ"ÿò°l#| Ô2ÿÿÿöÖ˜#|¡Rÿÿ“z#zÔ5ÿÿÿËO¦#zUÿÿ“l#|éÔ5ÿÿO˜#|JUÿÿÿòÁz#zæÔ8ÿÿ ÿöߦ#z\XÿÿÿòÁl#|!Ô8ÿÿ ÿöߘ#|X*þçë¤.B23273#.#"#"&#"#'332654.546#"&54632'654ô*b c<.:DOcXvV2g %bC7DB^]Bgx  !".>2 R¤""ÕXT4)(H,5g>Mi"Ô[V?2/I47V9L_üÎ 3&-T823þç\Ë1E273#.#"#"&#"#5332654/.54632#"&54632'654 2+"++l-'S:T   (&-4:@5M;!:C   !".>2 R¸ ˆC8&+@7%4L œ '!-!$B*6Eýº 3&-T82þçQ–+#"#7!#.+!5>5#"&54632'654þ6T949U6">þÜ> D  !".>2 Rl.RªªS-þ7 !@þú 3&-T82 þçC/#327#"5#&547>7672#"&54632'654ÿe 0HY5 8   !".>2 R þâ/+# L- >* tý° 3&-T82ÿÿ¾v#YÃÔ+ÿÿÿûçv#YÿðÔKÿÿÂB#e¾Ô$ÿÿ%ÿöºn"e-Dÿÿ ÿ)U–#z–(ÿÿÿ)¨Ì"zBHÿÿ"ÿò°‘#sÔ#ZÃ82ÿÿÿöÖÑ"ZLx"jSRÿÿ"ÿò°›#Z¹B#h½Ô2ÿÿÿöÖÑ"ZLx"hMRÿÿ"ÿò°B#eÃÔ2ÿÿÿöÖn"eSRÿÿ"ÿò°‘#ZÃ8#eÃÔ2ÿÿÿöÖÑ"ZLx"eSRÿÿ¿-#ZÓÔ<ÿÿÿ&ÛY"Zc\ÿBÌ-7#"''674#"#5>=4.#"567>32764#"326B7M{<ÿÿÿö˜Ì D½ÂÀÿößÌ&%'5#".54632>77'54#"326ß8SX,9N~a3> #’`FA=-,;$S%1F`8c•# þ£#MÎcvL,P?$ÿÿÿùíÏ ðýÅÀEÿöÔ« (32654&#"7"&#">32#"&5>32™:'>DE;'<›79N.Ke‡c7.54632#".#"6324#"326}?9+ >?|d2c ?B10T:;&+L%U—=d[ HrGf‘7.""oC:cx4e/ÿ&[« 1726=4&#"7#"&5463254&#"56732632#"&5û%4>(9DL—0PSfzV63[825)SV**æ((9DL†79“0PSfzV63©-<**æ(32327.54624'326²0" ;'&|dI=ù-L/BJ~T99/4  &"þžÈ'1?Bw,2$7 @--4Jf‘0F1- HD61KYK Ã3)â,oÿÿ)ÿöÍå)ÿöÍ6?32654&#"#"&5463232654&#"#"&54>32#")(Z3<-$ .  1#(*# "61AhE*/GgC‘l ]>3%45 +9$#=<(5A.@E)ÿö‡3V#".4654#"#"'732654&#"#"&5463232654&#"#"&54>32>2327.5462‡0"\ E*/GgC‘+(Z3<-$ .  2#(*# >A!S0 m& &"w,2$7 i !(5A.@Ev ]>3%45 +9$ ( ({KYK )ÿ÷Ê0%#"&546324&#"#"&543232654&#"326=L'WmnV'L=G//G\-$ . " . $-+)J]\K)+k(8‘ZX8(.AA%44%+=}MNƒ=ÿºÿ&Ì5673##"&54632326=#534M-PL??VS)52eeŠþW jp<>M- .<ÿ&m«.<"&#"#".54632326?#"&546325>323276=4#"C79/\@2)+7DYFZ^.2P^-;þ>12$]@JDKYýÊ'GD(CHmJx_l”py#þ­+PC "Îdgÿ&©Í /73276=4#"".5463232657#"&5463273n>12$]@JZ2)+8DYFZ^6=6 /\ñ+PC "ÎdgýÜCHmJx_l”$ þ7'GD(ÿ÷ÞË'%#"&546323273#&#"32=4&'53Þ‰sƒ‡aQ*j*?"SSK&½äˆ!~r`„t&AH(Vl#m% ÿçÂ+9#"&54>7&'53>54&'534.'32ç'p&<=42  ’!Ë>D'Ÿ·  !:¯*Â!ET@XT8("%!0JmmOýÊB7$!(#8ÿ÷)Ì ,.#"#".547&#"'6326324&'32>)g6V@-0 , /BJ~!#~/.,.'/ 5R<+k`9TLX=1- þù8a32#5>=4#"#5>5>32879#D,{)Ô+K3,Ø+P^-<DKY¾-'ŸÇ4 3Æj"ñ45\py# ÿ&««4"&#">32#"&5463232654#"#5>5>32879#D,{VS)52K3,Ø+P^-<DKY¾-'ŸþÓjp<;PYj"ñ45\py#ÿÿ«"èLÿö0Ì"57327#"=4&> › 0HYŠ7þ»/+# LÙ!Â7#5>=4&'53³4ò44ò4f66ö66ÿê4«+56732673#"'#5>5&#"#>3254&#"c< 0)0ì/# 5%  oþÒ 91æ)( .14˜#ÿý«!+##5>=.5463254.5673#.#"`,ì+"""#b=`´!!0Ü*)Ù µ!þž) ÿ&i«32632#"&54&#"#567¶25)SV c<©ý*P;<pj4#ÿ/«-4&'7!#5>54&#"#567!#"&432326ÎSV“þþ0ì/ c<>”[WƒaF:(a/32HuçþÏ)(Ý#ç äxMZp*80=ü/ *Ùi)þ$$ÿ&ÂÌE4&#"#5>=4#"#5>=4&#"567>32632#"&54632326n +B++à+B:(Þ*HD>0=ü/ *Ùiþæ)ý$K/TT²þæjp<;ÿÿ&åÌ04&#"567>32#5>=4#"#"&54632326PJ@3;#7?%Ð&I*$VS)52-%O0!OGå%"/Ña"þ¤jp<;ÿ&[Ì4%32632#"&=54#"#5>=4&#"567>32¨25)SVI*$&Ô&J@3;#7?°ÝP;<pj°MÑa"þç+ø%O0!OGåÿùãÂ##5>5.#5354&'53ã,þÚ  -~þ-¡±/þ›lþþ !0- þÂÚ/ ÿÿÿöÖÌ…ÿü†Ì/?%"#"&54632;#."32673#.+6:>74&#"326†BþùBVjsh^Ü)5Y()Y )! þ¿(#1 7)'rrƒXj‹ b •'(¤ !()E="(XM)ÿöŒæ7%#"&'##"&54>32&"32>54&543232>54Œ`R9??9R`\ŠKu½ÐÂu '",/.+1äW—I;;I—WMy<‘z‰b'C* 0=.546754&'53>54.'kc‡€j0ì/k‚j0ì/EQG5TGPQË |aiy k)(hyj^~ w)(ýÕ zI*PH þg™ nPKxÿÿÿûÿöE UJÂÀÿÿÿûE• JÍÀÿûÿ&±Â172326=4&'5332732632#"&'5#"&546",2"3ð0E25)QW%4X#:á+ &ú!BP;<kg\5)ÿ8OÌ#"&#"#5>54&#"567>32(,2"3ð0PD%4j#:þW+ &Â!\5)ÿ&SÌ)"&#"32632#"&54&#"567>32(,225)SVPD%4j#:þ˜P;<pjN!\5)€Í".#"!5>=>7>32V 9 =þü6 L/-;fYð87|B:$"'#ÿÎ:Í"#"&54632!5>=4Z;-/L 6þü= ±#'"$:B|78ðY ÎÐ&2;#'##5>54&'52654&#"ábSzr t‘(*Ø$ %¥H?/7ÐK/V"ª"Ñi,) .3%Þ>&"8·ÿÿ ÎÐ ÛÐÀ3ÿ&\Ë>273#.#"#"&'32632#"&=332654/.54632 2+"++l-'S:Q25)M4 (&-4:@5M;!:¸ ˆC8&+@7%4L5P;<drœ '!-!$B*6Eÿ´ÿ&€«>32#".#"#"&546323265gP_-;9VS)52Âqx#&%YýÊjp<;P ÿç«)".#"3#3##"&546232=#53#53432ç$<{z{{´"B$'23š25)SV5ce¢þ1P;<pj¢  t ÿÿÿúÿöîÂ" ŒúX ÿöæÂ'%"&54635#"#53"26545#4&+2æƒÀƒ`Hl·:?Z„Z@:¶ hHa©[XX[H^ €ŽN;BXXB54#53ï%f*á,Y+Çe,# 0•³˜„'+vƒ,% ”?35ÿ&UÂ"%2>732632#"&5!5#"#7!'. 25)N3þ¥ Š- [þó "#´P;<ft•!7vþkÿš©Â&%+'>7#5#"#7!36324&#"326©c7I * ' ‘ Š/[þó9m@"S!7*S6WE C•&2vþk¤X2Aÿ/jÂ4&'7#"'7!#"&432326$SV“¥#0”[WƒaF:(a/32Huç#u äxMZp*8&.DþþU:6D/0CP@F á*–3·_VX6EsW5&%63'œ¤%2#5>=232654&#"#"&546ÁZdP0ì/ DWK= "[¤‰n^|z)(ÂmVMa.*='œ¤&2#"/.#"32>3#5>=.546?[" =KWD /ì0Pd¤=*.aMVmÂ()z|^n‰ÿÿ'ÿòœ– 4ÖÀÿVœ£#4632#"/.#"3267#"&5ƒX?[" =KWD+>$ '&>!Sk¬oˆ=*.aMþ‡Ul*4 4 |aÿÿÿöÖÌ"y{ëRÿÿÍÐDÿÿ)ÿ÷Ê ýÆÁÀÿ÷ˆ£2#"&#"#&#"32=4&'53#"&546324632ˆ1a*j*?"SSK&½‰sƒ‡a'.xa";k<¶xt&AH(Vl#m%ˆ!~r`„ bƒÿÿÐOÿ[« $.#"&54632##"&5434.#"5673#"325 RS4'/DšOMS§'#0'9xýS(8C#D/sNþ7 0#3†ÿÿÿù NÂÀ®Ð45"32>73!5265h /ô2#Š þ}/ i,)(7þÁ "|'ÿ'n« 173276=4#"%"&#"#5>=#"&546325>32n>12$]@JÖ79)ì5$DYFZ^01P^-;ñ+PC "ÎdgúKYý=  *¼Jx_l”py#'œ¤-23##5>=#535232654&#"#"&546ÁZdPff0ì/^^ DWK= "[¤‰n^|:1)( 1…mVMa.*='œ¤.2#"/.#"32>33##5>=#535.546?[" =KWD ^^/ì0ffPd¤=*.aMVm…1 ()1:|^n‰ÿö«#+:%".'5##"&5463254&567!3267#"'54&#"326”|z *WY]vY:0&V=LþóŠE-kŠ0$V?(,;B1=‡‡=@ƒ]\š+œ%çþk(E(0áæ(M%#".546232654&#"'7#"7'5##"&5463254&567!54&#"326ˆhC:* DAH@, ϰ/"(“*WY]vY:0&V=F§WeþQ?(,;B1= fq, \G@F á/·(4=@ƒ]\š+œ%ç3·_æ(7#"'5##"&5463254&567!3632'#"%4#"326%54&#"326 c7I * ' ‘*WY]vY91&V=Lþó9m@"„Š0$E$6Z7*Sþe?(,;B1=6WE C =@ƒ]\š+œ%çþk¤ý(0á4 ŠAæ(76763#;2654.546323273#&#"W:Î\5 :]]3#./BC/S9=  T.0FE0w9H-Tt þ¾T&#-#'@)8B ‰{$1#&< ÿ"«-4".#"#"&546232=#"5#'>76763432#32"$<´"B$<,<\5<p´"Bþèp3 n&%Ytþ@é&%Y 8-VtéýÁUþÝU ÿšDCL%#"''>7&'#"5#'>76763#32>7&54632#".#"6324#"326}?9+ G 2X\5<ee3  |d2c ?B10T:;&+L%U—=d[ HHq-Vt þÛS  (/f‘7.""oC:cx4e/ÿ&¶«M".#"327>32#"&5463232654#"#5>=4+!5>5#53>32A 9{e"3;#7?VS)52I*$&Ô&=z =þü6RRP^-;DYt O0!OGþÊjp<>Maa"þç+øPþÆ87: py#«55673254.546323273#&#"#!5>54&#"c<0iQ/BC/S9=  T.0FE0V;þ¥/ oý²)?-#'@)8B ‰{$1#%<(8@(Ý#«!567!32>7!5>54&#"#"c<KþóŠ'. þ/ ÝŠ, oçþk "#‡(Ý#þåÿPÿúÏ–/_77.'537654#53#"/#"/&'537.'537654#53#"/#"/&'53~3; „*2 PP  ;I  Ru3; „*2 PP  ;I  RuÉzw!ir  »Ž¾$ yzw!ir  »Ž¾$ eÌ–%#"'7!.#"'7!.lð¢ð¢Ó(§§(†(§§(ÿVÒ6%326754&'53327'#"=4#"#"&54632K3,Ø+ Q""E,{21;"#8# ¨j"ñ45þ)  0-'Ÿ¸c<5'H'&ÿÉÔ@%32754&'5332632#".4&7#"=4#"#"&54632M85-Ø-21;",  :X|21;",  ¥j?ñ0#!1þBc< $'))*RŸºc< $')))ÿû1§%#5>=4ȷ632#5>=4#"[Œ 0,+4P ‰1#Ñw ý  ·3`h^?ÿù/§,"&#"632#5>=4#"#5>=>32¾ $%+4P ‰1#%Œ 4=&`-6h3`i_?&x ÃCH q¼Ž567#"&54632326=4&62"&4S,9n"   Ð þîƒ $%.˾ÿÿM¯K¤L õâ&#"32632#"&54632í"&'/4=<*%½#-*;4*> T ýâ732654#"#"54632#"T #&' / 4<;*&#-*;4*>L õâ#"&54632#"&#"32í%*<=4/'&"0 >*4;*-#fÿöÆ632#"'732654&#"f*99*!" » ;R: ++XÿèÆ&#"327#"&4632è "!*99*»++ :R; ûB¢#'#73B"zy"|>ûgg§ ûB¢#'37B}>|"yz¢§§gg #BY!! 7þÉY6]û=¦ #7632…(“û” ûò¦ #'&54>;2ò(š ûa ÿÿ ÿgBÿqýD2þØÿƒ #'&54>;2(š þØa 3þØÿƒ 7>;23“ šþØ” a þ’Aÿ533!5‹6€þÉþÈ··66 þbAÿO#5!##‹7€6ç66·%þ}'ÿ ##5#5353'f6ff6ç6ff6ff ÿBÿO!! 7þɱ6û3˜ 3#"&'3326|8Q 50,.˜FW2/(v Ùn 2#"&546¦n(C Ç 2#"&546"3264&¦);;)*9;)'&''Ç;R::*(;"&6'&6'@ÿ[ù#"&547332å5;*6.,IL, .+#"K~3#"/&#"#>32326.0) 1# 4&$" ~91 .14 ÿýûy¦#7632#7632Á(“#þÊ(“#û” a” ÿÿ±‘¤ •ÿÿþÆûÿ¥¦\þ³ÿÿÿûÿð¦[þ³ÿÿþ¾ûÿõ¢Xþ³ÿÿþ´ÿþ~hþ³ÿÿþ¾#ÿõYZþ³þ#ÿõY!!þÞþ"Y6ÿÿþÍûÿæ˜dþ³ÿÿÿ) ÿŒneþ³ÿÿþÅ ÿïnjþ³ÿ õÿ Æ#4654#"#"54632œ%( )37õ&U0 $!&Hÿÿþöÿ½Çfþ³ÿÿþ°û,¦iþ³ÿÿþ¾ûÿõ¢Yþ³ÿ7ûÿ{¿ #&54632ž ûþôûÿ¾¿ #&54632#&54632[ Ÿ û‰þ°û,¦3'&#"3'&#"˜(“#6(“#û” a” þÍûÿæÍ3#"&=332>'4632#"&7€:P_& —˜NJa"! þÍûÿæ˜ 3&#"3>327|8Q 50,.ûFW2/(ÿÿþÿ ÿ¨âSþ³ÿÿÿ ÿ°âTþ³ÿÿþÿ ÿ¨âUþ³þ–±ÿ!¤"#"&54632'>54þì&$ R ,&<)/Z ;þåþØÿÄÿƒ #'&54>;2<(š þØa þæþØÿÅÿƒ 7>;2þæ“ šþØ” aþâþJÿÏÿ#5353#g··66þË6€þÉþãþJÿÐÿ#33ç66·þË7€6þãùÿÐæ#5#506·æí·6þ³Mÿ}42654.54632#"'5þû"0 & #&/K53i% #9/5J"ÿ þµÿ›ÿ|&#"327#"&4632e "!*99*++ :R;þ½þ’ÿôÿ533!5Â6€þÉþÈ··66þ½þbÿôÿO#5!##Â7€6ç66·þØþ}ÿÚÿ ##5#5353&f6ff6ç6ff6ffþ¾ÿÿõÿO!!þ¾7þɱ6þ:ÿþ×.!#5367"&54623265þ¾90 -B."  »!.- þ“ÿÿ0.!327.5462"&=73þ¬ ".B- 0˜ -.!» ÿ(ÿÿŠÿƒ 4632#"&د! þÅÿÿîÿƒ 4632#"&74632#"&þÅǯ! ! þöþµÿ½ÿ| 4632#"7"3264&þö9*);;)**"!'&þïR;;R:¥++&6'þøþçÿƒÿÚ#"&54632'654²  !".>2 RŽ 3&-T82ÿÿþçÿ)ÿ¸zþ³ÿÿþóÿ[ÿ¬gþ³ÿ7þ¹ÿ{ÿ} #"&547ž ƒ‰þ½þ£ÿôÿO##5!#BË676çv¬¬þ½þ‹ÿüÿg+32>32654'&5432#"&'#"&54632Ý    ,K9(AK %=*2))1)?<X5$*6*$5Yþ¾þ´ÿõÿ[#'37 }>|"yz¥§§ggþ¾þ³ÿõÿZ#'#73 "zy"|>þ³gg§þÍþÉÿæÿf3#"&=332>7€:P_& šNJa"þÍþÈÿæÿe.#"#546327 &_P:€þÈ"aJNþ´þçÿþÿQ3#"/&#"#>32326 (2'4.#¯) .(= þ¾ÿÿõÿO!!þ¾7þɱ6þÿÿõÿO!!þÞþ"±6þþ­ÿõÿO!!!!þÞþ"Þþ"±666þÆ„3#"/&#"#>32326  (2'4.#„) .(= þÌÉÿ­ô%3#þÌááô+þ%Éÿáô%!!þ%¼þDô+þ1mÿÕP-þ1’þn”¼'¼þV2ÿ¯‹%þV:þÆQ:þÆÿþµÿ©ÿ|632#"'732654&#"ç*99*!" ;R: ++þ½þãÿôÿ53!53B6þÉ6çv¬¬vþÕþJÿÚÿO5#'!!\™6þûþ˜˜Îþûþ¿þªÿóÿ["2.#"#".'"&#"4632>]!/%   5 % (¥/ % !(% 8+)(,þãúÿÐæ 7'77'þãQQ%RR$PP)MMPQ'RR(PO%MMÿîÿ“í4&5467'6¬4/; 5446 55/& 7%þ#ÿõÅ!!5!!þÞþ"Þþ"Y6¢6ÿUL¶#"&#"#>323267L6'T%6*U¶)8+++6+þË-ÿîñ"&462'#.5462"&462((RU((q((D"`" L3m((ÿ4ÿÿÛÿµ#"=33265%]JL¥XOc.NþDõ§¯23267#"$#"'>ÏC J;u8?;$3þÆ0?q+u›TA'1C! TF"]DþH÷ˆÀ.#"'>32ˆDGuG-9qR\Dg˜U}Óþ*6& 32š‡â @2<".ÿ!È #"&547ȇ @2<"ÿ(ÿµ#"=33265(]JL¥XOc.NÿÿPÿsÛËX-Êð #7>2ÊS(Õš ÿÿ < "·1jÿÿ·"·ÇÂB`¸Ö"&462¸"2""2´2""2"ÿÿÿ~UŸ#·ÿ&ÿ¯Æÿÿÿ…¾™#·ÿ-ÿ©ÈÿÿÿÀ;Ÿ#·ÿhÿ¯ÊÿÿÿÐÿò°·#·ÿxÿÇÐÿÿÿ¡¥ #·ÿIÿ¯Õÿÿÿ±É¤#·ÿYÿ©ÙÿÿÿÐÿö "¸¾ýéÿÿ¢$ÿÿQ–% "–#.+"!5>54&'5!"+)(ˆ $7þè9!6%,þ6"';±5!v¢)3 výŠ6 ¹Üá¢ý€Ýþ#ÿÿ U–(ÿÿ U–=ÿÿ¾–+ÿôÊ¡. &6 4."32>#4&+"#53;26=3ÊÈþäÈÇ[2o”o0&5N.8\8\’’ÚþâÈÈÇþ©HŠeeŠH*UP>%9[j-#(Á*!ÿÿ;–,ÿÿ"Ó–.¢!!#532>54' 3#5>73Âÿ«²DÆ5Ðù  1œþO*=HëýÈ  ÿÿ _–0ÿÿ ÿõÖ1=;– !-#4&#!"#5!#4+"#53;2654'3!533!26=3;&/þÇ0þb;£ £%bþVC"&ç/,'4¯þIB"Ø"þI¯[1#ÿÿ"ÿò°¤2¾–)5>5!!5>54&'5!¾þê:þÑ"6þê: 8«7!"6&<òþ5"&<±7 6þD5"ÿÿ–32•) !#.+"!26=32ýÜLþ¶ dB¤ IS]þô1#)LI±@RMRZþõ2#ÿÿQ–7)¥ =4.#"#"&54632>32#"&54654&#"3!52>53)&$"9$-N7% #7K,$9"$"S/+þä"%KyI2 )!7 %324+5!&#"6324&#26"Ëa^S ,' þâW q¥!8IO(T *1# 3bT4jkU^bþÜYcZ55 (/^xl+J3#X)11U7Ucþ|mm„^XÎÿÿ À–;L–Q4.'53234.'5!27>76;#"';!526=#"&'.546U 4%$/+&= ZA"+.##7$?`;+ ;"þÔ#A 2n%($/  ?P^SC Y@þ¦ BQ^P@   *C;Kdq &%!q"U: 8!ɤ-#32673!5>54&#"!53;5"&54>32É‘kœ$þîSbhczaTþî¢k‘7^sBDvh<œlŸ9(š©VhŠŽdW©œ(9ŸlEi=:k;)#"&462"&462!5>54&'5! ((|((Ïþ×;&&;):((: ((((ü×9¼9 8þD8  †'P"&462"&4624.#"#"&54632>32#"&54654&#"3!52>546Ø((¢((/1$"9$-N7% #7K,$9"$"S/+þä" ((((ýÊo¡R$ )!7 %.9 d:Zks\AJ  T#+¡<-$2 9,.<ku#!8H‹\^’cG {r<B~,UF0LD"+OAOZHÿ7ì£9%#"&'332>54.#"#"546232>54&#"#4>32ìgW,G8'4 / &)$ 51#/R,R9HeŠTcÄXt0)'@K&:9$! 061J!<5"ýdU5\U1IEd/ _ÿ ÍÍ+4>54&#"#4323>5>32#"&Çt1K-*&^^œ5[9 =û'œ/?bB\\tn¨– |H*+,ÿúê¥%3%#"&546327.54632#.#"4.#"32ê}db{xU( =,/>15YG*(0GTG0]@0@> :'yÝa‚}^Rs $,/8C2(6)&;AdM-M:T@#EC))ÿöÍ6%#"&54675.54632#".#"32632#"&#"327+‘CgG/*EhA16" #*(#1  . $-<3Z(lvE@.A5(<=#$9+ 54%3>]'ÿ>Ȳ?#"543232654#"#"&547.54632&#"632#"'32632ÈyIC'C5W9 dSn0[N1 (; @W#Q&6/.12( ( @<-FO&)7ch¶‰8*,)$0?3›O1> .ÿ ÛÍ##4#"#4.#"#4323>32ÛT>U*[$ F='4 à&cþ´@gd",,D`27%3ÿöã )".54>2"#2>5ã .PhP. 0L`L0 \øøø-:-U0WbG//GbW0+VZD,,DZV"þÞ!*M5775M*;ÿö Ã%#"&5332>=3 /97/To;>;9Yþ… # á'>32#"&#"3#5254.'#4ȷº€m*+0f³%â,06?H%-\>O'^á?AKøQ-&ÿöÊ¡)%#"./##.#"#5463232673ÊC:€U² $$(- b [e'ãþ²Ã4 *5*@" &P/M?^o^?83;O/hN.". $4K&P][z\2D)€$bxoM(455$ / !-5 :M2)!H?7^/4M68$''+3*.2?A(0A&#- ,ÿÿÿöÖÌR#ÿö(Ö0+32653#"&5##".6'3325#"#>32327(*6*i21†f R24  BP1Ä1#Ö< þåEN*œ@3AþÛ#$%$0L-,ÿ#áÍ*%#"'#>54&54>324.#"32>áwfE6 T1V8ct\ 8&| :%!/ éh‹+ST/ " 6×65_P/€‰$IN1Á"IE,!89'ÿµô:2654&#"#"&5467632#"&#";72632#"&54632E)cI`ŠU52L$;"C6 O&6 "D,#. 0“*!~an¨(  .8+=V!3(6@-")ÿö ß"#"'#"&546323274.#"32 5/"*2x]b}~h~2 ;*=4ƒyßS _4^ˆ†bh‡ þÝ(JQ1gDò ÿö’Ô%#"'3253#"&5&#"#>32327’40: (+=00;%˜%"Ô9(þèw(+6+!=9ÿöÐÍ$#"&54654#"#463232654&54632ÐÂHP#0(610$2=F=?1þÅXI$‘$9\:FO4|6@g@(Ž$”ÿçÿ Í)42#7.54632.#"&54>4.#">(: zhT4L<+TK'(-)QQ $:• +]\iÍ'@A"lœÖÖ "4_=Vƒ!iK€dB,FV@8È67"ŽþñŒÿ/ÍÍ-#"./#'.#"#&54632733273Í + +†Y¸- 4$# /{W¬"+Y+9Bƒþñyu$N#)?)Œõþ©?>F+Sÿ }C0#7.54654#"#54323>54&54632¨ ^ _w!2d/2D?EV3 -X ÖÖh^s8_„O1x?G5ýË rH(‡ *";lgF)ÿöŒÍ@%#"&'##"&546732>54&543232>=4.'5Œ`R9>>9R`j]*  #",/.+1!+ &]jäW—I;;I—W_ˆ#9(  8&(0323>324#">4#"32ê|cqn4'‹R$5Nkn!%fBawP7E…^]F ƒ'8 GAàd†šuhOh#"*?Rm>Ji;)dB1þkÅ$>@%Dnÿö9Á3@#4##".546=4#"#4>3232="546322/.#"9AÉ3D *'#"-"kîQ:˜$2'´ &$BU!!þ¡"@B.LTV#*;:+ 2 &22Ѹ¤:Lþî88XF9 !ˆÿþb ?#"&54654&#"3!52>5465&6.'.54;2>32b"$"S/+þä"/)"2kQ! (4 $9? 7!) Là$‘$'T9EGF;-  LB',!*B*+<ÿÿÿ„b®"·ÿ,ÿ¾ÿÿÿþbC"j„Õ+ÿ U@%#7.546?34&'>U†oFo†—jj–TZPJX×PZWJâlzÖÖzlg~ss~gRuþc|tSM|ÿö J##"&'##"&5467#>3!54.+"32654&543232>5m66`R9>>9R`33#* K)ó] %Ü$ #1,/.+1!+µqBW—I;;I—W@o/Sþä 5!# "2! 8&(W6"t88s7V*L6&!ÿnõÍE%#"&542327#"547#"&54>7654#"#54>3267>32327õGK$<3 f%W`* #"? &Z5Q$]?2 –Dsq p¬'&H+ "%?6j- 4,²!"1<67OM6iKÿFט3"5463232654'.'&546323273#"&#"Þid/K H_bY_^n/  -;JOZTbbR ”º9&=- KGGLs¢ ?<fN(/83+3&Ycÿ>—Ì2"5463232654.'&54>323273#"&#"„NJ)E4MPA &X<X% */:GV=MN;†Â'6' 97AxW1.bG+'!'OXÿ÷ó+'. #"67'.#"'#'>554&/é  +3!’!;9!:ü*#=™   é‘H!ß5!,º? 7ÿ Ó1#"&#"6323273#"&#"#"54>32327 (/</ ;H' (/ 6#$2*$N:W& Ó2-+%:&=Q2-3%„ *68fP;ÿ9:!>"&54?654#"#!>?>54.'&546323263![P#– $ (þå&€.. !I#–# +%€ . Ç?,"7î %0ÀC& F$%4î &0À(- ;ÿµ:Ÿ1>?>7327"3263!+657654#"#;&€( 'U7–# +%€%/– $ ( %0À:ŽTî &0À8+P î ÿÿþ­054''&'"#"547.+"&#"&5467>3232#>¼ŒÖ*w þÁ!A" %a J$ ~™F;BNH*Éþëì þ` ™;  ÉŸ>Ð14Ú! åJ<"#"'632&54654'654'#"54>?654&'"&7>7.˜0):M¦%   l[,]ˆ! $'Z]4 !·! L8$ e5"JIU,g99B4\GJg$ .PH -‚+5!ÿöõÍ=%#"547#"&54>7654#"#54>3267>323273õ !W`* #"? &Z5Q$]?2 …+¬'&H+ "%?6j- 4,²!"1<67OM6iK)ÿ áÍ!2%#"&'##54.'&546324.#"32>áwfDh 39>8.+EKN0qpct\ 8&| :%!/ éh‹RA#39D4. 64gu£€‰$IN1Á"IE,!89)ÿö°Í%#"&54632.#"3267°=kb}~hd=;1t - 2=LV†bh‡V( À!+F*!)ÿÿ Us"(C®Í$…f >4632"&74632"&4!#.+3253#4&+;2673!5265&&-&.ý.-%6%þý"A!&ƱZ(6­!ŽKI$8ý×@#&$$#"##$%àF,— , þ÷dò52ù=G«-Fÿ&à–7"&#"32>54.#"5323'!3>;!5.=>322;#Lo18Z6/<*6U9ýÌ9T6 >$>".#8X*M¸< p›T8r`="-ï-SªªR.þ @! 7ïS{Bƒº "s!7!5>54&'5!#.+"7#7632É!:þè9 7 6Uˆ (“#m6!#>±5!C& z” ÿòy¤!3267'#".'!5!>323'##"&#"·•UŽ.iv ÀE˜»B=e '=hD,–ºâ!!Ãÿÿ*ÿòë¤6ÿÿ;–,ÿÿ ;+",jÿú½ÿÿ ÿòr–-ÿó´–0;%#!5>5##"&546322676=4&'5!3232654#"´3ST,þú:Ø%E.)< ( ,:;#EBd:# þ¬e`®"µ3K&"?òþñ4suL$#bŒÎ6!7³'60ˆIM“´–3>%#!5>=!!5>54&'5!!54&'5!3232654#"´3ST,þú:þÑ 8þê:::/:;#EBd:# þ¬e`®"µ3K&"?ÒÝ5 "?±66³³6!7³'60ˆIM“¥–.%!5>5#"#7!#.+>32#5>=4#"d">þÜ> 6T949U648"7?%Ð&I*$m7 !@ô.RªªS-ñ1 OGß%"/Ëa""¡s=F#"&#"3#'.+!5>54&'5!3267>32%#7632Ž$> C1(X ¤‰ :þæ; := 7YI1XþŒ(“#\"P?]C‘' Þ&Ù7#>±5!7½YCY;>j” ¾s+4754&'5!!5>5!5>54&'5!%#'&5432Ñ/:: 8þê:þÑ 8þê:::(š"Ò0'66þD5 "?JþÐ%5 "?±66Ÿaÿô×e/<732>7.'5!654&'53#"&5463#"&'3326—  –&0u™)õ73Ñ+KC(7c|8Q 50,.oc7>$9þì*7 =þgSE#öFW2/(ÿI¾–'!5.54675!!4675!!3547¾: 8þê:þÑ 8þê::$8"6¼5 "?þý5 "?þO6‘ › ôÍ 3!5254/!3#5>73„&'þæH 4þë=IÆ!$zôÍýŽ,0w .'5Z©þé'`®%4!#&+32#!5265%4&#"326ˆ%<~¨FHm>' „oþº;&]Sa##&K];:'sþø'6/Th&4.#"326RA<2D 5pPþÅB"#ACf;$ s^G!:)4#*T9,'J[÷1W .7'":;".E¥F,%3.ARþô <þä10þã R*_®4!#.+!5265Œ)9.CY±,8þÎ<&@8$œ5=ýÒ$(: ÿ@Ê®!*4!#";#.+"#5>265#ì):A('#3 noÁEL!% 8V-Ý"á n;8)$/þ&0-ÒlT',1<Òb…¦oþ!$¸þíŽ$…®(4!#.+3253#4&+;2673!5265‡"A!&ƱZ(6­!ŽKI$8ý×@#*F,— , þ÷dò52ù=G«-Fϵ`%;!526="#52>767.#""&5463232754!32>7632#"&#"3#.#'W þÒ3/ 0T±)F-G # -A(0'>G<6 02.8* 0;'!(2*@%# !"$'/D/±¬ fT!0ï-)M¡4.+526f8,ˆi1Ro‡!/$Ši‹JEg,= &K4g^!7-¥ÌdO…! $?'Xm‡ a41600!M#®/%265;!532654&+5!#"4&+5!";!5ö/!þ¬ /þÏ(*+, 1OT)*212!2þÎ-.žþ]++(3ß/!PþZ£/$!/þ!.-ÿÿ#s'döÛ*#æ¶:"32>7632#"&#";#'.+;!53254!H+*/E) +V[&C 5@)T*?B. ³«&7&RþËV225œ%0Ò(BDH98$!<ˆ Y;Z?í7(ïKUã0"ÿùÊ®%72>=4+5!"3!5>5##"54632š#W =3/*8þÎ5/ã®V";D6[^3æP!,þ*'!.!þóþ‚?(+²¯$4&'533"3!5265##5265'=ÒôñÐB""BþËC"þöþõ @ñC!&;7ýó ,Fþ[F--F»ýÀ@þEF+,G#¯+%>=!3!52654!"!54!"3!ÞE!þ®#BþÌA""A4B#R!E6B"#AþÊ*GÇÆF..E¥F,-E´´H*,Fþ[F-%ÿñÞ¾ #"'&5476 2654.#"ÞSNTeŒjiff fgþ¤f{ 1R4@\/xY[¡48gh˜’jjhhþ*¬‘*RYB+=df7²#®"%265!;!53254!#";!5ö,þ²+þÍS03ì 1%TþÍ/,ýé,/Vã.#+)þJI¯"#"'3!5>54!24&#"326I|b=H$CþËB !A%{‘|[B$&4!COîNnÃF-+F¥F,kYHV þïQ)ÿñ·¿"23273#.#"3267#"&546Ÿ3Q1  ‡U%EE2 6WW,M"d¿™ÒÖ¾.ébb.IxMV~@M; ©É”œÔ…®7265#"#7!#.+3!³@#Y9.] ,)]%@þÌ.Eþ)››%/þF-ÿñØ®$72327.#5!#"654+53#"&54ÃA$(ÿ1#$ CÅ’; ÓF)Ç?{(1]-HÏ0%' þ¤R$ )[þCŒ!2'?®(7G4!32#"'3!5265#"&54>34.#"32>%327&#"}0325.0Sz>¡ƒ.*9þÎ:)0 y£+AjD#<@#7P)ýÁ)P725'L." ..LL)o‡1&%2†p!?@0î;V,þb)DF%%FD)ž -Kö®5!"7654#53"3!5254'.'#5>?'.'AEuŒDì%,<3oš# "þÐC\¢Bá%A(³4>2®& ¢ª'B<ˆ×0$ %#"Ä$30×ÙI+%ÿ@®-%;#.#!52654&+5!#";2654+5!#"­%2 nnþ10()1&(!ç!P1/!p5)ÒlT(9Ú-"*6þ(%"íO**ȯ*4!"32754!";!5326=#"&5u213;)2?Af(<321TþÍ+*x]bMM-"('¨3:)ä.)"2þM'3Ï9UN$>®6%3!5254+5!";2654!";2654!"å'2ûæZP 4#!¥!+,4#!¤!+,.+h*,OæU-/þã7%-/þã4(%7$ÿ@>®:.#!5254+5!";2654!";2654!"3,nmüëZP 4#!¥!+,4#!¤!+,.+'2ÀmSOæU-/þã7%-/þã4(%7þ(*,Òή,7>5#"#7!#"32#!%4.#"326“B @', ¥,);[€>4gFþ½À%P9!#)J\,Eÿ2' (:¾$<=#<<%Æ,0þÚX&´®,@4.'5!#"32#!53265%4.#"3264&'5!3!5>5‡ 0T;Jq@) "5[:þ¿)*]":="#&L\ü!G„,50U:\€>3gFþ¾/#]%=9 #&66!F4 FÚ#><#<<%,-Y,> þÚ!Bÿñ–¾""#"'#3>32!!#"'326&#-Q4  †TlŠþÓ-’wb 4;X0‘ÓÖ¾.êbe¤€+Œ£† #1%Ç4Ò&ÿñ,¾&>"367632#"&'&'#3!5>54!4.#"32>R6*•_`ŒŽÄef„T03•'9þÔ1/00,_)86.6+%(BF'6<-œ&3̓bcÏ”fgZLQcà-,$0â/#þ¤JsF- 0DiAYB )Btʯ$,"323263!5.5467354632"Ed3®›/I0³  ! @+? 7 þMWD$)è¯"8:ƒ-À:;B½F++F¥C-·=Wþê(ÿòãÚ'42327#"'#".54674&#"#"54653276íZ='=3=WL+-~<"+',d”o%$!Ú@Uè0*LTT7+>\0^:%  **5?þƒ¶/,! 1ÿòûÇ!-"&546763273#>32"32654&f}SS,UH5VZ7G< FM*/B5&EEh0K^:.NSœéA'?w_;O 0W8jKLÃNe€oUae‡ÍÐ(4Ȕ+5>574+324&#"32>h +×^`ZuÙ×,ó€# ‰>J(#3 s'$5DM[ƒ'*÷U°|&8¶ $®Ð.+3#52654!™  Š#2ô/ !.ƒT  þÁ8'),&|ÿ„úÐ$4&+"#5>7654&'5!"3'265#è?IÂx 0 . ,JÊU|0L|Ž5,"Z`)((4þõEŽœ!]þÚj ÿòžÛ327#"&54632!7.#"c!G.a$^MXlp^OaþÆÔ5-. =J4kIh„lp‰fT'7@+"¸ÔY7.#"#"&54632;545"32>32#"&#"#'&#"#5>=&#"#56?6ë % (1,$%Ù(#,1' $  6&'$0~e)Ù' e}0$&+ü 2.$ #+=>+q)!$&q+>=+ B QF@°8Œ&")Œ8°@FUÿòÛ%4&#"#7332632#"'732654Ȏ7*^ D'MZ{ŽlRiJ OM.==G0Gh)2€@5Ri>KV =;0)?,Â+?4.'53#5>=#5>=4&'53¢Í Ð%%Ð&Í&Ð&&Ð%‰á%þà%"/Ïá$"/ü/"%ÿÿ‡"daïJöÕ82>32#"&#"#'&#"#5>545"Ë%0/$"$  % 3"{Iå, -å$% +==+  (3&$S"Æ$ŒG$$*'#.gÿò÷Ð#4&'5!"3#5265##"54632325•0­- '&í."¥89@ # /l+$))þü1%'5BöqW8# €Ð#453"3#5>5##5>5b*ž”›š*Iß)«¦ &¯,o('þ¡_(5þúI#$%þ€€þè1#&-Ð*"3545#526=##56545õ"!Ð "Û+#&Û(Ð*ÜI+ܾ,ss* $%þî- #&††'!H("-ÿòûÛ%#"'&546322654&#"ûFGbYDBˆgYDBÙ9FWE2LY÷gOODBc` DEþÂfSd‡Sbd‹Ð4!#5265##565b++#&Û(Ð*ÜIs)"$&þï- #&Uþ«'!Hÿ- Û!14&#"'73632#"'3#5265"32>54&d “FZ'6+FFXC.%1ú2!Æ?6%--LB0&7jj 0V5sGJ+€7&&7÷B¬95)P7Vlÿò«Ú327#"&54632#".#"jXJm"o?\re$;"#$;H]pqWd‹em‹%+%_ÌÐ.+#5265#"#7!· K&%æ-K ˜T þ­*')N ||ÿ,äÐ%232?&'537654'53#"&546X 5,%¡!+Ï  qM.„~(R9)od(gJ$ýÔN *Gþªi]$ÿ-wÍ*2;;#526=#"'&54763254#"'73632#"'27&#""3254u$%è&$+4A0100B1. ˆ,4E]]E2.š+)"`G$('#bv* !/.FFigFG.¨3=þà.Œjl‡. +O,þZ¦,þ±+Ï×ãÐ-37654'53#5254/3#56?'.'Ñ&*0$š4?1N39Í+BU,—,9YO,!Ð CF ]I{R7/i~U„{/%ÿ`åÂ#%#.#!5>54&'5334&'53â90þ­%%Ð&¯%Ð&¯@`% %"/þÆL%"/ü/"úÐ)45"327545#5>=#"&5U&Ô'!/2:'Û*,ç(&B`A)t%%$&S){&$#&þî($)„),?Ð74&'53"3!5>54&'53;26545";265z!#Ú($"ý & +Ü+!]"!×(#Vv',9ÿ)*%"',þì#$ )--þò$ÿ„Ð:%3#&#!5>54&'53;26545";2654&'53"Ê(ý¤& +Ü)!]"!×(#V!#Ú(b/!Ž|*%"%.þì#$ )--þò$$',9Ð("#7!"32+52654&#"326/2#8GU_pÛ,"ÿC, 5D° ! |(/`!*8R&#UþÖ5,¹ 8µÐ%9"32+5265454&#"3264&'53"3#5265 3#9FXC"(PÏ''&(ôZD,!6D²,ç-&&ç&%¾'0`!+2A ,+þ¶5,¹ :*%((þé''ÆÐ)"32+5265454.#"3263#9GU# (PÏ''&(ôY$#!!A8¾'0`!*0 ,+þ¶)¹ @ÿòÛ>32#3#"'32654&#"#"'#J# s™™ƒQDMh[xwY!L  B/¶ÐP h“liˆÿòðÚ&4"3>32#".'#3#52654&'57"32654&-qw_]ˆFI_4R- q%&ç&&$(ç÷6B%7++MS¾$,oW„hiJL)9H1Š('-!cQGh0Wdf† ÎÐ&7>=##532?&546;#;5&#"ö*(‘t rzSbÔ% $ØT?H7/),iÑ"ª"V/K%3ÿ. V&>·8ÿö¨Ÿ$3267#"&54632%3.#"7#'&5432a010G$nGVeu\LT þÎÌ *.ZÝ(š"?[-09QVygo‡[\ A2La ÿòž± .64632#"&74632#"&327#"&54632!7.#"b&&¬«!G._&`MXkp^OaþÆÓ5,(4}%%þ£=J4kGj„lp‰gS'7@20 ÿ'Ù«9"&#"32654&#"535#5'632#335.=>32U25)SVA8,D#ss] pp+Ø,3I·<pj6FO'-—"w "þW54ñ"aþŸP;Ÿ#.+#5>=4&'57#7632} -v%Ð&&o(“#Â}7!þ´%"/ü/"2” ÿöœÌ%"32>7'#"&'35#5463232654&ôZkS$?(#$>+5##"%3267654'&# # & 0FV iu½&’K1B¤0&+B +o8†/" O -3Q"/:Àxnã (@°Â3A%+5>=##5>=4&'53354&'53"32%3267654'&°iu½&¯%Ð&&Ð%¯&Ò 0FV þø0&+B„3Q"/u‡%"/ü/"%tb/" O ) (@ «24#"#5>5#5354&#"57673#>32#5>5‡K3,Ø+pp D/ss#D,{)Ô+,j"ñ45©" w"—-'ŸÇ4 3ÿÿöž&[/øLÿÿŸ&\zùJÿÿÿ,ä•&dTýUÿ~åÂ'%#4675#3376735.54675#T¯%Ð&&Ä( Ç%%Ð&%L%"/ü/"[ 67% %"/A÷¯D4&'&'5#"'#"&54>54'5732754&'5!32>Í$Yâ!ª‹€&!9#‹ª!âT)&9`=J&!@)=%$T=`9&4r '  ! 2bE¨Û£6!Û¨F^1!  )w3%IN;&8É9"4¼F&;NI)ÿ÷ŒÍ/43232654&'5#"'##"&546732654&,/...10*AYncOnnMel[%-a-0I86?Ndqfa‚e]ƒƒŽ_d„ @92ÓO>‡€– 32=4#'.'5!3#.#72#!5>5"#7, Å®¡16"¯8WEBd:# 1RU.þø6T9Kþü•“÷"&ªM3¨'504J& 3°2Nª­/A7>5#"#7354&#5673#.+32+%4&+32737>=x 4,  w 60GW(:l½323273#'.#"!!#3767§+“S›`Gi#BþÌO"A4C"j;M_F?s!  kMk|/þõ%"2C=!eaq=AfV‚³F.(7§ @(,DÅMwB* !!âHY˜},Ch<' \ÿ÷ŽÐ;%>32+.#"3#32>7#"&'##56545" ƒL<^=K±¯ Q?),[>YcX'ÜI*Ü&þ`n:-&)"`M%BX UG‚`~*E)!"'w¿² #&35>73/#56=46=#3!$Þö"%#è2M+2Kþš$$OL8¦Jœ!:BýÊD#£v©0- ! P­“1ÉÂßÏ%(35>7632/#6?4>=#3 € x) Ÿ.' ! ¹ #,i)S&"A1.þá\ Pr\; *zu9i² CF%6=#56=4/#4&'5!!3!5>?!!5>5%3'$OL8$÷K)2M+ý« 8 0ŒöýW Aþá!7þê8 ÈœR N­“1! bv©0-14  þmýÊ'+"©¬3"#?ÌÂæÐ'3=@45"37632!5>?##565%>54/>=#7'b*Ü&âI x#þ6 (Ó(ÜI# .‚ "-“*(t)!"'Ž·1# þáM% eg*Ei\4 r±zuÐiiÏ–8C%26="#52>7>73'.'5!"33#.#;!4&5!765[20 1S±"8/&8 fF1(8$¢' ‰k±!""±¬ "V þÒQþéq(2ð ,+OŸ#BEa#iE2% «þÒ.ìTc²Š1¸Ñ@O&+5!#"#"#;#'&'##5>='#"#56?636;?>=2='#½#Ò ,2  '!$0~e(Ù' e}0$&3(!\U À˜' 9N&%;@°6‚)* 8°@Fa~  ö°KV%26="#52>7!!5>54&'5!!'.'5!"33#.#;!4&5!765‚20!1S±)F-O!þƒ!7þê8 8F1(8$¢' ‰k±!""±¬ "V þÒQþéq(2ï ,*OŸ;M‰.ä3"#?Ë4 #ÆiE2% «þÒ.ìTc²Š1¯ÑWk45"!.'5!#"#"#;#'&'##5>=&#"#"'#56?67!#5657>=2='#Z*Ü&rP7Ò ,2  '!$0~e(Ù' e}0$ þø'ÜIÆBU Àt)!"'w|C 9N&%;@°6‚)* "°@;:ƒ*E7i~  ÿ1è@P26;#".546;2327654&+52654&#"#5332632#"3#"&=332>–S +%EC(OT+I#cRad=9ˆf5Pr‡FWL¹iU/2!+1# ,U@-2'/K'6##(75#"#675!3"'5.6.'&+3'&'37#!5#"&=332>76ø9D /$!BXþè)0o+#&4; #?Sq04,&6CPA ²% L'  2EQ.3> \> 2þ§+[^ZC  A9gh2>r2'q ;'!ÿ }H2#&?54&#"354323'>=&#"#3QJ†5,d2#ua ^ )C+! BŸ‹%Du :ýÆ €¶6I„_8­]hÖÖ$1A32#&#"#73ö "D # R"¶Wƒz*mCJ(i"= QþÝØþ¢ÿÿÿöv'z Іÿÿ ÿÿÒ 'zZÿú‡%ÿò5¾$K#"'&=476 26=4.#"%2327.#5!#"654+53#"&'54Þ&'¥hŒjiff fgþ¤hy 1R4@\/{A#)ÿ0'$ AÅ’; ÓF)Ç?{$3YOWRofh—’jjhg•þ¾¯*RYB+7>>32>=4&'#"€5gY7%FvI6iY75Wh5(6(eP V\^Zä 5VƒL7qgK !6VƒLJX8Q-@qG‡¥ ªyz³ÿÜÖë12#"'.=467>"'>32>=4.'ëQjeC! MeUH! %6!% &'+! ë {Zb{ ƒXUxf L4_}(^@+F; A÷OW4.5475'+"'54675!2#5#".546?67532>7;>7#5!53÷!âK' %9`=T$%=þ×;&&J=`9% 'Kâ!¢Œ4  %€Œ¢ýÃP PƒF^1!  ! w3%IN:&F¼4"'3É8&:NI%3w !  ! 2bE §Î&$ £ΧCNnBb)ÿøŒº8@74>753273326=4&'#"&=46=&#"+"5#5!53…-%\kcOo_QamZ@+^/--//.`tP Pæ3:?†b]Ž‚e]cƒb`¼P=Š68 ˆ54&/&'5#"'+.'54>54'57;2754&'#5!35.+#526=#"#7!Ä=`9% &Lâ!¢Œ& 9#Œ¢!âL& %9`=J&!>)=%$T  K%&æ*!K, ˜t&:NI%3w   ! 2bE §Î£7 Χ F^1!   w3%IN:&8É9"4¼Fó  @(!#,<)3||)ÿ÷Œ³:W%4&=43232754.'5#"/##"&=467;265.+#526=#"#7!C/-..^,"YncO`nMel[%-`-0Ó K&%æ*!K, ˜ † 86Œ?N¼0?8‚d]fƒ_d„ @92ÒN>˜  @(!#,<)3||ÿgÛ¤/327!5>="&'5467323273#&/&#""2F=!ze.þ×A ?l–´¹Œ ?s!  ! =Xq}RKs@) e2#*F.!·›¿!!âK' =§‚ÿœÞÛ,%#5>=#"&=46;23273#.#"327"š,Ø+0.[xwX!L  !* C3‚QD0"2 ’kgƒˆ&5mhÐP )|7'7'77'77''_6]LU6hqU7ZXb5uÏ)@.w8@=¾É/@4w>@C qº!5#!3Q PþàPXbBn#‘¿>3267.#"4®R'L3Y- 6œWa»J-,M; *-9D8 ¹¼#53!=98~Q1œ38 ¹¼!5!53#þ„~89Q83œÿ|Y )7ESbr""5462#"432#"&""%462#'&"#"2#"&#""542#"&""54#"&"#"5462#'&#"#"5462%""54632#"&V 0'1" F0 x2 ¢0 #  0þ¹ 0þŠ n   N< &‘!! &B: & :þº  & þ  $$  ¢ &  ‡   $ÿVQ (.6;254#"3254#"%3254#""3254"32544"24#"32$24#"I112‡1551F2112x2U221†ddþ¹1221þWf51!1221u/12T113‡412þº2112þˆ332T220„d#ÿnw3K%;#'7#53265;!532654&+5!#"4&+5!"$2>32+"&'54632²!2z&Yæ0 þ¬0þÏ+''0 1OT%.230þÎF0QieTm.-’'k--Ÿþ],*,.à-#NþX£-&"-«(/((A>*(/ÿn¨.E7#526=#5654'#5"74#533"&'543232>32|Y•&Ð'ÜI$Ü&ÐBÛ(! )zUJ#% % fkk (óò*E.!)îôD)þî+"’¯<(&#*##*#)=– .32654#"#!5>5#534&'5!3#632Êe`®23ST,þø8AA9;#DD'Bd:# KþüIM“™3K&6|6>!!7 6v'60ª .73267654'&+5>=#534.#53"3#32¢0&+B¸iu½"99Ò770FV Ú (@V3Q&Ð66& #–-327'7654&#"72'#"'!5>54&'5Ê"G+U'U`eN-TS2JO'Z5^'#;þè98OþüU&U!2MI3&J4[6O&Z¶7!!?±6ÿ'æÌ4327'7654&#"4&#"567632'#"&'#5>5ŸE#%e'_C8#CT ?Q@PI^GW'Z-4 + 8ò,Nö,e&_0EWi,# MOx]xJW&Z/' "ÿ!"!5>54&'5!2673þÊ !:þè9 7eU6 p þ6!#>±5!&C##5>=4&'5!2673}Ø%Ð&& - þ´%"/ü/"!7 "– 3#!5>5#5354&'5!#.+"É““!:þè9>> 7 6Uˆ NŽ6þã6!#>6i5!C& Â!#.+3##5>=#5354&'k -vNN%Ð&11&Â}7!{6›%"/‰6=/" ÿ&E–8"&#"32>54.#"546;23'!!5.=>32~2;#Lo18Z6/<* ˆU6 ýí7 9:!.#8X*M¸< p›T8r`="-Ñ &C!5þO>#!6ïS{Bƒºÿ&¸Â3%4#"#5>=4&'5!#.+>32#"&54632326dc %Ð&&k -v'1+0Dj`#;2%,;¿ p%"/ü/"}7!¼0 Kg;s« <$ÿœj%"./.'>7632326=4#"+54675!#"&'.#"32632#37>;!5.=3223ø$%XE >$X1I]7 =þä: 7]I1X$> EX ¤‰   ;9! "‰…,%‘]?P">;YCY½7!5½YCY;>"P?](‘' Þ+Î>#(9Î."Þÿ”äÌ^32632376;35.=32323'.'.'>3232654&#"+54675##"&'.#"0)  ""./"Šs" 6ê "s,+"/.""  )$0):,ê6:)0$˜+51 :_ ÈŽ' È48{ _: 15+&FFƒ  'tFF&ÿ%ë¤D>32+32#"'632#"'32654&#"7>54&'>54&#"#"'#`c<.:“200@ X/vi+‡Q& %'-:C.( OfA922eH*b ÏXT4)­969&)@e:BY -' %8eI7gW3K`""Õÿ)cËG""'#3>32+32#"&'632#"'32654&#"73>54&'>54&¿!: 2+#/9#%''<4$)E&-& %'-:C.( IB6$-UË ˆC87)$7A)3)57 !#Z -' %8L8'C5&5F"ÿ³œ>.'>7632326=4#"+54675!!5.=3223'".'º'C >$X1IY7 =þä: ;:  ‰…$%$#]?P">;YCY½7!5þO>#7Ù &%Þ•,%ÿ”íÌ;2654&#"+54675#35.=32323'.'.'>32§$0)C,ê66ê "},+"62"% )t&FHƒ  'þâ' È48{ b9 15+"¡œ@353>7>32#"&#"3#'&'#5#!5>54&'5!â"6%8 I1X$> C1(X ¤‰*6" :þæ; :=l‹~L1Y;>"P?]C‘' ÞDp†Ù7#>±5!7êÌ;#"&#"#'#5##5>54&'53353>32Ó) %"26"Šn6,ê66ê6 ('$˜+51 9b °Aq  '' ƒkU:,("¡œC3267>32#"&#"3#'.+!5>5#534&'5!3#â 7YI1X$> C1(X ¤‰ :þæ;KK :=QQlYCY;>"P?]C‘' Þ&Ù7#>|65 66êÌ>#"&#"#'&+#5>=#534&'533#3267>32Ó) %"26"Š}" ,ê6??5êBBC)0$˜+51 9b È  'ê6%  6@HF&#œ?#"#7!3267>32#"&#"3#'.+!5>5þ6T9«;# 7YI1X$> C1(X ¤‰ :þæ;l.Rª!7½YCY;>"P?]C‘' Þ&Ù7#>IÌ;#"&#"#'&+#5>5#"#7!"3267>322) %"26"Š}" ,ê6D- 9 C)0$˜+51 9b È  'K!7} QHF&ÿÆ–/%#.+5>=!!5>54&'5!!54&'5!f:>Qh:þÑ 8þê:::/::€6§H9"?ÃÎ5 "?±66ÂÂ66ÿ”êÂ/!23'.54675##54675#35.=3z,+&%Ð&¯%Ð&&Ð%¯&48{"/%"/bt%"/ü/"%‡u/"¾–046;23'!!54675!!5.=!!5.5f ˆU6 ýí:þÑ:þê::8 /:8 N &C6ÂÂ66þO?" 5ÎÃ?" 5„Â/323'!#54675#35.=335.54¼b- þ•&¯%Ð&&Ð%¯&Ð%!7}"/bt%"/ü/"%‡u/"%5ÿ&â–@"&#"32>54.#"54675!!5.5!!5.=>322;#Lo18Z6/<*:ýU::8 /:8 .#8X*L¸< p›T8r`="-¬66þO?" 5ýþ?" 5ïS{Bƒ·ÿ&»Â=%4#"#5>5##5>=4&'5!>32#"&54632326gc %Ð&¯%Ð&&Ó%'1+0Dj`#;2%,;¿ p%"/:þ´%"/ü/"%0 Kg;s« < ÿ¤A^2654.#"4/&=46323'##"&#"327+#".'37#"'4&546=4>32ŒS %Z@AZ%lu/J1 s7œ»€k[Fg; R) šR4 !$  ‹_ApNUuB A+N°‹ª73$Ó!!È—}¦_„©.T 3ùFd‰ $  2 -'ÿJÚ0=".#"632#327#".'.54632254&#"n#$?D" ”?=z[!1a$bI%5,%%I‚b-D!`r1*0@"G%+%cHP7¢D:Tg !kLd'J0oUq‡& þ÷^.DN>'ÿ)y¤4327632#"'732654&#"'7.546323273#&#"-LQ.viY¢ (.C:-'% #ޝÀ@p !  7 mRWAev4% '- U·–œÃ!!⺢ÿ)›Ì9"632#"'32654&#"7>7'#"&5463232654&óZbN& %'-:C.( 6#$>+DWK= "[̉n]|Z -' %8%)" 4*mVMa.*=ÿQ–!23'.5323'!3>;Q>:6U9ýÌ9T6 >9H§6ì-SªªR.þ @!ÿ”ÇÂ%323'!3>;323'.D- þ` -De,+&c:!7}}7!þ´ 48{"ÿÿ¿–<ÿ<ÝÂ#%#5>='.'53654'53*0ì/h#Ä fc/‹H¸)(´ùN$ ÿ2¿–-33#!5>=#535'.'5!#7654&'äÛ'8+”ee$CþÎD!llƒK3$ .”'–-Bâ 69!Av6Àj2Þâÿ<ÝÂ)3##5>=#53'.'53654'53œrrr0ì/qqh#Ä fc/‹eþâ6)(~6ùN$ ÿ ÿÆ–:!23'.'7>75#'&54>35!35.54?"Q>)'À’140î)(q*U þÒ2=FmC(&é, 4w_329H–+¶:! 2Š;v 4g ÁPA”ŒLÿ”ìÂ6>54'53#.+5>54/3#5>?'.+53ø  (ž3SŽ!+,f[O(‘r^  Ï+.0)*x× {84 Œ{ ¥#Aÿ»–'%!4&'5!#.#!5>5#"#7!#.+d‘ 8::>Qý¡:6T949U6,ý5 "?þb6§H96ÿ.RªªS-ÿ”¶Â'323'!3>;!23'.=4675#!D- þ` -D%º,+&&Ð%þý!7}}7!þ´%48{"/ü/"%þ´ÿÆ–-!23'.54675!#"&=4675!327Q>::þê:LR>S:þê:jSH:9H§6©66Õ=V=66~Uk=°?"ÿ”ÛÂ/7"&=4675#327323'.54675#ñ6%Ð&U+G-&e,+&%Ð&#Å"$d%"/T9<2c/"48{"/%"/j0¾—/536754&'5!!5>=#5.=4&'5!ÑI86@8:: 8þê:8@6dƒ::)9Tš– -Õ66þD5 "?°/ tpjQ~6ÿÿÖÂ3536754&'53#5>=#5#"&=4&'53¥!6&Ð%%Ð&6+U&Ð%qe#D@ j/"%þà%"/c WJ<9T/"¾–)%4&#"!5>54&'5!632!5>5S>RL:þê: 8:HSj:þê:ì=V=Õ66¼5 "?°=kU~66ÖÂ+%4&#"#5>54&'53632#5>=C61#&Ð%%Ð&-G+U&Ð%·$"0j/"% %"/c2<9T/"%dÿó@¤ 5.#".546;2>32!327#"&=4Ë *K/Vlsa<<6J«zIvB/ýé0NP)zh*›Q’µ¢+E3&zd08'76s1CW=7U|?e;DÁ—!ÿ÷ê+36;2!3267#".=47#.546;2;674.'#"×5R•þÌMK3G!A“5N'Q,=W(Î ,&Y—5·cw72¦*FG''!*<'77(="bE,qÿR@¤IS327327#"&=47.=47"'. 546;2>32!%.#"'0NP)zh$‹U)+4< )4=[F3 <6Jª}IvB/ýé¢ *K/VlKU|?e5D!$L+ /'.F€S '76o‘1CW= +E3&zdÿ]ê;C6;2!3267327#"&=47.=47#.546;2;674.'#"×5R•þÌMK3G!7u ,4< ),LUQ,=W(Î ,&Y—5·cw72$L+ *&x]'!*<'77(="bE,qÿÿ;–,ÿÿÏp'dIØ(ÿÿ¸™'dÀH"ÿ&ŽœF%4&+!5>54&'5!3267>32#"&#"#"&54632327>-ˆ£ :þæ; := 7YI1X$>  ( 3XN.ƒo)52 *^l|Ù7#>±5!7½YCY;>"1BT %;]:š¬<0#dÿ%ÓÌE2654&#"##5>54&'533267>32#"&#"2#"&#"&54632. 0GJ,ê66êC)0$) %N„dV )52¸fsYk  '' ƒHF&+51x[z‚<ÿoÊ®*7232>=4+5!"3#'7#5>5##"'546E;$W =3/.4y&Xè40ã®Ul(:`Y.çP ,þ.#‘'j ."þóþƒ=ÿn÷Ð+7232>=4&'5!"3#'7#5265##"'546&#  0­'&#*z&Y£0 ¥6;>O#6,!¡*%!/þú,*’'k'4CönY5ÿO¾–22325!!5>54&'5!!54&'5!#"&546‹ &þÑ 8þê:::/::XQ+87 B„Î5 "?±66ÂÂ66ýë^g( ÿ&åÂ1"&#"32654675##54675#35.=3$25)SV%Ð&¯%Ð&&Ð%¯¸<pjq%"/bt%"/ü/"%‡þûP;#ÿn¯3%3#'7#5>=!3!52756554!"!=4!"°#Az&YíD"þ®#BþÌO"A4C"R#C6B"…F-’'k+EÉÆF.(7§ @(,D¶´ >'+EÿoÐ.45"35453'7#526=##565b*Ü&Ð$Û(! )z&X”%Ð'ÜIt)!"'ts'#(þí+"’'j!'‡†*Eÿ¾–-!"#7>=#"&=4&'5!32754&'5!VQ>:HSj::S>RL:: 89H§6¨=kU~66=V=Õ66þD5 ÿ”ÖÂ/32754&'53#"#7>=#"&=4&'53¥61#&Ð%%c,+&-G+U&Ð% $"0j/"%þà%48{"/c2<9T/"%d+ÿn³¯)%33'7#5265##52654&'533"N#Az&YïB#þöþõ @ñA#'=ÒôñÐB"…F-’'k-D½ýÀ@þEF+-D£:8ýó +Eÿn‚Ð)%>5##5>5453"33'7#¡)«¦ +¯, )ž”›š+Iz&Yš#"'þ€€þè+#0+$þ¡_)3þùI’'kUšõ,%73UYGzÁk’ÿÿÂe"$dÂÍÿÿ(ÿòã‘&dHùBÿÿÂ+"$jÁ½ÿÿ(ÿòãW&jIéBÿÿ_–ˆÿÿ&ÿöx̨ÿÿ Ue"(dŠÍÿÿ ÿòž‘&d:ùG%ÿò°¤#"&'!654.#"'>32!326°´“‚±2sR{g*žN“=þahYZhÞþØÄ ‚$Q„We&ZaåJÿÿ#9'jõË*ÿÿW&j`éJÿÿ%ÿñÞ?'jÚÑ0ÿÿ-ÿòûf&juøP"ÿò°¤ "&5463232675."c‡º¸·¹þo^`qp¼n¿š—ÂÁœ—¾@ƒ™™ƒ6ƒ••ƒÿöÖÌ 2"&546;265'.#"ú`|€¼}{ A:7? K65AÌ€bhŒ‡egƒþüKkbT6QaVGÿÿ"ÿò°+'j½ùÿÿÿöÖW&jSéúÿÿÿñ–?'j£Ñ?ÿÿÿò_&j7ñ_ÿÿÿñØ 'ZÇÇ5ÿÿÿ,äB&ZTéUÿÿÿñØ9'jÆË5ÿÿÿ,ä[&jTíUÿÿÿñØt'i¼Î5ÿÿÿ,ä£&i8ýUÿÿÈ:'jÆÌ9ÿÿú[&j`íYÿÿ&´9'jFË=ÿÿµ['jÀÿí]–'74>354&'5!3!"&5'"326 #:dBE%982þør”T9­Å µ06'¶6"#=þN;  Y[m‘–ÿÿÿöë«Gÿþj–.8%26=4!"#"'!"&=4>354&'5!''"326*?2/536-Mbþør” #:dBE%976Ÿ9­Å 3:3©-!%*©NSY[06'¶6"$<þN‘–ÿìc«*84&#56732654'5#"&'#"&=463226754&#"TV=0)2€>6d/KUd{U54Y%1<*=@U=ýº 7*^ C)K[D Av_o+þ‰(ç(6Rg7*^ÿú´®2%##"5463232>=4!"26=4!"#"&üã®V;$,6=3/43/536-M\ZRŸåþóþƒ>(:`Y.ç)' ,þ>D+2Q©-!%*©MU?ÿÖtÐ8:7232>=4&'5!"32654'5#"&'#65##"'546%5&#  0­'&<)2€>62m¥6;>>O#6,!¡*%!/þù:7*^ C)K[KC EönY5#ü¯D"26=4!"#".'&=35!3!52756554!"!=4!B"43/536-EX)/+þ®#BþÌO"A4C"R#C6œ+EþdD+2Q©-!%*©LP9/ÆF.(7§ @(,D¶´ >'ÿØ›Ð6%".=##56545"354532654'5›>7I>Ï'ÜK")Ü&Ð$Û(!<)2€LZJ1q†*E)!"'ts'#(þò87*^ C ÿóŤ1.#"32654!#"&=46323273_2H.v€"5E?T>;ÿ-QAB Ä¾™9p Ñ&27¬‰ElA*RmI. (f?\ µœ™Æ!!Óÿø˜Ì*%2654&'5+"&=4632#"./"2==(eSVh€[OJ ?IU>(0  Rx}_mŠG !)$bKXk¹–*%"&5#"#7!#.+26=4!"#£_F6.6" 4 >>443/536- )(,>^Ì "*)ªª60þ'782Q©-!%*©<;ÿ×àÐ/.+332654'5#"&'#65#"#7!· K<)2€>62mK, ˜T  þøB87*^ C)K[KC A)3||þJþâÿ7ÿ– (3"&54626"&54632"&54632"&54632"&54632â   Ä S J  þâ s   !  ! † þþÝÿÿ” "&54632'"&54632'53þÿ    ñ þÝ  u  44þ ÿcþâÿ£ "&54632þÄ þ[ÿcÿ!ÿ£ "&54623"&5462þ~ u   þ[þÔÿÿ£ "&54623"&5462"&5462þ~ n O    þtÿ`ÿ<ÿ”53þtÈ 44þCþÃÿ ÿ”53#2#"5463þCÈO !  44;G<Dý_ý²j .4632ý‰  þJþÃÿ.ÿ’ "&5462"&5462"&5462þm A R ®  H G  ¹Tù 7"&546326¹ 4¶3#3444¶qI+i%.'67.'>7+ C$*+$  ($ ¦  % C%'U'% !,ÿûèHU64&547.546;237"&4632#"'./2+".'.##67632>G%?& aX3K,1:18 1$32#@à (/( s %‡3H;%$< "dBGE26(2(=/M*4H#>*&>/¤:.= øV"&547;23!7!4&#s((Î0G6#þC#r10º!67=PþÆll.'(V0"&547".5.5##54?>7>54'54&#" 7;   >vx# '± .B   /þø,Z)Ye. w )ÿþâT3!2++'"5465!"&545;$  þç1&T!'þ¢ < –)(8ÿþÑV73!2+#"'"5465!"54#'"#"54654&546324;*  þèZ4 V!Aþ© .—V1þM;$2 0 =V d0ÿV%2+"&554&#"#"&546732326¦1 .!!  3&( þ¬M E5#8 7ÿÿ V3"&543##"&54654&54>7"#"&547á     17t ¤ !Ž'.% ! + ?/W/1*6('&ÿþÒV#"&567"&5477!2+#"&5!A-';+ þ÷(230-1 Aþ§c —-þÆ7ðVB!654&#""546763632!65654&54>7"&54674&#F^/T='$X  ,B%  þp ++3+P C(¢ KŒ8$)1*’#Y0FB)Fi;7 4g#/J) 40!*9:=Aw"&546732632#4>54&#"v " "# )Þ$6 )%¯4)þ§ð43!2+#"'"&5!"546> E*&  þåV4&&þ8sZ.,# ÁE6åV$"547;2#!7!2654&=4&#eFö%1+=þ’$B3=ºW569'EUJSl,8 1-E.K12!2#"54>='&#%"=7>54&543Ÿ # 1.X  L[L  þÒK7*A"ÌG0T IGUq ¿" ãV#2>;#"!4&#"#!"&467"3…!:þ> +  #~þà/(%36>þUN.>B*â(45 çWF%!267!754&#""&=4&5467.54677>3ã(þ±@u_,H)  %.( H >P'  Hjy[u&7B4 b#B]6‹'"/   /"&@A.T=:þ©ú4"&547+"54654#"z#$U "9 3 ,0!#m9þC%.J 8/V"&547;2#7354&#"$!' 8%+¬7$¼#52 -P „nbSl %ìV3;232>54&#!7&547;2+".=4;&?! +Aþÿ+ö!/[S#1^Q "I:[E?uH?&=4$ . ‹!<6+F` ßXH2>57.54>?#"&547;24&#267>=4&&'&54673ž&Pª© ˆ!  !K  '‘ %'%4*Kþ° P "DH' '$N  K4.'U21ƒ1  =  þ­å3172654&#"#"546726;23254/5+"5®/.! :* šAK!¨Á<#)¶+>& Pf çM÷²j’’ # C$ G(2ØV772654&#"#"546726;2!!>=4.+"5¯0," 9* š&1þr#¡!"A-Á<#  Ø,:) $5(¢ld¤,CV7'#B$ 32 þ¨Ö4E."##"&54654.5467>7>7.5467» C/ (1(9 #-%(= i 0,þ&ÃEy 7 /$]>æ í&,-/ . ÜV>4'!67!4'.54654&+"&54677&546q!)!1(þL0:G:4!$ ¥'*V &!,# À .%2S ## D,#3  N<M¿.3þ©ã4/F%4.+".'&547;2#"5467>"4654&=4632É(0.Î" Â".# *GFOlB4!þƒ"   æ>F$ 2 +;M1 /&#() J&(þœdJ\¥p–#@$ (%+çÿÿÕV(2#"'"&=54&#"+"&5473P&& &á-* 3 4$=IZ&6:   L.!0<V]"&546764&#65#"&467&#3>54&&'&5467!4&5.54>?Q   * k" !|ï*@&% 4 75þ´* Ç:  /  1+­32?  +%þÔÖb 6 ,Yä‰ ' -8, ÿÿòV<;2#"5#"&74&#"#!+&54632.547"&54Gè8þÚ #&G / V  þ¬S aE&":$2#C5$*K#h?1%9ïV$K2+"&554&#"#"&546732326!2+"&54&#"#"&546732326–0  +$!  ÿ0  ('!   3'1þ¬M E7": ((þ¬N E:#8  !ïV$A2+"&554&#"#"&546732326"&546732632#54>54&#"—1 -""  þÇ  "!# *3)*#þ¬M E5"9 v%5 *$¯2'Aæw8"&546732632#54>54&#"!"&546732632#54654&#"] " "$ )þö " "# (Þ$6 )"²2($6 *$°/2)„ô)×2#"5467>GL @× $fFz$-ôZ×2#"5467>32#"5467>ÅGM @˜GM A× $gF{# $fF|#bÃõ¨"'6&>7632õ 9C  "2"  <@ #" ,-6µÚÒ"&5472+"54&3mE# : 5F‹8,…^E.  IIDFE“Æ… !*4632"&54654&#"#.'&+"5632“C7C5"!'@#.Å,<62—2CF.$ & #>. Q;#?F,þˆ:33UyIà"&#"32>767.54673(1# L›+6' D08k8F6 4u<0 $$5Z9( šeQ23267#"&#&>54'7š6 "(/7: 10##06 *$7E(ü{KBBCCBBC'P ©);Z>?# -2.!Â¸Û "'7'?'74.'7!"&547ô@CC¡@CC°ABBWAý777F 3*BBCCBBC7CCBþ8@N?)R­*7K~c)&|ÿßë)-237#"327#&'&5&546767.#">'7J¾oX­îJ6'M5p¸0¢„.-?>^4l62/<Ñ544ë!?fkLQ#A?&./1@? DyHv 0'þ}553zÿ4âù*237#"327#&'&5&546767.#">J ÃpY¯ïK6(N6nÅ%Ÿ¡…/-@>‘^3s42 !"5ù >djKP$A=%,.0?; CwHv !pÿZµÓ)-237# 327#&'&5&546767.#">7'74±iTþ½Š3#G1iÆ–˜}-*:=‰X2j1/  2c,++÷;ÃFK <<%;<- ;9>oGn  ±,,+rÈ«4.'7+"=7~  5"8Ê7 $"O )8hCN`&rȧ '7.'7+"=7/977„  4!7È6 Õ997þ $!N (7gBM_&ÿÿÿgY¿76?>54'E €16hSEF$¿EOH ñH 1 dcR&-WÿÿÿgYŽ'77>7654'F8;;7 €+"R CRm?Ž *! k( $Z$e44$"-E&!  A/@ e9FH*-MC1H8@D8%|ÿâ¹¼:>BF254'7#.'#"+.5473267654'732=7'7''7'7l1',&$";0-#&Œ )!j( $!/11"/11$/11Y$c42% !7I,9&?f6DG*,LC.H8>E 6&---:..,“---‚ÿé´Ò(32##"567>54'77674#"23276@$&»–%FS8ÔQkA\-?",x:1JTPg‡@Ò 8'!""B[0±oVNHNT!45GIHix7Rƒ‚ÿé´©(372##"567>54'77674#"23276'7@$&»–%FS8ÔQkA\-?",x:1JTPg‡@”100Ò 8'!""B[0±oVNHNT!45GIHix7…RƒI000ÿùÉ8"6547632#!'%4&#"!6¥V? sg&(=ýÿ9%&a~SE›µ2ƒ @.QO-'8ÿùÉ8&'76547632#!'%4&#"!6».//èV? sg&(=ýÿ9%&ad../þ‚~SE›µ2ƒ @.QO-'8‚ÿ%†ö&467&'=476;&#"32>73.‚>>W#A8F5D L› b. 7kD#’Iƒioh°²:C5”4K*>91*8%Q"CK{HL.A$8‚ÿ,€%)467&'=476;&#";673.'7‚B9W"A7E4E Mž _.wp#Idng­°:Á011><0J*>90)8$Q:BJzHI/A$7A000€Í+û$.246;2#%.'672326;2=.73275.''7P;,1Výò+""2È1!„!U8M(e$U'*122°;}0/@^B\/K6LN$"0 $ƒ =1'J¼223‚ÿÄÏi1B'7'7+&5&5473!367654'&#""5476767'#";27254'&'Å777f877ßG_¤Ñ3   `8K_(4!p!) &27777777þNŒ/8-v `zaFt&I 3 %1;53+l,  yǺý/+%"'&547;!654/&'&546?´Çmk"*ýµN2Ob }= "4[~£¾W3 t*)$2=,'$eW@C@-(MD y¥A4 $ê‹?0~ (A@ 2[-yÿŸ¡ú"'72>5&'7#"'"&547¹;::C[N&(:*HP8 ˆiÃ777ýò'M;œ `G¬NF^/jg\aJ:“ÊŠ4#"&'&5467'32654&ûHG 6@:<$EA*4#?4P‚'2 & (s &P. dIÿƒÆ"46;+5>7654'#&57.#"3232½@5 Dj;l5w=-"c*˜- %/AV ¡Up‡K F5J7)F42fÿÿƒÿðöÑ‚ƒÿDöÑ3'7'72&#"32632#".547$7&+"546ÍACCßACC !!"]P ?„YuRv<S 4h^..c_†zBBC"BBCç V%vO5#;>"ksb‚S]8A6.ù 7>77>7¾1:—;1:—îJ wJ ,ÿïÿÝ7>7'7>7´.9—;.9—™J >J 6ˆù 7>7¾1:—îJ 3kÿn'#67.546324&#"6Û 2"]G5  3"  'ò @$'I   "2)   ,ÿïÿƒ7>7´.9—™J X™ú4#"'#"&5473326732654'7ú !  $ó #-   2rK'7Kojj”|}z ›N #".'ÒO- >.þûÙx¢ÉAd¬¿42>7#"'#".'7,! ",K3    92<00Á & &aE~þÈu ÈB^D$e·8.326763232=>32&'#"'#"'65&6.'/,  1 M< '  , 8>&2; 11x-&_rça;2DIj?I²±S-2632+#"'.'732>32#&#"a%' 5H0 !A.0 7)D #'£ >kþüÕ£„_C,4,"  .½°&7"&54767'7#"'32>7632>54&‘;(*'h4WP;:<3Ea7  6 $%D½IGcb9€«g Ia<5Ðb¹0Q 6 + 2¶O‹Ñú'2>7#"5467.546732#"&#"÷ L9TáC[?VCu4$+ /.C'/ $-ù“ .ÚL :2~" B!/Ë„4'77#&546Ôs2q>aH" A0.[”þç‘Z-ém-/ $ 8dz)  '67:6C$š—&ClPÎWd¹þGaV  M¥¥4$%&547#"&54>32327.#"Ž…3%7.21=/0þé'*!¥yß" 4" '5-‚oLx>’"'lœ37"&5463267O'#%·. 8'90+N-ì"&#"32>767.54673Ë   !1e%,$Ê$- " !L$"#:Jrÿv¸ #%'7%4.'7!"&547'?'7ü455Ñ Bý,79G 4*Ÿ455‘555774Ç3C' @(U°+7O}e*&þ˜7749774{ÿ-ëú 6%'7'7'7237#"327#&'&5&546767.#">¡>??Š>??©>??¸ ÄrZ±òM6'O7rÇ%¢£†0-A?‘a6o63""5p??==??=º==>É!?fkMO#A@&-/2 @=CyIv "ÿÿÿgkó '7''7'77>7654'k455466455¡ €16h ./C&!K221G220¨221½EOH ñH +7a@65-Wy˺[/3+%"'&547;!654/&'&546?'6´Çmk"*ýµN2Ob }= "4[~£TþÐÂW3 t*)$2=,'$eW?C@-'MD y¥A4 "ksb‚S]8AZ¾º767&Z && &&î% %& ÿãqé%#"&54>732>?32q¬#   #'+)'" ÒdS   ÿžÿϦî)%2632##"&54?32>?&54632G % *#51&m"% #  #m"& ¾0 !  J :% $ ÿ”ÿÒúè?"54?326765.54?6732>?63226732#"'"&#">. +       3 1  R)8K.)R     !1 "  B ,ÿÙÿÐÓ,%"543>?&54?632>3"'â2- C.; #M>O1 l’ &&  *  ÿÿ˜ã&2%2#"&54676?64+"6?>#67&H,$(o:?DL9$ ( P:  Å"% &ã,'%+*6&H $EH   8ÿóÿ»lç672"32>?"54632?>?6&&/4?>Û+       ::\G&)  f)* ç      $& 6" # 3 I’ë 726?632#"&54654'4>™' VA, .Ã"- Þ# (:! (y / ÿÞ€Ú+72>;2#"/4>?>54#"#"=4?6*!VEH,   O@I#%9C9 ED  & @2*  ÿýÿ¨‚Ù%%2#"543632?67&546"3"?654*@K[Š&/) I3S55 (Ù"%(1=T&!  1$)N4(ÿÓ†ç%%"+&54>?2#"&'4>;26765&&)" <"!*   +Á «  "oQ e ÿÔÿ}p27&67'&46763#"#"&54>?'&Ó,(K ):  KcK"k0x      7 >   D" ÿºÿŠºû@%2674&/&'4?2?6?2#"'".4>32;2?67&'6325*   ! / 5Wš  7J '!O        9 SJ  /# &ÿýÿ¡˜Ù4D7#"&/463232>?4/&546?632#"/.'"72>54/#"ÞŠ( !  R#5970! ]   *<    IL   S ÿÎÿž¹î$%#"54?2>7>7#&576?>32¬ +mK»"+#/¢© 6#¬@0`) _  ÿÿŽí274672327474/47>72"+"&  ="&.K7  7u'2    +   ÿÿÿ¨ÚáM'"/.=7>75.5>?2376323>32"#"/&'#"76?6;2n%! ± , $   h  G K&"F  # *&      ?4  ýã(7'&546?#".'74?2722!36?>32#¡A<  % ª A n%j+   " ?CgÿÖhæ(7>3#/&'4>7/"hX  +&)6i  ]O0E Wš:    $, ÿ}¶íC72>722#"&'";?632'.54>7&54?26â d +   ? H  t/"h..CP #)   Æ4     )  2#;,  ,ÿuÒø:DP%2#';2?672#"&54>?&/&54676?674#"7>32674#" 6 h!(2L-"vQR@86  " -*$*ç"õ (+  "2/+ "8  S!  ÿ¿ÿȦÝ3747326?6;2#"&54?67"#".'>?2?6765&”/&'1 00 !' '!,v   >[©.& ˆ  1 $@ )5 ÿÔÿ}r =+"546?'&67'&46763#"#"&54>?'&r!  Ÿ,(K ):  KcK"k0"#o      7 >   D" #ÿgŠæH74632#"'32?2672#"/&546?>?3232654/".òc   50&6\ :rG :   ! ².  4- 6'  %5"  ÿšN€8C2#"&/"/&54?254&54>7>7"36?45 Zk 9)%!. ,#  +3U‘BUÞ** € /Q 6  $ %;H)4 Õ  ÿýÿ˜_ Qa%4632"&'"&546322"&46#"&/463232>?4/&546?632#"/.'"72>54/#"F !   S ! Š( !  R#5970! ]   ë !@ !!þÚ*<    IL   S ÿçué %%"&546327#"&54>732>?32P  ¬#   #'+)'"   ¸dS   ÿÎÿþ\V %4632"&#"&54?6;2>?32 ! L‘«"!  #&**'" 5  ^dR  ÿºÿŠºm L2#"&5462674&/&'4?2?6?2#"'".4>32;2?67&'6326*   ! / 5Wš  7J '!mþâ        9 SJ  /# &ÿÙÿÐÓT 6"&54632"543>?&54?632>3"'" )â2- C.; #M>O1  !¬’ &&  *   ýb F%"&54632'"&546324632"&'&546?#".'74?2722!36?>32#©   O   t  ! ‡A<  % ª A n%Î !K  9 ! w+   " ?C ÿòýã1%2"&46''&546?#".'74?2722!36?>32#€! ÒA<  % ª A n%3!7+   " ?Cƒ Y+2"&46&'&'46;!>?>?2!.'>£ ! þ¶%Ð$ M+ýü ; /Y!‡ "'  5 *  (ÿýÿ¡˜Ù >N4632"&'#"&/463232>?4/&546?632#"/.'"72>54/#" ! 0Š( !  R#5970! ]   "  :*<    IL   S ÿýÿ¡˜F >N"&54632#"&/463232>?4/&546?632#"/.'"72>54/#"/  rŠ( !  R#5970! ]     þý*<    IL   S ÿ»€Ú 54632#"'2>;2#"/4>?>54#"#"=4?6Á  !—!VEH,   O@I#$ !j9C9 ED  & @2*  ÿÞ€M 5"&546322>;2#"/4>?>54#"#"=4?6>   þÌ!VEH,   O@I#  !ì9C9 ED  & @2*  ÿÿŽv F4632"&'4632"&4672327474/47>72"+"&> !d !  ="&.K7  7u'U ! !þí    +   ÿ¨ŠV "/".46322#"543632?67&546"3"?654&   @K[Š&/) I3S55 ( A"%(1=T&!  1$)N4(ÕrÝ*#&=467>7632ÝÖ – \žjÝ„ #&5&>7632463>7632#&5ÝÖ"yA þÁ †# Öþ>07P$”þ|ÅÿF2"54>7>£  |('V$5º    N #% …þBËÿY2#"5467>"&547672}+Ä+>p“ cq JHC §' r"Fþé/J -('¾rºR 46;2#"&'4>7&#"+"#'&'ÞM&6\2I 1=; ! $2a) ,pO>>32"&54>?4#""74632/"'4'4>7674/#".O0&0U#HC% -_&$"&ôG0k6 G% 4 #" 0# ( \ !  ñiÓW272#"/&54?2]'  72 %®# U2¥  'EP '#On=0#"546?632;263226;2#"57>72%1r:9 s  —' lb w- |–C9$ V  ,9` G UlX9"54?3272?63"32#"&#'.5#"?>?"Å;,+ 0"63 "“#`"%ò"$    *V!§q»"4632"&5654&#"32?632#"&§½I.=j Q=ƒ 5 E%6ÐE¦/(=M =*z+% $9ÚqÌI 4632#"7";2654Úg8&-l.X#0 >½;Q+$9P 81ÿã«:ƒ!#'5".5437>54.732™877k0[;$]3 /5ƒ777¡1C>K:$3$/0µÿ$#'5Ç877$777t #'5#'5ÇTSSSTSSSSSþýSSSÿÚ…bZ367>=#"#"&'!2+"&=##".'432>74&##"&'&'&632656&#".7>32W XB C >Ÿ> ñ@S;K>2mM4  .4) 2$$!Qp%QV.Ž&Uz U % ¤?? ýÇ:&±;PJaUJ5'( $  d"!"( o23ÿÚ8cc367>=#"#"&'!;+.5#"&=##".'432>74&##"&'&'&632656&#".7>32W XB C >9 >žR>d@S;K>2mM4  .4) 2$$!Qp%QV.Ž&Uz U % ¤?? ýÇ: ÞýÇ:&±;PJaUJ5'( $  d"!"( o23ÿÙÿ‰PbC463235#"&'!2#"&+"&#"2632#"'./#"'&6323267"#"&KIQÐ&9@  à [E>g Be+,4   -8b6 -.0/ hBa|0%E=<”*b1"; -^2 %(W(./fÿÙÿ‰PWV463235#"&'!5.54632.#"32+"&#"2632#"'./#"'&6323267"#"&KIQÐ&9O X3)#W5/&3/Ã?è [E>g Be+,4   -8b6 -.0/ hBa|0%E= _+(56; 4",<”*b1"; -^2 %(W(./fÿÙ|bD4.#"#!"&'!2+#"&'.'476326=4.+"#"&54;26pþä&9C#=Ë%)#4BL]¸:  ;*32&5&?654&#"#".'.'43232654'&+"&'&'3ÞCOþæ F ?þ)%,  $HŠ1I)%,  E91^D83EC$Y : ;)$ +;.ERD 6SIM9#  ÿÙÿÅîb_25!"#"&'!32#!7&5>32"&#"32632#"&54632'"&=#&7>7.#"'.7>Ž=c9þß =» ?ýϵ U(T $8 9.+V{W.4Y*"A,‡ Aï#X"%5=^Ä13³?? ¾% Ms"857q+.HP  þù; ™G @ {  @ ÿÙÿ‚cbe>35!"#"&'!2#!;2>".54>54&#"#"&54654&#"'"'&546323 dIþW <3=þé'0'&7:/ ' 2A'(G,*<=*5Q( AT#*5$'A LŠ7),O!J 7.)R2FY™o.:ÿÿÿÙþçµs#òŸÁÿÙþçµc62654'%.=.'!2632+#"&5436=##"&'4&£# þÔO47x > ñ9#>Wò14/!#:Ê)Î635;B þë=5@  cËþžÒ#E/7ÿÿÿÚ8p"¹òAÿýÿÚ8~y2+.5#"&=##".'432>74&##"&'&'&632656&#".7>32367>=#"#"&'!.'+"&56;23Ý@˜N>d@S;K>2mM4  .4) 2$$!Qp%QV.Ž&Uz  XB C >\!9S;>U[6m" b<ýÇ: ÞýÇ:&±;PJaUJ5'( $  d"!"( o23  % ¤?-9;#?7"m9 ÿÚ8š+.5#"&=##".'432>74&##"&'&'&632656&#".7>32367>=#"#"&'!.'"&#"&'&324&'./.7632328Q>d@S;K>2mM4  .4) 2$$!Qp%QV.Ž&Uz  XB C >Y&ŠH 8 \ÃA:18…vY¥=ýÇ: ÞýÇ:&±;PJaUJ5'( $  d"!"( o23  % ¤?2A5`L([ =^Y<ÿÙÿÚb7K25#"&'!2#!632'.7654&#".546=#"&54>2654&=4&#&ª:/Ú&9ß=þZ&C‡ 9,W?,P)<3325!&/&2654&=4#"33 =E <= ñ@YŠ%6,F8þÚ9<XVF Nòz6I7?>Ë#6+6(ÿÙÿÚÝc-43246=4&=.'&+.'!2632+.5##"&7  7 ; ñ>ù+2,d47 )u ;C ýÇ: ÞjÇNYÿÙÿÚÝc?.56&'&'!2632+.=#"&54327>=+"32632#"Y/+  ; ñ>BXQ}O(if å #5 (  )3D#ˆ)=) C ýÇ=….}96€ \ »  %ÿÙ+c<C463235!"#"&'!2632#!"&#"2632#".'4763267"#"&%#'5cJGSþÛ<¾>þÍ XG> [FaoR;nG-A sEhiD`Ì877{1&E?@ ”+b/;I:TM5+R8?e)777ÿÙÿÚc+8.=#"&547#".63!635!+.'!2632+"326=#?H9 ñþÿ!2«&<iw<&% Á>@ È>',ÿÙÿiŸbs‡%.54635!"#"&'!32#!#"&76?>74.'#"&54>&/&5463:'"#&#"32>76"32>72654&5"&#"3 &n9-þU=n >þ§ W +\# A     ®It dc:!  #1EP?6&# Vi U‰96#*8 ' v9+-*AX$ $;&ÿÙÿÚUb572654&'.'!5!"&'!2+.=##".'432ü"+"$3þ,<%= ñ>Ì](/UbZ `‰3(A)s>? ýÇ< dT&9*OŒU  Z_ÿÙÿ‰ib>S463235#"&'!2+"&="##"'./#"'&6323267"#"&26=#"&#"263232KIQÐ&99= ñA>C# *,4   -8b6 -.0/ hBaà [E>)I$3Z|0%E=? ýÇ:$¹ != -^2 %(W(./f ª”*ÿÙÿÚcD2>75!+.'!2632+"&=#"'#"&542654&#"#"&'&76323G,(þœ9Â> ñAD0) *{?2A & $a*0 Ï>@ ýÇ;"­2K!rL + #aI!6A ÿÙœc6'4>35#.'&'!2632#!#"32>7>#".7Z[/Þ a ?þÝ -YU58J!,-  l`=oH*ù0E#s A ³#D,"    " 60HOÿÙœc&9'4>325#".'&'!2632#!#".%4&'"&#32>:tO ñ 1a ?þó[zZ:nJ-¤$" r‹"::W(û63s(A Áp2BY/FQ 6WH$ %6,ÿÙ+´c<463235!"#"&'!2632+"&#"2632#".'4763267"#"&cJGSþÛ<w > ê XG> [FaoR;nG-A sEhiD`{1&E?B ”+b/;I:TM5+R8?eÿÙˆb.94>;5!"#"&'!2+#"&54632#".2>54'#JWBHþö =N&;ÕECYJ#8^(X./mQe! ?;'p.> $(C ýÇ: Þâ#7":]3fþâU>!Œè*&ÿÙÿÚµc546;5!"#"&'!2632+.=+"#"&'&4CØþß =x > ñ>… $2 3 8   …I#2Oo?B ýÇ<'&S7  r%[ÿÚÝc4B4327.54632#326=#"&'!32+.=#".74&#"2326 '943( +€]H,Qt;M # ñ?-O9mD)¦ #%\*C($-rKAR o=™@ ýÇ<u';NE¢ )ÿÙsbJ463235#"&'!32+#"#"&#"&+"32634632#"#"&/4&"#".XZNé':; ? ñ " XW  51&%4 4 9   :iD(V?/Q:@ ” .>. ,62'#I+3MXÿÿÿÚÝc@7"&547&54632"32632#"327>=#"&'!32+.=õQ}2Z3=-. '  )3D#(if ;M # ñ>B‹}96L<*(@+! % \ »@ ýÇ=….ÿÙÿÚµc$46;!5!"#"&'!2632+.=##"& % þß =x > ñ>»%$b6&Ÿ?B ýÇ:(è"_ÿÿÿÙÿÚµc#éÿZÿüØÿÙÿÚŽb(%"&547.'!32+.='26=+"ÿT•'T = ñ?!k8T» »¼ˆ / @ ýÇ;‘ O9¥YLNÿÙÿÚ;b2@.=#"'.547.'!2#!632'.54>54'4&#"'26=+"Ž?$C82>' ?þY$B†" 0 (/!Û7Uº&;‘ 5*W / @ l {K[w  4 Gh-  3!8§Y#{ ÿÙÿÚ”b"0925!"".'&'!32+.=#"&5463654'&#"327ªTHþû   1Z = ñ>4]˜cMY +%#G &''Å@Ž(? ýÇ=D‰C8JZ=)   %B" ÿÙÿÚÝc/4&'"&'235#"&'!32+"&=##"&546;u(#<aP Ë;M # ñAË#_4È-?Y$81DÛ@ ýÇ:&¯8  ]%ÿÙÿÚÝc#46;5#"&'!2632+"&=##"&735#4< ; ñAó$_­óóÕ?C ýÇ:%¶8]PÕÿÙÿÚÝc%54&+"&'!2632+.=#"&'&56263>26=##• G; ; ñ?2GU˜&'8 5QtØ-V>,ì?C ýÇ<u({Z #0%þðo=™5:>T ÿÙÿÚfb,3267#"&5!32#!.'.U0ª%8/ >þØ 1"@DA- "R,D$š jN>> 'JH-(L81,F.NAQÿÿÿÙÿÚfb"éàÿÙÿÚ:b@4632327>35!"#"&'!2+.=&=4654#".?&XF#l:þW < = ñ35!#"&'!32#!#"&'##"&54632"32>?4&2>54&#"L R)þƒ%8F ?þ± !odI;s8T@M?&I4\7N!(K, Lä(>#&50#F+#A„=? †  \\E^Fd”YF\!,ZA2$>K ñ&/# (*24  !ÿÿÿÙÿ±wb#éÿLÿÁãÿÙÿÚ”b"625!"".'&'!32+.=#"&546"32654.'&ªTHþû   1Z = ñ>4]˜c/<(   C[$Å@Ž(? ýÇ=D‰C8JO 6% A@ÿÙÿÚŽb&%"&547.'!32+.=532>7ÿT•'T = ñ?!§ÈÚ"("»¼ˆ / @ ýÇ;‘ X¾¾<&j ÿÙÿÚc0>267>7#"#"&'!2632+.=#"'#".26=# - )C <Â> ñ?A#Gc -RT WbN3uæ/š%R;@@ ýÇ:%Ò-5za [‚¥&‡ ]0 ÿÙÿ/ˆbG46;5#".'&'!32+"+"32632&54>7&#"&'.547.m˜3÷ 1N =ó 3î '[€2 @"%:Tv7Qb-2_¤œU#0%@(@ …9q2"F? 1'E7">,- 7-R«54./.54>7;2;2#"&+"#"&'4'432¤%9 " ~`5BV#4)Eš  > ("1*"&.o7! =57" -j5*>  t@KÿÙÿÚ|c.5"&'!;+}>;0 >ð&: Þ?? ÿÙÿÚ~(.5"&'3=4632.#"36+}>;U8H3°F* X€>/K£ 3î&: Þ?¡ 7:2) 0 +),3V , þŒÿÚ|~%.5"&'3.'&#"&54632;2+}>;S 6<2R DaJT¤/®@æ&: Þ?({9*'>-b¢n = þ¹ÿMC%'4632#".'&54332654&#"+"&€D4jG-HZa& !)7X5:22' ( 'b82*+Y=(55%5 ' +ÿ:ÿBäX#'4632#".#"32632#"&Æ4).t^D (19M(&21  .&=y #)G`T-@@-&  , qÿbÿNœC4732#32>#"&ž¨ )¨06.C]ƒK0 I   jÿbþÇÇD6467&54>32632#"#"32636#"&#"32>72#"&Ž 47@ 'BgY/= *O$((X&=& +Y4Rv¥ 4*% ! &#- #()+cÿã«:s".5437>54.732Í0[;$]3 /5«1C>K:$3$/0ÿÙaŽ~#".'"&#"&'2Ž %0@i> <xÖVi(:;->qÿÙaš #"'&'"&#"&'2.'#"&'&56323 ¡Ž =ašgUB1c¸/e d:8:N< #" ®xÿÿÿÙÿÚ|s"òëþÈÿÚ|~%.5"&'3.'+"&56;2;2+}>;S!9S;>U[6m" ´@æ&: Þ?-9;#?7"m9<þÈÿÚ|š.24&'./.763232+.5"&'3.'"&#"&54þÐ\ÃA:18…vY¥=î>;P&ŠH ?)`L([ =^Y<ýÇ: Þ?2A= ÿÙÿ/ÿð .'"&52 %B*'<Ÿ†Ñ>¤ÿÙkª#†#'5#"&'&'32>=4&5432>32'&'&54>7654#"#".'&632654.'&#"#"&'&>7654&#"#"&54632{877'N>^¨;3c#&;@ýó0 IV28c<"#$    49_6+6  $)8P#ª777^2_sb 9"1*?þÇ)6$0C@ # -*(  ,67 /5.?< #!?+  9(* > 3C<4ÿÙÿÚb7KR25#"&'!2#!632'.7654&#".546=#"&54>2654&=4&#&#'5ª:/Ú&9ß=þZ&C‡ 9,W?,P)<35#"#"&'!2+.546=#"&54>325!#".2654&=4#"3#'5 . C => ñ@YŠ%6,F8þÚ>: FS QZGz6I7ýÇ< J„9!0 1g}/xq [‚¥†6+6(777ÿÙÿÚÝc-443246=4&=.'&+.'!2632+.5##"&#'57  7 ; ñ>ù+2,d87747 )u ;C ýÇ: ÞjÇNY~777ÿÙÿÚUb5<72654&'.'!5!"&'!2+.=##".'432#'5ü"+"$3þ,<%= ñ>Ì](/UbZ `ú877‰3(A)s>? ýÇ< dT&9*OŒU  Z_*777ÿÙÿ|´c<C463235!"#"&'!2632+"&#"2632#".'4763267"#"&#'5cJGSþÛ<w > ê XG> [FaoR;nG-A sEhiD`Å877{1&E?B ”+b/;I:TM5+R8?eþ777ÿÙÿUˆb.:A4>;5!"#"&'!2+#"&54632#".2>54'#'5#JWBHþö =N&;ÕECYJ#8^(X./mQ54'4&#"'26=+"#'5Ž?$C82>' ?þY$B†" 0 (/!Û7Uº877&;‘ 5*W / @ l {K[w  4 Gh-  3!8§Y#{ «777ÿÙÿ,îbŠ25!"#"&'!32#!7&5>32.#"32632#".32>2#".5465.54632&'"&=#&54>?>7.#".'.676Ž>c8þß =» ?ýϵ U( 0%>9 0 , +'B+N0H, ¿ A @ Â/ _!:>  8Ä22³?? ¾% Ms" #:  ! * )95++)90'þù; ™I ? c ÿÙþÞcb>35!"#"&'!2#!;2>#"'";2676;2#"&5462'&54>54&#"#"&54654&#"'"'&546323 dIþW <3=þé'0'&7:/ ' 2H! !9=L$9…  %*==*5Q( AT#*5$'A LŠ7),O!J 7.)R2FY™o.:ÿ2ÿ J;26#"&54654&#"&74&#""&5463232>32Ì0*%/0C2< - #5 >.1(&3TT9( P= ! *7"T$Efÿ2þ¦.JR"32632#"&=465'&54654&#"&'4654#"#"&54>3232>322>& " *- 4L 2 )% *0+>/#''2T0"Ò  +\=   &>& U$'*e1:  gÿÚ¶a 2.=54l >=aB ýÒ< ýõÿÚa 2.=5432.=54ú >=Ç >=a?ýÒ< ýB ýÒ< ýÿÿgkÔ 4>32#"&2>54&#""3+G•#3+G”“&: ' 3A)>‘I)>@"1+$!( 'ÿÿÿ.!b/>"&54?6'4/.'&54?67.546;22654&+ã @  W> V$iM 9z?60 • 8e-"  ,Ò>   ^C N n5KF‹b)JK4) ¢ "8200;$1$ÿi¶96#"&'.'&"#"&54632;2>54&'&#"#.54632¶…F,— 6d $ O'>D2)'/1U=p›XgKj7è71¤N+J+ = e+ÿizE@%#".'&#"#"&546323654&+"&76;2>5&+"&54;2z '%?E GD "N<)pBs)4 ¡< m4!M¦(JeZfQ2S&B +'@ '>*7 MK:a!174>7.542?632#.>54.53†#"² cFâ  @Ö*R.63oe%S ÷5%° b: ¯ > ¦TP&9q%  GJ ÿúÿ¢ñ`9'467367#"&'&=4323267>7432+".'#"&F.#] > &P   > @..À*0b=V(C[-&E@=B}=c9"6AA> kãA©+8<7HÿÿÿiµiL%"&547.54>3:"&#"32632#"32676.543#"&'.'"H•%P%>9  , oU  !==49*:('G 1 2 '‘I3+ `,&5   G0  = S*% #B" Bj0 Wÿÿ;a&94323267"&54632#".'4&"32654&5.'& ; +"--)b$RŠJ-I|Z.@?B5(³?6 #R [; R`? $0?G@7¥wm %8_w­fD*,0 FÿÙÿÛÞð+4.5!2#!&32632#"&7>7"#"&5476!$$¯6 þÚ ? !r9G[( > :t'Oiž&5  uŒ(e <@ $)q%eOÿþÿfåb%7"'#"&'&632;>'&/547>322654'"&#"AB3!ºK5&4  $IþÛ J*DrÈ*N78±6e/ÊK54$L6k$'u[@6' .ªÈ2 4>32#"&2>54&#"ª21=l21=lt.1 . »+:s7+:s76(& þÌ~ÿ» ##"&'72>72'#"&54632E# +T B î!0 ]8"  #%   /ÿÆV #2654&#"'&/5'&4>32#"&sG*$•9!6jfE;Ô))/=7(,C]7-%þÎ-$qT}U+:™#0L)'GTN# #/732?674&#"72654&#""&54>32#"&54632z$ !"%6D+#§31-?3&53;*'IK'Eo7!¨5-#Ý*FU,+.Pÿ)KK531?ÿìÿüf.*2!5!#./.'#"&'32654&##"&54>âQl:þz[)YQ(…M.&!!-1áqXeI22þ<. M¶§ y0"'92! ÿìÿïˆ;4'#&/.##"&'32654&##"&54>32!5!632'4&53#'‰J2 F$]S‹)…M.&&(1Ti:þ <:b`2šHþ$ZK´§ y0"!?2! sVeI28KrZ32ýó4ÿçÿ·J23!./3267.#"#"'67./#5!7654&#"'#".54;2327ð?QƒþÖ%/8 Œ?CQ@Ês<>N5^) ?"/k©&!!8s-7%)WºL3 2 0+j+,.QDD†}'110'4(S" 2  /!4(ÿðÿøZ67'&547"&'4>732654&#"#"&=467'#5!654&##"&'4?32?6323¦%+%3VR8>*() B=:(3 !P %+"u} ~!,R  O* XLfü 0" H(6-ˆK->-gSVJ UL>) 7S#' )%/'2 <2)I12ÿñ>0O23!32?632#".'32>54'#"&=#5!?4&#"#".54633()4#zþÐ "(6dS*F0'#/O0&;  V*&Ýf' 7-A+? ,7¹ 5$2”(.m6Tg -O>c5.B^K5,& #H.#½2 (  !ÿã7L O23!36?67#./&'2654'#"&=!5!2?4&+"+"&54732>7Ra€þé $  YqX9SA5W/[ .L0µ2 ;9#  '%q“426753#/&''./>7'&##"&546J1:)^6þûB&)4262tt!A7]841’ V1š+1R„?2'¬2þô0‰%<2þl/Wñ;F5K+O $!&"6ÒL32654&/.'47#654.'"2#"&546È4HV>2?ZQL,KjkKK% #$2=.N>>D',=12$ !) +Y@C2@.  ?#-<*ÿýï3;'.'&#"#"&547326324'632#"&546›5 5* HW* 9( >&&1&  $%.‡39þ/.ePJ:+7%' l  5  (/"K‘,ÿü?QP'.#.547326324'632#"&5>732654.5>7?4 '(–*4!)CO(:#10N %!1(0;*CHffH!axr ù&1+ þ‘6- $@+P52/-E'h  M5 +8,G+ W$2!=,3 *!>&9ð84632#"&/32654'#"'4632654&#"#"&ŸŠF7E',RA]‘;"!&9 #.-?8. $,#M3'€CUG5@-)?54.5467 +-c/9<+8"W@4]A;%k¤.9%"%%;2R({^85&&IhiI"! # ,D0 -491=8G6RykBEþú.&!$ .6&$$+=YN *F(0B54ÿðF.+%675!5!#2#"&54>32654&+'.'*Ij+A!þèœ|þÆVêBy1#)X0 *vR‘L.(*´s#'22&vU(4'3Jþpkbô‰03#&/./32654'"&54632>7ŒST  7S>S=v9f*%0)&"?H'Z=S2þ *04! g9)E '-*4C#L *_õ ÿîù83#'.'632'>54&#"#.5>32&/&=‡[[2$B*--((6>:I  "Q>[e^# 2ýò-),7*+,!3N&AL )3RgV*1‹ÿóÿþé.*27#"'47#5!#/.+"'767#"&¬26RfA± =ö]q<B+#*:‹'5 Nlx/:22þ45KD0 =¸>2654##".'32654'"&'5&'7632#"'6ë*<Qw -XB?e:( '4F4 \-J  &W*3I86‘'A> 29*CQEb|[&5/#"&5#5!ÐA-1!"„7EE.‘<>QµP'3þå-E' Ã)3)"G±Bp22ÿóÿ´ç. 826=/&'%&/&/32654&#"&=#5!!7|G)*FQJV;bt'@710,?•(,?F3Háþ™p2$5 ? ! 1I#T:'h& \P5/ ">'Ó22A %5-ÿñd.S47#5!!327#"/&47##"&'"3>36323#.5472654&'#"&~HÕsþçN82KT'   ;s 5 %K 'K<8V. eS#H *3F{7J229McrMN z@7.H! #(J&;N³)ÿýð,[%2674'#"&4633254&#7#.''.#"#"&47.#632#"54>72>7!*"!% 2a ]Ÿ*":9$-fM\*•.>N .K `U]#1S/*B'&.!*X78I'20Ò:)iœ1(2oHI.( \8d03p8OG65!?ÿÏJ´:23!3267#"&54632.5#5!754#"""&'>73Ø?QLþµ+m /1>vO!5JJD  F2[ /»G52þ¯$k-#!69B‹M$;20;3   ÿñ*¦_?72>54'#".547>54'#535&/&5473!7>#5.!60 J6*>16$ Ä¥34;%FÐV-7+_J0,N3,¦3“93I6&80-E'(2  NHA"30)[$2ÿö=#.(#"&/5#5!!>7#".52654”R& Ð-þÖ$F[ !N8;_5$ 3R4@RRFÍ22ÂD"3r5H0Dby^$8ea;N+"ÿñI­.!7"'#5!!>7#"&54632¢)/Y¼þÐ1P!%) /9.IOd22þ° W2'$//+K2&Ð2.=&53#'4&#"3'4632#".'&54632R G^6O:> %-3+ WA;)† d} >2þ85c.3)&'1" #CW<$ -ÿóD=.+/2#./264&#"#"&546%!!B/I(F'!&4W95!00H)1_A 1$0HþÙJý¶Ð$2>-DV/?hU>/ O6M2(Wn3$("6-+<^2 ÿûê‹13#&#'232654&##"&54>;25+"`# WTz«O@, %#*=2+O¨'<' N2 :2ýÿÒhV4  %(%8 Nÿñÿüô.'#5!!767'&54?CnCBþq5cLWA#+[m>E22Ó,RApvNNqf@'ÿîÌ4$32?53#'./7"&'4632#"'FeN}6Î! }†T ™T;~.8*10 ‘+H@]T&IB2ýòUO^1( 0 ÿôÿòÒ.2!5!#'.'#"&546¡/]þ«ÞW#*7&#*"4L”bA 22ýöLwB- #(+35?ÿú#p .&#"23#'&''764&#""&5632'5;4 "%!ôDM2#«G+ " 1”?t Ì$ 9 2ýþ-ÿe ª.* i^~“ ÿñr.94&#"'./7.'&/&'#5!!632#"&546323279, -4N+: )#,þ5J{,b Od/% C!)þx(7*S~    22I+gH7X_H(0! "ÿîÿ÷Î.%675!5!#'.'@]dwJþÖ—“þ®à\ #<`9ŠH2q¾k."22ýû&9C/ÿñL'.$(2767#./32654'#"&546'!!ø$BnnV[…- @8C*8NP>,?&Ö6ýÊÌ$8#>:./b2ÿñÿýù. '24.'&/#5!#'.'#"&54>„?U9°-6A  #]U,'0-%$ü+wA9+\» ,:22þ6p,4#$ÿñÿûè. .'#5!#'.+"'>ŸN3 ;[\‹‡*÷W€FD1Gü/D 9"z~W%22ýÿNqT+6ÿñÊ.""&546;2675!5!#'.'@]eCbŒ%%¶tµþ±ÙX (A`4‘Jd1R#$UB!22þ?K3ÿñÿû0.725!5!#'.#.'"&54632+"&54>3246H%þU?b2-".0#7 %(, ;P(" D&+É!%‡22ýÿ1%.++*1 !(,!O@&9 >*ÿÎÿü‡93#'4&#"#"&'#"&'67'&+'32>7'5¸ CZ2C4&, #   L A2m208!'  K 2þ.?` 5'/@#&3($''=$‹u ÿñå.,&'5".'#5!#&/.#'>?67&#"Y&+%&hKÂ; õ"ôY †; D, %2 0-2_z*"ŸB(22þ'&bX(  ÿñÿû.025#6?6&#"/#5!#'5.'"#"/7270 Ø$K]<',e2  '-.)!  )¤<  ?o22ýÿ9Ø! "!!9K# @ ÿìÿ¬Þ.+&/3674&#""&567654'#5!#6~BLeqÇÅ7@k~ *- 7''n*¤Õê/1@0J 0€DÇ$‡.G3!; <%22  1þÄÿeÿ8ÿÜ #"&=4632È %] "* ÿñÿ¬Þ./2&/3674&#""&5467654'#5©21>0nm¬à7@k~ *- 7'!S*Ÿ.".9,+>{D¼/‡.G3!; &82ÿ¯ÿï׈>23222&'3#'4&+Q   .ZX2@D.93ev82ýó4{1-ÿìÿ÷>7'&#"3#'#53'& %?(Xš4 TVeDV „r2Z^,t  "L= A8[)+2ýû/Ö2/þ…ÿûá-'23#'#53.#"2#>754#"&54¼B€_ rr2UUša2fO+; F5 {ET-;xL2ýÿ2Ï2cj*/2 $1(dþØÿN#a6>54'5.#"765656=3.'#"&54>Ò +#8W$#5)'%8 " d  ':* N-% ÿ ÿRK!#"&54632'&#"367?,:!-E  )";‡r5)('0rþáÿÿÞQ./?8 Zc‘)n  \å@:j2QN <%%ýûþNÿ_H#.''&/&/?'?·tn *'  -2b‘ 6‘)n *&îO5N% ;j" j2QN%ÿô:. ;&'467#"&547#5!:*E1%' $ 5"L_eœFý.>oF*> #1”mry2ÿÈ C 923#"&54>32#.547#53654/.5473;|)MS<8\/,?1= +A$i‰¿N-@; A µD1 2]=LH#" /.>M6f‚2 &  ,+*ÿôÿï ˆ34&+5732&'3#'&'>7#"&547#5!›@D1 . UU0þŸLg)@3)5"N^fœFž1-293†U72ýó4ÚavDCX")1™td{2ÿÈÿïJ N4&+576;2&'3#'23&#&54632#".'67#53654./&547Å@D1!7UU0ýkiWS ,|& m ("7+1F!  _‰¿ #A/* ž1-295†U32ýó4•0G2<,Et 14>^C‰n2   *,ÿºÿ^£.3#3#66FN›3.2ýã …4 64&#"267>54/&/&'4632#"&'" 65 ###Qg%  } ZG': b/D " ))$,)Á )  þe 4+ ?…A^*" dO-.( $N4%þóÿñè.3#'#53654&+"&54732632‰ hh2RR -k^RcDŸH 2ýõ6Õ2E+!#;ÿñÿŽ". <4632#"&"'5#5!!>3#".'2>54'è%(#0<×1þØ 2(1fL1R8,%0L/.4$S5* "":W»22™  *#g9Yt(>VQX8/NZ>. 6$!DÿñÿŸ³. +4672#"&#"/#5!!3>7#"&54632{  1 îˆA."ZÂþÊ/N $*$2(0#?!kA–X>22þº V1 'H%ÿìÿøê. -4632#"&'.+#'67&/&/&'#5!# ,0<oFÌ#' þ!~FC:Z #:'þbü: 5&"qþV"$GQqU=C  #22ÿ¯o’I26753#'&/&//&''&/?./>7'&##".'4>J1:)^6þûB&F-272rr n *'2>w‘B41’  ^š+1R„?P¬1þô"-‰%<2þl :ñ2;N%+'HjK+O )!6þñLk%#654#"632#"&54>3265654.'5+654.'"2#"&54632654&/.'47+-@@-" 4    #'7(:;. % #$2=04HV>2?ZQL,KjkKeB!4&$ #@   & !$L)$2@.  ?#->D',=12$ !) +Y@4jþêþ·ÿõ#6'#654&#"632#"&54>3265654.'467Ì )+k!A     "'7=JD #N( #$  ! !$K)! (#* ý×þwÿõ#8o#64&#"632#"&546326754.'467%#654&#"632#"&54>3265654.'467þ! +!("!   "%&8(:;.1 )+k!A     "'7=JD-  / $ H  %9L*$+2 #N( #$  ! !$K)! (#* 07¼¸ 4&#"326%4632#".'&~-6Ij8-!$ /A.0G%.- >}"ÿ¯à1!&/265&/.54632†K?qC$ ÇÆ1_G"Ec5 "0?'3?EP5&@¾*ª/(I+ $!" 0Jÿü%Üÿ$%#".'32654&'#"&54632Ü )I.1H@>,“M2`*E4'$3J:9sû/?3$5Sšd{©U54.#"&'>7.54>2Ù)7[( A&)+N!5'-+<,>(Z>6f C*33#H^E4U. Q(+¾ %+9&!* Í K9+6%R:5= G)/7& /& !F æ#074>7.'3.327#"&5467Û-%'/F^-=;&e )(?G112)6už^R¯+G-;"!“K#@'FG 1M+'>j_¸ÿÿ Ï(4#.'32>54'"&/"&4632>p_$@(;e=, #0G*)<  @!$>! B¢Fv!$:*Lgy[ *I=@/ !1')!,1*†""+#žA\Ó!$"36=4/.#&=#"&/46322!N› ±!0”Pk28q1íT-!!(þA  D±G"=gt7þêä' 64&#"2657""&'"54632>72>7!#,) kË  5)e[: 9& 9 & 9C  #ªdB¦   73F€Z8.Kj73'654&#"#"&54>32Jj  <~NVs/" 1(! 3FÁUßGD²ÚBFC"?&3*-!1 c) <>732>73#"&54322332654&"#"&54632#'#"@-"8bC8! !2T‡Q3L>  8/%0'0?!1'F“-DbVe7Z·¦h6FI2!    ')4J5'9 /„'7;#"54#632h &(&%‰9TG&7N-S()"+"=4#6232?>32;#"=4ÿ">#%F   % $&ŒO_OOî&6HüF&2! Ký8Sõ©#· 72>74#"'4>32#"&5|+:?!2 0 /(+< Z34SÚ**H(! =V&9 )(=R733&+"467#"54632- '0!%9 Eb  %-6  / þÒ/1 "*4e '-'J'4$ %0! u2Ø0%#"54674&'#"5474&'#53>733##5Î(19"< MV(262U8 e##8˜r2@ÓAJ490g nR#+%:AS,š9€+ U D?3 9þ#Óÿÿt#™Ømÿÿÿõ’»#³®šÿÿÿõ»#›â³ÿÿÿaDÚ#œ0´ÿÿÿ DÚ#0´ÿÿÿõäÑ#žô³ÿÿØ #ŸÆmÿðDÚ#-3#"!##"&'.'#5362654'!!!> ¨¨Ff Ú9'$_MQƒ# +û+Aþè>þ†$#'ÚCG:9?€ .BJTrL-Æ<9ÄýY8+*!® 3H0tÿÿæþ#¡*m&74632>5!5!##&'#"&7267.#"#_L1~þ@&@B&ˆ3L]E7Zs m#-7È*>gA(q.2D.G9rÝþ#D*J0;`O-9Cu[=+.p‰frK-1wÿó#,!!2#&'#"&54632654&#!5#5!.#"32þN,15L FIW>_YAs9@+#þ° ÀN)PSVÝt@3b7!=D548F.3­9þL!85ÿóö##"&5#463!5!5!3254'!öe_Vl83Eþböþ¡K8…þúÝþõhweD-8¯9þÌ@v¨ ÿô@"*3#!"3!2#"'.547&5463!5!5!4+326%;5#"@2þ--2&,nh<$- :0*þ2@h^-1&4þª3)/-%9Ý•+B2+D F./#0/;\9þ]@€!%€#Ü##5##67#&543235!5!Ü2@Ò@8` Òþ–ÜÝþ#×!“#:\8Í9.0!3267#'#"&5463232654&#"#"/7&'#5!Øþ¦%‰RJP 1C<;8‚ KY.W;70>A%z :z'3>.Ý‹?LEK "J*G <&&0/A%@99õ$#!"3!#3263#"5"&547.5#5!5!õ þ¹)=è¨9Gã7J? >ò`þì&Ýš0 9k9¢>2DM9ša,5ÿôþ'7>32;5!5!#&# 32>;#". )&;*G'' þXþ-+þðg;43# q9'[O4¶* –99ÏU^/#?[,F6ÿô74635#5!#2#"&2654&""BôèB†li‰ò9sk‚kt¢Hx{99{xHLba%G)9KL8*Fÿòü3%.#"3223265#"'5!##"54632654&#"#"54Sj)@qFŒl09b£ƒü22D5hH¸S;=u327&'!5!#.'&#"327#". l>0)6&"þà.Ö 5$+-S;,?€EzTuX?TV²GO3Z99(aG$f$+#5O|Sd #MÿúÔ)23265!5!##"&'632654&#"#"54…l09þ‚Ô'O>-!4Qz Su?N<)uLFe>;;;h7K2ML> N3)(8-. %5!32'!5!'#5!##5#"&'654”þìTbPêþÑ_ 2@-CIž'¯i(,TáŒ2299þ#\*Z4:][ÿôè%#"&'#546;35!5!#!32>3äj?gk 8(4ôþnèþÌ„B4 ŽAYŠu7,G±99êÆ10 7327!'#5!##5#"&'64jTbP$þÑ$i 2@-CIž'âT?IFAÐ99þ#z*Z4:šÿþ $74675#5!##532654&'3?"&]oê àl^mM#Ir89sJ"Mo„DiEg99gChG@F;57o o65;H73273##5#"&'64'#53jTbP$r2@-CIž'' V.âT?I9þ#z*Z4:š+9ReDÿõê$"&54;5!5!#!">274#"326@u£–ÖþlêþêT=\vR\&V'E<%&; ›Y~v99¯F:>*4715êµÿõ "&546;5!5!#326=#BR§;0äþh 2VûuA*1Î ‹Y2?“99þ©?Rpo5,~ÿþÆ297467&'#5!##"32654&'.'327#"&!>2AS#Ɔ#RBkO20^K'M""N'K^.NnÎþÐ ]00`¤3K8j99j6K5F`9F)&M89N%*E9`<ƒ…ÿþÿúÆ <C72"&467467&'#5!##"32654&'.'327#"&!> AS#Ɔ#RBkO20^K'M""N'K^.NnÎþÐ ]00`< h3K8j99j6K5F`9F)&M89N%*E9`<ƒ…ò##!"3!#3263#".'.546;5!5!ò þ°Fè^J92BmH9QD2þþnòÝš9;79"N791.;a9ÿú%!32#"&4"546?&'#5!##5# þðàŒ 9% H2@à ÝRÐ ,@'T(ŸB99þ#Ó;8-ÿü!3"546?&'#5!##5# þðàþÒ9% H2@à ÝRþð@'T(ŸB99þ#Ó;8-ÿôõ7325!5!##"&'&546;#"a\H~þ}õ2¬FV/,D5484Ò9l199þ½¦%=:<6D9TÂr7#5Ânrrrœ##53|@<œÝþå99*»#54&"3###5354632*@!6!<<@22K12J($%,9þ#Ý9.1FH1ÿ„®»###5354&"#546323®2@<žs1² SZkþx ÿÐ #"54632&#"+"5432.þ´- XÁ gmD$F>‚&‡Ì”V@%4".Zþd<ÿ¼ #&+"'3;2D4š_0–8,<@†F=þ7 ÿ¼þ"&5465337632#524&"3#ö]v Ž==\@  @rF9 I)o$"#ÿ4ÿH2ÿè &##"543532SW"H@W¸M -$ÿú'##5#"&'654'#53!535!322"&462@-CIž'' V*rrþòTbPþïÝþ#\*Z4:][+9T]±þ™}53T4 ÿþÿôZ )%5#"32!5!####"'&546;2"&46(†%/+$LþØZ2@€zZ=9B8þ÷a( //+°99þ#Ýþ}f=9L;Fû ÿúÜ"##5##67#&543235!5!2"&46Ü2@Ò@8` Òþ–ÜçÝþ#×!“#:\8Í9þ& Ô/23265!5!##'#"'#'&543232654&#"#"54™$K.@þ„Ô )OIHH2!LD@,(‹3I6&N1]a W/990W0JI1L: $TZ% 2*)")/9ÿõê$."&54;5!5!#!">274#"3262"&46@u£–ÖþlêþêT=\vR\&V'E<%&;þ¥ ›Y~v99¯F:>*471554&#"76ßy–J:Nur'3O‚Lv72…F5‡,d$wbA]–x6*R9EC8Q-F:ÿþ¨74&#"5632#'#"/"&5432654&#"#"#"54632326XS_k;Bdi‡$:Td( Euj?I 8r W4L[%7ƒ!4#EJQ98++?1F&("?)6%¤$.2654&'52+"&547&54632654&"ÒLF9-I]P8aC,Bb8P]I.8>QFhFIbID+29QCN2)CAUW?C)2NDP93* "ˆ,12+&))ÿø 72653#5#"&'654'3Ó2[@@&YMz"B3µ&ýê $91`;HMDVFG:ÿü½@%"&#"3!!"&547.54>7&546323"&#"2#"&#"32632d(.#þÞ:K9#5/.;'x\3r8)A& r"BX:0 †*7¬%!#9B7G @'- >-;5;F5&$ $&1) (*(é &54632#52>7654&#"r jQUqþíÖNn_T M87C "!!LZcO“Å9 /V87FA5 ÿü ".5#463!!;ÞužW$P9W|þ„+JvT.2h‹dX9X9EbW3;ÿüÙ%!3#".5#4633&54632&#"iU@þŽV‰u.\…Q/H7QîWkV 3C=5]4[lE9"9\dDN2HIeKM97þ>ÿeÏ#654&#"#&5462·( 2 &@V@>0 & #((# ÿõä%%26;#"/467&'#5!##&#"5!,! l=h?g9#N â,)03C7 .f~þÖ7%.`BW2S*[7Š99ã*.B ¦5_ÿðDÚ)16323##"&'.'#5!.#"!!>2654'! +Ýl 9'$_MQƒ# äuIGe zþ†$#'ž+Aþè>Äi[9?€ .BJTrL-Æ<92OG:C3H0tþ‡8+*!®ÿøÔÀ+@IQ[#54#"&#"!##"'.'&'#53>32632".54632#"&=%!3>4'#326%4&"26Ô@9uC+20H —1" RBD=1- `D*#Yi)FüÃ*@\;?X`B<"&@þ¼ û!+ñ6n'5þ5B55B5O(c:X595g)7?I5*j_G19OxN0"þs,&6HE9él :Wf·);,cî%•0ü'('(ÿÙŽ «4>32#"&''9.D-%.! BU.%5 - &$:fÿÿå[ %3?M%32654&#"#"&'4>3232654&#"#"&'4>3232654&#"#"&'4>32þ*0" 6!/ç]>BS'8/BSýk*0" 6!/ç]>BS'8/BS*0" 6!/ç]>BS'8/BS‘':A2+;DTf:$5 M>':A2+;DTf:$5 M':A2+;DTf:$5 Mÿ2b:8CS32735# &5463!654'&'#"54>3234>32654'"3:>7!!#(0Gö¨þÂÓ' NzL4 ;)}$0*I`L6ì)ý)*!+-5ÙKlW:&8%# ýØ:ü`&&+;Z^elV%/<%ácB#>(*$8!3O\FZÜ ‡.'0I%8ýø)=  $;%ÿ/:^iy5463!654'&'#"54>3234>7632#".5463232>54&#"3273#"=# &32654'"3:>7!' NzL4 ;)}$0*I`L6ì)2EJ\4`œ\&SQ5?7UB?VG25"++! XGö¨þÂÓ()*!+-5ÙKlW:&8%# ýØÈ%/<%ácB#>(*$8!3O\FZÜ ý‘dD/eZ:"@)(%  %1 .S3?/&&gY‹el4.'0I%8ýø)=  $;%ÿB9lwŠ254'"7#"546;2#"&'#"5467&54>32273#"54.#"632654.'.'3232654&'&#">‘Y45Að !E1–gO%&JN:%&)7"2QP).|/lk³K;9$G_”ZR„V@!>   C>n{LJuJ6,{VS$@(=ä4HNB8;›Q‚A@Me.}EV}aFcBs§TQ,@2_Z-/Hk/HxLIY 0F(6P(5}Bt$uZ:3SJQ9%.D@R9"þ;,,$3 _Ý]ƒE'8VG^.¿nk::A"UWC,ýZ&N $A>$1‰ZF,$M94€<,ƒÅX!K7237>'&5&57263>54&'#"547!"#32632#"547!32632M$ (þi8#5&G8 › !2)Gþ¸!&5$ "2) ÁIYœW 0 'þr&(MYœ+.þr&)ÿÿFW 72654'"7#"54>;2!#!"54>7654&'˜!745?í D1”%D+%Dj;' =;/J[»þ!AIdƒ.6^<<m#'F(9.QN((€ .&,>L73M7"!/=4>KIu(ÿÿp] T`4#"32674&#"632#".54>3263!+"32>?#"5463#"32>7#"5%4'"326#!"54>764&'#"54>;2(R)23/(#€=;*C' %[5G\I(<  %6\9p-K4e &EUK &EýH43A %3€ ú÷A-NWf&6]=9/J[*Y+"H5É2&&2$BE:KY#0<(8G:(621þ÷# +5R 7ð# 1/RÉF(9.!("þ¥8+?”t'J8<€ .&,=L83N6!!ÿûÔX6C4>3!+"3267#"&5463#"632#".32>54#"-BqEŸ V -"!1 Þ1O, 'd &bJ,E$T7)% VHLcR9þv1!6M3<.=S3S#;%bn/@O5558(.r.ÿmÔW6C%#".54>3!+"#"54>5&67#"63232>54#"_`H-G%-BqEŸV .>9ON Þ1O, 'd &þõ7)% VHÏ`p.@P5LbR9*þ0/J+  2Bã.=S3S#;758(.r.þ‹FZ x4&#"3267#"&54632632!"&#"32>323254.5476#"'#"'&54327>54&#"32>3#"=4&#"632ø(*+014'!JcBGTmuO)‘2K+ þr3c «%6/5H  2%Š'+ `rk?VY=?ÈÚ›!-8&R?,I %DGP*C' $\5G)'0+!G67632.547372#"&54632326'767.54632Å3: 2"/(3+ "?;R,¦}fYO3*pBSmF\q+SY#'OÒG-C7)? 19,JE&6L}hF8`u -UFP!7_s\P1( #*>)75 ,"%b;Ka3Q U6hOTE ;p„g6ngP6;j¡>^.$7-$<6.A  R†^MM7632.547372#".54>32#326'767.546322>54L/;4‡3: 2"/(3+}9e¤^/LCC2 *pBSmF\q+SY#'OÒG-C7)? 19,JE&6L}a€4S. 1: *8 / 7.8]!7_s\P ""3 ª (0ó1( #*>)75!.g^=%8`=OTE ;p„g6ngP6;j¡>^.$7-$<6.A  RTW'/# 2@2%  ! 35:# hN[x  ,"%22ÿÿÿýþ’²Y'æÚÁþù4X =73276=!"%547#"".54;547!"#32#"54?>74&+ThMP;þô)TÏ .@b8# |8 › ‡eQÞPCBEATa¿=K2Eo-_•+•þ ):4•W 0 '•WMº  =4GH‚¬C[L7#"547!"#>3232654>7#!"54;>54&#"547#32?2¡.,G8÷ › D-+3#M+Ü)>þ)#$¨5G7) #-%*²!fMYœW 0 '­>4#I0Um° þ>,eA6H ,0&%&+*þr&ÚX 073276=!"%547#"!+#".54;547!"+ThMP;þô)TÏ ¹ï@b8# |8 › ¿=K2Eo-_•+•0‚¬):4•W 2 '•þFZy…43232654.#"#".54327>54&#"32>?3#"=4&#"632#"&54>32632!"&#"3267632#"&4&#"326Òt'$H0-S.8MC5T1! ÈÙ›"EFT>0+ &DGP*C' $\8D]HJQ "4^;uO)‘2K+ þr3c «%6//M(@§6O(%I3QfÚ(*+014'!ÿ;- (9 Pb1+!1A9Ñ,m`Zx ) Ô# 6*RÍ'E'2#BE:H\uP5I;*^\ /C;!þ› –1K%?N|352/OF'0+!G6ÿÿþÍ,Xan%.#"3267#"&5463#"632#".54>3!+"632#"'&'&762>%32>54#"ÚJ/"-"!1 Þ1O, 'd &bJ,E$-BqEŸ V ;3 .%þÚïÔ“¯r F(8J5{sdž^>ý`7)% VHvQDy1!6M3<.=S3S#;%bn/@O5LcR9ß2&D,Ùÿ˜ÐÕ‰dÄE}UJ%D2Mg^v58(.r.Ã\%#!"&54>73à ýÙ=))2//5¶ þ ÿýùXt’732>54.#"%#".54>3263263!+"3276#"5463#"#".5467&#"#".5467&#">327"32654'&%"32654.Y /% )!, aO+E%V®p_lWnWjATŸV &"R ÏIŽ (C)2K#=3NXT"hT,F&>8HI;WE7[5 &Ö"GG8)@n ƒK 7&.> &¼ '- (/.'#ao-?L6Yœe11,+- þv1(G9lo¿5A6$=[LD‹4%Y¼q‰->M6J…0' !5dB:#;à™CF…]xŒA›@=K3fO8Z5# þ»CX J73276=!"%547#4.+#".54;547!"#32#!"#"5463!2>ThMP;þô)TÏ E/aï@b8# |8 › ‡Kd'6@ªþ¤  /Hn;W+¿=K2Eo-_•++•ë6B-‚¬):4•W 0 '•V~—=H(-Co=;*DCþÈŸXG7262#"547!"+>32#!"#"5463!2654&#"#"547#¤, G8÷ › B-*4$?}Vþô  /Hov3* #-%*²A( +/YœW 2 'þÎ?2"J10WS1(-Co=;Qh8F-X($Ó+*þr&ÿý_Y Td732654#"".5467&#">32#".5463263!+"3276#"5463#"74.#"326X7&)#V++ä3K%99>HFo>* [5 &cI-F&ͧUd@SŸ V HR ÏIŽu.'4'E4%)D¼77G(q0â7VP$1Ÿ9,>N7:#;%`p->M5Í)(þv1(€lXÈn†ë73!2654>7))>þ¤=))D )j>,/5¶ þ ° ò\%265#"#432#!"&54>73&7M RO |lcþX=))2Svþ‚r´ƒyž¾/5¶ þ #\'%#!"&'#&54>73274>73!2654>7#)>þ¤4,;Xh)AB))D )j>,"%Gc¶ þKeI þ ° ÿmX/72>32#"547!+"#"54>54>3#"i 4(GBÑV /=6-7- ÞA AYœS, þ1/J+  "$7â1þs'þÁ`=42325432632+"#"5&546;2654#"#"54#"#".5Ÿa$&O¦-UeCä  /HØy_\*2&(QLF!, k(0h…42ªþÆKi8(-C"- =;sk“>;þ…43yvuþ¦[.*ÿÿÿþX<J%#".54>3232=4./632#"=4#">324&#"32>f$99:V%=ds=4D! tW $*G=·¬w7W0 [5 &O+/E7&% Î;V,Ws:VˆN'@G6Ç­¤$3& aq{þõö‡¥,.377(/ØXIX%262#"5463#"3262#"54#">32#".54>32>3!+"%4#"326Z.,G ˜_!.,Gq]¤ [5*,#998N! 2L^W$v"22sVýßZ+ /)#B(LYvþ¸&(LZZrŽu:!C.;V,BaGFvK6J&$, þn5kr" '- Gþ” \K%265#".5!"&54>73!432+;2+"#".546232>>5S¤R-"þç=))  ƒe+HTV@MOZ"5"/5`?0L+ !6"-L?7J$&2œHvþ‚ž /0/5¶ þ r´‹‡Nj6X/' +!2:2!'0# &26G#683z[AM4.#">32#".54>32!2654>7#!"54>4#"326*V91F:/G01U#99-F$/J\Z(;]6$ -(7 ))>þ¥@080úY'0 :7)"0KU: %:jD7,KV;V,/@P3BsM8#5HC#8dG-° þ>, )3p;r)'$\Fþ¿$X z‡%4#"326">54&+#"'676?!"54>54.#">32#".547632!767.54>32'3254.Y'0 :7)"L'8 O7 - A‹E6ƒd 0 0D*6,þÔA -, *V91F:/G01U"77.G%?m«;]7# V0)'WS!.8)-G'<M>§! b; ¬r)'$\F¦#3)Bd -&)=Mþ0'3ð"&€j):`:KU: %:jD7,KV;V,/@O5eV™#5HC#e•&*81#uA,F'*3% &< =2#1::  (\J\2#"=4#"#"54.#">32#".54>3263232=4./64&#"32>§I8·¬I $-- ,'6V0! [5 &aQ:V%,BqFt65_[@tX%$ýŸ+/&  /% \le{þõö‡£%M2þÂ03G.G#-=O3:#;%`pWs;LcR8„„azÇ­¤BI þR2> '- (/þ³$V w%4#"3264>54.#">32#".54>323265432632#!"#"5463!2>54#"#"54#"#!"Z'0 :7)#` -, *V91F:/H0 &cJ7P#/U…N;]7# U1ñŸ`%$Q¦.UeBüç  /H @W.\*2&(QL-;þëA«q)'$\Gt):`:KU: %:jD7,#;%]sCaI6ugB#5HC#g’'h…42ªþÆLi8)-Co== ?L3“>;þ…43yvuþ¦+(X+62#"547!+"3262#"5463#"32 ,!GBÑV# ,!H Þ!j*.YœS+þ`'(*.Yœ1þr&ýø ‹%"#&546763?62#"54.Õ?Y*7i.0.JIM".,G*;6T!74</8.D#:BFÅþ-&#LYØGl=' ÿÄt•« 7254&#"&54632#"&54õ&"!A-jAYxW6Nš¶4;6D*(*;*3V([!Z@1l*8;1(þî Ób354'#"&=4'!263!2#¶ÎÏ 6% þ§ yG_L³% +ô.1•( 2c•_ÿ ÿ–¹ö8>'23267654'&#"32+"&=!26;!2#"&545467354'#4 ':nHS©-2FTja„ÖG'²6$þâ ù#R~J.`¼{ˆÖ±Î³l"01"]LUÁSdtXc•!/0Æ27Uwn=sÄ{~In³% ÿþEv J%2654&#"4.#".54632#"&'&5463232>?2#"5©)-!-,&3IYE%JR?)">†$*[A 96 4eGb9,¼ØMjU< 2#DJF832#"&5467.5462654&#"ó4#,-!0V 96 |g¡È4Ojc2tY!56F^* cŸ54.#"%#".54>32632#"54>54&#"#".5467&#">324&#"326Y /% )!, iC-G%V®p\hHbBi?)VK.7.…_-:gT7P#9:HF;WE7[5 &V[%"GG828¼ '- (/.'#jf->N4Yœe.-#5GA!S¢=+;qBgƒY¼q‰@^I2—8% !5dB:#;]†™CF…rÿÿÿþžv'Ú‹ßÿÿÿþÿÿÀw&àþÚ­ÿÿÿþzv'Ô¢ßܯŠ".54632X!, > * %$Ü&#/(%$ * ØYGV%262#"54#">32#".547632>3!+"3262#"563#"'4#"3265.,Es]¤ [5*,#99-F$?m«u#22sV ".,G˜_ýZ+ /)#B(KYZrŽu:!C.;V,.?O4eW™K&$+þn5(KX±wþ¸&kr" '- GKÿñ\ 2#"&5462654&#"ÔI?H=;QK;2B;1?65S5CWY@>Ké7,2;E+((\ÿíâ$ )7"546324632#""3274&3254&#"¥H#'#c,"!HC.)B,.–K%'!(`(", ,%2,Ò,(!Hÿñ¿?73254#"32#"5437&5432#".54632#"54732654#"w/+.üÇ …"H(,%O96P%/-'$? ŸTV9-Ö)&%M *C>0 9=%-A55>'#B "‚?QG(&ZÿðÚ(.6A%#"&54632#"=32654'53"&54632'654#"'"32654´§gh1/#"?8<.M<ภ!!"+$!/+ª‘hPg6E'$; 3 )5  :*,#%%/(*R 'Vÿ³’,=H%#"&54>54'#".54632>54#"+"'&"#"&54632632%3267&#" Q$5 C/V0 B8  r-!3)_,þþ1$%E [6 "&  #!0;I25!  #%22pS'&-/'ÿöÙËQYbk%#"&547##".'#53>74.54327676323223&54632#"'654#"24#"'4&#"#32>Ù)"$-ªXB(5&SRP7"!  AN@#0El")")5[R95 ÅI4$5 øó =,.!N$+1$ BM >+8P   8L1 P4#,%((& $ kN&u4D,!(1'Lÿó¶”S%3254#"7".#";:;!32?3254&#"&54632#"'#"&54>7&54;2<*)*)W9&-B !;! þÄ+#, !X  4$&N:-?,M&B* m!ƒ"#4&3$+%B" $#"^.::9@D(5+ *"& BTÿÙ¨zQ[d~%#"&47##"'#"&5467&5432632&5432#".#"!&5462#"54654"254&#"'3254&#"254&##"&47#32?1%-%$" ,‚:.B2-5N= T 9)+G£%>& d31ë+)&X !$È,$3 è%"(5/H-4E;!I3Ge$&.) 1!#!3)"-' (Ó.05!{B# $"4#*#)-$YÿíB60m2#"&54732654'&54'2#"&54732654&'&542654.5432#"'#"&54>54+"&5463232>7Ð !)@5.9 '9-0cÄ/D?7,: ,20.:)µ$'# C0%4 ,#0,5,5 '. #'*3*5 $3"L5BR9.221Ce_ODT9-4/4D4@ þì)5,? U\"=27:&*!-! $'%!)#-3(6)ÿöe532654&'263#"&54654"&#"#"54632>32¾T&43 o#/W† I#  0+ N0# &,€P@3I//"A#©' #Ÿ*dm L#1W#0)Wÿî‰j"(3723254.'&5432#"'#"&546"546254&#"Ÿ&%I23" 9F+,8 6!-(iC48"˜&,&^9N(C36032&23254.'&5432#"'#"&546"546254&#"o)) /-0&%I23" 9F+,8 6!-(iC48"C*8*#- w&,&^9N(C36054#"&54>70;0<*& +'< .J-  %%62;251' î-&+(26$,1&.(( .%"0(-( 4  [ÿñº¥D"&5473.54323232673254'432".3#"&54>54Å1'E  !+2<2<*& +'< .J-  %%62;2( 3@*) , %!1'+(27#,1&.)( .%"0(- ÿñ]È`&#"32"&'47##32673254'432".3#"&54>54#"&547#53654'"#"&#"4323!2H%;7=D1§&,2<2<*& +'< .J-  %%62;251'+0†#U? Ý)6 0+$,%-!1'+(27#,1&.)( .%"0(-( 4/' *+%#Tÿñe3*%#".543232654.54632#".#"eJ>(;   D8,.AA.6-+H & YGTG\0;-# 4"  ("!0 +Yÿ¦Æ4:CM2#"'#"547#"&4632654#"&5463232654.546&#"3262654&"jD(/ 32+$)D"+,,{0%&cA3 -*O/10!4V[-/#!2'D :0)/*,#"z;22A,5 ?ÂWÿí1"2#"'&>54.#"#"&54>ïIX8 &* 6%-R9 6@1dM.c&E( %-I5=Fd/5>*Zÿ¤v39DM2#".54732654&'&62#"'+"&54323254&'"546"3254&#&54%PH,+ &:+/<'Ï(Pe8( )I ! ! [B*€54 3hOME)  /2->:E  nOv5/"I V;K «$*P V!Zÿë¾3E"&5463237332>73254'432#"547#"&54>7654Æ1'.)!-4VÂI!4  .=  O T&11"' 2$&$ ^^"' # .--1#L  O4&!,Sÿî´902#"'#"&547.5463232>33254.54Nac5 #2"$ X&&=%! 1H!//!9lU‡><%0 '!,-.1,V3F Tÿ¤µ91<2#"'#"&547.5463232>33254.54+"54Nab8 #2"$ X&&=# 1H!//!9jU†>;%0 '!+"1+U2E þþG,&Yÿô»<P%2#"547#"&54>7654#"&54323254.'&5432#"&'32>73254'4 4$P*.6- *:(Y#)7C  /"7 L,5   H> x1%.J @7$  . 5I& !-,!#0)"( S/ ÿìÿ¤832#"'"547#"&54323254&'6323264&'&546 $=34 4 .54'#"&54632>54#"'4#"#"&5463263273533#&#"321  K)-BG.S K; =') =0\&S!^ÑC/H0]B -*  #1'!$ <I7L  $(52rL)‰"H0(UÿóÇ‹>G%2654.5432#"'#"&5467.5432#"&5472>32'254#"e$) & $A7A080:>5 $$ V& O--./(4->gH:W>32#".2654&#"74&#"326] @+FTPE#8!2QD3:EDa'’.:'VEJ]'/%[9B2@F4/DŒ(\ÿïÁ/1:%432#"&'#"&54632#".#"32>23254'#"7254#"7FB?,7 06/kXp  9,GV&!&$IV7<<%'%{=U5?4U2QfLZD!*&%L>4$\ÿ¥Á/6?J%432#"&'#".54632#".#"3276323254'#"&254#"&54747FC& 6 0%1kXq 9,GV!&A IV7%<%'%_}32#"&546322654#"&#"3"532>32#"&5464&=&546323254&#!.#[, &4)0U")CL mq %'54'*511"ç+!‡,O7#"&5473254&5.)”' 2^GE]XJ$"/  %6"S@@%¢M',/DSYCGg *%" !+A) ;!^ÿ¦©1'/;74632#"'#"&#.%4&#"32>32326"54672654&#"^aOGT?(3*),1G<*5$D!:)!, nVmjOF<87BS?M <*]$#E+*>#+':†  ^ÿó©1)74632#"'#"&#.%4.#"32>32326^aOGT?(3*),1 7%+5$D";(!lXmlOG<87BT-. =)^$$F+^ÿ¦©1'/74632#"'#"&#.%4&#"32>32326"546^aOGT?(3*),1G<*5$D!:)!,nVmjOF<87BS?M <*]$#E+*>#+':`ÿé8&2#"/&"#"&543232654&'"54öBe60.D<%+%MB8[k7H)@!+?"J !;$B_ Xÿí¨&*2#"'+"&54323254&'"543654&#"/(Qe9) *J!" ! ]C*²5&pQx6 0"K!!X54#"&5463232>32E"&# $+/$7;"0+5+6!&.J*1*2""(2.A  i:";2>@:%)!.!#(F)#*#1-XÿŸ¦7F2#"&'#"5467#"54>54&#"&5463232>323254'.76õ)@& ]  'N)2) &+ #'(1(9($8Eu#7*:7u00+ 6O , # ((-.1'Qœ]ÿï174>32#".2654&#"] @+FTPE#8!2QD3:ED’.:'VEJ]'/%[9B2@F4/DSÿö£-*5%#"&54632#"&54732654&'"5432'4#"326£"77H[<1F$ +0,9X%#  ³+«3L%bI9Q@$I#2 :C(4 7&Mÿõ H2#"&54>2654&#"÷2H!#@(Ee#@2@B0/CBH*=1 %2)`J $2)þéD.1A@20B8Þ¬'2"&42"&4672654&"2654&#"iD11D1S<1D11"" ¬/H//HÏ(+$//H/ þLÿöÀGUh74632632632#".54>7&#"#4.#"#"&547&#".2654'2654+53264&'Lt`F+4Gv.3[`B?QB&8 &1!'N;6T .(B20(J0C"042 i<;RLÿ`©ÀYgz74632632632#"'732654.'#".54>7&#"#4.#"#"&547&#".2654'2654+53264&'Lt`F+4Gv.3[{?ZWŽkD4$&`|1%QB&8 &1!'N;6T .(B20(J0C"042 i<;RLÿ`Â9E3"3!!"&5463!2654&#"#54&#"632#"&54632632#%2654&#"¾!:\ý¤2>>2uEPN>'0TH56Y$:0?D2>2uEPN>'0TH56Y$:0?D26@4CTmYD] $:0?D2=I…jGi5þ“!# !QjJKACd'II-A1 6hWOc( ‹h<3SA  \z-*I:%,7dLViA28HnMZG^t.KL}1%"/-#'0OÿK¢À/;FU2#".547&54632#"'32>5#"&5462654.#"%3254&#"2654.#"BPxx?zS2\b;xxQA4@?3?&{9SI&)>4>?A!!þº#=#€Äy,GE#%HF+ÀgMŒ)^1. ?-`+ŒMgE59I>\A !@/>J84FÑ0$ !%."WT#1W".;þ90* *0Rÿö¿+5?2#".5467&"#4&#"#"&5463262654'!2654'Žf‹UD)< :0`AS1&10: <(BW‹f]>D·'6Ug6þH(7gU4¿šqQm.C5:r$.%þÂ5H&p:6C.lRqšGGþuI8nHQl3GF4lQIm7JNÿ>îÂ6>2'654&#"33#".5#5654&#"&54632354626=#ókš2ygT\nS?4(< òH:+0@1<\KHb${‹"-¯ŒÜmg¿xš¯ˆ1#þu5G&>> -O/9F9G.[M]YJ:*0§Éýº' =7MNÿ@ð¾OW%#"/32654&+532654&#"33#"&5#5654&#"&54632354>3226=#”'5K< #2)&UE"DA(S?3@PòH:+0@1<\KHb${"5GC"?`.þ‹",† R>Jb?=-Â6V^g2'654&#"33#".5#5654&#"&546323546!2'654&#"632#"&54626=#%264&"j’›2zjRZpS?4(< òH9+2>0<]JHb${‹ü¤a‚y1W^J)A% ,=2C?4AN…ª"-üq&'@()°‹ÝlfÀ{—®‰1#þu7E&>> -O.:G8F.[M]YJ:*0§É„n“HAxYp"/>*HQ@9GmTy“ýº' =7M³-H1.H0NÿõJÂ1=2#"/32654&+532654.#"632#"&54>2654&#"f]|EPP<# % '/(((!<9É,?1BB6;IsT<_9$þm.%#0-$-(NÿôÖ R^2#".'332654&#"#546!2#"/32654&+532654.#"632#"&54>2654&#"'O`^N*@ 2'3C:1'4 Vþ~]|EPP<# % '/(((!<9É,?1BB6;IsT<_9$þm.%#0-$-(NÿôåÂ:lx4632632#"&=332654&#"#54&#"#&5465%2#"/32654&+532654.#"632#"&54>2654&#"]FN/6LH681cCQo!+)7O`I:",T1 ) þÙ]|EPP<# % '/(((!<9É,?1BB6;IsT<_9$þm.%#0-$-(KÿöÀ)08C2#"/32654&+#"'#"&546;4632#4&#"325#32=#"H?C1&!'2ETER'!A:IRU%N?%:E8,+44*fã?"bÿT57I/3'4&f€PPV:H1Vk#.=#:PM=I=Rµ? %`UMÿõÃ$02!3!5654&#"632#"&5462654&#"7^‰VSþIebI)A$ ,=2CB6>K !)' *&ÃzdkX—þGJtPi"/>)HS<:HeS~˜þl.%#0-$'.Mÿô±À+2'>54&#"#"&547326=46N_ =-$3 J6%<ZCUe|42I<%8a¿u_9KC6I2#"/3254.+532654&#"#4&#"632#"&54>3262654&#"zGbBJ_G) 8U--'$.717/ASS,¥-?1AD9=CQ7ëSýrÓ+7$)#* + 9(R>I-—þG"?/"80! $. Hÿ÷ÃÀ1>%4632#"&547&#"!532654&"#&546323&2654&'udbECR@8Jo$Mf_ý¼Ë"-(D- +H;AQ2¸<'1%fße|QL`ZrXF„ZmWx;">-*3.%=IY=D,TB@F>TTc!1 KÿôÀÁLYb2+"32$32#"&547'#"&546;2654&#"#54&#"632#"&5463262654&#"324#"3>+,W;ñ,8!>2,86-#< ?¸`/8fSÞ9L5'(0R@0=$(&'*5.lS\:!“þ1**Á ?*.-&t3H,-!Z3&5AC5+57,Vg#0& 9E;$BR56þf ÿfLÿôÝÀKW"'#"&=4.#"#".5467&#"&546326323265332654.'2654'X*9 kª9.RB_:-(lUD)< 9/-M^^!kwb?4.MJX<)"?S2):N 3#ýD)5We(À@D3c„MLaLa :2ZzRl.B6;n% nW~?Mjƒ`M]LD,#Dþì4>iM-94þK6oIPo #,MÿõRÂ=GQ2'654&#"#"&5467&#"#4&#"632#"&54>3263262654'264&#"Xo‹{1WkY mSB?P9/"6CSS,¥->2B>6@N1QR+RE9\7.8P+3Wf6þ >&' *ÀiŒHBv\{ [|RjdS54&+"&54>32&#"36HT%=> ‚D=o6-.5a:J(O7‚D5i?L) ?5*= G9 ''F4/.G80)"MÿöÀ 2"&5462>54&#"'d‡‡¾€yQ1<*bGHa"IÀhd{afˆþn!H0Id`G3>+MÿôØÂ@#"'#"&=74&#".5463232653327654&'W)8 "/:)S92YHa5!(0 6.*; qK7\G-50S(.5*.G)À@D08X1 MLePSG>%M2J74>32632632'654&#"#4&#"#4&#"632#"&2654&#"L$8\:i0/Xj/*SN:A 3)+hK;'3S@2&6SS,¥-> !*E4>Lw,(*&°%HJ8#OMHJ=Df3U6 A‹Rf-$þÂ3B)þ¾,)5ÉG =*:Hj0,#'0-$'.Lÿö Ã-72'654&#"#"&5467&#"&5463262654' t5'1VqSnSB@P9/&0H#^!k‚X:84M*5We2Öf,<=Cpa~]zTheR;n%0G=~?Nl„ þrH8oIPo4EMÜ 2!33546"!54& \uýqT¥ps@P#RÂycæ¹þiâWg3YFιSaMÿñäÁ*2#"/32654&+532654&#"&54623K"KOgL%-1;G4+*4==2M](Á .% @K;P 7)"'2,)"$/yfO` rL{’MÿôáÀ.#"'#"'&54>732>5332654.'a&,nQV98PJ9; <*#*0B9(,S2*9M0"À 6R0g‚MM@Dc4F?o54.#"#4.#"632#"&5463262654&#"eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4þ´$%&'Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþn.#%1.H1MÿõóÂC%2#"/32654.5463232654.#"&54>32#"&#"326+8PWDM /  "7 /^AIf }BLo9#3( +'Mÿ "2!546!54&#4&#"6!7>.þNk³ % 9 "ÿBUFI &e« $8dA¶ž‡¢,/6  jm36 4Ý…{OÿöÀ!/@%2654'7#"'#"&54632632'>54&#"%327.54&#"!WmL%XŠn8*7€œVEK,@T*?Œ@!-7-.>DþÏ "2R31D1#&1"x]nBN{n“ •sSoVV*=4M4:)@UTÄŒt]pWGƒ[x]o@J”g‹þp>H=UTc:8LÿöÀ2'654&#".546/]t"4-bXADY0#*.À~f3V6)2vK\]M(82 5P/iƒMÈÁ2!!3!546"!54&^uþ²ÔSý…sv@U(PÁ‡j/—þGÐl…0UC6%N[JÿM.Á=G"3!!"&46;2>54춮&#"632#"&54632#'2654&"·!:wþ‰1<>/± . =$)7QBRl$:/@B78LtAQ7II$4+Ñ"$4 !)I6V@#5/$*4L98G98J\Cg} ?+=+B$3 1#$/-H2MÿøÃ&12#"'73254'"&5473&546>54&#"o$9 PK ?4c%F>]xK%#G9+O"==/%#*Á$, 7\+3F6<mMT6#+=@W?PMDþâL-)75+KLÿöÌÁ233!5654&#".546)\{SÌSþvkZBFT+ )7zÁyÊ\—þGNcL_bJ'51!AD/d†Mÿ÷Ã-72#"&547&#"#"&54>7326=463254&'iPA8Px(*2I[HRb >+'5!/' $:i[?MlÔtVnWG„`"_HIOe~_7HC:@,2J!BJCZiþã:8{(lWKÿö™À.4>%>73!5654&#"&5463235".54>3273"54“S‡ýpH8.1A4D`MJc%À/9( 6&B2·e5·þ¿' ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# _%O –g*<. w>LÿöÔÃ8#"&=4&#"#4&#"&5463263232654.'H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7KÿöÒ¿22'654&#"!5>54&#"&546323&546õa|"6,aZHF\L8þ@(!7,0=5D\KIa&æM„¿~h5V4)2qKa\LH^ E-6=.G!2[FVSE7.Ejl‚Mÿô‘ 2#".5332654&#"#546âO`^N*@ 2'4B;0'4 R†cbƒ'9/'=jNIa10  EbÿÙÿY2#4&#"#>q=QT1'&2"VYI=þ-¾,70'AN*Y!2#4&#"#"&5462654&#”BTS4' #,$%1Q*"YI=þ-¾3B' $-2'4C®#&9,ÿ  À"7#"&547654'72654.#"« #>20A]6r’R) " '' 4"2EK4gvN’$D ­Zþ¢. !",#",(ÿü¥#"&547654'7'&#"32'3265#"ÀZ>Y2k‰6[5(- $d%%%çE2`rE‰#@! XŠj/U+- !+)"Jÿ }´$.>54.'&5473#"&54632264&";']Q=8aG5V@5(5(?)'@(#Ô ?3&/[Ú!&4cYf_2AY5>8E223 -B.-"8LÿõÂ(2'654&#"632#"&546264&"9a‚y1W^J)A% ,=2C?4AN… &'@()„n“HAxYp"/>*HQ@9GmTy“þm-H1.H0LÿöÞÁ#,62"&547&#"327&54632#"&5462654'>54&#"4Hb3R6* DQRC+:)&3aGj€~¼ =**2ÁD6'0.%/%m¨q-(1-&6Bec‚°742ê*1-Lÿõ8Â(HQ2'654&#"632#"&546264&"2'654&#"632#"&546264&"Ua‚y1W^J)A% ,=2C?4AN… &'@()þva‚y1W^J)A% ,=2C?4AN… &'@()„n“HAxYp"/>*HQ@:FmTy“þm-H1.H0“„n“HAxYp"/>*HQ@9GmTy“þm-H1.H0PÿËh>(BFkw2#!".54632>=4&#!"34632"=332654#"##53%2'654&#"632#"&5462654&#"Õ>U$5+ý+5$V=È +$W;ýb=U$5*ñ2AŒ…z/$I'#%VVþ®/A4%t.UZB%=" *8/ ;1=G{ #$'0>U=þ±*? ?*O=Uýº6!÷@SU>÷*? 4DC³½xHE‹(:P)°'F,gU?^AZ&1!:(# /9RD\þ½.(#$!PÿË>)EIpx‚2#!".54632>54&#!"34632"=33254#"##532#".54>32#"&547&#"327&54674'324.#"6}+4$$5*ýf+5$V=v+5$U>ý·=U$5*‹:9Œ…zSJ %WWÀ&RC2H& 6: BSE3ii .L."(".> >*þ±*? ?*O=Uý® ?*>UU>þý*? @L;´½{ Œ‹ O($+5":="4J&4+H $,š -&l1 )/‚+' Lÿô¥Â64632632#"&=332654&#"#54&#"#&=6M_CQ-6LH681cCSm!+)7O`H;0T2 ) QjJKADc(JH,C/ iVMe!'‹h;4 @, ÿѶèX2654'3#"&5473k$0*Q=;NM.î-$  =ID8 )Lÿô¥Â64632632#"&=332654&#"#54&#"#&=6M_CQ-6LH681cCSm!+)7O`H;0T2 ) QjJKADc(JH,C/ iVMe!'‹h;4 @, Oþò¢À-8DRs73265#"&54632#".547&54632#"%2654&#"%3254&#"2654&#"72'654&#"#54#"&546326xq”|†0<2>A1AO‚‚6\`65b]7ƒƒP@1A=3>{%3!þ¶$B"" èa~d&II,‚¡$0?) '%+"2 80('÷mZWoQR@;NtX¡0j0E##E0k5ŸWuM D,<"!MÿnðÁ<IS"&547632632#72654.'#"&5467&#"#4&#"%2>54'%2654'æAXEDh[C@fGz@Vo[@U ,&PA/9JE$c*NS1&. 194Í  9?-þ1(7gU4 nPjPQPRVNuQ_w;aN0BYwH5=e l-!þÂ5H&o;(7-<-$ GI*(&F4lQIm6KI¤j7>3!#%"32654'3#"&IS>È2þ(24&'2!> X@73546"!54&Ê[vþ¯¯-8& Mtr@T(UÁuWö (7)(øF]8M;Û²MdMÿö£À23!5654.#".5464WuSöþŸk>*IVm>J}À~_e\"Nc65!YJuD(t@kƒNÿö¦À%23#5654&#"#4&#"&546326¶@TH¤æJ:*'!@%/D[gU@NÀƒaiQ"WlLi2þÂ;4eKnUj|_…HHOÿù¢#2#"&5".5463532654&#|¥kRDYBx'T AYi9T0;iV1Âl[~J7gJ:0SzEfˆÊý±S;Qcþý#NÿA»NG2#654.#"3254퀆&#".54632#"&546ElA* C5hGv‘‰s–Ijˆ8)Ib#)‰d1<);U 1W9…Ÿ®N8Wsk5 1)?s;qpD¿œ†³ž;&1g(lPRO*I;b† 4#\s5;+ÑŸ²ëPÿC½Å52#"/32>54#"#4#"#4#"&543263261)9 =FiP4.I$?;#[?:C&TH"Y„5&EC#Å0[kGqbr9E†[Å.þ¼]'þ¼"W¯~KY“éD@7;MÿC²Ã$12#"/32654'&#"632#"&5462>54&#"~‚²“pP6 /QTnJJeYk4GB[);0Nj°( ;"@:ë€ÆD—tfFGjLCQ<*? vWo–þg(&.(*!+<PÿC¤Á%233#"/326=!654&#"&5461]tT¢Tp*Y ==lQþôjU?E[k‚Á€]~F•þChM";1H7–F``FpHEše‡Pÿó©h*32#"&=#"#4.#"&54632>3534&+32ú2H% 5$-7"+G"! f_ h\IA':4k.<)BÁ1QQ*#CC(aGîþ¨4' ·zAP–d„F)§þSfhþûOÁ3r 64>32#"&Á 1'<h¼ 2#"&546"2654&ãHd10FGe`L %.EfJE¼aGF24cHEd- 4"3JI51F2Ò #/7#"/4632'"32654&'"&54632'"32654&ÒD* 7(,=i&- ).-?4),@5<$.!)4•5.H(;9 (")++d6.);:,(:¯*" +, #(ÿ {l9HX2>7#"/27#"'5#"&5463224/"#"&543327&#%4&5747326Nl G7(7'$@&8[„­¨† :Y(qP  "D[¦.' 0lU90=+ G'9 þÛ*"(Õ Öƒctƒ&HOþŠQu† kUI&,<$"$ÿ»cs2#".#"37>54&'.'5;23267>54&'&/"32?"&54632#"'&54676323#".546232654&#"@+%   &= K|AXc 4e!.eH/R2LB&h-$5NC9?K†D'*°QFiG=XE1„e!+ &7/*A 0P &56.!9#  !9&'   )T)Hr  3% e5  J98CI@Gb1°W{!,=hA"€ 1*$6 ,% F4B 6'-6.ÿþj E^ju4632#"&74&#"2672322#'"'.54>76?>74&'#"2>767'4632#"&74&#"26[+ #/. 0 *õaAQ  d"%D0až:IM,B!$8XQr(FQ ‘qbx VG3V#!NL'(2$'#/. 0 *÷ ..# .0‹3d 1\ vX:l!@C5=`;8#5-O (ýýTb6!+ ;g/&/>ñ1.# .0þ¸ ZC%#"'.547>7632326374&/"#"&/4;2#' 32654'71HyJFN‚ oH8Ly ( - -&*-l -8C/Ôþô™yâPT aJ`P8/Õ¢B PD*’  Ki#9 F%‹´Q}*$ ),7;?ð#3,7? ‡°NÈÌxp< A3 !¬T@( €x8I$"®$6 &Q;# ÿÿ: o–4&#"3274654&#";2>52>7>32#"'#"&546?232654&'#"&4632#"&4>75.'4&'.#"#"'6;2&×$$$ë+ (*?2+@ 4$''5*  *A(|"?(bp;@#"#'Z?JO%" 2+>=+?igHPrè?6²?$s2uy&†<3u(( Ý("(: .F:(/D6# !  4MA<"n&µ~`s$ :($2<6 %21N3U<;IIwI6.;<A&cK4^GX,PF#‘Yc32654&#";>2+"/3264'&#"2#"/#"'&#"#"'>7674&#"#"&5'4632>yz4=µU‡DE23®—Ó##,' \HNMo-!4%JY@AH5V. I"H*  6q] % "=#_K9=2.MÿuV;?k’w, Iˆ¤x<\4* uàTS3$G9GuQr%I‡+y˜G"^/  32?>732#"''>54'&#">%4>75.'4&'.#"#"'6;2&g%4(+ )%N$A5'MU 1X7j…#'+L‚ 8H"Y@K+50 1~Vi5,?6²?$s2uy&†<3u(( f.*3N;*'=‰c9N?-pf/K$ ¥?ƒs+@A'7T'UQC/$+I6.;<A&cK4^GX,PF?¤\[%+'.'&54632&#";2>5&'&'4>32#"/7;7267654&'&#"672e†k -0," ~A@Rh…8RE 45(I".AN9q™]*8M!  #. ::V!4Jb,,¹Lf -6Dƒ§ p\7T* 'K  *5U2" ¤v4?…$  =l^x" XH !@: Nu"2654&4&#"2>7>'#"32?6732732#"'#"&5467#"&5464>75.'4&'.#"#"'6;2&_*ÍPO ![ ‘-45A73#"&'&54>7+"&5434&#""&54672"'6;2&'4&'.#"#Cd@]PcF&,T/. .JrB—½*" '(J(9119(„$s2uy&†<:H6%)?6²?¦:&-E"RQ! #`767654632632#"&546?632;4.'"+"&54632+"'#"n@0!4 2+ ' €  þj#:acFi#G+@ F+=|$k€0G<6[:@²èN<"6 4  bX2AT5/ GgØ"& #* " "%œ(9"y::F7*(9 85."'>?>2.IHsEª~=P #:(N6'B K" n2654&#2654&'&+46?6?632632#"&54732#"&546?632;&'"+"&54632+"'#"n5!£°¯@A<{=0 :D, ))E6B .( *%! A;T#30Ý£²èN<"6 4 ObX2X. 5/ Gg#:acæ!, þ¬@T,I>\~! !1*0 -""D;vœª~=P K :(H4B:(9"ÿ0Âa«726532654.#"632#"&54632>32672&#"#"72?#".547>37632.'&#"#"&5&#"2#"&5#"'&#'>74&#""&547>772>?ß-S"A1HQf)!@w( H 1  _D*6 DzbSVO`_† *G A^0NG`&# M’D/=9.7^. 2–O  3)Fj+;4!YE $:< b+(  6k=m6! ,+<'(F"7>4&#"4632632&"72?#".547>32632.'&#"#"'&"#"'&547632326"&547>772>?IG,/  ; 57ƒmQ;4^BS9/$(o-NG`&# Mê& A>W<)1 ß1z± $ D/   -1&b+(  6k=o7" ,+<* sRKdZ\{p[e,.!))-? Lþ~="7%* ,(+:!@"!2673#".=74>;&"'6;2'654'4'.#"#1H# ¯/:2wœHšr *F)E /-$s2uy&†<;q&% * :.¼aË/.”y]4Ÿ2w6i?B &0)LA&gHJ@/$+ 4YJ]*KV!"&'#"&/467"32>532>=&'#".547./3267&'(+='6WUq‡w?g1R,0:(6@_ 4H'*= " +R]F  2J¡H6<I€ 0DM„a*iˆCX)T1"F/(-Lr!$X?##3(2: *Yc–QP$/6#2E[>:=d%;72732#"&5#"'&5467#5!4&#"#"&54632'"26%4>75.'4&'.#"#"'6;2&}.=š) 86$D:aa:S9:",HF3+L B/EgÕ( XA:6F?6²?$s2uy&†<3u(( ã /¥qo!!B10CHI_E@-AI'%EQ%." 17>+I6.;<A&cK4^GX,PF*^i"#"&'4672"326?652>=&'#".547./#".'#"&546?#"543!4.73267&'MA#ÿÿô2my¡­¸4&#"632#"&57#"./.'#"&'>?&54654632%672632#"&5732654&=4./"2654&#"%2327>54.'.54632#'.'4&#"3267&#"þ:D '/ $-1F=,-D6?BZ%?;(3  [‚aD83Cþá)]p<" 'e-'$D;(*=058%"' &%­&$6&23ý"KOs4L"#! þ£ O<'5&%,A17#8&#$"?7WPjY&> ;'!B1+;$?G?  ,7#4õ7"0&(!1s % F8&5 " ¦/?$'!2 0'+: #$ %!&$÷JD !R[m4&#"#"&54>32>322+"/3267654&#"2#"&/&''>?64.#"2326& $&+4(* #HA%,9RB .z*!e|ä& 1")B& & #.+>lCWi*;?0.ˆ¤6 *B+:K=+(*2* >›3I Ê.E!+£1EU%ÿüð'/;".547'&'#"&547>32&#"32654&''327.'%9 0 V `«»¡Ä.,E9SZ@ag-‹´Q}*$ ),7;?ð#3,7? ‡°NÈÌxo42"p`!7 €x8I$"®$6 &Q;#ÿ0M_;V&##"/72?#".5476;632.'&#"#"&56?2"&547>772>?Je  eLNG`&# Mš&:&)b+(  6k=n8G ,+<' <&ýl="7%* ,( :4[3".54632632#"326732732#"./%4>75.'4&'.#"#"'6;2&ç0K)e} -^cV@BW"">'š) (/e!/  5¼?6²?$s2uy&†<3u(( ):I4–‘i`B^/0/1¥ ‡,Y$&  ôI6.;<A&cK4^GX,PF‚WQl2"&'>5'&#"#"/46;>72"'7;>74&#"#";267>54&'1D6' •KGRq329." ++!-rF  *zZ0eaF"' N - 7©‰/ I C6)#  (!CD(32B>¼ .R4"&;ODV X…99%2#/-:q%91 2X9J*Ka( 0 Ib‚¢%)-*'  5*<@ÿFl#>[4632&'";267#&'."#".'>332654&".547>73272747¼GU;4C;I=*ˆ] S V9;ƒŸ} 3S@Š_& A>I)7,C1, $U2'C$“µ"G.   )D*]s %,hnD sBILGüî))0% 0 3$4 - :iJU!"&546?632;4.'"+"&54632+"'#"2654&'&+'46;24&#"?27º²èN<"6 4  bX2AT5/ Gg#:acF°¯@A<{gI '/c݃L&0Zd`, ª~=P #:(N6'B:(9"@T,I 2i 4-#~vœû/D5%ÿüð'EQ".547./#"&54>724/"#"&/4632&#""232654&''327.'%9 0 V `«»—Î0eH% > PD*’  Ki#9 F%‹´Q}*$ ),7;?ð#3,7? ‡°NÈÌ”t#>@*A3 !¬T@( €x8I$"®$6 &Q;# : Mt7"32654&'>32+'37>732#"&'.54?32654&#"4632#"&'&%4>75.'4&'.#"#"'6;2&Ç"*%+Â"2B;c”?: d#<] Gb=M$,_ZNw 7'+?<*%.6£?6²?$s2uy&†<3u(( ¤'4)&).@d;&v]:B$# ‚[Th$X* )#-!@#B&?9*);#EsI6.;<A&cK4^GX,PFs^I4632#"'72654&/"#".547#"547!4&#"&54632"32>54’_‚ou&F"#D[`W!Dd%jN|7#"&'4632#"&54>?4&#"326?67#".'&'4>3232654'"'6;2'54'4&'.#"#è&! *! "15%5 74={E0(BJ$K ®Zs# 3?*wœ;”w %,! ;0]BUhGü$s2uy&†5&) $]B, :ZI+D! ˜*w?i63I6Z5%3"?02NA>)-A&(¦]J* =;<: ‚©4&#"32623>7>32#".54>74##"#"&54>3232654&'"&54632#"&54654&#"32654&546?2274>75.'4&'.#"#"'6;2&æ#")09-# ob55!81 ?>dn&W=0 I68U 4L3L)1OdEF[HD02.'"'@%1!!&=ó?6²?$s2uy&†<3u(( ø(0#&þ -8  ”¥<-!  ,<³„L|R)/ E1* $ &5/&*9O3=Ll#& •q8A  !(PI6.;<A&cK4^GX,PF,=aJV46327&#";726?33>?4.+4&54632#"&''"'&4&#"3226,u]&-#-68vhJ! E  e@P@%J/†~A=P&$]S8S"8¶Ò7Dm"‚>  j"$kF6h2 ;#:5>O )0"7U72## D>19#7,X0)3±0aÿýýi'B2#'&/&'4>76?>?2324&'#"3267>5Æ &7a;‰² a8FHiH.?-O (3d 1åVf,0l' +D0ÿbùTY2#"&'&547'"'672#'254.#"327>54&'7#'.'.5>7>ˆ´{¸04Læx$0&Ž%L[BHa%  U„ƒ?  $ 5 #1R,&!Oo6ID0MtTRy} &   $[0? JC7f*H0,p= DPF'4$7 4:JuU4'@4<&*þ:1Q4672#"3 73#".=>76374&#""&"'6;2&546/4&'.#"#a9119(Gç2W_832.#".54>#5 *,%/  !2[;Wb ,$ /S5W'%b_J1*B@/5< >r^–&+/7rG‡”08 &($ -48(<56*  § (,=1#8@1 )7. V…m‰   54&#"3263232%""&547>32#"2;>54'#"&546;7&+"'4632#".54634t<Ú#1**ù!iG/d )ÜF@H.×° !T+iO?O.Çào¢bŒj`""#¸!&D#[9 ME š!2 9(L,$$!1!!9PbD@ \)|“5{^ZmW/BhQb32654&+"'46322#"&/#"&5467#&547!4#""&547>32#";265%654&#"3263232º"F0QaN=T+iOAR @{bEOTAcz&1I =e]93GhÂ,V%Q8CI3G/32&+"#"&54632&+32654&&546?2"/632>74.#"6$"#2‘[oŠ~C.Q  X/c(  . ¼`M ;y%)¢Nl‡^y67C! *# +Z8*¼,&4&He„i @0P o$' !8c tDQ5&+ _Š ±y$…h3  <&?zVÿ0fVh%#"'&546?632/"32>54'4#'".'54'32654.76"#"&'76324 !8Db%+kjšu’ŒW`cr !0& -Ke 2\; r0LbP7”z   0/  é$ 95P({R94632>32+'#"'526754&##4&#"327"&(j…=`D`w%g)6+Vn b74&'eO,:0">YJ?(,†¬$¯{6B±ˆN+NO ]YUu ,\=v +L.<\,¦ýéþ—!*".'54654&#"'&5463232632'3254#"ýÐ #(5&[ !)/ñ þòB€ W7 (+%.687P]+"'4632#".'53267654'4&i# L6 +6-  ,L#4 1*#0 =33M@)>¥*6!)% 52¯<'?Sÿ~š&543767!37#.54?67#„ 29T \(ci)W&/{ ~èX;J* s]HE‘49ÿÊ–0#"&'.5467#57+*.'4?732?6Ê| B?)9332þ}$!& 8g5&6#![2RQ)' 6):#76W8 &.#$…XE#/.$.B % "+N' üíþúÿž(2;7!"&463/";26þbg€"ý½/?J7 (9M&€§7¾HýÒQhA % -&1/=üãÿÿ™#"#"&54632&#"326327.þž(Ú?]_2( "H@.9­; c' ¬Ã5G;$: #)3I ¥Býò , ÿþoZ#474>32674&#"'>32'&#".763267& &7-/HI:#B W/9O%!),9*/¸!0:'7’5P':G_$$.7[W/SˆD%' NÂ+#*#"Rs!!in5A#.54632#"&'&547632'&#"32654&'&#'"32654&Õ"/ J,B3)qSR’fW}# $#3;)$2<[(6@7=N*$M>f‰gP3A…^`  RTjUkWG>?X?1 /5*/E'!19B‚M†bb<   #%5>aE O*a€ZV;e<)F  U,305z7gUþ…mTF@  þ³**0  :LFË;-7%#!5354>54&#""&546;2326534&"26Ë&þä9'%"#&4&F1BHGZþã$$R"0é&<% %)0 "00"5GL/ 02 ë(åx((((F:8B4>3263232653#!5354>54&#"#4&#""74&"26F& ($.@KZ&þâ7!'!#&4B$$D4 *)F3 02 ë(åþ"0é.H#/#  !)0 "0R((((Fÿ7'134.54632#4&#"4>32#"'4&"26ž {]d}ZKDHV 0"*#(P$$Hn7S0Wp}kþ±2c†W@3,33 !.ÿC((((F 73=4632632#4&#"#4&#"54>32#"'#4.%4&"26FQ<:#C;AZ$%,<  0!)#(U"ÿ$$nYp66gUþ…™?1')Y.2+03 !.ÿFl7T((((FC:@JT4>326323#.'#"&546754>54&#"#4&#""74&"2632=F& ($.>-bZZ '>'P848/!'!#&4B$$ "# D4 *)F3 02 =:ÂýÉ"4@+ rXL+,C .H#/#  !)0 "0R((((þÅ45YF¨74632#7#"74&"26ë&./:UþóüB$$ÁD260þ/tþÜAR((((Fë7",2#54&'+"&5463254.#"'>4&"26 ^€Z+*$&,%F:,+oBrU$$7hTþ…e².  30"%0G0,@ ^>Hþø((((Fl7+1;2#"=#5#"&4632>754&#"'>254'%4&"26$a€/848P'>' U&&./:c,PFvEz&FFþ©$$7gUŠ C,+LXr +@4"ï0D260¦9<zEU_ :Lþ4LY¾((((FË\+5@%#!5354>54&#""&546;26=3%4&"2654'326Ë&þä7!'!'%"#&4&F1;E&Z13dþã$$Ã&GIR"0é.H#/)0 "00"5G;*`C> €ˆ((((þ§åc!W0ë(F\7EO4>326326=3#!5354>54&#"#4&#""54'3264&"26F& ($-9'Z13d&þâ7!'!#&4H&Kþú$$D4 *)<(cC> €æ"0é.H#/#  !)0 "0þåöa)0 ë(((((FÿöÒ7:@J23#4.'#"&546754&#"632#"&=467.'>2=4&"26a€K.ZY 2"P848/PFf?*I&&./:,305zŠFFY$$7gU‡/€ýÉ;;, rXL+,C |EUB Ã0D260Î*0  :Lþ945Yr((((FþÛÓ72JT^232653+4&#"632#"&=467.'>2654'3#"&54632#"'74&"26%4&"26a€RZ&îV;f?*I  &&./:,305zX(1JRT>I.+&&$$þå$$7gUþ(åþ"0mTFB  Ã0D260Î*0  :LüÀVH e{Q2'60D0"r((((õ((((Fÿ 27@JV2#&'#"&546326534&#"#"&5463254>7.'>4&"26&#"326Qa€Z&5 E'6FA<87-V;f?_(  ?2'#&'% z_$$º43$-:$77gUý’D+&,2! 7-6ñTFB@ à3D5"0¡+  :Lþ((((«#(Fÿ 27GQ]2#'#4'#"&546326=374&#"#"&5463254>7.'>4&"26&#"326Qa€P7.( 8,951,/'-V;f?_(  ?2'#&'% z_$$**$/+7gUý’80#(2! 7#!,% eeÿTFB@ à3D5"0¡+  :Lþ((((­#(Fþƒì3-R\fp22673#"&#"632#4'"&5463254#">4632#'#&'"&54632775#"4&"264&"26&#"32ò k  ,bL>5_JZG &4&-$45‹<,aB%,*-?3)%+#%( .2*$$l$$™ .1 -!BPLþïì4"00"'/0 eMkýD251ÓBB6$$( ! JEzÙ((((þ((((‰F}<@J%632#4&#"#4>54&#"#4&#""&4>32632'4&"26CMP@%8W)(#"Z##&4&& ($-2>“$$|ª8"þ½(e ‚w~.H#/"!)0 "00D4 *)D5/\0¼((((FÕ7FPV2#.546326323#4.'#"&546754&#"#&#">7.5464&"262= '!&/&\%%V/@"C:<K.ZY 2"P848/$;+11 '%#E$$+FF‚9I@^.L{g5hl66dT‡/€ýÉ;;, rXL+,C ¨@0'BPA+NV1 /"4S((((«45YFÿö47;AK2673#"=#4&#"632#"&=467.'>254'4&"26a€.KU/848P"2 YV;f?*I  &&./:,305zóFFþ>$$7gUÄ/Cþº C,+LXr ,;;mTFB  Ã0D260Î*0  :Lþ4LY'((((Fþ7(23.54632#4&#"67.546324&"26‘|[d}ZMB8[1 + %#) (&/&O$$?k32632#4&#"#&#"7.5464&"26 (&/&\%%.)@"C;AZ$;+11 8%#E$$–1!PFc.L{g56W/66gUþ…™?1'BPA+NVc/"4S((((Fÿöÿ7(22#4&#"632#"&=467.'>4&"26a€ZV;f?*I  &&./:,305z1$$7gUþ…mTFB  Ã0D260Î*0  :Lþ((((F<<)%632#4&#"##"&4632'4&"26MP@%8W))"!U&&./:U$$|ª8"þ½(e‡t£0D260((((Få3",22673#"&#"632#!53>54&+326ë k  ,bL:8To&þî&a©8<P.1 -!BHS¿"0iMkþ$Ì71þ’(Fk7!+54632>73#"&=##"254.'4&"26F&./:],Z/848&/&;' T»" þª$$ÁD260þ¥:<Cþº C,+L-+r +@4"£þ«4Y5§((((F!7"463232653#!53#"74&"26F&./:œZ&þ–7B$$ÁD260þG(åþ"0‹R((((F!""463232653#!53#"74&"26F&./:œZ&þ–7B$$ÁD260þG(Ðý0"0‹R((((F72#"'3#'#464&"26¯.&&‹’ZZ’ƒ]:k$$73!"0þ–ùöýÉõõÑ06T((((F#2#"'3#'#464&"26¯.&&‹’ZZ’ƒ]:k$$73!"0þ—ùáüÝõõÑ06T((((FY746323# ##"74&"26F&./:~~Zest_B$$ÁD260þåþåýɰþP£R((((FY#46323# ##"74&"26F&./:~~Zest_B$$ÁD260þåþÑüݰþP£R((((Fÿõ27,62#4&#"#"&5463254>7.'>4&"26Qa€ZV;f?_(  :/.&&'% z_$$7gUþ…mTFB@ ò063!"0¡+  :Lþ((((F 8 *446323#.'#"&54675#"74&"2632=F&./:-aZY '>'P848/B$$E"# ÂD260ß<:ÁýÉ"4@+ rXL+,C ³R((((þž45YFÿöÒ9,62653"&=4675.=4632#"'74&"26!(! "!?Z>Zr¢r?%:0;0/&&Q$$‡$  8;0*;;*Äþ<4II43=?  :"(;>3D0@((((Fÿõå3)322673#"&#"632#"&5463254#">4&"26ë k  ,bK:8hB:/.&&Œ=*a$$.1 -!B LN¶063!"0•fMkþ((((Fÿÿ7(22#4&#"632#"&=467.'>4&"26a€ZV;f?*I  &&./:,305z1$$7gUý“_TFB  Ã0D260Î*0  :Lþ((((Fÿ÷ë7*42#5.'#"632#"&=463254.#"'>4&"26 ^€Z D24!&&./:PHb1,+oBr8$$7hTþ…ê1HC?A0D260ŠIXS8,@ ^>Hþ((((Fÿ 27,62#4&#"#"&5463254>7.'>4&"26Qa€ZV;f?_(  :/.&&'% z_$$7gUý’`TFB@ ò063!"0¡+  :Lþ((((Fÿõé7&4.#"'>32#"&=46324&"26‘-+oBr:\€:/.&'$$m,A^>HbWþá063!!.C((((FV!3=34.54632673#4'#"'267&#"4>4&"26ž {]Y?[)Z!*()1 ]HV 0W$$Hn7S0Wp6#2N84Eþ©25)!.ÿ–!_W@3,3S((((Fw72<F4632326=#.54632#"'3273673#!53#"4&"26'4&"26F&./:œ ?H.+&&)Z6T&þ–74$$ò$$ÁD260þG(…Q2'40D0!Cÿ3KuC«"0‹.((((”((((Fÿ÷ U08B$#"&=463267.#"'>32673#5.'#"6327=4'4&"26#&./:PH", E'oBr:Z>[&Z D24!”!m$$mD260ŠIX ! *^>H/2I6&Oþ±ê1HC?A˜ "! þí((((F=>%/9%>7&5462#4&#"##"&463274&"26%4&"26(3&.@. X!,F2[&&./:ñ$$þº$$_‡‚. &%55%. )þ¯,)­À¤0D260((((((((F¿ &0:46326=3# ##"&4632#"&57";54&4&"26œ'.*9&@7-est_&&./:~~+6?# þÃ$$·"2.)+=0SýްþP£0D260þåþ 1%>#4#C%þñ((((Fÿöë7&02"&=4632#"'26=4.#"'>4&"26 ^€r¢r:/.&&?Z>,+oBr7$$7hTþø4II4ª063!"0|*;;*ú,@ ^>Hþø((((Fÿöëd,6@4632653"&=4632#"'26=4'#"7"327&4&"26FzLDB;22r¢r:/.&&?Z>W†V´L3"D7).$$ÆY&'+A-2Iÿþø4II4•063!"0g*;;*ú;&*g "#ñ((((F´<(2".=4632#"'3274>32#4&#"'4&"26½#3 .+&&= #-W  -$$],# (60D0M ##5%þŒ:'#+ ˆ((((Fÿÿž6+5?#"&54632#"'3267#"&54632#"'32674&"264&"26žxX>I.+&&,0FJxX>I.+&&,0F$$$$6_Q2'60D0!]fþ©_Q2'60D0!]f((((þ½((((ÿg|¿\#"&54632#"'32674&"26¿xX>I.+&&,0F$$\_Q2'60D0!]fR((((By7 !#4&#"'632yZ$,=<Xd/L˜33X †GVÿ³y"&462#4&#"'6324&"2M-@--@YZ$,=<Xd/Lþ´$$ïD//D/üâ˜33X †GV &&þI[ÿ¨4"#"54632&.#"32632þ²0_D2J%sXN>(4vª%S!-?* O 7S%&þ[[ÿºo"#"5463253&.#"32632þÄ0_D6,?sXN>(4vª%SPŽ/IO 7S%&þI[ÿ¨n+"#"5463254632&64&"2.#"32632þ²0_D"!"$/sI N>(4vª%S""'3b O~7S%&þ[[ÿºo "#"54675353&.#"32632þÆ1\C>?w\N>(4vª$S;B PŽ/IO 7S%&þÿþ²ÿ§ÿ¼ 4632#5#"74&"26þÿ%,*-@B$$ºD251¤vR((((þþ«ÿ§ÿ¼$463226=3+"&=#"74&"26þ%,*-@!N!B$$ºD251rѸ 22 +R((((ÿVÿLÿÅÿ» "&5462;%&$ .!~!"ÿuQ"*29@%+#5!5>54&'5!53'4'>"#"4'&'6&#Q1^? Bÿ>"">BÜ+§ˆv$'¸ e‹Í*°#6)‹‹"7¼7 ƒ„™ 1#¯oý 0Xæ¹dþç øFÿö7 $#"&536324&"26&./:U$$lD260ÛþSR((((Fÿö7 #-$#"&53632#"&536324&"26'4&"26&./:U×&./:U $$ý$$lD260ÛþS0D260ÛþSR((((((((ÿ ÿöP%*42632#"&54#"463232673#"&#"64&"26>hB&&./:Œ=*s@%(   ,^Z:2$$LNý‡0D260´fJn  -!B ü­((((ÿ·ÿöP(2<$#"&54&#"&546;2#"&546326324&"264&"26P&./:=%$2%&$!+JY>?[Ñ$$ß$$lD260-BA.#!20"#/Y5>YY>ý ¦((((ý((((ÿ‹ÿöP!+>32632#"&54&#"&54324&"26D,%9&&./:`›$$j[R9$üÐ0D260=(!?[:ü:((((ÿŽÿÅ7 #4&#"'632ÅZ$,=<Xd/Lñ‰33X †GVVÿ Ç<2<4632>32#7>54&#"#.#"632#".4&"26V>/%' 22 3W3 ('0$&&( y$$´9?OO?9Þ )0B#&0D0DC5((((þ]|ÿÏÒ5?4>3232657632327.54632#".#".%4&"26þ] C0=,.6PSE 2 %$% <0   :@$$**'41&'!-? ,!$/(%1CN$((((ÿZ›ÿ¤Ž#"&'\Ž’a]–þ»šÿâ]%232>73#"'567#"&44&"26ÿ*%&;7aABS]$6* C/%B:"#'6  þ#šÿ¶]0:4>3263232>73#"'5654&#"#4&#""&74&"26þ#%%   %';hc8 *Tá#0"!** C/Nu >!&''  ÿ ›ÿ§: ##5#53533Y7-::-7Ö;;*::þóšÿïz 4632326?"#"&74&"26þó5>  !&-9&!"'oß'< )& -'+ ÿ |ÿ§"&4624&"2Y-@--@ $$ïD//D/d&&þº}ÿ§µ#4>32&#"&"327#"&4632&÷ %9& ($ 1"11"2{   ? &-!07N74G}6$4&"26"&4624&"2"&462ÑAZAAZí¦ê¦¦ê‰”Ò””Ò%SvSSvîZAAZAãꦦê¦þ|Ò””Ò”8vSSvS<ÿöüž"&4624&"26üƒºƒƒº3SzSSzS"°||°|ÖNkkNMll<ÿôüž,62#"&54632'654.#"3267#"&=464&"26$-V.Ccƒ]\„M<G#+ 7Y1%&  &*>$$9*6tˆLX|ƒX9†5z/L* pIOj/(0!!2S((((ÿó*…=G%"&54632>32#".=4'7326=4&#"#.#"63274&"26 '6F6/ .=eIY?;D.VVaI' + &" $$z^154&#"#.#"327.546274&"26÷*6-gD< 'O.[IE'$/*  -1*# &4&R:$$ -K.Y{UTi[?uFIR$4  p;1J% -"00"8?w((((=ÿÿv‡3=74>=73263&5432#"'&#"#"&%4&"26=<`tt`<9ci{&$bOE B\&& HL'f#‡(Rd©$$£?[3(%-P7GQ74>7&5462>=7#3263&5432#"'&#"#"&4&"64&"26<%C/R(2F2DX;UFgMBbOE B\&& HL'f#‡(Sei 1B$$¡$<&' .#22#XA :W+ -'E(2H&Rh0D0#$ %$\w$î((((ÿåÿöÇ„-774632#"'3264&#"'654&'7632#".74&"26<2!&&2C6DD6!O,F/LX:=TvvT-H) }$$œ*32 "0Gjžj#%.Dz ‰M(|°|(1$((((<ÿñÃŽNX'>54&#"#.#"327.5462#".54632632>54'.'4&"26˜;`<. :}U'$/*  -1*# &4&R/*6-gD< 'O.[&$BC ec.$$Ž*3D:C%OŠauFIR$4  p;1J% -"00"8? -K.Y{UTi[+l$†U33umýü((((<ÿÿgƒ?I27#"&#"&5432;27#"&4632#".#".5>324&"26Úr 3"&‘'–'<@6C&&$5) ([H$2H"mO!£X$$V";/\V5%€>9'.'0D086#4 .-%/@7Uh,Ã((((<ÿû=ƒ=G2657#"&#"#.5.#"&5462#".546326324&"26à ! :"y4P&!-1G&4&9,*D' gD< 56’$$c€#6$CB(3]½#)4G16:)p;M]%"00"./"132#'54&#"#".=4632#"'74&"26cVþ¸%#1V  7#3 .+&& $$7mþΘ7±%56%-,þõ—:'#+ ,# (60D0_(((($ÿô±>ÿ(/7?GPW`gp67&546267&546267&546267&546327&54267&5476;#""&547'"547.'"&547&'"&547&'"&547.'"&547.'"&547&'#".54>32#"&54632#"'32>54.#"32>7&5463246'4#"64'32'4#"6654/'"6544'32'4#"6654'54#"64'24+"64'24'32Y& -% &   .  óø    (   "&&#2& "&¡m5D7&,CD":;"/)-?0 "*)''26?=(1MH!:bD.,&$7  S š \ µ v ã  Ž üµ þÑ! ¹ €  È,MF?,01$; $!L'.  +( 1? $  "("  0(  $ #" $""  ,;<"+  11 : ,4  -6)j34LB¡ *?mEJu@!(T<9T(09*= 8!.&J23I%=lDNt:9`jZ6,fQA1 3 *"7Ny©c=Sz(J/ThM1a?;G3d32632#"&'&/.#"54&#"26„BIwGrP>!"G28;1AD`E_*[((P]‰=$`%MH1 #B/3#1g'*11255DB.. 33! i8D(!H3]”… <…% N Û¬*%"&54>332654&#"#"&54632Xl 4$ 9*(<3#$4?"_QZko ]N"*‘"&&"á"'%$/)/BO[gþâUmM Ô­?%"&54>3326=4&+5326=4&#"#"&54632Vk:) 9(';11$5"#2(]LÃ`! \ aI20  “ '%"òt *%#1 '!BP–j$*e/<M Ï®,92#"&=4>=4&#"3"5463254&#"32Ÿ 6'7>*VkNs2GF2),+©aHI`0;&A9'a)'(=(a>ýûÁ#%#%Á$%M ¿­"0%#654&'"#"&546326324&#"326¿FG12$:lUSmgZFLB8!3&þ¯>"&;=#':ÍXj,4Þ!*3)þ®Pnh\*Nf11"C-þlÞ1*!þ#.)M έ(732#".54>32+7>54&#"­ )9)R84M(’8-%7˜ET)387"#9<þÙÅ+à *&"MЫ-2#".54>3326=4&+5;2=4¸a#>mR6R):*8$"B00 &9%«’b 9&…@Z)<320(3ï1x!(N M§R%.'&#"#572.54326326327>=4&#"#54&#"#54&#"M@1P'f%@U| =F3.¨9/<3<00;©F2 ( ,H,)S''+>&JóD+ #9'& +-H,//00=< x3#%``/%#``1/Z3% BD!MM έ#1%#"&463254.#"#"&546354&#"326Î%T9MrqP6* *%8'wGPp`02&87+&8Ë7F0qžrÁ "6) ((9^oPþ–G6*‘'99L ί%3#"&'"632#".5432324&#"3265Î ,+a 0/*:= %S=%<+ ÀC2E5,)6<%(6¯/ò "O<(>C%&M4R‘þ‘"&#%Á'!1)M ¿­-%#654&##54&#"6#.54632632¿N?17!$0I;%&;&4@pQX-4P5:(ÍTm&8á-$$ÂÂ1*!þM3 wG2Bn$$)H+M έ;%#".54632326=4&+532=4.'&5467Î)P<:A-%;%*8110 =$'W*<+`Ë*@8!@()() Á+$< (  7 $M Ϋ*2673#"54633265+5326=*N0(='Á;=8$50'':S? J6+þ)!«&O/x )4ß G5- L Á¬=%#6=4&#"#54&"#"&'&546?67>32632ÁBP25!$1I:L:('$1 Ixù-. *J4‘X9 Q:V)+W4H"ÉZd0.Á-#%‘‘!',"‹>#%T†w.b'!?100$/&&&?< Я$#".55763232654.543ƒÁ,8)1U";(!RbV-5"'J1À 5ýï!%/')!6fD 0­BO%#"&54672>=4./326=4632#"&547.54632'54&#"3260$5V4p‹c,%]4@9+&0 -"+AO)&=,j#sXÁ0û>B2!Œ^lˆ%lÁ1B8$Ç0*/  6*P './1d#,kÉ1/1#M 0®92#"&546732654&#"#54&#"#"&5432#"'26326›CRÁSn9@ ;%':.Ha%g&®PBþ¯ÁVS(Nz)%#â%$I``) I+ LG @­;I#"&546326=4&+532=4&#"#"54>3263254&#"326@bb'T;Ul@:9N;010$  $O—7B%<$$BLGþÜ"  tV_ ;?%[K%S‘"&&"ñ0H%, &Ž7F$$=œ!L ̰1%#"&546332654&#"2#"&54632557673Ì'Q8Rm=:%'.33% 8"g@3.010’*.9>?TR%&6ª M …®C%.'ȳ.=4632>32#6=4&"#54&#"…BJvFrP>, cAI/5OTFL1+:,U+  %6%27T.# 'A/1!:!h9E1Bc3I-…""ll# T)0#dMÏ­+%#".4>3265#"&54>3326=3Ͻ7S):* 9N9/GO\ 3% 4'-8aÍ¿);3&20  "&&"7X1.208ÁM ÿ®-;%#"&5463254&#"#54#""&463263254&#"326ÿ)O7WjlU4-,H*+NN=",#"BR`>#&;8- =Å$>8 ZfWjò"II085X4?FþBÁ/+ ¿!'&M ϯ!-%#>=4&#"#46326324&#"2>ÏeC 1:VaSV>SÙ"S,A(‘( 3..œ726=4&+532654.5472t#*#T(/X?Õ6( CjB$$$!; %‡1 :!$>&4PB#é•.9J21+þp8WV9w2..'6 L ί%%#".5463254&'&3254&#"326ÎqQ*8/!qO2/7*Hxa7,&77*'8ÌNs )H,NrÂ'8sOþ—+66*‘(99M -­-6#>=4&#"#54&#"632+463263254'"2-  "I 078 :7!”aIH;$$7*6%¾U-.ÁL` 1yyIØ$G1qfBB$$*þa`E þÇM Å­7B4632'4#"#"&#.'326327672#"/#5#".5&#"32MS7, ' !*0-"1.TV .`&66Á%7.G<’& &! ,*É: lR :çÇ7  k б)%#"&557632637354.#"326ÐpPOq0\*7/00‘` *%:+&8ÊNpqP¾ þõah'Ü’ "9'‘ #9Mÿ{/®+%"'#74/#'763273&"7/0(xr6 0%Á~7 7.T‹`##s£*#0Ír VG@*W'$$ +Çñ Çþ‹ N Ï®M37632#"&5463232>=4&+532654&+532654&#"5467ã '0'. U/2)R8Om$% a HH%HH'5R’& 6><65 CH.H x,$(%$7K Ì­DM#"&5463232=4.+532654&+532654&5467>54#"g % %)''N)%&T;WeG8*0F3gZ !!!: ¼3( ' "$5:M03MOEQp;1<‹»„„= $&($ OþâdGK0IR 3­$4%#"'#"5432327&54632326'4&">3-HD26,”/#;&}\CE[W/<+q,8,!SIG+  GVh*OG2þ—*a™20þj'/MÔ®.2+>54&/4?"#".547232>¾iD1Noo$@\<%Q9 A9.#5,L+£ %ß:C3];# (BR%#F­ '5" &M Õ­E2#"5463;2>=4+532>=4.54632".'"Ð%2A '?(Â@9;&** +5+A("D %2;2Ë.43 U&!•I+j  È#&+/*-! 8M έ!,5##"&5463<.&"546323#3'54&#"'"32ÎIJU@YW¼YCEWIII©"6CD4<=„5OICY; “DJCA…`x© ($$`&"þǨ.`H! ¥î(#".5432326=4'&54>7Ù.4.[i32654&#"26¯36"VP$-"+ ! +'K "6%>zέ<*! J60$-Œ+HH/‹ <)3G6"<"¤!  )/A(`d: <#f!/0Ø„ <„% !þð¢-#".=>7;>54&+#"&54632¢½;R'8) :&&87$.*^JÂOÁ42/1"%&!Ü4#$/*AOÀ!þ>#"&'54>7";>=4&+532>=4&'#"#"&54632£gWVk 2#D$:112$ 1%'YO^cb+9RRmYP!))‡)(ïs"&#$0"&AOIGn :-! £­0A%#"&=47>=4'#""'5463254&#"32>£[fUlq9)D,$¨bG58$80'6(`:%&<@ š:VKEaR2, m8"I  lF= 7$(*5!‘Á&% Á#% ! (77432>732#>=4&'#"#"%5.'#"26!Ç#3 -/!/` GI ,%/ 0„Ç) .'&7=F?׸ 67#4Vh & %.%G`aÂ#&Â.0! ¢Œ)2#7>=4&##".546á)9/!;)?#$;$3 oŒ)J/9*&)À0*/-D6Zl!þ,#"&'&5467326=4&+532=4&'52£lQ?i@8 9&(90;%4*c[a(9SZe.&"+2Iz!%#$î1x!%HGQ2=þðŒQ.'.'5632.5432>326732#2>=4&'#"#54&#"#54&'#"D‘zgÏy-;+.¨=> @/<ŸFI &"CH,S )/.U<6þðD_*$ 7S6/5[ x,H``/ !``100b# 2G`! ¢ª&6%#"&5463254&'#"#"&'54673254&'#"326¢oQMrqP6*7)0 (mQPl`5+&86*&8ÊNqqOPqÁ&8/ # @LkSþ–-36*‘'89! ¤®(7227#"&'"6732+".546354&#"326É0S:?"#i%:06(d_ ("(OI‰5,)64+)5¬ :/ò )E,nV'?'RDKý¿Á"&#%Á"%$! –87"&54747632>3#6=4&'#"#54&+632Ž1<2a$A$QY`100$ 1I=#'7" fVI[$Q> Nq00À*%$/$$’!  ¬;#"&'54732326=4&+532=4.54£ I>¬$6. B,.4&O-T  )(!Á+$<$)!þðŸŒ.73265#+5326=326=3#"&546˜;%$< 0, S< `.b/%M5]`: 0y '-Ü G( Mþ##='h@#R! •«=26=4&'#"#54&#"32+.=46?677>3267÷IU F.35" 1I=#&:<*9]b’E}!XI‘DNI(])!h‹Ma)\L?Á,$$‘‘/+#‹(3:-»Rg(<C[N06+%&$! Ô®+%#".55763232654&'5463Ô(J0+9)1U !;(!TI:2„#'J2À 5ýï!%0&~0(9+>*!þðÿ‹FT#"&54632>=4.'32=4;#"&547.=4732'54&"326ÿ7`;t{M: ?8$7%* M18NkaBqW¾(!#OJ1‘^j %5¿f7%Ä$6  /$!55*P (%ZW K oÃ00ÿÿþñâŽ@2632#".54673254&#"#54&#"#"&54632#"'32>º')2@H&K3>>(>:<([G X!   )-‹PBþ³)9&#A)4FEy"$GÛ%#,__*E  $$!þðM[%##"&'54>3326=4&'&5463>=4&'#"#"&54673263254&'#"326   alRLs/ 9&(92. DER@?W<#BGMþÝ16 þ% &D^Ve_G " ˆ!%#$î # H@NLDFG$(C˜04!!þð¡¯525572>73#"&'54>332654'"#"5467Î.E01 0TmgU 7' D &0T6 0HR<Žñ$ýe[Z@ "-$&x'%#Þ3$# -f,E!þñS‹=J%74&#"&'&'563.=46;6732#"&754&"326+ 0C/! 6%LV ï :'"\F#,"/C>_37$>`ä+8,*)öA" S* (/D)q/X9"f7F/DA/@ Dƒ""‚!þí£Œ*#"&'546;265#"&5463326=3£_^Ot>6 9N9/GTWD4 <#,5aT\c]L S  ‘ '&"6S=8Y18Á É­0C743254&'"#54&'"'.'546;672#"&'&%4.+"3265FÂ4-$H=M8%)2”^c4s #+&  4-@ÇÄò/II11%)4 …þœLm6:&‹#  ¿ '*! £®&0"#4632>7237>=4&74&#"26ç(-aPY>RÙ164$WR$2( 61_tþÒûL]C6<;)`"…L!þñÄŽ<%"&'54632#"=4>7326=4&+5326754U)&' 3,0YuÒ7'/w>6##"ü. %  '?IAouæ’.8I0138þu‹M=x6((! £®$%#"&'5463254&'5254&'#"326£qQNqqO2/7*Osa6+&75*'8ËNsqPNrÂ'8qQþ—(86*‘(8:þðå®),#'>=."#54&#"!#'467326;2#åDG$("H )-´Ë>+P&$6‹†ÐbL); .. xx! Òý{,2&8&$þ«þG!þñš¬KX$"/#"5767;>=4.'5#"&'5463254&#".5727632/&#";6š  0%/`C ÄsB*0"9ME8# I ')"bS0  TT³™ <„ 0$g>H#h!;d"#-‰!` L*3EË *  Vû< lS› k! Ó®*%#"&5576;637354&'#"326ÓpPOq0+* *7/00_7)&98)&8ËNpqP¾  þôah&Ý’&87)‘(89þñFŠ9%#"&/#526754ȷ'&#"&5467267#7327F;.L% N''Ne\WeD9(2F3eZ!"!*n'  A«#-1 "$5 @6LLMOEKu<0<‹»‚„=I$'#$ &jL !›4 âŒ*8%#"'+.546;327&=46732326'>=4&'"â;C=03A,E2 &TIFZ…12¸%#(+RH$    ITH'QE4H^? 00x-(x+!þô€Œ22>32#>=./4?"#".5432±$WA hD0Cet4'+N,# Q)8DG/#0/!Ý=4.+5326=4.546;2œ " 07WB'K2!;@&;>0+') **-,4,>'%*E(^;"c):* "G3&M3z$ #ä  +6%6 - ) ! ¢¬)3##"&'54635#"'54623#3'54&'#"'"326¢ISI@Wes¼Y†YIII©6CD4<#„?DJFGB`‘DJI;…`x©*$$`&"þǨ.`H+Eÿÿì,73267654.76?2#"&54>4'&>?632ª#&52**+­\?Z ' !(^4j~D'.> ‹? ˆ³U&*sND , þÕEÿÿëD%#"&5""#"#"&574676.7>3232>54.76?6322>72ë2)9 7  ¢Y@[  L ")$&(< 6-$2V% ú 5,o¦T'õ+!þÅ4W|c+?sV1ÿ× XN7"547#"&546'&676;232?674&76?2?267>;2#"."#"&#Â!ƒH"+8(y+ ++ @M@ ) C%  ;)8%   6PÑ /!X  &N"N0 *&…Œ#  *"ÖX57"547#"&54654?632327>/&76?632+Â!ƒH"+&%!y $ 7  gg  06PÑ .!U  a %:`(2ÉÄ,ÿúàY9I747+".546'&>;2327>'&'&7>3232#"&74+"'326¢¥#$ M K3?  O >W*56m. ØF 3KÔ# X +J%—*0‚—3N )+,  ÿö<a=3232>54654&54/&54632#".5465#"54>54&7>œ!4 g!;8! [&¦7>54&'&?26.#">j#$*N /;-?T" "! *)%/    bX$  %D'(( :'5&-#%U    :#þî ()PRy)!!   G" %011!\37467'.=4?2632+".'.'+"1ˆJ 5 '*., B  GO  K cmñ* M*3u\z2 VqŒ)8¨Q& 2Á\B7467.76?22672#"&'+"#".'.'+"2R'*+ 52/*h$ )'89+7 2K J`rè!B  %F1[:2 1-ŒS  ‡¿+ o%* 1ÿÖü\G7467.76?23>4676;2#"'"#""&+"/.'.'+"&1ƒQ'*+ !' !# ;.1H#    2g Jckí B <$2$3%Z'O(  *!2 2~t1´`* &8#\4+"&'&54>767&74?2632+".'?9\ 7 2(;6  ?## A —l7 * #B+- R4?+;ø7  ˆÁ)2Ò\3A7467.76?232"#"+".'&'+"%4&+;2652‚Q'*+*.P&fVO/, "( 2p>9(/ %bnê!B P0VË.$ Ë/Äc! ^Q-ÿòMU@L7467&/&5&>32"+.'.'.>32#"&732654&#"- R-*)  0%+   5$ <_E(3'%,$ /,d$#Hvú!9  1 .)P0$`C$ -ކ3 ,Š, 8%'  >4*, 1uUVb74>7&74?632?>7>7>32+"#'.547+".'.'+""32654&1@b097    @D 7 ! '3u %=%(@8#"(e>˜!!cI¤zN  00  7&[)$ ¾@  ¿+ !¡] ! M ( !9ÿv\V7"&54>7&74?263272>#"&5#"&'&6'&5467.'.'+T 4K>;6  F !5 4-- 0-8'§%71%() e„c9)4a@'R"L1tA  1 6)00 A Dà8EU  J_74>36=4.7>322+"&5>'.#+"54?"+"#"&5Rwd" O =¼" +3D9 E) BQ7) pBd1˜ "š>8 4 I J/!1 ?j$ ;1oB%S9#  -Jw74>36=4.7>3227>7>#"&5+"54654.'&#+"54?"+"#"&5Rwd" O M[O B@2 )(;c 8%<+ E) BQ7) pBd1˜ "š3 1 5+ $ Q&G*= ?j$ ;1oB%S9#  -ÿÖJq+"&'&=467>37>=4.7>323263>32#"'#"&+"54654&'+"&54?gG_-,  ƒm% O ×C ? D. 3,GH @o_ E3,A=&(  *-.A,+\  ¬Q 1 U " 1 3&T DO@h% $1oI\7+".5467>3>&'.7>37632+"&5>7'.#+"/&5467ƒ, <1){4   "F‹e +:I5 @  7'6#´ ,62Y  ¤(P1W C/"2 b  ])¸J`l74>36=4.7>3222++"54654.'&#+"54?"+"#"&5%232654&Rwd" O [kLRd^K3 %=* E) BQ7) å) pBd1˜ "š'M2*# + (E*< @h% ;1oB%S9#  -ME"’n4.'632>322+"&5>'.#+"54?"+"#"&=4>3>54&#'56 -'"* 1'=¼" +3D9 E) BQ7) Rwd" 1)6F     = •>8 4 I J/!1 ?j$ ;1oB%S9#  -0Bd1Œ  IZ74>3>4'.7>376322+"#"5475.'&'"+"&547+"&58O_G   "_oN &  (  B:S+, p5W2" -S%!— @) 7 9 %@#'9)" (ÿtÂIk†7+".5467>3>&'.7>376322>#"&5"#'#"54654&#+"/&5467#"&54654&767272632ƒ, <1){4   "\qO– )(9 $}] @  7'6#29,& U57  ´ ,62Y  ¤'Q5C   0 6+%QEU b  ])à 'K69\]¥F]ln%".#&#"#"&54>3276323632363632#"5+"&54?>.#"&#">326?64+">3>k #T(0&DsB#* $%.  ?>,i) =   6 <$ - % ^ P9 . (1þa 3(LQ; *7Q/!  m) &f3."',@& 2ªM1¬ {¡:\O¥Tk}%'.#&#"#"&5467632326323632326327>32#"'#'&+"54?4654&&#">326?63232654&+"k#T(0W*HR1B6$.  0 E.9I,! BJ;.@, )/# y?$ - % ^ à )=1þ¤a2&5m248" / 40B %#€) *×"',@& 2ªáv2º7.ÿÖ(d[v€4."###"54>?3263232637632767>32+"'#"&+"547""+#"&5464&+"##32723267676;?, ';PxmŒHÍà  ‰  '  C$!4 NH  @"[$) ($   *$&LýfNJ/]I ©)\9X)   3þ®1% . 3JMÂ(Z ) W) <>(Ð#E.—d8Wa%467"&'&54>'.###"54>?3263232+"4&+"##232632632676;?¦4#Ll %  ';PxmŒHÍà $‰A!Š  *$  )  ýfNJ/]IJ&œD  %5'*©)\9X) *.4þ°2&þ! Y >H(Ð#E+ÛdEdo€%>7"&'&54>'.###"54>?32632322+"#"&+"54&+"##2326326326763?"326=4'"&#¤?Ll %  ';PxmŒHÍà $1> Nq&6,   1‰  *$  )  ýf NJ/]IŠ %"5[-¦"  %5'*©)\9X) ,.0‚†##*  A½! Y >H Ð#EþÍ+ );‘dAS`3"5467>7&547>32$32#".=4&'#"#"+"4&#"#326=26=Jƒ ½311546 ?toR$E<  %  'R&  1 Ý%355"þJR* 6 #… ^81  V?6G ) !^/JN&O0'Ú/1376#".=4.5+"&4&#"#326=%346.+7N."š| 0û( VC¸x Ò1/?6372632326327>32+"&5##"&'&654&5467&4&#"#3263272>76;2?¦[$)  '$ : ˜(I?PzY$›šl   ‰ ^W  /*;[Tj9,( fƒ Šf $&&  ýeNM[~HPÂ+Y!¥8 9#2K&2'3þ®/  * 4-&I 5 Î'W*CL$ÚO>UÐ[#"'#"&'.54654&54;263232?>7>'&>7>4&54;232654&76;2632(T7674&7>7>54&54;26323254&76;2326ò*(:9 6k)H4G 5M L 5   + 'hC5‡  · 7+ 6- #2   !Ÿ0!  *  L( 7U ‡#>H .* ÿ×L9~%4>7"'&#+#"&54654&56;232>7>&?>54&'&6;263234674.76;2363>32#".#"+"'"&+"Ö%`>{&$, ;&    ' IV A t "G+ /2$  . $M0pb -$U  _ !    (8]#  7"þ¯65!- ²9a%467"'&#+#"&54654&56;23:>764?>4&5&6;26323>74&76;2+"&Ö6a>{&$, ;&  & IVA t BT0¸ -$U  _ !    &904þ¦7!!CEDgu%467"'&##"#"&54654&>;2;2634676474>54&76;23>'&6;232+"#"&+"7.#&#326= ) +II#+ ,   # / % 3ž  @ ] XcDO%  1"Ó#- V+ž?1#V ))) %>  &:43+4 4/þÿ54'4;23654&6;232654'&6;2#"&"#"/&+"vw>)Š , "!= < gL3=2b<$ X>, "Ñá4  #'[  n!3D >1' 27.+"&546'4&56;232632726?654&76;23274&76;2632#"'+"`:kH%"+=" 3  0 ot 3   -aAZ8ED8 7b–1#b  !N' U.)2 f; 0;(`\cÿvG8‚%467"."#+#"&54654&56;232>7>54&5&6;23>74&76;237>32#"&5+"#"&'&>'&5467&×5#A& {&$, ;& $ 'IU @ r  0V 0.8P 8h15' eƒ S4±  -$U  _ !  X;-6"$þ¬6*0 6)"Q & $0ÿ÷+2"'#"&547>7>372327>32½I5#MdvDX. G $9DE9$0(915(  * , B7^T/>E2  -M71.0A%+5   RP&F7467"&54>=46;2;2>#"&5#"#"+"&Ä9TGTG - /BB/7L (O2*2*:  ? 0 m!'(A&9 " *=$ 0   4 4- u !1&746;232654&54?2632#"&54>765‘ 0 '9.9 r0;Ž* 0L0y!4O$@9K k  #@-, IS% 2!+ $#,3'F6%) GM0ÿðÄ'N%#"&5#"&54>76=46;2632327>;>32Ä()::$$f<;\B_aJ -  7MPN7+#!) Oy i 5," & '5=6W>;P0 -J5/< %)$/'=" *1Ž+?K%2##"'#.54>74>?263232>7&547>3>32654&#"3%6%B@N778!?\]F 8 ;9NL(/,!$<Hy+$ð4(0  2#3V@?V2  ,J8)2=M"= #/ i*,!-ÿÿ'G%"'#".5&54&5>7272632;2#"&5"32>7>732½I0J1*,sd:/ X 1+A)5"H3 1@(  * , 2$& 2 ƒ–  +3Fš• $ "#  -ÿÿ~IIW%"'#".5&54&5>727263232632#"&#"#".47#3263>7322654.#"½I0J1*,nh1 *"E%73<9"- >MU)G@(  *! $ , 2$$ 4 ‚• 5(&9 )'„r–Q'"#  ( #0ÿñß{r".547>5"&#"+"&654&5&632726;23>32#"&+7>;>32#"&5#Á/.TVR46. (=  8HF* )$6,#3#8EG;+EB!) Oy '):#*  U / !!,G06R8  ! -$  )4 # /L4-*->& */ '=" .5, ) %-ÿûHE4674'4&546?26322##"&5>54&#"#"=4&-sO C ¶ 9G)45! 3& KZ0  1 ~"à $J¿ 71'M5!F<,C -ÿûHe4674'4&546?26323;2>#"&5#"#"5465>54&#"#"=4&-sO C šHF2 1*9] ;E-D]3& KZ0  1 t6  2 6,  ?; j¢8/_MB7+C ,ÿÛH[4674'4&546?263227>26467>;23#"''&565>54&#"#"=.,vM C gO @"  : @K,Œ F+B`2 ' J\0  1 FB%Ó + 4^«!80aM%%G8+C>v,ÿûHI4674'4&546?26322##.45>54&#"#".'.,f] C ¶ (A//;)3 %7b0  1 ~"à  n¦-6!I2)7(4-ÿûÏHN\4674'4&546?263222+"&5465>54&#"#&=4&4&+;26-sO C ¶ Ñ&6,1F, "0' 4% ;"1 'K[0  1 }“M  j¤80$A)82+ @Ÿ±! 0 -ÿûGDF4675./&'&37632632#"5465>54&#"+"=4&7-h= 6& V°YE*Bb2 & §GZ =aà# v~580`N%%G8+A £Â-ÿûHP4>74'4&546?26323#"54654&#"#"&=474&-CS, C IR  9 @/19'  8  "1N& 0  1 ?7c/ˆ+6!E.; $+ 9: ;3.ÿt G\467&76372632236#"&5''#"'&6'&7>34654&#"#".'4&.€B C  · Å ((:;8T2%() ¬)E+19'  7  $Cbd H{5½/-&1 8) 11 A  Dì80"F\A  >ÿûpg2>7>;2#".#"632#"=4&5>54&#"#"&/&546?6=##"'5>54'46?6‚@ ?;N!C* $F%* 1$=2<99&.5$  Z 6E(,P1 !X3 # 0 ]5*Õ" ( +Ë6)#G/‚# +E;;2M Z! " ÿû €2>7>;2#".#"2632632#"&5"#"#"54&54654&#"#"&/&546?6=##"'5>54'46?6‚@ ?;N!C* $F%* 1 M;?o(+7 ) S9&.5$  Z 6E(,P1 !X3 # 0 ]=) -, 2 8(u 0#Î1*#G/‚# +E;;2M Z! " ÿÜ0v2>7>;2#".#"632?>763+"'&54654&#"3#"&/&54676=##"'5>54'46?6‚@ ?;N!C* $F%* 10-= Q!  4 P W1!<#-5$  Z XK,P1 !X3 # 0 ] /@³; * 0 3$ Þ0*"F.ƒ5  +E;;FM Z! " ÿûpc2>7>;2#".#"2632#"54&54654&#"#.'&54>75##"'5>54'46?6‚@ ?;N!C* $F%* 1ž X9+:h 4 2F:,P1 !X3 # 0 ^p-¶* 0,Ê&.\CK'P (D&d! " ÿûÝr‚26726;67323#".'.322+"'&546=4&#"#".'&54675##"'5>54&'6;234&+;265Ô8C9^  /0# FR Ð%6,u 8) "+# Z  mGBO1  &.! ¤"/ '& 8  4  ]52~M 25Ä$, $=&\1 ‘M_ e""þ73 $ÿûŠy4'6;27263>76;23#".#63#"=4654&#"2'#"&=4&=4>75&/##"'5>[5 X8(!#!5$#'  4MY9&>Y  <  );57 1 "l ! !  -  02<#¾ 0.¬+4(^Kˆ (( d%A' TA"ÿûpr2>7>;2#".#"2632'&54&54654&#"##".'&54>76=##"'5>54'46?6‚@ ?;N!C* $F%* 1 =]  h8& ",$   R  6-!,P1 !X3 # 0 ]3;\ . e#,":$'…    %;' Z! " (ÿ†‰4>75#"#"'"&654&=463272>72723>32##"&+2632;2632#"&5+"''##"'&>'&763;&546=4&#"#".J2G:,%-  '08   " HC1 *  ))"5Ÿ#$V +(9. 9U9,+ ?<>=&G[ 7)E'c   ! 5 A $ Rp¶:  1 7+8C  6©( .)h8G A4@ÿý{G=NZ"=4>7#"&=4>?4654.76372632###3263>7%4&#">-  '0R7L[P   _ &J@-YQ   *|K !"L9!!))GP +;  M2L-# $‰ (>Y%1+& –"@ÿýŽGTeq"&5>7#"&=4>?4654.76372632#>7272>32#"'""33263>7%4&#">+'0R7L[P   _ &J@-YQ ) 6)! +3J .  Z‚K !"L9!!)$i +;  M2L-# $\&241 (>Y%1+& –"@ÿã€GJ[g"54>7#"&=4>?4654.76372632#2367>32#"'&3263>7%4&#">,  '0R7L[P   _ &J@-YQ # C- ;*5CáK !"L9!!)5 K4 +;  M2L-# $– !,!* (>Y%1+& –"ÿï´GGYa4>3>54.6372632##"&54654&763232;267>7"5473272?65654.'w>]K   _/X$/35$3Rj8)3   A -U:)x% !0 âm",+> - 3 38*8))> 0 %) 6CC* >&@ÿý{G8IUc"54>7#"&=4>?4654.76372632#2+3263>7%4&#">4&+;265,  '0R7L[P   _ &J@-YQÑ@>&&œK !"L9!!)!, *4 J5 +;  M2L-# $;L% (>Y%1+& –"ÓJ?ÿý{‘Pbn4&'5632632632####"=4>7#"&54654>?4654&##"'5>3263>7%4&#">®B34 %- &J@-YQ   *  ,1N6LZQ  ") K   L9!!)X 5J-# $‰ )GP +:  T þÍ&>Y!2+& –"Aˆ3ANZl%"&=47"&'.54>765654&54>32632#654&#"32?4&#""2>7>5N84 FTI>"F.**?+0"I^ 5:>K  .#7 &k( % ù-4 2< F / .&, ,(= ( $ 7 nS$.Y MY$-- @ÿýGUfr~"=47#"&=4>?4654.76372632#32326;2632+"#".547#3263>7%4&#">32654&#".!'0R7L[P   _ &J@-YQB )+Q )52; %F(W   QK !"L9!!).#$)“ +;  M2L-# $&6(%7! I(>Y%1+& –"µ*")!@ÿýñGq‹"=4>7#"54654723274654.763726;22>54.76;232632#"&5"&+"?####32?%4&#">.  8+~å   _ 0b 8 A R 4'8/$ Oÿ¾zGgr7"&547467>7>54.763722#;2+"&54654#"#"&#&#"&'&654&76723>7&547732767"267654.'ØLNtM (   _ w^$$WT 4 .   8 '&9  % #  ^ 4{JzI Ó%:F 7/6?8 7& ,  T $4  6  HÒ j 1zL2€* ÿlzGOgr€$467#"&54>7>54.763722#32"'"&"#"&=4654.7>7'263767>57">5&'4&+;265 !WB2IH7   ^ w]2XO-1:(.|u  ^;,&%yG[  -'ôL.M="'$ +<j"!0D? 16@8#!>M 1 ï 7=>,!“ œ ).S þÅ:@ÿý¶Gfwƒ"=4>7#"&=4>?4654.763726323:674654&76;2>32#"&547####3263>7%4&#">-  '0R7L[P   _ ?Q /   D '+*4/˜Y%1+& –"ÿýªŽkv~4'6323263:32>'>3232#"'6;2"#"54?65"#"54654>?#">32637%&#">L'/ ! !l#%.  @" 5+JA' Â!0BX   T!6Š6R?@! V1!kA&Mb L:, 3] ` #   <5 @.<%7 ‡! !é-— ,K¥,ÿýªŽŠ•4'6323263:32>'>3232#"'632"27272>32#"'"#"#"5765"#"54654>?#">32637%&#">L'/ ! !l#%.  @" 5+JA"Nf '/7 % 6)! +3JE  W6Š6R?@! V1!kA&Mb L:, 3] 3+     &24  4QQ<%7 ‡! !é-— ,K¥,ÿ㪎s~†4'6323263:32>'>3232#"'6;2";67>32#"'&#"5465"#"54654>?#">32637%&#">L'/ ! !l#%.  @" 5+JA' Âb‡  # C- ;*5Cl 6Š6R?@! V1!kA&Mb L:, 3] ` ** )h !,!* 0–<%7 ‡! !é-— ,K¥,ÿïåŽhq4'6323263:32>'>3232#"'632##"&54654&763233265#"547232>=#">2>54&#2635‡)- ! !l#%.  @" 5+J`e6 :S5"-Xj8)3   !GCe21„Ò@" V1!D %.;Ž "*', 3 b%3" !4,)> 0 @L 8x_! !ð-1¬–  ÿýªŽgrzŠ4'6323263:32>'>3232#"'632#"2+#"5465"#"54654>?#">32637%&#">4&+;265L'/ ! !l#%.  @" 5+JA"Fq9D4Ù@>#$+! 6Š6R?@! V1!kA&Mb L:!-% *, 3] .4"  "K& 4Œ<%7 ‡! !é-— ,K¥,Ç1 $ÿý¶¥tŠ%"&=4>?#".>7"&+"&654&54632;2326;26?>763#".#""76632####"547"'32637>5.# T:6U8: n) ))9C!  - -%7"   )9"'(G!<;# YU   +" +'@ Ì&$(;5Ò %6 ; " ;%  9  (  ‚ 1¦I.—!<"-Aˆ¸Yp}‰›4'56322>32"632+"&=47"&'.54>765654.5467&'#"'526%4&54;2632#"&546654&#"32?4&#""2>7>°-'"*& *5H3& 0"I^ 5:>K  XN84 FTI &&-5 #V <  8'#t.#7 &k( % ù-4 2< l  " 9* '!( $ 7 F / 7 (#   !2 #ëS$.Y MY$-- ÿýŽš¢®4'6323263:32>'>3232#"'632"32326;2632+"#".547##"54?65"#"54654>?#">32637%&#">32654&#"L'/ ! !l#%.  @" 5+JA( 9=$1v( G (!R 18O (_  R!6Š6R?@! V1!kA&Mb L:-#$, 3] ( %  "$;! 9 5 @.<%7 ‡! !é-— ,K¥,©*")!ÿýñŽš£°4'6323263:32>'>3232#"'6322>54.76;232632#"&5"&+"?#"#"54?65"#"&=4>?#">;7%4&+">M)- ! !l#%.  @" 5+JA!'>3232#"'632";2632+"&54?'"#"&""#"&5>76&54;263&5465#'.54676?#">;67>=4&#L'/ ! !l#%.  @" 5+JA( 3?."HT 5 0< 7 F' `  6P /.FB@! V1!iH,É$,=<, 3H %    *D)    >: "   –35j! !ä1|8- ."9+ÿOªŽŠ—¡±4'6323263:32>'>3232#"'632"#"32+"&#"#"&=4654&54>7&5465#'.54676?#">;67>=4&#4&+;265L'/ ! !l#%.  @" 5+JA#>?&#CL  f]%7* -# ^;+%%/r, 6P /.FB@! V1!iH,É$,=N1  œ35j! !ä1|8- ."9+þ§1 ÿý¶Ž‘œ¤4'6323263:32>'>3232#"'2>323:674654&76;2>32#"&547#"#"54?65"#"54654>?#">32637%&#">L'/ ! !l#%.  @" 5+JA *J>/   D '+*4/˜ê   T!6Š6R?@! V1!kA&Mb L:, 3] 1& EV   2 BK  <5 @.<%7 ‡! !é-— ,K¥,ÿüé4B74&54632""#"&=465>54654.#"#&546 ªvOd ,--;`  %aÈg|I<4á5" . $³3&4dt ' À=ÿü×4V%"'"#"&=465>=4&#"'#"=4&54>3267>32wK  0 >0/1 0 ' 2EV=Nc* G) # <í3*d4!  $ - "½5 4?+W;þ÷@>Á5S- F:h"/ ÿÚæ4I"'"&546?54.#"#"54&'467632?>3†Iœ' 00 2 & 2HRQ)LA<G.!B&4")#ÙE / -X=)[i ;E‡G>`#)?24é8 !- ÿüé4?4>32""#"5474654654.#"#&54654&2GV<Od ,&' AW  P $ Z4R. I<4á5H, à / oQf '  ?Pÿü«4CS232#"#"&=46?4654&'#"54&54>4&+;26,:;%l]"4&"WJ6%1  0 ' 0DT=0"3! '4 7&-¯, #";­%E.@(R7'{vA?¼6T/ þ$ 1  ÿüá4J"&54&'#"&5465'&7>726?>32#"=4654'&#"9 `B$% ® K]H*K?   ( !E// @!*3²% 3A 3 4L"@1*þó(D 0ì4.;+X;þä ÿüé4/4>32"&=4654&#"#"&=4&1DT<+LA E.D.+5$51 Q7U/ @2(& #% 0='R8þë !"*±ÿtÃ4\#"'&6'&76727&5465465.#"#"=4&54>3232>#"&5'&#"#$8-)% x3!5)@V  F) 1FU=*L>"E22 ((:<A 8 &I; #6ç7++oR59)  A W4R- @14å6 '  1 6*ÿÚÿü7È(k226372>7632#"'##"ᘖ&'64&54632""#"&=465>54654.#"#&546EDŠ6  :+4H$$ S26. ªvOd ,--;`  %©2    )"3  " /ý¸Èg|I<4á5" . $³3&4dt ' À=ÿÚÿü×È(226372>7632#"'##"ᘖ&'6"'"#"&=465>=4&#"'#"=4&54>3267>32EDŠ6  :+4H$$ S26.WK  0 >0/1 0 ' 2EV=Nc* G) # <©2    )"3  " /þD3*d4!  $ - "½5 4?+W;þ÷@>Á5S- F:h"/ ÿÚÿÚæÈ(r226372>7632#"'##"ᘖ&'6"'"&546?54.#"#"54&'467632?>3EDŠ6  :+4H$$ S26.fIœ' 00 2 & 2HRQ)LA<G.!B©2    )"3  " /ý14")#ÙE / -X=)[i ;E‡G>`#)?24é8 !- ÿÚÿü7È(h226372>7632#"'##"ᘖ&'64>32""#"5474654654.#"#&54654&EDŠ6  :+4H$$ S26.2GV<Od ,&' AW  P $ ©2    )"3  " /þ±4R. I<4á5H, à / oQf '  ?PÿÚÿü«È(jz226372>7632#"'##"ᘖ&'6232#"#"&=46?54&'#"54&54>4&+;26EDŠ6  :+4H$$ S26. :;%l]"4&"WB=%1  0 ' 0DT=0"3! '©2    )"3  " /u 7&-¯, $ "ÛE+G(R7'{vA?¼6T/ þ$ 1  ÿü/È(s226372>7632#"'##"ᘖ&'6"&54&'#"&5465'&7>726?>32#"=4654'&#"=DŠ6  :+4H$$ S26.! `B$% ® K]H*K?   ( !E// @©2    )"3  " /ýS!*3²% 3A 3 4L"@1*þó(D 0ì4.;+X;þä ÿÚÿü7È(X226372>7632#"'##"ᘖ&'64>32"&=4654&#"#"&=4&EDŠ6  :+4H$$ S26.1DT<+LA E.D.+5$51 ©2    )"3  " /þ¨7U/ @2(& #% 0='R8þë !"*±ÿÚÿtáÈ(„226372>7632#"'##"ᘖ&'6#"'&6'&76727&5465465.#"#"=4&54>3232?6#"&5'&#"#EDŠ6  :+4H$$ S26.8-)% x3!5)@V  F) "9@E0Oc69,? *':!8C 8 ©2    )"3  " /ý:&I; #6ç7++oR59)  A]+G-!I<4æ6 1 6+%ÿý´GW%467#"&=4654&54>7265>54.7>32>7>#"&5#"'##"#" i3%&).Z*   R f"G 1*9"; ' V. ý- 012  *7  d   1 7*þÑ%ÿý´Gw%467#"&=4654&54>7265>54.7>32>7>#"&5#"'#>?67632#"'"##" i3%&).Z*   R f"G 1*9";  !Q!)5K  &,ð5 012  *7  d   1 7*Ö-. 3  %ÿã´Gj"54#"&=4654&54>7265>54.7>32>7>#"&5#"'#7263>32#".##- &i3%&).Z*   R f"G 1*9";    C-  +5& 1! 012  *7  d   1 7*<Ç  $#ÿåüGg4>74654.7>322>#"&5"#"##"&54>'&5432332>7>5#"'&6'.˜2Š5  T %M22  +(8&%  '5Up$ 2 ;5I&A% *&Vr ; V   7* (#):+,  ! 07&< $3 ?  %ÿý´GVg%47#"&=4654&54>7265>54.7>32>7>#"&5#"'#2+#"7";26564'4# !i3%&).Z*   R f"G 1*9"; ÒA> . ~ $'H4 $ 012  *7  d   1 7*ÒL% *'%ÿý´‘h>54.5+"#"&654&54632;2>7>#"&5#"'###"547#"&546'&54672>38  <  #551 # wG 1);+3    3$l +,$ /Z-5 v W " AV   3 8)H É .   #( Cÿø—3Vc"&54>7#"&54654&54>7265654654.54>32#>67672#"&5+654&#"0 cG& &)\, (;37J .'& )- 4(8e  PV.#7 E:$CJ<95 #4 8,!2 ,   8)z/4# wS$.Y 'ÿn´G€%4#"&74654&5467265>54.7>32>7>#"&5#"'#2636#".5&#""'#"&54>'&7673>3& &iA$)S–   R mE2*9)  "‡ 3%0 # 4W&  g <1  4A 2  *7  d  2 7*:Û  3 *' .# ;ÿþÖzo26;>7>323#".#"#>76#"&5"'3##"&547#"&54>'&7>;>?##"'52654'5>323&o& :C6;*8% H x\   "$+8d $%f$ & J L [ t !1"" !$,#3h  +9(  þÖ  +  !2  "   A# ;ÿþÖz26;>7>323#".#"#>76#"&5"'67272>32#".#"2##"&54?>7#"&54>'&7>;>?##"'52654'5>323&o& :C6;*8% H x\   "$+8d& 5)! ;'% < $%f$ & J L [ t !1"" !$,#3h  +9( Ó1 3.  C'š'  !2  "   A# ;ÿÙÇz„273263>323#"'.>76#"&5"'?2>32#"&'#"#"&545#"&54>'&7>;>?#"'5>54'46½@ §6 C6   :; %x\   "$+8d (;4$  8%0 $ f$ & J L Qv  :S3% 2 " 3h  +9(  /U  /  '  !2  "   A"1ÿåz763237>323#"#"&'>76#"&'#"'##"&54>'&5432332676?#"&'&654&54732632674654654&#+#"'5>54'4632aa YC6." $. 7  u_ /(74)Vz9(2 A 3[b2%&nR  Ou  :D $- s  !# 7*dV%0.: ! %?e  215  ;A":ÿþÖnu‰63276?6323#"'>7>72#"&5#"'32+#"&545#"&54654&546;>?"#""춮'46324&#"#326;265ø° W H:02Fa d ,+ '(;G.Ep&6,#"&f$ &D(L "! ;,!:B' .! '. '"3 —  )6) Ê#) &  "4 1 Œ"!þ6Xý74654&7673>?#".>7"&+"&654&54632;2>;7>323#".'32>3>#"&5#"'+"545#"&u  dL : o) (:3 K 5# :@"-R 8 l` )*:H @Ee3%'ì7 ˜+  (7,   0' S    )  ?2 c¾ 2  878³១£³>54'5>32:;5&54654&76;2#"'>72#"&5+"#"&5467#"#"&54654&476;27254654.54>7'&#"+"&#%112654&+"ƒ$ %#)   # Q  ?0$ +W-_B9 (,9A  O L -%&4T  0 nj*! /  C#' #  *  (+71J   8 >4$ 8('Š '/  9  (,(  ±/8%R ;ÿnÖz—26;>7>323#".#"#>76#"&5"'326#"&'#"'""'#"&'&>'&54>7&547#"&54>'&7>;>?##"'52654'5>323&o& :C6;*8% H x\   "$+8d °  &,7*  0V% ) -x( f$ & J L [ t !1"" !$,#3h  +9( þ× &700 #3  #  #  !2  "   A# ,CW43232632654&54;2;2+"&546754'#/&#"#"&="#"&546'4&5U!g 7 A:  E7   ‡++'"»C  % S %Ü*Ó  *8=  ÷Cn4;2326326=4&76;2;232672#"&5#"+"&54654'.#"#"&="#"&54>'&4J ! d 3  :,?0 (*9-    E:   ‡$ ' », 'L#C 1 7+ 8> *Ý!   "1  ÿÖÿCr4;2326326=4&76;22;2?267632+"'"#""&+"54?464'.#"#"&="#"&54>'&4J ! d 3   (": & \ 0" M -0   ‡$ ' », 'L .Ô 0 - 3?Â6   "1  ÿÛ%CU4&546?6654&54;232##"&54>'&6;232>54&'.+"5465#"&'&6LN}) 7 ?2@n;$1   J-WX6 3 R*% * ‘  C  % S w-+?!7$1   A-f!  $5  =ÐCVc43232632654&54;2;22++"&546754'#/&#"#"&="#"&546'4&326=4U!g 7 @'ÌCB#@8   ‡++'"É .(&8»C  % S %žL% ,Ú   *8=  þ× ( 7DV"5465"+"&546762725654&47632;2;2+"&546754'#/&#"I0Z 0 ’V  5  A:  E7  ‹!=8  I`  %N %Ü*Ó 0Ndp47#"&54654&67>727>32633>72632#"&#"#"&5473273632+"&54654.+"%2654&#"(DG+5i1 h-#?<,/5 . #,),+N*    = = @!"=,$=8 1 &,-C $$ !E0=>A55   ª-&‘Ct432632654&54;2;23263232632#"&#"#"&547#"#"+"&546754'#/&#"#"&="#"&54>'&2654&#"5W.U  7 BA! ( 8*56- / 3'47 -  E7   l2%& •2  ºC  % S ) 6'(67&! ­ ,Ô  00"û!!'–C‹43726326=4&76;22;23234654.76;2326#"&5#"&4>7#"&#"+"&54654'.#"#"&="#"&54>'&5W.< 3   (!4  ' .0„  2'<œ    E:   l15& º, 'L ,1 4 n " 7, 'C#0 *Ý!   "P$ÿ TCy43726326=4&76;2;22;2+"&54654+"'#"&54654&54>7&54654'#.#"#"&="#"'&6'&5W.< 3  ;1; 7  4 '!& ¹<-$…¾ <  l15,' º, 'L 8³ %.  T   ,T2´    "PDÿƒ³Cp~432632654&54;2;22"#"#"&+"'"'&6'.67>7&54654'#.#"#"&="#"&54>'&4&+"32655W.U  7 ?oW"5$ $ o2J&"/x@ ;  l2%& ) $)&ºC  % S ' e-  87?     00"þÜ6 >Cu432632654&54;2;23>54&76;2>32#"&547+"&546754'#/&#"#"&="#"&54>'&5W.U  7 B9 7 E 130  G8   l2%& ºC  % S !+ VZ 1 A 2t,(*Õ   00"0ÿþZB6;2#"#"&5476&+'&'4654&#&636BAi †_! 8B$m /è    …  kÿþAN%"&5#""&=4'.#"#"54654.54;6322632326Ñ*7, "  I ‰ '  & C")‰ *š6,%?B!   ! k   k M  ! lÿìÜAB"'##"&5476&'&"#"54654.54;63276327>3}J; F u'  & ""ˆOI,":3  ! k   k þÑ"- ?)E#"&'32632632+"54654&"+#"54>726726323(7"*:3(  l' <84 ?*O2 5 \ » 6) a:@D  ) ‹R'5," /]¢A<J%++"54765&#"#"54?4654.7636327226=4&#;¢(:-#91w0 #G-J^«(!+ ! V! % " @ ! i ^;)W @ 2ÿþ'G4&#"#"&=4654&54>?632;2#"'4?>'&+"54?66 -2#&3N=n  P9*m G  t  N  ó   563   4 Z# ?ª ¶ D!?fP\"&54732>7276;632+"'4654&"+"54>7263>32#"&#"72654&#"u",),+ )  ?. ( C@$3@/# 8)?> ' ; .>!"y'! !E0=>’  ( • Q+F( - ! -&%ÿtk)e46727&4654.#"54>7>32632#"&'3263263237>#"&5##"&54654&;2R4! > E)X<« -(5"*:3(  l)I!  ((<=Uj<0#  S5A0( 2 6) a:@?d  " 4, 1E0 IÿþÁzn4'46323>7232>56;23#".'&#"#32637632+#"&5454&#&54?654&+#"'5>; b &[..& "  & z#ˆ2 $s !" /.  F  ÿ    N A"Hÿþàz2>7232>5672#".'&#"#32632326#"&5#*##"&54>76'.'"54654&#"&##"'52654'46?6µA 2&B &NE% #   0% ‡ **7(2(  <D& E (z !S3 +/ _   5  ! 6,cW  +‰V% j @#" HÿÙÅz‚2>7232>5672#".'&#"#32?263272>732#"'+"#"&54>?>'.'"54654&#"&##"'52654'46?6µA 2&B &NE% # &$F G /* :+3N *+ 5 O E (z !S3 +/ _  D•+  )"3  !§ % j @#" 3›—„2>7>32#".'&32672636#".'"&#"32632632+"&54654.*##"54>7>26&67#+"'5>54'6E9cN !*  8"$  $/)   ( #H4E& n(  +0 @&# 4 O1 o2  . : +V?>=˜ ” Q6$ " !#+¥‰l2>?672326763232#"'326372632++".'4>?65.#"&54654'#">54'56"32632>5654&#&šD ( % 8  Q 6+GI'*¦(:.#9 b G;-"0A-$a32 . 4k  O9 @! #Î  i "!þ,]  6ÿýv”~&>7#"#"'"&>54/&54322326;>7>32##"&+"2;2#"#&546?4+"54?654&'"#"&74654&7>3,*  5)GV.  >'&  .)!4+Q1¯6s)!J! ,3&' vÜ     6( ",     `" ë #  < 8  553 3Η‹4'632723263>32#"&'237;2632#"&#"#"&547.#"32632732632+"#"&54654&###"546747#+"'5>2654&#"i 2B §  , N"   3+ 4E -:4&!/# 6 *%<4D&L)  ! B @w: 4 Q0»$$ 2$ 4 >) &)"$ X@;A ’   TF[E"#²+6ÿtˆž·7"54>76567#"+.>54&5432;2;26;67>32#+"&+"2632#".'"&#"+"#"'72>373263237>#"&5##"&74654&546727&4654."+›?:DA2 ,' 5)F3 0  ?' !*  T ( # % '%I!  ((<=Uj<0&2R4!- íP5J!  !5("- # &5+ (/$"$” " 4, 1E 1   /8M7467#".'&6;2322+".'.#"#"&+"#"&5/gvX L)7  $,;,  H 47L ;  $GËk: u ' 4.U% $O-&?  /Ç8V7467#".'&6;232232672#"&5#+".'.#"#"&+"#"&5/gvX L)8+rT *?0 1*94-B  63N ;  $GËk: u )5J 2 5+#y "V1"¢=  /ÿ×*8a7467#".'&6;2322272>7632#"'"&+".'.#"+"&5/gvX L)8+, 6 #)5K:  M , 2; $GËk: u )' Z/9  ) 1  $A$   &s7 /8I74675#"&'&6;2322+".'.'"&#"&#"5#+"#"5&5/‚VT L)8;'3B. $#A   +# %B•K”,)^ u(  |{ "R0 32 % /Û8Xd7467#".'&6;2322632++"#".'.#*#"&+"#"&5%4&+23265/gvX L)8+ˆ+ aT&7/A  , : ;  E#$4 %$GËk: u )-L. "T.   _V Ei(Lj4'5>32#"'>4>75+"54?>32;26;2+".'.'"&#"#"&+"#"š) hN-3r:OG+1   2  ' /7-  4    [ 72# þ50t\C   -      5.d, #S0  sO% / 8G7467#".'&6;2322+*.'.#"+"&5/fwX L)7  $'@-    2 :5HL !HÌl: u '  #" +"&Ÿ> ÿߎv4'632326;>7>;2#"&'322+".'.#"#"&+"#"&5467#"'&'&"'#"Ȏ8#! 1'B(+B$    9&/07  $,;,  H 47L ;  gvK  (}# 1 L/ ' 4.U% $O-&?  GËk ` @#BÿümU74675&'&54?656&#&63637632632#"=46=4.#"#".'4&B:   $'OQ33 #& )# 4Q#)   ÝLaS! *k/ 5$ þõ B.¹+(vŠž   nAÿüÑmf74675&'&54?656&#&6363763263272#"&5##"&54654&#"#"5'.A;   $'OR%B7¯ '*99     7'7P .& áJ_S! *k/=0?!   6* R ) # !(ä-8w‰œF,UBÿÛômf74675&'&54?656&#&63637632632>6467>32+"'#"54654654&###".'4&B:   $'MR>b C#!  1 M ~) ;%5O )   ÝLaS! *k/;Cè#   ,3D ¸91y‚    nJÿümJ47"'&5>&'.'&63637632632#"=46=4&#"#"&JG3  $GX14#(7'8J H ]=  HK c( 6&5®7C Ç ,5qX!&  0Aÿü«mM[74675&'&54?656&#&636376326322&546=4&#"2#&5'.26=4&#3A;   $'OQ%B8 eXÎ%@7S $ Ã''1áJ_S! *k/&'&763637632632##"54654&>u=B   $'XE43 + )A229  %   \† F7 H=% )o( 5#0²8?>Ò35 [6 *T2  BÿýmO74675&'&54?656&#&63637632632#.54654.#""#"&5'&B;  $'OR22  * )&6R(  ÞL`S! *k/ 4#b  r&0 sƒ© ""0Q>±Cgs4&54;2+"546"&547#+"&'&54654.#"+"54&5'&54>32;26;232632#"&#"7"32654&L  0 1r)5]7 .#7M 9  "1V5Jq^/  ( 2 +54+ 5 .9"!#  7S Lþw5'yY+E92;22€B$¤ 6F9'SH6(&7•!! >ÞCx4&54;2+"54647#+"&'&54654.#"+"54&5'&54>232>76;2;2632#"&5#+"&L  0 1*i7  )7M 9  "2VjQ(fP   [ 0.8.G  7S Lþþ &Uf+E92; $*A$¤ 6F:(&8.', 2 7* Qÿ´oCl4&54;2+"546232?674654654&+"+"&54>3232+"&54674'"&#"&'&654.7632_  0 1i@XO ) 8 *L0Wx9  6  ˆ=$(    7S LþC kOK8QC ;PA.s]Æ  1  / :26 Qÿ³×Cmv4&54;2+"546##"&#"&#"#"&5&6'&6323267654&546=4654&##"+"&54654>32324&+326_< 3xYi (/:#0$ $E`A2-0 8 )U8Wy!.:(f%5  V Lþ“.  *. < $ %&IYœ7    M[?t^ l>hCq4&54;2+"546"&5"#+"&'&54654&#"+"&5.5>76322;254654.'&;22632L< 3×(8™ 7 5*'.! 7 =08F4[  N% T * V Lò9) 33PY1?J,+(L*W9º  ¹Cn &-) 6 <,3  ÿüµ—‚63237>322#".'&#632#"=46=4.#"#".'4&54675&'&54?46'4#&##"+"'52654'5632À} gD) 00& 4OQ33 #& )# 4Q#)   :  . $_&#/*=#. n/ 5$ þõ =.¸+(vŠž   nLaV  .%  ÿü€—“63237>322#".'&#63272#"&5##"&54654&#"#"5'.54675&'&54?46'4#&##"+"'52654'5632À} gD) 00& 4OR%B7¯ '*99     7'7P .& ;  . $_&#/*=#. n/=0?!   6* R ) # !(ä-8w‰œF,UJ_V  .%  ÿÛ£›’4'5632>?>32632#"'632>6467>32+"'#"54654654&###".'4&54675&'&54?46'4#&##"+"'526?#/*-? v%   7)I:MR>b C#!  1 M ~) ;%5O )   :  . $_&$%  - 4x/;Cè#   ,3D ¸91y‚    nLaV  . ÿüµ—u63237>322#".'&#632#"=46=4&#"#"&547"'&546=4#&##"+"'52654'5632À} gD) 00& 4GX14#(7'8J H G3. $_&#/*=#. 'J( 6&5®7C Ç ,5qX!&  0E]= r  .%  ÿüZ—zˆ63237>322#".'&#6322&546=4&#"2#&5'.54675&'&54?46'4#&##"+"'52654'563226=4&#3À} gD) 00& 4OQ%B8 eXÎ%@7S $ ;  . $_&#/*÷''1=#. n/322#".'&#632##"54654&>#"&5&547"'&547"'&?6&'&##"+"'52654'5632À} gD) 00& 4XE43 + )@229  %  =B . $_&#/*=#. L ( 5#0²8?>Ò35 [6 *T2    \† F7J) .%  ÿýµ—|63237>322#".'&#632#.54654.#""#"&5'&54675&'&54?46'4#&##"+"'52654'5632À} gD) 00& 4OR22  * )&6R(  ; . $_&#/*=#. n/ 4#b  r&0 sƒ© ""0QL`V  .%  ÿü6—¡®63237>322#".'&#63222636322632#"&#"#"&547#"#"=7654&#"##".'4&54675&'&54?46'4#&##"+"'52654'56322>4.#"À} gD) 00& 4OQ32V+  /0 )55+2 0 )4: / ):%5Q )   :  . $_&#/*Ë#=#. n/ 6% 6$)77'¨ @pp:2vŠ    nLaV  .% þD " ÿüe—¶2>72326;>32#".'#"63232>76;2;2326#"&5#+"&546547###"&=4654654&#"#"&'&54>7"#"5>54&#"&#+"'5>54'6323È ?. [ C1 ##'&\G21] P8„ -)9.L^  >"4S .  "6  O-  7 >%.  V. 6%((* T   7+ † $! Â7/x…,FV6V" v ! ! ÿÜÿ´Ç—¢2672326;>;2#".'&#63232+"&54674.5##"&'&>'&632323?674754654'.#"#"+"&7>75#"546'&"##"&#+"'52654'56323š:A [ D*5"&% 4+8Zw9   6 Ig8+&   :X1(4 ,2#)$  #O-'#3! > #. _#s]#£  0  / 1;   @8@('{;2 -)v s! #ÿÜÿ´/—Ÿ¨2672326;>;2#".'&#63232##"&#"&#"#"&'&?654&476;32676=4&546=4654&+"&5675#"546'&"##"&#+"'52654'563234&+326š:A [ D*5"&% 4.3W}!.:(Yi /+8%(  "  ]I+$14H)$  #O-'#3! 0%5 > #. _#q[  .   &/   $ @^wi¶- s! #þUl ÿü —Ÿ63237>322#".'&#6323265654'&;22632#"&5###"54654&#"#"5'.54675&'&54?46'4#&##"+"'52654'5632À} gD) 00& 4OR8]) M P 2*8 £  ( %<#5Q G' ;  . $_&#/*=#. n/30- <  2 6+3¾5I.¼25/v‡ž F,UJ_V  .% @YÄÚ4BQ2>3232632;#"+"#"&+"##"#"&5467>&#"326%4&#"327>@ 1  XZ""-a+  *   NT!s4; … 3, !/:& = "Î7>;23#".'"#&5"+"#"&#"#"54676327>76&#&#"%4&#"327>.7! hf//.  A& 9 :%( A =   -K•&$@$R<2 %:¸:& = "Ð ;UAv /  h(„$@þï;ð /6.{A2 c7ÿìƒ3J\2672632#"&54632654&#"3263>32#"'+".5>7#"&54>32>7"&#"('4-@T %?', ?(# @HC.3,FU 04)134 £"M&,&7ÿþƒ3BT"547#"&54>37263>67>32#"54632654&#""32>7"&#"!!?J4L=1  2=VX3A  =& -  ) )" $7" ß =2/DM9#$,0 <@*9XþÁ g"M&,&Kÿþv4ER^"54?67#"&54673263>2>7625463>74&#"2#"32>7"2654'4&+:=Hwk  "P=5 G )<!    "=<$=9!DŒ+  :SÙ#"*# !%{: ;2BY!1))-$#SABx< %  g" "I&Yþ’ L @YÄÙHUh26;327>32#"."#"+"#"&#"##"#"&5467>&#"326%4&#"327>A %pYG C- -3! !%<(! <!PR#s2< … 3, !08& ->"ÎHE  # 6K',90p%1þ¸§:#º?5Þa4’)1<H7"=4>?67"&54>7326;2#&+32674&+2326D/A+'n_ /S6 'Wi_9% G_1 5 9G3$Ý*3 3# %!#) :$"/'P?>T -::$ è;6 !=58&”A2Nÿïý2".547676632+"73>76=4654.'!*;| .0P8J" s *2A)(SAM8{A[  EP2Žh' še /.(:8%2ENÿîüý0H"&54>766322672#".5+"73>76=4654.'/ +?9#-&-)‚  2&0 R4MR*2A)(TwxAb;&  6$70 *( †p ›(= /.(:8%2F<ÿÖãWJ[4.547#"&+"&54632326327>3#"'"&+".'4654?6%326>54&#"È  %–4@›z¤(?  E]H,"2%T:  B  <þÝ" <+4Nb( :,L^v'M# œ  "- 2   †@‹!, S./K<0W+<%"74?6.547#"&+"&54632;2#326>54&#"…' R  %–4@›z¤(F g þÚ" <+4Nb-¹:,L^v'M Ü §!, S./K;™NASb4&5465+"#"&5467632;23+"#"&+"&546?>'2654&#"3724&'"&"3256È#!‚95&?OY#C * #ŠA?  8 6 š?4L#*"+   K1H <(1=#F-P  @$  }$!::?$6 .& #1þöQ% AÿóÌ0-B7467&/.5&6;2&"2"#"&73267654654.'A@Z @   (Z :,n #8g: E1+Ÿot, !=5%$:$$+ #OX{^4 -; >R@C+N(57"&54>767&=47>32+"+2654#"t!C.Mr>YO H1A{ §F4u 8E@N)($,Q63?+‚S  +EJ~x ]"ÿþÞF7>4.76?2632#"&=67###"5454'.>32¸ ¾ &$ .  80¿   % &/ B*³H K()#þ¸$"" å!¼#BJ$ "ÿþ¥\7>54/&763632>72#"&5#"&547###"5454'.>32¸ ¾ !#g. *(;=  $#¿   % &/ B*³H K$ !"¥0 5+M.(*Þ!¼#BJ$ "ÿغY7>4.76?632?267>32#"'.#"&=4?##&5454'.>32¸ ¾ %% . $  C% *1;e ¿   %/ B*³H K("#!þ¬  "" "&F¤!¼#)J$ "ÿþÞF7>4.76?2632#"&=67"#"#"5654.636372¸Ç &$ .  80$  K(. 9À d K()#þ¸$"" åD  ?æ  $"ÿþŽJ^7>54/&7>322#"#"&547###"5454'.>3226=4654&+"3¸ ¾ = Ô"4&!E$¿   % &/ B*"+"!+  ³H K$ & %‘BK   ò!¼#BJ$ þ(% ÿýª`2>74654/&763632#"&=467##"54?654&+"#"&54654&546326ó÷B& *  O###!þª&æ Ú #BC¸A "% %6  1"ÿþÞD7>54.7>32"#"547###"5454'.>32¸ ¶  D).) (¶   % &/ B*³H<1>ð 9&g!¼#BJ$ "ÿtµs7>54/&763263232>?6#"&5"#"'#"'#"&74654&7>2727&54?"#"#"5654.636372¸Ç  B+/ ;; " )*9 0  : W -* e&  $  K(. 9À d L$B"þ¸$ 17) !) 1 ?°D  ?æ  $&ÿý¡5j?>?2632#"&'6"#&=467#"#"54?654&#"#"&=46'4&54>76;2ƒÀ =' s1 .&8&! , #%#$   #   ! '  <+&":S*3##M%.+2 5' 4þÛ(A Í ë#D F·A $# ?2632#"&'>2#"&5"#"&=467#"#"54?654&#"#"&=46'4&54>76;2ƒÀ =' s1 .&8  7f* *(;/ $#    #   ! '  <+&":S*3##M%.+2 5'%&H$0 5+SR!"Ö ë#D F·A $# ?2632#"&'7>467>32#".#"=4>7#"#"54?654&#"#"&=46'4&54>76;2ƒÀ =' s1 %&84!   9+ ,6%  _(  #   ! '  <+&":S*3##M%.+4 5'"3ãF   " B ~P ë#D F·A $# ?2632#"&'6"#&=467#&'4&5>54&#"+"&=4654&7>76ù.\C† =' s1 .&8&! , #%#$ œ  I   & +}÷*@ M%.+2 5' 4þÛ(A Í  * /;]&! &9  4 &ÿþ¡5k}?>?2632#"&'2+"##"5467#"#"54?654&#"#"&=46'4&54>76;226=4654&+"3ƒÀ =' s1 .&84Ó%5- #)  #   ! '  <+&":S*3##+"!+  #M%.+2 5'"0;n?M AÎ  ë#D F·A $# 7635#"#"'"&>54&=43232;2326;23>7>32##"&+#67267>?2>72#".'#"54&5467"#"#"5454#"¡)#4S ,'+  4'>, - # A'3 %(!6 #]KD, @2 (#,1 0 %# '!)f   ^%.-$ =   A   !+# "-"  8  ,! "'3 &  -&% þê  @ Ö$  !@!6=< &9 &ÿþ¡4q2672>?>7>32#"&'&5467#"#"54?654&#"#"&=46'4&54>76;2ƒŽ *r0 3&9" ( !'¶#   ! '  <+&":S*3## )'1 5'  2¨ !kë#D F·A $# ?2632#"&'2>#"&5"#'"#"'#"&'&>'&7>;263&=467#&'4&5>54&#"+"&=4654&7>76ù.\C† =' s1 .&8.# " $F44 +(: '  . I& &  A6 !œ  I   & +}÷*@ M%.+2 5'$Å   : 6*#3 #   Ü   * /;]&! &9  4 0¾(-;##"&+"&=4.54>;2'">74¾£} %  '! #:eB;2#7272632">74¥)9   - 15qQ65'4F-! ## e *œ'3"7Q%i5,`9d"6)!;<$$(@$     1 © E/'5).0†(M[%"&45#+"&=4.54>;2#254&76;2326#"&5">74U C )7sQ @3£} &B 7)‰ 1*:¿'3"7Q%z B&T1#!::"'Mf# ; " 7+˜ E/'5).%ÿÞOD*<723267.54632#"&"#"ᘖ'56">54&!E 4"ˆo–¡€]@  BTC6*K!4)8- g ^W-`v\Mgº  5-"Ç ,7&!:%&0L(IZg%"&#"+"&547&'+"&=4.54!32#3;26322632">54&"32654. = ( #<"   4 <1¦y$ S 0. !'%þù )!.G'"ƒX ' L ' T /&¾'Ne&   '&º">( #+ þ· 4ÿñiDBN72727.54632#3254.76;2+"'#'."&546'&>2"654&m5.,Šn•¤z "+@ + 7>)F#-5(*"(; »| %ž4Xu]Mf&:& O 8 !&  #> ; ²+@2$†%0š(GU"&5"#"&##+"&=4.54>;2>2%">74X*9< $-Y5% +8oM<-++Q0' 2þº'3"7Q%8)"] 'S'8*::$&5.   ü E/'5).%26DP72;27.5&>7632#32>#"&5'#"&546'4&5&6">54&VA(B - AGEŸu ; C'.':4:)1" ,D3?+%› _F$ "-Lg\  2 6, 0< ;  …Uh"B++ÿþGDkz2;27&54>32#326?632326#"&5#"&#"#"54654&##".#"&=4654.76%2>54&#"W"B6*DE$©%+)( ,3„  )):6  H l   ;#3 .6'(./ ; 86+>Z* #*! 6, )D%  # ¼    +2 2 .7")<,7+ÿÙ/Ds‚2;27&54>32#263726326372>32#".'&##"&54?6&+#".#"&=4654.76%2>54&#"W"B6*DE$©%+)(   ($ O  =3& 4&' 2* , L   ;#3 .6'(./ ; 86+>Z*   È  -  &v  +2 2 .7")<,7+ÿþ`DRa2727&54>32#32637632#"#"&54?4#"#".#"&54654&76%2>54&#"V,; 0*DE$©%+)( #("  4 3  0n   <(1.6'(./ : 86+>Z*   Œ .  (8 8 /7")<,7%ÿû£6FR\72;27.5&>7632#3632#"&#"#"&547'#"&546'4&5&6">54&"264&VA(B - AGEŸu ; "77C;(! 2 ) (¦5:)1" ,D3?+%š,› _F$ "-Lg\>%!))" 0< ;  …Uh"B+þc"*%Å6Xd72;27.=4>3232672#"&5#"'"#32>#"&5'#"&546'4&5&6">54&VA(0+0eIHF,1B. *+7A  $)T4 ; C' 2':4:)1" ,D3?+%› DN#?A'"-412 7*\  4 6, 0< ;  …Uh"B+QïE>N7467&54>32632#"&5"/.#+"&">54&QmbA .T5A`:WD?:,J" 0,:: =K  *c/?)<(/I…AL$3*)04L% * 5. }DXD #!( '+ÿtD‚‘2;27&54>3267>363232326#"&5#"&#"##"&'&654&5467263&54?654"#"'&#"&=4654.76%2>54&#"W"B6*DE$¨$5C4   "H 3 )):B6 3 15( 1T6 ;o$  9&1 .6'(./ ; 86+>[$7  ½  1 6+#Q 7     +  (5 2 .7")<,7%ÿ‡l.^h46;2"+"&5232>7'&54632#7>32#"./&/&/"&##"&546'4&5&"654&1 .  0Ú#>!aQ97!‹i4s7 )( .%7 " 031" -D/ 8 þ9 dF1Tp +FSš' 2    F ; “‹$h#0ÿŠï=s‚4632;2&#"&52327.54632#3263263232672#"&5#"2#"7>'&+#"&'4654.76">54&  1  1Ó-;-)+v_«”k &:51B. *(9 . Q 8 %81# ,&.. %.)&% 7 þ‘ s'BQZFS' 2 8*0Œ'² )  2 =<-0/)ÿfÙ=|Ž4632;2"+*&454654&4763223>7.54632#3263?262676323+"'"#"#"?654&"#"#"&"7>54&  0  1 þ =#%&-xb¥1M5"## % %. 1 T  1 NN9  =  w!<(1D &'(%  9   þ#3 w'CR\*= ? >0 -3»  )9· 3"6 %&ÿŠ=\k4632;2&#"&52327.54632#326376322#"7>'&+#"&'4654.76">54&  1  1Ó-;-)+v_«”k '"#; Q 8 %81# ,&.. %.)&% 7 þ‘ s'BQZFS>·"'² )  2 =<-0/)%ÿS£.Zdn46;2"+"&5232>7'&54632#2637632#"&#"#"&547'#"&546'4&5&"654&"264&1 .  0Ú#>!aQ97!‹i'  E<(! . & ',Â031" -D/•* 8 þ9 dF1Tp +FSv *>&!))6( F ; “‹$h#0þ0,%ÿ‡þ.q{46;2"+"&5232>7.54>3232632#"&5##7>32#"./&/&/"&##"&546'4&5&"654&1 .  0Ú#>!&J3£ 0U()8De4s7 )( .%7 " 031" -D/ 8 þ9 XK#??(] "5,>Rš' 2    F ; “‹$h#04ÿŒÒ=O^4632;2&#"&5467.54632#632#"&5"/&#"#"&+"&">54&N  1  1þæhh!!zb£“k2d2O ,'78 1Y   &b.. %.)&% 7 ýÏJz!`#EO[ES*  3 9* tR  <-0/)ÿX¶vxˆ46;2&#"&527275.54632#32632326#"&5#"#"'&6'&7>3&4?654#"&54654'&6?>54&#"326 0  0Í,5*&-yc£’l%A66 0’ +'9y$C2%'' ›.+.+& 9+1Ô8Y%'5 _8 þ‘ v'DQ\DS? ˆ  2 6+  00D  $k$   < 3x B4(559%ÿ‡±‡F™2>7>;2636?2>76322+"'"+"'&67"">54'>232>7'&54632#7>32#"./&/&/"&##"&546'4&5&"654&§B 1 )     $. L 7 9 5'Z! 37#>!aQ97!‹i4s7 )( .%7 " 031" -D/_3   03 =6)"" ýº dF1Tp +FSš' 2    F ; “‹$h#0ÿŠï•0Ž2?327>;2#"'+".>7##"'5>54'62327.54632#3263263232672#"&5#"2#"7>'&+#"&'4654.76">54&ŠBI'wD* ;+4IS 8 4P2  -;-)+v_«”k &:51B. *(9 . Q 8 %81# ,&.. %.)&n3 # ,!3L#! #þ s'BQZFS' 2 8*0Œ'² )  2 =<-0/)ÿfÙ•<Ÿ±26>;2".'&+"&547&#"'5>54'6323264654&4763223>7.54632#3263?262676323+"'"#"#"?654&"#"#"&"7>54&DDI D*$ 8:&  ( 7 '  S!  3"# 2&þå =#%&-xb¥1M5"## % %. 1 T  1 NN9  =  w!<(1D &'(K #/ D7 # ýÆ3 w'CR\*= ? >0 -3»  )9· 3"6 %&ÿŠ”•0w†2?327>;2#"'+".>7##"'5>54'62327.54632#326376322#"7>'&+#"&'4654.76">54&ŠBI'wD* ;+4IS 8 4P2  -;-)+v_«”k '"#; Q 8 %81# ,&.. %.)&n3 # ,!3L#! #þ s'BQZFS>·"'² )  2 =<-0/)%ÿS±‡F‹•Ÿ2>7>;2636?2>76322+"'"+"'&67"">54'>232>7'&54632#2637632#"&#"#"&547'#"&546'4&5&"654&"264&§B 1 )     $. L 7 9 5'Z! 37#>!aQ97!‹i'  E<(! . & ',Â031" -D/•*_3   03 =6)"" ýº dF1Tp +FSv *>&!))6( F ; “‹$h#0þ0,%ÿ‡þ‡F¢¬2>7>;2636?2>76322+"'"+"'&67"">54'>232>7.54>3232632#"&5##7>32#"./&/&/"&##"&546'4&5&"654&§B 1 )     $. L 7 9 5'Z! 37#>!&J3£ 0U()8De4s7 )( .%7 " 031" -D/_3   03 =6)"" ýº XK#??(] "5,>Rš' 2    F ; “‹$h#04ÿŒÒ•0jy2?327>;2#"'+".>7##"'5>54'6467.54632#632#"&5"/&#"#"&+"&">54&ÄBI'wD* ;+4IS 8 4P2  Vhh!!zb£“k2d2O ,'78 1Y   &b.. %.)&n3 # ,!3L#! #ýNJz!`#EO[ES*  3 9* tR  <-0/) ÿX¶À<¡±4'6323?26;>7>32".#"+".6=#"'5>27275.54632#32632326#"&5#"#"'&6'&7>3&4?654#"&54654'&6?>54&#"326E)-"  -B" B&   (6%  ?8 6 V0 "+5*&-yc£’l%A66 0’ +'9y$C2%'' ›.+.+& 9+1 Ó8Y%'5 M 0  : 2""þ‚ v'DQ\DS? ˆ  2 6+  00D  $k$   < 3x B4(559#ÿþ°52%45.'""&=4654&54673>3"#"G4$9+')?'61LH  (3d$: -J0  K0þ’#ÿþ‚5G"54765.'"#"&54654&547263>72#".'"(& 44$B#'{T&0MF]$ 3 #3   6B $: 5D4 K0˜ 1 * ¤  #ÿÙ5?%45.'""&=4654&5467376322>7>323#".#"H4$:+%+=-,.TH*E4:+4& §)3l $: .J0  G8þ“ % '%ÿÄB2C4.#"#"&'&676&54>7632##"&54654&7>;2>54&5Ú" H&  *j%$+$M )8^iO;+,g1Ke6¬ 0  >: 3 :0Y:Q;$*P 4 "CO6!!#ÿýE57E2#"##"54?654&##"&=4654&546732634&+;26¯2rX#6%! *& )7% ;,%+<W#0M/!/ '´ ó.:.Øb @:G4  J2þ¢?'ÿý$5/:&54?65.##"&#"#"&5463226322654&"˜# 14'!6-3'bM!#j,OGJÿ&"2 >þ#<'*4 *;HE7þŠ ›)3ÿýêP<4#"#"&=46=4&767276=4&7>322"&54?>‚i  +' X+ EJJ >U) ˜. %+3 +& H&Fù" Tà )#ÿþ@5O\%45.'"#"&54654.7673>3;267232632#"&#"#"&547#""#""32654&G4$B#'U)71LU & 9 *47- - 0 )3e * ( +!3d$: 5D2   I6l  6R38% ×6###ÿý<5d$4?4&'"#"&=46=4&547263;24654&76;222632#"&5"&+"5467###&$%5$2%&{T&5H A  ) ,6P -*9;# B/  M#»º'9 332Q+.&2 2p1 7, 5+Îô5Z4'"&##"&54654&5473263232+"#"&=46'&+"#"&'4654&54>?>II G(^y0G?654&#""#"&54654&54673>;22#"74.'"3256¿1GD2&$""b,  d7$!"& %(?=U 5KLG_&7/<  (FY  88 >   =ú 4 %5  2 H& Ë*! M=% #ÿýå5Z$4?4&'"#"&=46=4&547263326746=4&76;2632#"&5+"+##&$%5$2%&{T&5H 8  C U 3,7 !W/  M#»º'9 332Q+.& H ,=1 9/+ÎÿöÿþTÈ1d654'56323?267>;23#".'"#"&#45.'""&=4654&54673>3"#" 7),/˜,  D' ;$' ä>+FG4$9+')?'61LH  (# 0!   - þd$: -J0  K0þ’ÿöÿþ¼È1y654'56323?267>;23#".'"#"&#"54765.'"#"&54654&547263>72#".'" 7),/˜,  D' ;$' ä>+l& 44$B#'{T&0MF]$ 3 #3   # 0!   - ýÜ6B $: 5D4 K0˜ 1 * ¤  ÿöÿÙÉÈ1q654'56323?267>;23#".'"#"&#45.'""&=4654&5467376322>7>323#".#" 7),/˜,  D' ;$' ä<,EH4$:+%+=-,.TH*E4:+4& §)# 0!   - þl $: .J0  G8þ“ % '%ÿÄŽÈ2u22672>7>32#".'##"#"ᘖ'56"##"&'&>'&54632632##"&54654&7>7654&=4&ž!) ´  D% *1'  ZQ$+6) $ '  I*^!2R2a{`;+, i|ƒ8©  "    1!¡!2  ?H CX; *P 4 .00Z <4ÿöÿþ€È1dr654'56323?267>;23#".'"#"&#45.'"#"&54654&54726322+"#"74&+;265 7),/˜,  D' ;$' ä>+EH4$ +&z\-Q2m^%8,#)#&Þ#1 +# 0!   - þc $:  %* 1 H6þù -!`9ÿ÷ÿýTÈ/^j226726&67632#".##"">54'56#&56?.#"##"&#"#"&546322>322654&#"d@ ´! :*6 $  ZQ8,*¢J$04'!6+5 'cK&:;5Lþ‡©2    )"  "ýœ7Lé#<")6 )":G Q**)ÿèÿýFŽa267>77>;2+".#2"&54?>54#"#"&'&6=4&54632676=+"'5>54'6U@ ( - 8A1 *4#  &JJ >U) i B$'R &6 Q0 !p3%#[&Fù" Tà ).5D4  >""?ÿý¬g463>2632###.=4&'&#"#"&5465?#"=46567>d & 259g " .F)   C 2# =)›‰ =/&“ +      *r]3  "®   Gê#&'$!    >V-O^?ÿýó¬ˆ463>2632767323#".'&#"#2#&=4&54.'&#"#"&5465?#"=46567>d & 44(8/$A ^)6%   #&$ ,:   C 2# =)›‰ %E,7  D" . 4PX' & ­   Gê#&'$!    >V-O^?ÿÖ÷ªu463>2632?>76;2#".#""#&=4.'&#"##"&5465?#"=46567>d & ):6a   <&& 52% -7   F 2# =)›‰ 6..Ï    1 ;3Z`(þì  Gê#&'$!    >V-O^>ÿþñS4>7467232##"'454&'#"##"54?67"#"#"54&>8ab96WpL (*9_R' ! ) :E3 5'49R*92‰   ,]-6 Ö  5 -e#"F.  5?ÿýתdv263232+##".54'.#"#"&5465?#"=46567>3463>4&+;265¾-67c#3E/&8)) $B)!  F 2# =)›W µ"0' (£7/)x # Ï$( þì  Gê#&'$!    >V-O^ þº  1ÆC465""'+"=>32+"=.'32+"&54?#"&62?+ 0·‹BcO:3 +0)) 9 ( Ua/ E0  (Ij(M2 "4 ;R ßK :ww?ÿëþÜP"=4674326;232623##"54654'"##"5467"e&Ÿ†;  BQH $,°  % ( %5,# <¶Õ  2'a 9lc  1Ÿ 9Ê '>sK/?ÿWõ‘463>>323267263#"&5"#'"#"'#"&'&654&7>;263&=6.'&#"6##"#"&76567##&546d ' 6a [1 3(:*  . ;34& " <-)/    ( Zb-¥l   :/+¤', 7)Q 4 #/O=1 n  P] ‚C n‡?ÿý)Àkv‚263232+#"#&=4.'&#"32+#"54654672+#"#&5467>34632>4&+32546%4&+325464&#"#326ø ;M+K1 SO!0& 8%4H; XM!0& Z) V‰^P!0& 8%"™z ã%2 #?ý4%#?P'#$¢,*$+m/! 9-JZ3 4 BC . 0 (é"lU-! =H[$1TþÄl+ -?+ l?ÿýaÀ~‰• 26326;2672#"&5#32+#"#&=4.'&#"32+#"54654672+#"#&5467>34632>4&+32546%4&+325464&#"#326ø =J9kKD' -)9jSO!0& 8%4H; XM!0& Z) V‰^P!0& 8%"™z ã%2 #?ý4%#?P'#$¢,6* 2 6,2r/! 9-JZ3 4 BC . 0 (é"lU-! =H[$1TþÄl+ -?+ l?ÿŸkÀo{†2632;2632#"&5"&#"#"&=4.'&#"32+#"54654672+#"#&5467>34632>4&+325464&#"#326ø =JM‚[ *(: - !* 3I": XM!0& Z) V‰^P!0& 8%"™z é%#?P'#$¢,\Y8o,  1 8*,_e 3#. 0 (é"lU-! =H[$1TþÄ-?+ l*ÿýá]lx‚>34637632632322+#.5?=4#;#+"&5467#2##"&546574#"326546!4&+232654&+326514Q…X& 0$ Ñ$UL87J  -ì !.VF**$ _o=QVF_»> &_'(B"& "&N//  }Ø /% ;b'L "*  º4 *#") + /- lØl?ÿýúÀ…‘œ¨³26322;>3>32+"#"&5#32+#"#&=4.'&#"32+#"54654672+#"#&5467>34632>"32654&4&+32546%4&+325464&#"#326ø =K|I ;# B'53<O "9JSO!0& 8%4H; XM!0& Z) V‰^P!0& 8%"™z [! "!%2 #?ý4%#?P'#$¢,m 7)#8.5Q>(#"ý.)"w& )S0 =Wj8&-0³Û 7I /");b45 F. 7 À' I[E/% ;Î '!&Fu 0  + ?ÿQi£|Žš4>3766323262#"&5#"'"#"'#"&'&654&7673>7&=4'.#"32#+#"5465"2###"&=464&#"&#"&6;265%4.#"#326ž , 9NMƒ Œ( )(<*  , <9+ )"  b %R.BUJMO#& ‹O^J <) #?¥3)#!B)l  ,^Y?h+ 0 5+*D 5&µ%(- 8.1 $ ã o/}‡Ïp  lF6^S`74675.54>76=46;22#"&#"#".5.'4&+"+"2654&#"FY698*11 8 8ZM`NO  >F  ..Ò\B%/ 67@„A('4 + 991*>$ *)   D v6 2=$(%'# $3Gç^_l74675.54>76=46;2232672#"&5+"&6'.'4.+"+"2654&#"GW798*11 8 8ZM`Œ$&m .-9C  413F 4 ,Ñ\B%/ 65BƒA('4 + 991*>$   1 7(J!%F u:2=$(%'# $3Fÿ×%^er74675.54>76=46;223272>7632#"'"#""&+".5.'4&+"+"2654&#"FY698*11 8 8ZM`nP  )5K%   ?L ,/Ò\B%/ 67@„A('4 + 991*>$%G" - 1  R mA2=$(%'# $386^_l74>75.5472>54=46;22+"&6'.'4&+".45+".72654&#"8#3( (7… 0 z304¦  3&I ,*   ;êM;!(*5–4 <)]. % W /  6?   %G  - «6*#- + #5FÛ^Q^l74675.54>76=46;2232+"#"&+./.'4&+"+"&2654&#"4&#"#3265FY698*11 8 8ZM`RQoW^(  $$MF  <Ò\B%/ 6s' $5B„A('4 + 991*>$- * "N w5 =$(%'# $3Ö,+Fæ^kx74675.54>76=46;2;2632#"&5#"2#"&#"#".5.'4&+"+"2654&#"FY698*11 8 +0; \ 1*9: ŠNO   >F  ..Ò\B%/ 67@„A('4 + 9 +1 5+/4 *)   D v6 2=$(%'# $3F^CP74675.54>76=46;22+"&'4&54&+"+"&2654&#"FY698*11 8 8ZM`ZY -/OE  <Ò\B%/ 65B„A('4 + 991*>$% /  x5 =$(%'# $38ÿv^ƒ74>75.5472>54=46;2237>32#"&'"/##"&'&6'&>7267&=4&'4&+".45+".72654&#"8#3( (7… 0 z304zV"N)&6,< I$ & $DZ%N ,*   ;êM;!(*5–4 <)]. % W / 'D0 0 8&  "2 =  P  - «6*#- + #5F6 HU74675.54>322#"&#"#".5.'4&+"+"2654&#"FY698'??" >?&,/INO  >F  ..Ò\B%/ 67@„B($5 1!2 *)   D v6 2=$(%'# $3Gç Ta74675.54>32232672#"&5+"&6'.'4.+"+"2654&#"GW798'??" >?&,/IŒ$&m .-9C  413F 4 ,Ñ\B%/ 65BƒB($5 1!2   1 7(J!%F u:2=$(%'# $3Fÿ×% Zg74675.54>3223272>7632#"'"#""&+".5.'4&+"+"2654&#"FY698'??" >?&,/InP  )5K%   ?L ,/Ò\B%/ 67@„B($5 1!2%G" - 1  R mA2=$(%'# $386 HV74>75.546322+"&6'.'4&+".45+".72654&#"8#3( *4[jXl214¦  3&I ,*   ;êM;! "5–4 >(1NA8 0  6?   %G  - «6*#-%#5FÛ FSa74675.54>32232+"#"&+./.'4&+"+"&2654&#"4&#"#3265FY698'??" >?&,/IRQoW^(  $$MF  <Ò\B%/ 6s' $5B„B($5 1!2- * "N w5 =$(%'# $3Ö,+Fæ [h74675.54>32;2632#"&5#"2#"&#"#".5.'4&+"+"2654&#"FY67:'??"Xk; \ 1*9: ŠNO   >F  ..Ò\B%/ 67@„B($5 ?41 5+/4 *)   D v6 2=$(%'# $3F 8E74675.54>322+"&'4&54&+"+"&2654&#"FY698'??" >?&,/IZY -/OE  <Ò\B%/ 65B„B($5 1!2% /  x5 =$(%'# $38ÿv lz74>75.54632237>32#"&'"/##"&'&6'&>7267&=4&'4&+".45+".72654&#"8#3( *4[jXl214zV"N)&6,< I$ & $DZ%N ,*   ;êM;! "5–4 >(1NA8 0 'D0 0 8&  "2 =  P  - «6*#-%#5Zÿíè/B74&547>632+"#".7>?26=4.'32676=]‘":/L'+(Š% o] # #   ^%£—9Ò:@J7Š|(7=E« "!!+!bÁ/)=& %#[ÿîí0DT%#"&5+"#"'.54>326322672%>?26=4.'37>765í)(9A+:$K .?85EDu  ýß] #  ! ªK=+(D %» 6+U +UeCj@)I="`"Z "*7 ) 3G -@f""ÿáA&8LU7"&54>7>7"&54>726327>3#"'#"&#4.#">72632765ä 7j„!G/*AT FXH-!"2,J(   ¦ ¾I0"  )!z8-(2'[0 >¢:-  !+ 3 ¿  ;,%M&"°&%8B7"54?>7"&54>72632+4.">72632765à& >h† H2()@ ,4 NX( w ¾+2#!./Ž7-'3'"2) 3X€?  ¿!$;' O! "&)=FS74>7".546726322+"+"&544.#">72632765"232654&Í %LM0YM(?W\Lr%6+  E  ¦ ¾I0" *"s B) +2W Y- $Ð#*  —  ;,%M&þê#<  Aÿõ¾0/@J2&"2#"'.54767&'46;2654&'.'>2=!  (Z .-@$/ >)% @ $   VPª:0!=5%&A#2 (@4‡9% { þÍ A *E2à…T'/ @7C+N(/77"&54>767&=47>32+"+.#">=t!C.Mr>YO H1A{ tN#7¨ 8E@N)($,Q63?+‚S  ß(sšM6-ZÿéÈI@BP%#".+#"&4>54.'&6?632>26;2>763%32654&#""Ž*6 '*7³75IA\\A 9 '!;;J!6T" ($ ]! þ7D2;+' 6…*a?j]GEW0A)G:.8-"! 7Q)#203!GIGUg7"'54?>7#"&54>54./&476376326;27>32#"'2+;2>7654'æ  !=/9(88( #*KB !.P-" *2J S:  Q5F  ,  $  C +$";+)5  949 <0  ", s  + %  ÿæŸI>R266;265<62;2+"&#"&54>54.'&476?6.#"#""3265—'7pS=',)$9( @ E(#9_,:NA\\A 9 T 2    7(7$I?5XZC "0*#97  ?W $B54^GFX0  þ,,'"*(%!/IŠH_s%"&'4&5>7"#"&54>54&/.763726>;2332672#"&5"&#"#"+"7>54+1 EB9*==* H %5_ +!& R  2*9 )  ž  ~-$<)(2  2*>=    D1 6, `  E, " #ÿ¯9IIWd"&547"&#"&#"&4>54.'&6?6326326326323263#"&#"%32654&#"2654.#"A-+ #''.6';MA\\A 9 '>^A:1E.  !$-A,2;;þ29#;"%5* $)QA Aj]HEW0>)B@L4#7!*!2J8 ³+$#63(¶  #1Š'i%"54?>7"#"&=4>7632;2#"&547#"2>54.54;2;2>#"&5#"+ >R8/RN:F7 4)AH„*: ++E*6 HG3();`  ?%,O)-7Q0  -(85*K! #? 1 7+ E( *ÿø«J[ev%#".+"&#"&5'&54>7263232632#"&#"#".5476326;2>;232654&""32654&#"  +1$ +%- K).I(9Q3267'>7"#"&54>54&/.763726>2;2>72632#"&5"#"32636#".5"+"&#"#"&5"7>54+"'&(GEB9*==* H %5_ $0  8X  1*9 (c 3%0 = 9@$2  j0   ^-$<)(2  2*>=   ? " 6+[  1 *' 3C±, " #&ÿýÒd@%45#"&54654&54>?>323>;2#"&5#"*R1%,(D-FB2 W (): Y !EÔ 25 3   & 5, þ] &ÿüÒdW%4?#"&54654&54>?>323>;2#"&5767323#".#"&+R1%,(D-FB2 W (): ; ]:*0#*  *J L"ÛÛ 25 3   & 5, Òi6  '%j & #&ÿÖÒdY%4>7#"&54654&54>?>323>;2#"&532636723#"'#"&#"#&+R1%,(D-FB2 W ():$5 m  :$JG  8IOÙ– 25 3   & 5, þB:= 1 3 ÿÑ YQ47""#"&'4676&54726323>32#"&5##"&54654&76;6367>5p;& % m]w& ro 2+8€ ¯d:$% Wp=Xƒ> #4  (2 7( y)\8J[2, #?K?&ÿýÒdDS%45#"&54654&54>?>323>;2#"&52#"574&+;265+R1%,(D-FB2 W (): k]<&""!,"Ì+ (I¿ 25 3   & 5, -¡†:.B) CÿþïeP7#"&54654&47>7>37>323>32632#"&532#".547#"Iz2$&Ã( & U‹  -*:*V(* 2 9%™‹  01 2  2 5,’ &Å50 <ÿý(dW"&54>7674'#"&'&674&546;2?>?>323>;2#"&5##E;]dc ƒ2%&GF& X‰ ():O7Z_f$ 716V5292  11 -   & 5,3,32;&545#"&54654&54>?>323>;2#"&532632#"&5#@#- 7R1%,(D-FB2 W ():%` )(<B9 4 Ù 25 3   & 5, þ]  56,1­qe2>7>;2>7264676322+"'3267654&7>32#"&54>7>5"#">54'56 A 1 )' ! 1 N63td/!‘ L  54&5&632726363>32#+"&+6363>3232#"&+"&'&5467""&'.54654'4.#"#"#&##"#".%4#"#"#326363>2637.ä®*>!/8  :'HE(% *)"4 & ‹  .  :4s$4^N%7 e$D"ý—@I7Q3ZI[A     5  &7 # >9,þÐ-  /‡  ^)˜ +"`5 X 3;˜Î 5# 1ÿæ«qo2>7>;2636?264676322#"'632326;265<62;2+""#"&54>5#">54'56"326=.#"#"¤< 0 )   ! :;&F2/6e'E 6* 9( ? F(>[.:N,BLB,7 T2 ,?!7(7$ 2  I3   '"3 ,T4W '5( 97 =X #B6*O;C;O)"$þ|<((%!/,'0™¸ý-43?632""#"=4>3>72#"=0**   > ;  i Ü>   ?Ö  E C¦™ý,BS4376;2"#"=".54=46?632#"4>72##"=74>72#"=¦ S ? û A =þð3  L è 65 i Þ > ?W> > ƒ 3  A 3A:X\D,A3254>764672"#"=4376;2#&=G )_*! Ä¥ X  ; P  A D    ¨  2  AÔ ??:2]…#9O254?62.4=43764>732#"5"54676;2D)˜#¼" . Lm2  M :" ’< (_+… …>  ?  ï  7 ›    ;iÒ-$=>32"+"=42546>32+"=4Ïd -  ø  -þí Ç3d $   / @ ­ ‡ /@ 0™Ñý(?437632"#"=4&#54?>724672"#"=4&0L , ¡?L*™)þ_!X  : Þ > @ x |  2 A0(¸n+C2#"=4632632##&=46"=4676;2##"§  M  L L >  >n  5   Câ A   A þ¨? ?  0(Šn'=Ui}•2#"=4672.=4376!2.4=437632#+"=454676764672"#"=4&4>72"#"54376;2"#"=‘ L  { . Lá . LÜ ))   Hþ­!X : Ó 68  : é L    W n 5 Ab> ?  >  ?  qA @ ‘ 2 A   2 " =   ?2ÿt|ˆ#HY{"&'#"&'&6'&632632++"&5467>54&/&6;22>54&+"3"&5"&54676&76326329(8 Ê% && -@‚í  3VhU /81-S(  ;3",4%Â"+ 4 l *8Ô +8$ R…æ  *ý3. #3  D' þÓ>O6Da '"  )$$4—-2)>Ž&®6+ #(% '$ #ÿt2–%Q[€#"&5#"&546'&6323>2#"';2654&+"&76;2+"&'.54>32"254&#"&5#"&5465'&7>;263221,8BO13&" 2J j…#!, Hœ,M#)!1 /FecQ'&76323>32"&5+"&5>732632632"&5#"&54654.76;2632M1(<·9.+ b _~)$ a*9p B D x[ & ):š9-, YiÇ ** 5+ 'K "   0í7+þî %   -þg6+ 'K 0'0 LÿtM—&:Jn#"&5#"&54>'&76323>324>3#".7"32654&'&"&5#"&54654.76;2632M1(<·9.+ b _~)$ þ2J>7E.u]4Q- Öo !5,A  ):š9-, YiÇ ** 5+ 'K "   0þô3M&'O5'&76323>32#"'#"&54>54632;232632#"&5#"#"?63>323"&5#"&54>'&76;263231)<·9-& b _~)$  B&0A'77'  5/T 1*95 X'f I- +*8š9-%  YiÆ *) 4, (J!  þA ,%>- ;./=" '71 7+E7%##'$- Æ6+ (K" '$ ÿ`2‹$bu™#"&5#"&'&654.76;26324&'63227262#+".'&67>7654'#+#">4&#";2564#"&5#"&54654.763263220,9\ZH, WjË  þ#3  „ LD_YiB 3 % M/#F, Qž',9\Z% %O|×   6(  ;8 / '$¢ . *"-  6U !"Î) %è 6(  "3 3 '2Oÿ`‹&x›2632#"&'#"&'&676&7>34&#"#"&'&676.7>326263>32726&676;2#".'"#"+"#"=4?6#"&5#"&54654&5432632iÈ )-7\Z$ & DŽ ? 2%( Jh ,(‘2!#  ;)8&  \/ } Î0-8Z]++&^}Ú  d'( 6(  "2    Î   32 )  6è     *"9Òþ$ 6(  *81'1QÿZ‘#s—>32#"&5#"&'&654&76;2"&54>'&54>7#"&'&>'&54326;2632#".'2632#"&5##"&5#"&54654.763232632V}t  )(<{A$-  L¿' (k3PA&& vM1K” * #R0ˆ !.*8TW_3¨,,8| B+% > ( h‰  u 46+D: 5 ýx " * 0C + +þÖ66* 01T 9(-Q3   'OÿtO—(Saˆ#"&5#"&'&654.7672632326322>?>54.7>32#"&54654&54?632>7"&'#"&54676&7>32632O2)9š9-& I AÌ þ“ ƒ N0-=\3@X$) 5) ¡)8™ +%  '&.CÒ ,) 5+ (J 5 ( 247"I9CQG0X ¡ þë&#%=N)#Zü2. #( '2 2ÿ`2‹$Fj#"&5#"&54654.76;2632>54.763732+"&'4&#"&5#"&54654.763263220,9\ZH% WjË  þ 9 ; &5 1`',9\Z% %O|×   6(  ;8 . '$þr è 6 æ   ã 6(  "3 3 '2%ÿd—”"|¢2632#"&5#"&'&654&54324>54'#"&54654&54;2$76;2#"&52+"&'4+"+"&5"&5#"&54654&54;2>32e¯  ));™G' Xv,,`2%&j (*#  1+9a 5C+7 d T  Aw+9j09-%M \{B  1r"+5, :7 4þ5+,;!  112  6+  */*&Ald' #ü6+ (I2  fÿd¥”$b‡"&5#"&'&654&54323263246;2#"+"&'&54654&#"&546323265"&'#"&54654.76;2632^)9™ *' X^» *þÕ]H XR * 6"65Ccg8  !%à*8f37,2 Hx«  0 6+  "' 4"% æFT6Iu $t96H)#2J$ZGTm #F/(aP@þŽ3. 'J2 !1 Hÿf’ˆ&yž"&5#"&'&654&54.76;2632"5&54?67&'#"&546'&;232635465.54;2>54&74;2+#"&5#"&546'&76;2632A.7™2$* N#f³  )P  .?;dJ*$ 5  :  5 HDJC>)(;f3& %$  O#c· ÿ6) .. 2  !5 þW #3  ,K B #V  # : U! Ü ¨ 5* "1 A !&6ÿfüˆ'g#"&5#"&54654&54;26323>2467##"&54654&36;232?6>54.76;+"&#"&5#"&54654&54;263232632ü&-7|++%Io Û% …3'" 8 !#$  C IDÛ0-8|H&KQ£ 7(  )72&þ;† 2FQ  a  ) þì  ˜ 6)  :72! 1CÿdÒ”*j¡Æ#"&5#"&'&654.76323>32"5467#"&54>'&676326;2632#"&5"#"#"#"&546'.5467>3>;22>326#"&5+"#"&5#"&54654&54;2632v )(<™$ ' HTp&$þÌ]% * =N1g” .,6;    é%#5\ N  7  3(:2J% k9¯1);f32$+ Jk¨  ƒ 56+  "1 4  þ¹ Q  !2  " 1 :'8 þË=  Z9s $ 6+&Il 5,// 3 !(1ÿd…”)n{¢>32#"&5#"&'&654&54;2"'#".54>3763232632#"&#"#".547"32>7>32"32654."&5#"&54>'&76;2632éSo%$ /';™$ & M  ÝK2F2:0(7K79 C !19 :#- TST2" /  :* "):f3$ %  Ikª  2r + 6+ !2  4 ýÕ, 6)Lp9$ ($9 '%nŒQ  '%"$ýÇ6+ "2 #  !% %ÿfbˆ&§#"&5#"&'&654&763232632"54?>7#"&54654&5&323?326;>72#".'"+"&5467##"&5#"&54654&763232632Ì ),9¨ *( Zs® þU0 ^2$'f)N8&~ KKA- - $     E4/   `)-8¨2$( Zp² x3 7(  "(3!ýÅ/Gu4 123 % )Ej' û6¿Ÿ 6)  ./ 0! 22ÿd#”(So™#"&5#"&'&654&7632326324&547>32+"54654&#"#"&746"&'4?>32;2#"&5#"&54654&54.76;2632#-(<*`% &  C!^¤ þI€;92 " 3#*   =,(Òc  3Q  1*:f3 ++ He®   & 6+"3 1 " +®  %3  B   *R 0þÎ š  (} ‘ 5, "' 2  !ÿd#”&JX"&5#"&'&6'&7632326322#+"&54654.546">54&#"&5#"&546'4&54;2632â+81Z *'%  E ]¥ -¢¤.TM2  1W| 'MR…1)'&7632326"&54654.'+"&54654.54632!>7&5474632!+"654&!"654&"'#"&54>'&6323>32.c /)9A„ *,  R­ ð  /^wYDþþ!Ä6`tœþÿ"  ,þÔ(D ‚)D [Y šH9-% +Dq“.#  -}+ 5, "' "   ý¿9 &<.AG5%}?0 # >BZ| 6 €6>$Z&57 ['ýÔa (I!  ÜÐ!#5654&'##5>762/ÜÄ.—/‹ €[A#ÄA@EI!A2(õx$¤¤ ™Â"0%+5654&'532'4&#"264.#2>™m@á'&½!:<$d3Go>;C$*34)x;='.& 1#K 9¢7#”,­' ¡ # ËÂ%+5654&'5324#"326Ë“o¾$$µw”X´&!dUßls$.$psÅþªZšÂ+%!5>54&'5!#.+"32673#.+6:>7šþŒ$$n'2ZY()Y *  rr$.#b-•'(¢   ÿ÷Â#"546323254&'53(E=M 'Ô²&û>H2-;% Â5!#5354.'#5>54&'532>54.537 í"HI&Ñ(&Ò'L/1 ²'$z¦  UF‘%)'$%ŒC,9  x²  šÂ%!5>54&'536:>7šþŒ$$Ì$ *! rr$.##þ¿ !YÂ%!#5>5##5>54&'533YÏ(©œž,'šŠ˜”$$(1þ~sþð#/%þ¨X#þÒ$ £Â#.##5>5#"#7!£ &2,'×*$8' N4#þ¦&*S7t ÿ÷ð #"&=4&'5332=4&'53ð+NQTv&Ð%:Az* ³#.²Sb[QÕ%$æ@8’².%ÿòÝÂ"&'&'&'53>54'53Ý €ZB#Ä.a8+/‹³!þ¿2(øu$ð‹tÿò¶Â>#"&'#"'.'537.'53>54.'53¶ Š \ p ‡  ´.*:[ &Ë $!(# {³ þ¦*ï(ð',V  uŽÇ5+ []T[RY ¢Â%!5#"#7!3267¢þ‡ Š/[þóŠE-‡‡•&2vþk(E ‡Â&'3#5>54&'5324.#"32‡/NI)&Í'$Â"<:"P/* qG,:|%('$ 4%( ­ÿë«.=#"&5462326='5##"&5463254&5677'54&#"326ë/!0""z*WY]vY91&V=(—?(,;B1=˜!., !¹+=@ƒ]\š+œ%ýÉ(,æ(54&567>54#53"67ù-!0" Á C[  ê ,h3Œ2Ì/]C&™(+ ˜!., !˜[vµ  â,þ` 3D"Â3 ÿ«*#"&5462326=#5>54.567>7-!0" Ó+"#b= ˜!., !˜)Ý!ý«  ÿæÌB#"&5462326=#5>=4#"#5>54#"567>327æ-!0" ¸(M(;" Ô&# K?;&3 ˜!., !˜&+Ña9þç!(ÿ9O">9&eU  ÿßÂK#"&5462326=#52>54&'3#5>?'.#53">54'5367ß-!0" °  T V(‘r^  Ï+< 9(ž4S5/; ˜!., !˜ † ¥  \ U *xWJL ÿÿÿ¢#fÂý$ÿÿ%ÿºÌ#fIýDÿÿQ!#eг%ÿÿÿöÔ9#eDËEÿÿÿuQ–#eŠýj%ÿÿÿkÔ«#eDý`Eÿÿÿ¢Q–#qŠý%ÿÿÿ˜Ô«#qEýuEÿÿÿ)y#v~Û‰ÿÿÿ)œ•"vï©ÿÿ­!#e·³'ÿÿÿöë«"e>ÞGÿÿÿu­–#e·ýj'ÿÿÿkë«#e\ý`Gÿÿÿ¢­–#q¸ý'ÿÿÿ˜ë«#q\ýuGÿÿÿ)­–#zÂ'ÿÿÿë«"zföGÿÿÿ%­–#X¸ý*'ÿÿÿë«#X\ý Gÿÿ U#C®ZÔÿÿÿö¨,#C^†Õÿÿ U#vdZÔÿÿÿö¨,#v†Õÿÿ ÿ%U–#XŠý*(ÿÿÿ¨Ì#X:ý Hÿÿ ÿnU–#hŠýZ(ÿÿÿd¨Ì#h:ýPHÿÿ ÿ)U[#dŠÃáÿÿÿ)¨‡"d:ïâÿÿ "!#ep³)ÿÿ9#e"ËIÿÿ ÿòÅ #q̳*ÿÿÿ&Ö "qRÇJÿÿ¾!#eÁ³+ÿÿ ç9#ePËKÿÿÿu¾–#eÁýj+ÿÿ ÿuç«#ePýjKÿÿ¾!#j³+ÿÿ ç9#jQËKÿÿÿ)¾–#zÌ+ÿÿ ÿ)ç«"z\Kÿÿÿ;¾–#dÂý@+ÿÿ ÿ;ç«#dRý@KÿÿÿnK–#hýZ,ÿÿÿáÿn+«#hÿàýZLÿÿ<#vÿÚo‘ÿÿ  A#vÿ¿›±ÿÿ"Ói#v®Ã.ÿÿù#v3ÛNÿÿ"ÿuÓ–#eÓýj.ÿÿÿuù«#eXýjNÿÿ"ÿ¢Ó–#qÔý.ÿÿÿ¢ù«#qZýNÿÿ ÿuV–#eŠýj/ÿÿÿu«#eÿâýjOÿÿ ÿuVô#qŠ›Þÿÿÿïÿu& #qÿä³ßÿÿ ÿ¢V–#qŠý/ÿÿÿïÿ¢&«#qÿäýOÿÿ ÿ%V–#XŠý*/ÿÿÿïÿ%&«#Xÿäý*Oÿÿ _i#vèÃ0ÿÿ•#v¾ÿïPÿÿ _!#e³0ÿÿM#eäÿßPÿÿ ÿu_–#eýj0ÿÿÿuÌ#eäýjPÿÿ ÿõÃ!#eÀ³1ÿÿåM"eSßQÿÿ ÿjÖ#eÀý_1ÿÿÿuåÌ#eSýjQÿÿ ÿ—Ö#qÁýt1ÿÿÿ¢åÌ#qTýQÿÿ ÿÖ#XÁý1ÿÿÿ%åÌ#XTý*Qÿÿ"ÿò°%#vœ—ÿÿÿöÖQ#v,«·ÿÿ"ÿò°Ý#jÂo—ÿÿÿöÖ #jR›·ÿÿ"ÿò°#CæZÿÿÿöÖ,#Cw†ÿÿ"ÿò°#vœZÿÿÿöÖ,#v,†ÿÿi#vJÃ3ÿÿÿ'Ö•"v ïSÿÿ!#ep³3ÿÿÿ'ÖM"eFßSÿÿ“!#eª³5ÿÿOM"eßUÿÿÿu“–#eªýj5ÿÿÿuOÌ#eýjUÿÿÿu“ô#q¬› ÿÿÿuO "qÇ ÿÿÿ¢“–#q¬ý5ÿÿÿ¢OÌ#qýUÿÿ*ÿòë9#ecË6ÿÿ3ÿö\M"e ßVÿÿ*ÿgë¤#ecý\6ÿÿ3ÿk\Ë#e ý`Vÿÿ*ÿòë#ec—ÿÿ3ÿön9#e(Ëÿÿ*ÿòë#ec“"ÿÿ'ÿö^9#eË#ÿÿ*ÿgë9#ecË ÿÿ3ÿk\M"e ß ÿÿQ!#eг7ÿÿ ÿöÎ"eê`WÿÿÿuQ–#eŠýj7ÿÿ ÿkC#eÿêý`Wÿÿÿ¢Q–#qŠý7ÿÿÿ÷ÿ˜.C#qÿìýuWÿÿÿ%Q–#XŠý*7ÿÿÿ÷ÿ.C#Xÿìý WÿÿÿgÁ–#jÀý\8ÿÿ ÿkßÂ#jMý`Xÿÿÿ`Á–#hÂýL8ÿÿ ÿdßÂ#hNýPXÿÿÿÁ–#XÁý8ÿÿ ÿßÂ#XNý XÿÿÿòÁ%#vš*ÿÿ ÿößQ#v'«+ÿÿÿòÁ¸#jÀJ,ÿÿ ÿößä"jMv-ÿÿÿõ¹(#h¾ª9ÿÿÿòÝT"hRÖYÿÿÿj¹–#e½ý_9ÿÿÿgÝÂ#ePý\Yÿÿÿõ¤i#CRÃ:ÿÿÿò¶•#CãÿïZÿÿÿõ¤i#vÃ:ÿÿÿò¶•#v˜ÿïZÿÿÿõ¤!#j.³:ÿÿÿò¶M#j¾ÿßZÿÿÿõ¤!#e-³:ÿÿÿò¶M#e¾ÿßZÿÿÿj¤–#e-ý_:ÿÿÿg¶Â#e¾ý\Zÿÿ À!#e¾³;ÿÿßM"ePß[ÿÿ À!#j¾³;ÿÿßM"jQß[ÿÿ¿!#eó<ÿÿÿ&ÛM"eMß\ÿÿ Ue#XˆÃ=ÿÿ¢‘"X8ï]ÿÿ ÿuU–#eˆýj=ÿÿÿu¢Â#e7ýj]ÿÿ ÿ¢U–#qˆý=ÿÿÿ¢¢Â#q8ý]ÿÿ ÿ¢ç«#qRýKÿÿÿýÿö'Î"jë`Wÿÿÿò¶±#f¿ÿêZÿÿÿ&Û±"fNê\ÿÿ%ÿöºÆ"V6Dÿÿ9#e"ËAÿÿÿu¢#eÁýj$ÿÿ%ÿkºÌ#eHý`Dÿÿ˜#tÒ$ÿÿ%ÿöºÄ#t†ÿþDÿÿÂI#vœ£„ÿÿ%ÿöº#v"Û¤ÿÿÂI#C棄ÿÿ%ÿöº#CmÛ¤ÿÿÂ#tÉ„ÿÿ%ÿöò¸#tRÿò¤ÿÿÂ#hŠ„ÿÿ%ÿöº@#hJ¤ÿÿÿuÂ}#XÂÛ Dÿÿ%ÿkº‘"XIï EÿÿÂ?#vœ™Äÿÿ%ÿöºk#v"ÅÅÿÿÂ?#Cæ™Äÿÿ%ÿöºk#CmÅÅÿÿÂ#tJÄÿÿ%ÿöºF#t†€ÅÿÿÂþ#h€Äÿÿ%ÿöº*#hJ¬ÅÿÿÿuÂs#dÂÛ Dÿÿ%ÿkº‡"dIï Eÿÿ ÿuU–#e‰ýj(ÿÿÿk¨Ì#e9ý`Hÿÿ U˜#tÚÒ(ÿÿÿö¨Ä#tÿþHÿÿ U(#hŠª(ÿÿÿö¨T"h:ÖHÿÿ UI#vd£Œÿÿÿö¨#vÛ¬ÿÿ UI#C®£Œÿÿÿö¨#C^Û¬ÿÿ `˜#tÀÒŒÿÿÿöøÄ#tXÿþ¬ÿÿ U#hŠŠŒÿÿÿö¨@#h:¬ÿÿ ÿuUe#XŠÃ \ÿÿÿk¨‘"X:ï ]ÿÿÿ;#tÉ,ÿÿþðý»"täõóÿÿÿu;–#eÿÿýj,ÿÿÿuý«#eÿßýjLÿÿ"ÿg°¤#eÂý\2ÿÿÿkÖÌ#eRý`Rÿÿ"ÿò°œ#tÖ2ÿÿÿöÖÂ#tÿüRÿÿ"ÿò°I#vœ£–ÿÿÿöÖ#v,Û¶ÿÿ"ÿò°I#C棖ÿÿÿöÖ#CwÛ¶ÿÿ"ÿò°œ#tàÖ–ÿÿÿöÂ#tyÿü¶ÿÿ"ÿò°#hÊ–ÿÿÿöÖ@#hT¶ÿÿ"ÿg°}#XÂÛ pÿÿÿkÖ‘"XSï qÿÿ"ÿòÄ#[äÙbÿÿÿö§#[‚cÿÿ"ÿòĈ#\Ñâbÿÿÿö¥"\_ÿcÿÿ"ÿòÄœ#tÖbÿÿÿöÂ#tÿücÿÿ"ÿòÄY#hÐÛbÿÿÿöj"h]ìcÿÿ"ÿSÄ#e¼ýHbÿÿÿW(#ePýLcÿÿÿgÁ–#eÀý\8ÿÿ ÿkßÂ#eLý`XÿÿÿòÁ˜#t Ò8ÿÿ ÿößÄ#tÿþXÿÿÿò:’#[ëìqÿÿ ÿö¬"[drÿÿÿò:Œ#\üæqÿÿ ÿö¦"\irÿÿÿò:˜#t Òqÿÿ ÿöÄ#tÿþrÿÿÿò:P#hÔÇqÿÿ ÿö€"hJrÿÿÿS:P#e¼ýHqÿÿ ÿW|#eýLrÿÿ¿i#CèÃ<ÿÿÿ&Û•"Crï\ÿÿÿu¿–#eÃýj<ÿÿþ›ÛÂ#eMü\ÿÿ¿˜#tÒ<ÿÿÿ&ÛÄ#tžÿþ\ÿÿ¿(#hĪ<ÿÿÿ&ÛT"hNÖ\ÿÿ)ÿö."á Nÿÿ)ÿö."á †ÿÿ)ÿö.ð"á [ÿÿ)ÿö.ð"á hÿÿ)ÿö.ð"á \ÿÿ)ÿö.ð"á iÿÿ)ÿö.L"á ]ÿÿ)ÿö.L"á jÿÿÿÿ®"ÂT«Ìÿÿÿÿ®" †ÿZÿªÿÿ0®"Ân [‹¾ÿÿÿí0®"Ân hˆ¾ÿÿ 0®"Ân \–¾ÿÿÿú0®"Ân i–¾ÿÿÿí&®"Âd ]ÿÿbÿÿÿä&®"Âd jÿ‡ÿbÿÿ)ÿö"å Nèÿÿ)ÿö"å †èÿÿ)ÿöð"å [èÿÿ)ÿöð"å hèÿÿ)ÿöð"å \èÿÿ)ÿöð"å ièÿÿ!;–#ÆæTÍ´ÿÿ+E–#Æð ††’ÿÿ•–#Æ@ [£¦ÿÿŸ–#ÆJ h ¦ÿÿ•–#Æ@ \¤¦ÿÿÿþŸ–#ÆJ iš¦ÿÿÿ Û"ç Nÿÿÿ Û"ç †ÿÿÿ Ûð"ç [ÿÿÿ Ûð"ç hÿÿÿ Ûð"ç \ÿÿÿ Ûð"ç iÿÿÿ ÛL"ç ]ÿÿÿ ÛL"ç jÿÿÿìh–#ȪT˜´ÿÿÿâ^–#È  †ÿ=ÿ’ÿÿÿîÌ–#È [ÿxÿ¦ÿÿÿÐÌ–#È hÿkÿ¦ÿÿÿä–#È \ÿoÿ¦ÿÿÿÉÌ–#È iÿeÿ¦ÿÿÿÄÔ–#È ]ÿgÿJÿÿÿ½Ì–#È jÿ`ÿJÿÿ!ÿö "é Nÿ|ÿÿ!ÿö "é †ÿ|ÿÿÿòÿö ð"é [ÿ|ÿÿÿáÿö ð"é hÿ|ÿÿÿñÿö ð"é \ÿ|ÿÿÿàÿöð"é iÿ|ÿÿÿÙÿöL"é ]ÿ|ÿÿÿÙÿöL"é jÿ|ÿÿ –#ÊÒT¿´ÿÿ –#ÊÒ †ÿnÿ’ÿÿ3–#ÊT [½¦ÿÿ•–#ÊZ h¶¦ÿÿ=™–#Ê^ \Ȧÿÿ™–#Ê^ i´¦ÿÿ–#ÊT ]ÿ¤ÿJÿÿ–#ÊT jÿ¥ÿJÿÿÿöÖ"ï NÿÿÿöÖ"ï †ÿÿÿöÖð"ï [ÿÿÿöÖð"ï hÿÿÿöÖð"ï \ÿÿÿöÖð"ï iÿÿÿûÿòZ®#ЪT§ÌÿÿÿûÿòZ®#Ъ †ÿVÿªÿÿÿÕÿò–®#Ðæ [ÿ_ÿ¾ÿÿÿéÿòÈ®#Ð h„¾ÿÿÿÕÿò–®#Ðæ \ÿ`ÿ¾ÿÿÿìÿòÒ®#Ð" iˆ¾ÿÿÿöÐ"õ NÿÿÿöÐ"õ †ÿÿÿöÐð"õ [ÿÿÿöÐð"õ hÿÿÿöÐð"õ \ÿÿÿöÐð"õ iÿÿÿöÐL"õ ]ÿÿÿöÐL"õ jÿÿ Y­#Õ´ †ÿeÿ©ÿÿÑ¡#Õ, h ±ÿÿÛ #Õ6B i¡«@5@ÿÿÿûѪ#Õ, jÿžÿ^ÿÿ)ÿöŒ"ù Ngÿÿ)ÿöŒ"ù †gÿÿ)ÿöŒð"ù [gÿÿ)ÿöŒð"ù hgÿÿ)ÿöŒð"ù \gÿÿ)ÿöŒð"ù igÿÿ)ÿöŒL"ù ]gÿÿ)ÿöŒL"ù jgÿÿ‡®#Ù¾TºÌÿÿ‡®#Ù¾ †ÿiÿªÿÿÿü×®#Ù [†¾ÿÿÿÞ×®#Ù hÿyÿ¾ÿÿÿü×®#Ù \‡¾ÿÿÿ××®#Ù iÿsÿ¾ÿÿÿÊ×®#Ù ]ÿmÿbÿÿÿË×®#Ù jÿnÿbÿÿ)ÿö.ð"á zÿÿ)ÿö.ð"á …ÿÿ)ÿöð"å zèÿÿ)ÿöð"å …èÿÿÿ Ûð"ç zÿÿÿ Ûð"ç …ÿÿ;ÿö ð"é zÿ|ÿÿ;ÿö ð"é …ÿ|ÿÿÿöÖð"ï zÿÿÿöÖð"ï …ÿÿÿöÐð"õ zÿÿÿöÐð"õ …ÿÿ)ÿöŒð"ù zgÿÿ)ÿöŒð"ù …gÿÿ)ÿ." C Nÿÿ)ÿ." C †ÿÿ)ÿ.ð" C [ÿÿ)ÿ.ð" C hÿÿ)ÿ.ð" C \ÿÿ)ÿ.ð" C iÿÿ)ÿ.L" C ]ÿÿ)ÿ.L" C jÿÿÿÿ‘®" ¦ Miýÿÿÿÿ‘®" § Miýÿÿÿíë®" ¨ì MÃýÿÿÿÏë®" ©â MÃýÿÿÿ÷ë®" ªì MÃýÿÿÿæë®" «ì MÃýÿÿÿãë®" ¬ö MÃýÿÿÿÚë®" ­ö MÃýÿÿÿÛ" R NÿÿÿÛ" R †ÿÿÿÛð" R [ÿÿÿÛð" R hÿÿÿÛð" R \ÿÿÿÛð" R iÿÿÿÛL" R ]ÿÿÿÛL" R jÿÿÿìi–# MAý Âÿÿÿâ_–# M7ý ÃÿÿÿîÍ–# M¥ý ÄÿÿÿÐÍ–# M¥ý ÅÿÿÿäÖ# M›ý ÆÿÿÿÉÍ–# M¥ý ÇÿÿÿÄÕ–# M­ý Èÿÿÿ½Í–# M¥ý Éÿÿ)ÿŒ" | Ngÿÿ)ÿŒ" | †gÿÿ)ÿŒð" | [gÿÿ)ÿŒð" | hgÿÿ)ÿŒð" | \gÿÿ)ÿŒð" | igÿÿ)ÿŒL" | ]gÿÿ)ÿŒL" | jgÿÿˆ®# M`ý úÿÿˆ®# M`ý ûÿÿÿüØ®# M°ý üÿÿÿÞØ®# M°ý ýÿÿÿüØ®# M°ý þÿÿÿר®# M°ý ÿÿÿÿÊØ®# M°ý ÿÿÿËØ®# M°ý )ÿö.À /@#"&533267#".'##"&546323733265'4.#"32>ƒ€CG9.0-È9 d:Zks\AJ  T#+¡<-$2 9,.<ÀXE.3.3ý«u#!8H‹\^’cG {r<B~,UF0LD"+OAOZ)ÿö.&7!5!#".'##"&546323733265'4.#"32>’þÉ7œ9 d:Zks\AJ  T#+¡<-$2 9,.<K6ýêu#!8H‹\^’cG {r<B~,UF0LD"+OAOZÿÿ)ÿ.ð" C z)ÿ.Í"1B%#".'##"&546323733265#"=332654.#"32>.9 d:Zks\AJ  T#+]JL<-$2 9,.<ku#!8H‹\^’cG {r<BþðXOc.NŽ,UF0LD"+OAOZÿÿ)ÿ.ð" C …ÿÿ)ÿö.¶"á Oÿÿ)ÿ.¶" C OÿÿÂs"ÂdÂÛÿÿ "Âq³ÿÿ¤# zÿ_ÿ´Âÿÿ¤# …ÿ`ÿ´Âÿÿ›¢# MsýÂÿÿÿ¬lUCTÿXaÿÿÿ(ÿµµ¥-N#"'732654#"#"54632N;*& $%'/ 4<•*> $-*;]U™¶#"&#"#>323267™6'V%6*T¶)8+++6+l-¨"#"&#"#>323267"&462"&462¨6'V%6*V((¢(()8+++6+¤((((ÿÿÿÛð" R zÿÛÍ#2#4#"#4.#"#4323>32#"=33265ÛT>U*[$ F='4 º]JLà&cþ´@gd",,D`27%þ6XOc.NÿÿÿÛð" R …ÿÿÿ Û¶"ç OÿÿÿÛ¶" R OÿÿÿÍä# zÿ ÿ´ÆnÿÿÿÌä# …ÿ ÿ´Ænÿÿ^¤# zÿCÿ´È ÿÿ^¤# …ÿDÿ´È ÿÿ¿–# M—ýÈv-ð #.54632#7254&+"&5432" evO *(--505 7c7 #8u-€ð #7>2#7254&+"&5432€S(ŒwP*(-Õš Rc7 #8]-šL*#"&#"#>323267#"'732654#"#"54632š5(T% 6*V>0 %(/L*7+++6+Ï 0 !.ÿæÿö À #"&533267#"&5332>=3ÿ€CG9.0-'/97/TÀXE.3.3ý¯;>;9Yþ… #ÿ×ÿö!5!#"&5332>=3þÉ7/97/TK6ýî;>;9Yþ… #ÿíÿöð/"&462#.5462"&462#"&5332>=3((R".((Ø/97/Tq((`505  V((ýâ;>;9Yþ… #ÿèÿö ð-"&462'#7>2"&462#"&5332>=3 (()S(~((Ý/97/Tq((Hš q((ýâ;>;9Yþ… #ÿÿÿÙÿö¶"é Oÿ|ÿÿÿèÿö$"é Pÿ|ÿÿ;["ÊdÃÿÿ Bô"Êq›ÿÿÛ–#Ê  zÿVÿ¦ÿÿÑ–#Ê– …ÿMÿ¦e-Žð $#.5462#"&54632#"&#"327Ž"g &99.+"! -505  Ž 9&.6')d-”ð $#7>32#"&54632#"&#"327”"' •&99/,#! Õ 505š© 9&.6')]-™L*#"&#"#>323267#"&54632#"&#"327™6'T%6*TD!/.) L)8+++6+þë /!(."ÿöÐÀ 1#"&533267#"&54654#"#463232654&54632ƒ€CG9.0-jÂHP#0(610$2=F=?ÀXE.3.3þqþÅXI$‘$9\:FO4|6@g@(Ž$”ÿöÐ(!5!#"&54654#"#463232654&54632’þÉ7>ÂHP#0(610$2=F=?K6þ°þÅXI$‘$9\:FO4|6@g@(Ž$”ÿöÐðA"&462#.5462"&462#"&54654#"#463232654&54632Ÿ((R".((ÂHP#0(610$2=F=?q((`505  V((þ¤þÅXI$‘$9\:FO4|6@g@(Ž$”ÿöÐð?"&462'#7>2"&462#"&54654#"#463232654&54632š(()K'~((ÂHP#0(610$2=F=?q((H‚š q((þ¤þÅXI$‘$9\:FO4|6@g@(Ž$”ÿÿ,ÿ#á"ñ Nÿÿ,ÿ#á"ñ †ÿÿÿöж"õ OÿÿÿöÐ"õ Pÿÿ)¥s"ÕdÀÛÿÿ)¥ "ÕqÀ³ÿÿ0E®#Õ  zÿmÿ¾ÿÿ/E®#Õ  …ÿnÿ¾ÿÿæ–#ÒÈ †ÿbÿ’|-Ÿð"&462#.5462"&462Ÿ((R".((q((`505  V((w-šð"&462'#7>2"&462š(()K'~((q((H‚š q((Ã-4ð #.546324" -505 ÿÿ)ÿŒð" | zg)ÿŒÍ@O%#"&'##"&546732>54&543232>=4.'5#"=33265Œ`R9>>9R`j]*  #",/.+1!+ &]j¸]JLäW—I;;I—W_ˆ#9(  8&(023S(Õš ¥-N#"&54632#"&#"327N%*<=4/'%": >*4;*-$'Éú73#'ööú1ÿÿ'Éú ‰ÿÿÉôú ŒÉôú5!!ôþ ú1Éèú5!!èüú1ÿÿÉèú ÿ)ôÿµ!5!5!5!ôþ ôþ ô×2(2s±þ¤7632#"&5467¨  !".>2 R 3&-T82O±Ú¤#"&54632'654¥   !".>2 R< 3&-T82OÿsÚf#"&54632'654¥   !".>2 R 3&-T82s²þ¥"&#".54>32À&, R $&9; Z/)+±ž¤'7632#"&546737632#"&5467`  !".>2 Rö  !".>2 R 3&-T82 3&-T82±‘¤'#"&54632'6543#"&54632'654t !".>2 RÚ !".>2 R< 3&-T82 3&-T82-ÿs f'#"&54632'6543#"&54632'654ƒ  !".>2 RÚ  !".>2 R 3&-T82 3&-T82+²ž¥-"&#".54>323"&#".54>32x&, R $&Ð&, R $&9; Z/); Z/);ÿk»¤."&'#54&'6=#"5463254&5462>32•\&*(*)S , ]$$$%-O”Ž+h¯{{EŸ3+„ +" 2f i="&:ÿgº¤P>32#"&'>32#"&'#"&5465#"&463254'6=#"546324&54632)$&\ \%(%\  [&$$&[ [%())S , [&$vg?"& w0LI"?f g?"& %6r +">f (Ä6Ò 2#"&546®:NP78ONÒO:6OO98N(´6ã7(´/˜oÿõxd #72#"&546!2#"&546!2#"&546¦!" !c!" !c!" !d" "" "" "ÿíâÂ*6BN[232673##"'#"&54632654.2#"&546"32654&%2#"&546"32654&È"0 ,5C,þR/Š5(#)`F2DtK '95O '@.2d@3FuT0Q 3S#D.2d?4FuS&? 3S"¤Bý,’ O”O:U€~A'‚VþÔ=8[P:Pƒ™H(O&2=8[P;P‚]d(O'1ÿíL 1?N\kyˆ #'#"'#".54632326732654.'2#".546"32>54&%2#".546"32>54&%2#".546"32>54&7þR/ƒ 4%+_G $rN#2",7?þC 5M  2 É.3e>%)wQ3*B#C.3e>%)wQ3*B#C.3e>%)wQ3*B#Âý,‡Q–:&E…#>þê-†C  =H7632œq O4A W (Là I-;Q ' 9^0! 747'&5432#"1€K6  7( AfD *¢]A 6";XDÿæb3 )3''7'77"&5462"&5462$"&5462"&5462=ÜÜ%ÝÝ%ÜÜ%ÝÝÊ&$ .!%&$ .!þì&$ .!¹&$ .!çÝÝ%ÞÞ%ÝÝ%ÞÞH!"þ!"Ñ!"!"ÿÿ‚ÿ÷:¤#MDÿøž¤,8#'.54327>54&#"#"54632"&54632ž-/)#46 86!<&2g<-3'±" "þ"?7:V2x$®TR Ž X3L% ,?EK#=ýÔ ÿÿ#ôUB 5yŠy732>7#"&5EJxI &P9O<>Z-=}`€Ùp "6 #8# )Z))‚5yŠy7>32.#"5EÙ€`}=-Z>7'.54>3254&5432>32#".'#"&54654#"&54>7'.54>3254&5432>32#".'#"&54654%#"&54>7'.54>3254&5432>32#".'#"&54654Ë&0*C =) 4(%8& $F!Y,$2Ý&0*C =) 4(%8& $F!Y,$2¬&0*C =) 4(%8& $F!Y,$2Õ.  7 -L' X9%'6 :N U þ¥.  7 -L' X9%'6 :N U .  7 -L' X9%'6 :N U +–!*#5!ö*””ÿXÿòK¤ #Kþ>1ŤýN²XÿKý¨74675.=463"&5X$77$OV3(#22#(3VOy:9  9:£S8 96·22 22·69 8TƒÿK(¨%#5>=4&'>=4&'52(OV3(#22#(3VO$77$y¢T8 96·22 22·69 8S£:9  9ÿÿDÿøZ¤#"¼"ÿÿDÿ÷©¤#¼"ÿÿ‚ÿ÷ë¤#"MÿøÁ #"'7!ò€Ù)+ ;r€3“þFÿÿÿêÿf–Cx¬À@ÿû1¥4>32#".7"32654&21GTYB21›P+%"$!Ø:U+s^\u,Yí¶ZZbR]Y9ø¥ 2#"&4657#5>=4’Ev"¿ ¥&&¾&× ‚!2£ ##5#53#527F´Ë/F‡¡9ZZ1 þþ³³ ²##"546232654&'&#"54657327+ nZS4 429> K˜‡df EU2',*6“B%Jÿþ0©"&54>7632'"32654&œGW &=kF£'@JPQ,,&!+aP9@0%|G<@Nê&*?@3,5;ÿý(£ ##"'7(ŽG† £ þx[_*¦!-#"&5467.54632'3254'>54&#"¶G-RL;M35N=:L*S'&( E> ,#'(ï'6&09:-&%))+83&*^&-%,<&$"(ÿÿÿþ 0¯ ½.µÀ2}úE ##5#5353úK2KK2ú2KK2KK2Èúú#5úÈú222–ú,#57#5úÈÈÈÈ22d22ÿó@"*5>7>32#5>=4&#"#5>=4&# H"&$0› +ï02(ze! xÿÿÿûÿ-1Ï ¹þ*ÿÿ9ÿ8øÎ{þ*ÿÿÿ8(Îtþ*ÿÿÿ0#Îuþ*ÿÿÿ82Í »þ*ÿÿÿ0 Ü ¼þ*ÿÿÿþÿ00Ó ½þ*ÿÿÿýÿ8(Í ¾þ*ÿÿÿ-*Ð ¿þ*ÿÿÿþÿ60Ù Àþ*ÿÿ2ÿúe Áþ ÿÿ2ÿèú Âþ ÿÿ2ÿ¶úL Ãþ 7„³H";54&'5!#.+"32673#./32673!5>=#"&546323273#.$23^F#i'8\ i++i#A>þ‘#^ˆ‰^$RM—+W;ff~% a- —'ž)© %4s &•tul™8Eÿuy.4=327#"'#7&'#7&54>3273733273#&'&'õÂ$.zh?o?&#.$1 9$?Œ:`yA)$*%/$2& f¼c'IJ-6³YýÓe!3&„Œ¢³\ÇQ†T.vy ‡!ádB ýæC@W|Oþÿòy¤J"6=4.#"5673>32#"&#"327#"'#5.54>323273#.y<@0J? NF"7' 2zh?o?81-Td:`yA5x& p|+BoGiŠ ú Y3(#:á-e!3&%yQ†T.!!áSf "–-.+3267#.+!5>54&'5!#.+"3267¨ +0zz0,),:z$7þè8#4 9Tˆ z;+Z hÇþ®/7!$>±8B' – + ÿøê¤ Q72654&#"%#"'#"&54632654'#53.'#5354632#"&54#"3#3#32>2N!&/­cG7W&(3* uohdoT=4.#"3##54&#"#52>=4.#"567>32Ÿ9C010vÛ) )' ¡&Do %,G""Þ HD&$6B–ª‘²Î-Ó&u¯"rNS452 þæ! ýK ÿõÖ159=A#535#535.#53354&'533#3####5>57'#7'#5#35mVVVV$ «¼Å'9ë RRQQÝÝ&8ë;&ä8€[YŸ 7%B.F.¢$ìYQ+2+Y.F.þíuL2.N£FFtootFF.SS\–%+#"'!5>5#5354&'5!23'&#"#32ò$$:þè;MM7FoM>« ´åå —Á¡¶6"%<I.:5 !M9..‚ `.vÿÿÿö÷–#V›5ÿõ¤–GLPSWZ.'5337'.'5!"37654.'533#3##&'##&'#53.'#5&'#%#3#%7##’!&##õ$ 5µ!#* M 'µ%Æ$ 9}Ž §·1+Tpd&;µ¥Œç -“^;þì‘J9ªV_! ‹-R<& ec*œ. &.‡Œ6Ýþís . 0 .t!%FFF.N|FF.K"ÿòä.%#"&'#73&547#73>32&#"!!!!327Ã(šM…¬K1F9³~K—'l‚(?3. žþqqþ¨xf{gq;D{. .uD;i,V9.  .c|eÿ1  'Ui#"&5##6?>324.#"32>%#"&#"&#"'>32>7>7#"&54>324&#"326 ¥q15@e1*h-A L)1K&*0K&þ”þþÅ?-£ F,"5 %3!@†` 3d•Ž;|ºjzl) QYmW(†­"r»é_o³}Š"4-%-@_W! .?\U‡Ââ*'&6KP/,J*6*9pB+B@b3Ÿ”p£#/J4J o+Õ*ÿ©"×%/323273#.+232>7#5$4670" M!    7%,$)/[F"þú…*; &=×?!!â6/$ý® &>=JIAž¹ýŠK.O`Be8#ÿóò 2 &5464.#"326‘ÑÓþÖÒÕÙ5L]H–bT¿ˆ‡¿ÂÕ’•ÓÓ—•Ðþ™JwF.l\|‰ÀÀÿòy¤ %%".54>323273#.#"327y?o~sb::`yA5x& pX947BzhþyPq!3&'O‰ZQ†T.!!áSfýße$ÝP£šÿÿÿò¥¤#&,rØÿÿN¤#),rØÿ1ã¹(6#"54632326767#"&54>3274&#"32>ã & ‹\N +]*9D#52W‹A=  2e:2g<ª)¨‚;`‹@  u6=„!==$F7@šm=.I&r0-u‘!ÿêØÍqz326?6323>3232676;2#"&54?#"#"&54632#"'32767+"?6?#"&54654#"+"54632%"67654#!'\&™ä€jÃaG14®tIc9#U( <^$:9L@<.yAÃP9K0#!$ ?4d–+H±J VÒJ3.)%4$ i'!&j3–bÜP0@73%•þÕ©@6FI?fE3K8 FD60TkY¨[ˆ)& @"×>YiyW963 kU™…pD+-ÿbp«D%&#"'>32654.#"''7654.54>7327#".'67p+BD< FA+! !<4Dv+U4'GF5hJ$ lK,+,)2O6>9BL0J=l8c{ÂP3nQ/S;+EO; V:!';45E%*J-@:/g4HN::1"–+9)5>=!!5>54&'5!!54&'5!%4&'>"þê<þÑ9þ†<<z9/999ý­   &<ÃÎ3#!8¼9!5ÂÂ7!5þD3#e±%#!'þD&"'ÿ÷Þ«23267#"&54?654&#"#654&#"+567632ÀQ  ( -?&7 Z'!K‡ LQx‡^%v þñ 2 A1KÏ R;.XsV  þ@Ó%ÿ÷Þ«;%#"5454&#"#'?654+5677>3232>7Þ;-R ^ Ksa y&PM.¤ ¼='@H Q i$&(.2 d)/]m¶#!+?@  ©:!Cä7K/ þä :ÿï¸Í J>74632"'326?&547>7632>54'46;2#"&ÿK(DO4Fws"<þy/#!$( v?ž=^5&xm£5LtG)(Gr  I9-/;Ý\:N!y:UE##E1TxÝ?":{VWAL6G, 0ieK[ yG*>b\‚( ÿËBä@4632#"/&#"'763232>54/&54?&#".9ˆl-“H_ƒ UC  +W Œ" "(WG„SD[+&6!,<#Vs.(lð&8D( V5K )))*)U?G;9(  %A ÿï ÍCLT"327>3232676;2#"'+"546;26?#"&54>32"327&"67654TO¨`O7\gZ#,-ΰd=dnG1x" M|3TxfR„IQEWP:V c€Yƒ:!þP11^:H@Æ&çÁU/¦‘H16Lrm:)$]°ŒU=B/KD22&1:Rz@=5sK ý£$ -mþ¿%xC.3ÿõ°¥%0327#"&54>7'7>324&#">°-S7**F?[8/5\ o%(?%$/=#+#+H%X$LI*‚\&v=W54&'5!34&'53&'>' þH&8þ±>##>'9ëýªƒ2+ýò$þzL2#6¼7 þNQ+ýý¹9þD< 3ÿñ›2>I!5!4&'5354&>7632#"&#"##"&546323265%2#"&5463254&#"t$ý%;ªû 3#,6 þÌ4L'(8 _@QXA?RU ,%G-$ '22L/þJÍ20'# $+@þþÅ|b#6PøK;?UO<@Ok=QW9H(&ÿòÒ¤83254&##"&6324&#"326'+#5>=4&'532l+E(=Å‘ÇÇ‘Ž¦wy¨©xu¨|D0? $¢$ %±0Cõ¨V))þàÈÈ Êþ¦{µµ{z´µÆ-0c  ñ .-žÿ-f=LX4>7.547>7>7>32#"&5463232>54#"#"&2654/ž) W0+, ,,0 RG!1y(8V/Nu>6A &&4f=Cƒè2$ 8Fp' $./O8"=?ee+  "\* O aH%2KX-voLA2&@oœDgþçs.I%; G'&+6AI!N;*=‚–"0#"'!5>54&'5!24#"324&'>‚=>–$$:þ„<<lq•m¾ «þ³  âN9;¶6" 9¼:Z\‘ þüб&" (þD( %"ÿN½¤',#"/.546324&#"326½!îh/'JI-Â…?s]83PX+9Uo~W1,,1[zþ¢L±z7 .L{L¢¸,T‡SNO. : C韗ýÇš_óQ©¨ÿþÿïwÍ ƒˆ>54'324632#"'326?46367&#"3267>=472#"&54>763263232676;2#"&54?65##"&#6‘Hjnpý/#!# >3;Ž=[Ž<{rä;7BF%?&mA7-&:*vW~q…J- $ "0>+ "K_/ ¦"!NQ4""J>ÌU;Pe$cz='U¶þÓ<" wU€ ¾f,~SO4 615 K:,«&")/%^z-A/ %E/(+0i(HC…2#qHnX€':ÿñ÷Þ[46327632327.'.+'7'&#"'&"'7>32>54&#"'>54.u`0)"ƒ ¡¶),!n((  ÁQ?&h&&FN+AW%7 _0 $ %55%\p._ Œ5gJ XSW-†K )qv^`2)X =7>ˆmœ•)" 0 1' 4  ">÷–!-;!#!5>54&'5!24#"2>4&'>÷¡î8 :þ‡<<x)KV4$=Î$3ݬ'$,K,#þ°  4Å4# 9¼: !K6&< ý-Öˆö:þ¸±&# (þD(! &ÿò“–)5!#'#7'!5>54&'5!2734#"2>“¡5-)š8 :þë:6)KV4$=T,&[$3ݬ'$,K,#DR{ÇÅ4#%<±6 !K6&< gLrp-Öˆö:ÿ£“:'+09#'##7#5>54&'5!27'5'654'&#"27¯t$=Î$3¡ÄI0K-:64-¿ô 8ÍHe@*B'6‚)r&< ý-ýÝ ]]%<±6 B?,Qþ=׿Ûf6=öøcŸ%U#5>5#3#5>=4&'533%#"&+"#5332654/.546323273#&#"cº$™Œ(#‹|‰…  ý¾R0F    ,,/445A=7 L!#&b&%$þ¥Nõ *ù!þÊ6þñ ]6> /#&8-+C {n%):/½–;#5>5#"#5!#.#>=##5>=&'533#î &«% 1 Y í% š — ƒ 0yš g  %ª‚þÊ$$6%XX%þ” %ìþÈ6ß$$ù0þË5ÿ$ÿ£¹:%%#.'5!'5654.'53#-L-`š'% .)J¿ô›4“Í$"ÞŠç WB% [¥?,Qþ,to9 "9ýÏ Í–%!5#"#7!!2>7#3ÍýTµÝ3B! †þP/?$ DAþ`=°°a.!"«ýŸ/#$Àý¶ÿÿ!ɤÙÿÿ!ÿöÉšCÙš@Àÿùÿ^B¢B%#".#"#>323254."'67&'732654&#"&54632B­w6K$9%'54&Ž1B4 6/ "3<:KOCs N:jKaFXgPs$44$%.'87'Ä!2H/"% 2* 9[>RlVAK\(Y;B^uÿÿ"Ó–.ÿÿ“‡"ÿò Är}‡"&54>327632#"&54>32#"32>54'#"'#"&54632"'3267>7&#"32>=472%>54'632"327&5,žßb†I4  5@K8[…: / +J.'A% =,oL%D5F?ÍU;N/"!$( B6;=IR™L?yoã96 +:uA W{²(SM€'+  $/ 5#V§b*!  ,9(i3">9~Q$ $/( !) /Xz.,%bY‚'%<" yVgm¤8'xQL5(ny J~Bao2(O® 2ÿüV«8%#".54>327327#"''654&547."3267V\[‹D%G/!1 KI*(=K&<"hY ^(&:) 1`CIy´X`iY+ejF,"^/#Y ")¨+RM)(Ÿ.0?.$-J)?qlA3:#ÿöóÌ%#"&4632!3267%!.#"ð~Ob‰‰bT€þ‡%54&#"#"5>32#".54>7&54>7632#"&546324#"3xF-#S6F+X<%8!?%3R.@K1Y6 -4'N _1MBR6KC7P)(9G6!B-K>MBr&$X+ Å6(n O ]+,>TP JND';.@:#^6 =n6$,V&,..T9."17+"5467>763267>32#"'"547#"&4>3232#"&#"32654&5463#"&>5&#")0#!$ ”+bV:@z ¦R):`D?&% $'#C!t 7(/ûgF`Ù~¼TBÄ? CÃ@G…W5A\{ p#4é-;@"@;_K&%!=Dif)A5"[ 537!.n¶(˜>aM'M4MU!5{>"Gz#E !ÿÿ "–).–ÀÿÜ¿Ïj7;>7676332>7>?6332676;2#"&547>7#"=>7#"&5463632#"'B: *Y:s IV<kþŒMH*© v-“/G-o  Gl'+-?IwEþô-47…B@Ca"Z7'&54>7>7"#"54>7&#"&/#57654&¯ Z  ¿!O +7$D2 3 VÁ 5 ¯:Õ" l!, 2'ò410R!- "!Uu/"=  4,3cá%S/5% l[¹$%!7!26=&#!"&546573!2[*ýì*¾ Gþà5& ,)R% ˜˜˜ /<)% 0  (+ þË #¹&%#&#"#73254&/.#"&54657;2# Á$­ #5& +!3N‚ ¡LL!,% .  L"ô¹##!"&546573!2ô   & þÉ5& ,)b '&t|nI")% 0  {«!5>=4&'52"&544(þ™42V==X;ºþ§((Ó(=X;;-+ÿÿÿòÓ¤#u°þ÷ ÿÿÿûÿòʤ#u§þ÷"tú ± ÿÿÿò¸¤# Ê˜È ÿÿÿñÿð¾¤"tð# ¼žþê ± ÿÿÿî´¤"uø# ¼”þè ± ÿÿÿûÿ쪤" »ú# ¼Šþæ ± ÿÿÿð»¤# ½‹þê ÿÿÿè¼²" ¼# ½Œþâ ± ÿÿÿòФ# ¿¦þô ÿÿÿûÿòá¤"uí# ¿·þô ± ÿÿÿòá²" ¼# ¿·þô ± ÿÿ$ÿòâ¤# ± " ¾' ¿¸þôÿÿÿòX¤"{æ ± ÿÿ;–,d–!)5>54&'5!!2654&#"dý®?"!@R?#$>þ×>#"?>$% 8¼7 7þD7!!9¼9!"8þD7#– !/%2654&#"!!5>54&'!>54&;>#"?>$%ì{?#$>ü…?"!@R?#$>?"!!9¼9!"8þD7#ƒ 7þD7! 8¼7 7þD7! 8¼7ÿõâ–,"!5>54&'5!#654&'53#.;=%$>þ×?"!@1.)—“ )Í%Þö'ƒ#7þD7! 8¼7[þ®o0 ;ýÏ%B'ÿÿÿõ¹–9ÿõá–,"#.'5!#654&'5!!5>54&¹%Þö %% .)—“ )õ?#$>þ×?""ƒ>ýÏ%C%[þ®o0 7þD7! 8¼9!ÿõ – 932654&"%!!5>54&#"#.'5!#654&'$=<%"|$þm?#$>ý¯?"">%Þö %% .)—“ ))þD7#"8¼9!#6 7þD7! 8¼9!>ýÏ%C%[þ®o0ÿõ4–,:H)5>54&#"#.'5!#654&'5!!2654&#"#2654&#"4ü…?""?$ Þö'& .)—“ )H?#$>þ×>#"?>$%ì>#"?>$% 8¼9!!<ýÏ%B%[þ®o0 7þD7!!9¼9!"8þD7#!9¼9!"8þD7#é–C"326?'.%!"7654&'53!563654/!5>54&'=?%#:#)BmJ<þ¤["U*q()î15/’À '(þ×23_w4 ,ýö?"!@‚"7þD6$!QÁ i3 v;Š2 !:¶þî+LŒ”A 8¼7ÿÿ À–; à–C%2654&#"!563654/#5>?'.'5!"7654&'5!¾7#)8.7/’À +Dý·23_w4 ,é'*@mF=2."U*q()?#$>#7¼6$#;¶þî,LŒ”A OÁ g4 v;Š2  7þD7!  – Q%2654&#"#2654&#"!563654/#5>?'.'5!"7654&'5!à=$%<;''ç6$&;.60’À +müŽ23_w4 ,é'*@mF=2."U*q()??#$>"8¼8"#7þD7##7¼7#"<¶þî,LŒ”A OÁ g4 v;Š2  7þD7!ÿÿ V–/ÿÿÿòy¤&ÿÿ­–'ÿÿ _–0ÿÿý«Lÿÿ«#LLÿÿ)«#L,#LLÿÿÿòó«#YLÿÿÿòÝÂYÿÿÿòñ«#LôYÿÿÿò«#L #LôYÿÿÿò«#L #L #LôYÿÿõ«#[LÿÿßÂ[ÿÿñ«#Lô[ÿÿ«#L #Lô[ÿÿ«OÿÿÿöœÌFÿÿÿöë«GÿÿÌP>4†Î%!'7!†ý$wÄÄwÜå!ÌÎ!.ÿ]Ç¥'#'7Ç!8 Ìáwý$ÜwÄÿÿ>4†Î ;ÄÀÿÿ.ÿ]Ç¥ <õÀ>4†Î '7!'7!'7†Ävý‘wÄÄwovÎ ‘!ÌÎ!"-ÿSƯ %'7'7'7ÆÌÍ!’’!ÌÍ ““ÄÄy‡xÄÄxýyy>ÿ]†¥#!†"ý-¿"é¿->ÿ]†¥#'''5!†-ý"鿇¿ý"é-ÿÿ>ÿ]†¥ AÄÀÿÿ>ÿ]†¥ BÄÀ>4†Î%!#7!'7!73!†þo-2-þçwÄÄw(*2*‚妦!ÌÎ!››>4†Î'7!#7!5!73!'7†ÄwþÛ-2-þ{”*2*wÎ!¦¦8››!;4ñÎ#7'3232>325&#"#".+7';Äw*cj2-Q=:D$5')XU-Q<:E$*cj2wÎ!’99/BB/&,Ub/BB/88!ÿý4³Î#'7#"#".#"563232>;'7³Äw*cj2-Q=:D$5')XU-Q<:E$*cj2wÎ!’99/BB/&,Ub/BB/88!>4†Î%!'#'737!†ýìwªvwÄÄwx¨wå!±!ÌÎ!±!.ÿ]È¥'75'7''ß!±!ÌÎ!±!£wªvwÄÄwx¨wýìÿÿ>4†Î IÄÀÿÿ.ÿ]È¥ JöÀ>4ýÎ%'!'7!7ýªývwÄÄwŒ¨wU!±!ÌÎ!±!8ÿÿH4Î MEÀ>4ÞÎ %#5!'7!53Þ8ýwÄÄwü84±!ÌÎ!±ÿÿ-ÿ1Çч OÿùÀ@ÿÿ>4ÞÎ OÀÿÿ-ÿ1ÇÑ PôÀÿVõ¯!5!''7'7'7õþ ô.ÌÍ!’’!ÌÍ ““ª2ÒÄÄyDxÄÄxý¼y>4†Ô!##5!'7!54>324"32† 5,8þwÄÄwí,1G9~??] .qq"ÍÍ ‘ +1F1??@>4†Ô!'7!#5".54632!'754"3†Äwþ8,5 G1,íwþ3~?Î!qq. 1F1+ !±@??@ 4_Î.'7#"#".'#".+'7322>3232>;'7_Äwcx::9:@CbwÄÄwb"F6:A3'+ 6D"cwÎ!iT` `T45!ÌÎ!/.dc>K>./!>4†Î'7!#7!'7!73!'7†ÄvþÜ-2-þçwÄÄw(*2*vÎ ‘¦¦!ÌÎ!››">¤Ë !##'73¤8ÂwÄÄwúâ!ÌÎ!>¤Ë '7##3'7¤ÄwÂ8úwýÌ!þ!>¤Ë ##7'7'3¤8ÂwÄÄwúËþ!ÌÎ!>¤Ë %'##3¤ÄwÂ8úwÎÌ!âýæ! ‡X5!3'31TpoT!7þ[¦¦nÿðZu3!'7!#7þ[¦¦nuýÏTpoT #³!#.#"7'7>32#AÙ™v¿(†!ÎË Œ(è“´ÿ™ÙˆloÎÎs‰°ÿ #³%'7.#"#4327#ËÏ!‡(¿w™ÙAÿ´“è)‹ÎÎÎolˆÙ™´ÿ°‰sl?É &54732654&''?ÓþÔÔj"[·‚¸4(">éfii–ÓÓ–q"a}‚··8Šfè>"ql?É &547'7&' 654'7?ÓþÔÔjfé? \··\#ii–ÓÓ–q">è@&`··‚}a"o>å†Î%!7!†ü¸ÝxÄåé!>4†%!'!†ýå†Î%!5!'7†ü¸Äxå8!>4†'7!5†Ýxý<é!8Ýÿ^Ʀ%37Æé8;ÝHýÿІx'7!5!'7!'7!†Äwý$ÜwÄý$wÄÄwܬÎ!8!ýÃ!ÌÎ!-ÿ^¦'#'%7'7ùÎ!8!=!ÌÎ!¦Äwý$ÜwÄý$wÄÄwÜ>ÿІx!'7!'7!5!'7†ý$wÄÄwÜÄwý$Üw!ÌÎ!þ‘Î!8!>ÿІx%!'7'7!!!†ý$wÄ££ÄwÜý$uuÜ;!Ì«©Î!8ŽŽ-ÿ^¦'#'#'77!8ŽŽ8!Ì«©âwý$Üuuý$ÜwÄ££>ÿІx%'7!5!'7!5!'7†Äwý$Üwwý$ÜwÄ£XÎ!8Œ8!Ì«-ÿ^¦%''73737Ì«©Î!8Œ8"Ä££ÄwÜý$wwÜý$w>ÿφ4 !7!'7!5†ü¸ÝxÄÝxý<Ké!Ëé!8>ÿφ4 !5!'7!'!†ü¸ÄxÝý†þ%!#7#'7373!!!%!3†þT2©LññLî2gþŠ'þXþò=<è€ii]ûý]]]8““JI>þ'7##7#'73733'7'#!%!3ñLõ2©LññLî2°Lœ=î'þßþò=<èû]ii]ûý]]]]ýJ““JI>†þ'7##7!5!7!5!733'7'#!†ñLë2þ–y'þ`¯2¦Lœ=ä' û]ii8“8]]]ýJ“>†þ %!'7!!!†ýyLññL‡ýJ=<·]üý]8JIÿ]¥ '#'#'7]8JI8]û´Lýy¶=<ýI‡Lñ>†þ '7!5!7'!5!'7†ñLýy·<=ýJ‡Lü]8IJ8]ÿ]¥ %'73737ûý]8JI8]NññL‡ýJ=<·ýyL>þ '7!'7!'7'!!ñLþ0LññLÐLœ=ýÒ=<0ü^]ûþ^]ýJJJÿS¯ %'7'7'7'ûý__ýû__“KLLDññNÞNññNþ"Nz6>?ýÌ?>ÿÙ° %Ù(ý0^ Ð'ýQ )\x3'Ð _ý0(¯x]( >ÿÙ° /'/'/Ù) ýQ'Ï ^ý0(¯x\LxýQ(Ð_ ý0'¯ (>ÿÙ° %?7?77Ù þ¤xýQ(Ð^ ý1'¯ {þ¢) ®(ý/ `Ð'ýRw>ÿÙ° %ÙýQxþ¤) ¯'ý0 ^ÐùýR )^w®'ý0` Ñ>ÿÀ†A%! !!!!!†ý½MþÊ5MCýŽhÚý'hq;]A@]8r8r>ÿÁ†B '7!5!7!5!'!5!'7†þËMý½rhý&ÙhýCMþÀ]8r8r8] 4$Î27'3232>732>3235".#".#"#".+7' Äw\A?:<=92), (#7A>9;<9D=5AcwÎ!54Nc bP>I>"854Oc bPcc./! 4$Î2'7#"#".'#".#"#52>32>3232>;'7$Äw\A?:<=92), (#7A>9;<9D=5AcwÎ!54Nc bP>I>"854Oc bPcc./!>4†Î%#53#53#'73†¤¤þࣣþáwÄÄwå8888!ÎÌ!ÿÿ>4†Î „ÄÀÿò2– #33#2þõþ*hµhw—K–ý\¤þçþ¿Ëlÿu`]%#"&54632#.#"3267` €nh’’hn€ H ZOJghIN[ opŠ“gôh’‰qPbhJþ IhbOÿöÎñ*74>32654&#"'632#"&%&#"32>(R6&A0TH5?)M6ošDa8PmT72>V0)%;¹DP7&C(uˆ 3DZƒ4=qÑ7|Y>G1HSC,–)5!2=!5!54&#!5!þ p!þÄ<þ¦é%2ñ%Ü%,ÿz )#7#53#53!5!73354&+5#32þÁ#4$‹O…Gþß+%0%Žb E{…N²!††%#%%„„þ×ÜþüþêñþÝÿäܱ'.#"'#7.54>3273'&#"74'32Ü 0R5+! 1:3 0R5'% 193¢&/!ã!¡'‚K(UaJ160®S(TaJ260®Ñ$A@T, Oï›Rýï`°3 %!Aýí’½°ýP3Ê$ÿí©Î !©þ¨þÓUçþIÎýáýÔù4äú%#"&46;#"!!;äºggº¾Jlkþ• pE¾”Ê”2eI2Jd4ÿšäh!&%#"'#7.546;733#3#;#"3#äº&0677#53.#"5632ž—{5!''9.%ÐÒlR"4,l†p¢( %E-7Ep+ ÿ›#ï3!5265!3!52654#5!"Â/2þÎ1/þš/2þÍ2/_^uýŽ1  1µýK1  1rcÿ›#ï%3!5254!"!4!"Â^üû_/232/f/122/ccr1  1ýKµ1  1ÿ…·ð.#!!2673!!^!;1þô¼ÉHVC6ýòéW K%'# þŽþ %=Ò˜Ó¥>å>%!5!>þå8>>!5!##5#53533>þä8ää8äÎ4þ´¶¶8ÁÁ>>¦"&5462##5#53533s,,êä8ää8ä‡,þ?åå8ââÿÿCÿò6¤ ±ëCÿò6¤3#C.Å1¤ýN>?™Â;74>7.546324&54632>2#"&'"&465"&>1U U; k  p0UU1 k  o³`ce^  _ce\>G³» #"&546324&#"32³mMOllOMm0R8:QQ:9NllNMmm†rQQ9:P>G³» #"&54632³mMOllOMmNllNMmmÿþÿ¿œ'7pû_£º{8A/3Oþ‡ ÿÿÿþÿ¿Æ#u`" Ÿÿÿÿþÿ¿Å# »`" Ÿ>a¸*:&#"327#".'#"&54632>32.#"32a!ZE!(++0/ -6@>RF@J$05-þü .,50Mš0x =#/)$*).fCK…GF#1Í ! I17n4>!¸#/#"'#"&546326324&#"326%.#"326!dOoa'w6GOfO;q#taGM9B7&f ++936þ¥i-47A7&gP€6XaHQT9‹`v;jO(94%D>8rE5;jO>¿)3!¿þ(Yþ¨>¿$)3!¿þO2þÊ6$þ>¿$ )33#&'¿þO2Ð)0u¡DO$þ«Y2T.‚>¿é-'4'6¿þ~ }€’”èè3K2r0J³1(XY)Pÿòð¤333P(P(²ýN²ýNÿëÿòT¤73##5#7373ð Dd(P(!De(P(¿!hþz\Sþ÷ß"iŒþžS>P,!# #3P9ÏÑ9Èþ8,>P, #3Pÿþÿ9ÑÏ,ýÔ,þ8È>P=!#4&#"#462P3}YW3žØœ9RyXþÇ5nš™o>P="&5332653PœØž3WY}3o™šn5þÇXyR97ÿ8*%"&54623254632"&5467&#"¦,C"'acQ,C"'acÈ.'Ï\‰.'Ïýs\‰7ÿ8w+V"&546232>54632"&5467&#"!"&546232>54632"&5467&#"¦,C"'%]N,C"'%],B"'$]N,C"'%]È.'!?B-[Š.'!?B-ýs\‰.'&!?A.[Š.'!?B-ýs\‰7ÿ8Ä*V"&5467&#"#"&546232>54632"&546232>54632"&5467&#"%#"&546232>54632"&5467&#""'#ZM,C"'$YM,CU"'#ZM#L"'#Z´\J,C"(#YM,C"(#: A?/ýs\‰.'& @@/[Š.û×/& @?0\‰9 A?/ýs\‰åa„.'& @@/[Š.' A?/Vÿ8z3:A%.546754632"&5467&#"#"&54623257>54&'#>nz†bdQ,B"'aLm/‡adP,C"(`TbmyVTbmnaU \h˜8\‰.'Ï8 Zo:g˜8\‰.'&ÏQT]Š‘ST7ÿ8wgkry2"&5467&#"!54632"&5467&#"#"&546232>=!#"&546232>=.5467546!!>54&'©,C"'% ]N,C"'%RmmR]N,B"'$þô]N,C"'%RmnQ]  þôù_GG_XH^^H.'!?B-55[Š.'!?B-B¸ŽB\‰.'&!?A.55\‰.'!?B-BZ\B[ŠüÜñùQÕ‚þÆ‚PR€>ÿú7ò #"&5462"&5462#"&5462p,æ,,þ,Ó,þS,,>ÿú7ò"&5462#"&5462"&54627,,þ,æ,,Ó,,þS,Hÿú²ò #"&5462#"&5462²,,Ó,þS,>ÿú7ò%"&5462#"&5462"&5462#"&54627,,þ,®,,þ,Ó,,þS,,>å>à "&5462!5!s,,êþÁ,û8>þì %!5!7"&5462"&5462>þÀ$&%!. $&%!. å8–"!þ"!>>ì !+"&5462"&54625!5!%"&5462"&5462>$&%!. $&%!. þþo$&%!. $&%!. ³"!þ"!8–"!þ"!8 Eâ %"&5462"&5462%632327#".#"u$&%!. $&%!. þÃ&w&TP T‚)TL O'©"!þ"!b„77m –76Y8ŸE@7632327#".#"8&w&TP T‚)TL O'¼„77m –76Y8ŸE@%&#"#"'732>32E'O LT)‚T PT&w¼ Y67– m776ÿüÒ3&54>54'7Ò65j ’!'!U€‰)\V"Y"Ž$I3AU*(80EÒ#"'#7&#"'63273327E‚.6A6N6&N(&w+5A6N=$TG–$¥Ä)X„$¥Ã+l>>·5!5#".#"'632327>þþ%uB0<O~ B.;M&9´…"*"m —")"Yÿÿ>>· ¿|6À8ÿÌE6 &#"!!#7#537#"'732>?332E'O JþæG6G®Å6:0‚T:B;63w3 Y»8´³8ˆ)– m 1 “€>;>û#".#"'632327!5!!5!>~(RKM&%u%SNPþþñ–66X„76lþë8â8> >û%-#7#537!5!733#!#".#"'632327>þ¿0D0{­aþò@0D0|®a~(RKM&%u%SNP<324d4324d€–66X„76l>ÿÌ>6,%!#7#537#537.#"'63273327#"'3#!>þÌ,6,–¬.Úð$ <1M&%u,456?P~Úð.;oo8r8[/X„&…ž l –E8r8KE·%#".#"'6323275#".#"'632327E!C/<O&&v&TP S)TL O&&w&TP S­—")"Y…77mÕ—76Y…77m8ÿÌE6.#"'327#"'#7&#"'6327.#"'63273327E&)NS9JJ6V$O&&w&)#0O&&v3KJ6U$S­—h0m —<»ØY…gY…:¹Öm>;>û$(#".#"'632327#".#"'632327!5!>~(QKL'%uB/=Q~(RKM&%u%SNPþñ–66X„")"l³–66X„76lþë8>>û$6#".#"'63232?#".#"'632327#".#"'632327>~(RKM&%u%SNP~(QKL'%uB/=Q~(RKM&%u%SNPG–66X„76l¡–66X„")"lþ£–66X„76l3<IÆ)#".'7327& '4>32I!(2C%&B3'! [¢¤Z[þºZ 01N+%C3'!½# # ggþ ff ') $ >;>Ç#4&"#53>23#"&'#532653>µ):(À•>Ç#4&"#53>23!5!>´):(Á–>9 "&462!5!!5!s,,êþþ,,ï8þý8>ÿÉ>9 "&462!5!!5!"&462s,,êþþË,,,,ï8þý8£,,>ÿÉ>9 !5!$#"&462#"&4627!5!>þþj,µ,þJ8˜,,ýÛ,,L8>ÿÉ>9 #"&462!5!!5!#"&462>,þþþj,,,ï8þý8£,,Qì!5!!5!%"&5462"&5462þþý¯%&$ .!%&$ .!J8þý8ü!"þ‚!">þì "&5462"&5462'!5!!5!þ$&%!. $&%!. Àþþ³"!þ"!æ8þý8>>ƒ%53&547#5!#3'4&#"326>þ¼ ½½! ¼¾'"!&€8,-98,+H(+,%>>Ÿ #"&4632!5!!5!4&#"32¢;)*99*)×þþËdR::R;þ«8þý8n,"$#>>ˆ 3''!5!!5!2´¨¨Àþþˆ„ {{ º8þý8>>ˆ '77!5!!5!2´¨¨´ôþþä„ {{ „š8þý8>>Í #3!5!!5!'¼üy ûþþÃ>>Ëþ}8þý8<††>ÿÌ>6%!#7#537!5!733#!>þçG6G±È:þþG6G±È:€´³8“8´³8“>;>Ç !5!!5!!5!>þþþ8â8â8>ÿÌ>6%!#7#537#537!5!733#3#!>þÌ,6,–¬.Úð.þâ4,6,–¬.Úð.;oo8r8r8oo8r8r>ÿæ> !5!5!5!!5!!5!>þþþþ:8r8þt8â8>ÿÆ>> -5% !5!>þþ` þHðò8Ãú5>ÿÆ>> 5-5!5!>þ þ`þ9ò8ÃÃ9ñþy5>ÿ„>~ -5% !5!!5!>þþ` þþˆðò8Ãä5Í5>ÿ„>~ 5-5!5!!5!>þ þ`þþyò8ÃÃ9ñþ5Í5>ÿR>~-5% %#7#537!5!733#!>þþ` þ¿0D0{­aþò@0D0|®aˆðò8ÃÃþÄ324d4324d>ÿR>~5-5%#7#537!5!733#!>þ þ`þ¿0D0{­aþò@0D0|®ayò8ÃÃ9ñý÷324d4324d4bü -5% %5% býûþ\¤þ×ýûþ\¤òñ8ÃÄ8òñ8ÃÄ4bü %5-5 5-5býû¤þ\þ×ýû¤þ\÷ò8ÄÃ8ñò8ÄÃ8ñ>ÿV\ž!)&''67.547&'7>74'6\7A#2 4,,4 2#A7u1 "''" 1uIFFFF k¥E-  ))  -E¥k»y)&&)y¼ŸqqŸÄpp3ÿÌI63%&+#7'>?.'7;7367IZ¤ U6StG (*?$$?1%  Z£ U6TtG!*7)I0-F eÕÑP "&M" fÖÒQ  M'#>ÿš>h-#'5%737>þë_6g½U6IŸºHü¤p‚îY‡Ö·K8W¶yM5>ÿš>h%#75?%573'>þáU6IŸºHþþ_6g½`p4÷‡Ö·K8W¶y8‚îþüY 5‚>ÿ^>¤%#7#537'5%737'!>þž*6*h|WÓ?M6AšRìÿONÜĆ:ih4Ûc—Á¢<8IÏn9yÅ£[?>ÿ^>¤%#7#5375?%573!'>þž*6*h|C¿Ú>þè+a6i§ÿON`Z):ih4§Z8gœƒ9óþ÷NxÆH*h>ÿ>>%-5% #".#"'7>3232>5>þþ` D0%@'94? :$!@*;0 Hðò8ÃÃZ8/")"K ''"*"!+>ÿ>>%5-5#".#"'7>3232>5>þ þ`D0%@'94? :$!@*;0 9ò8ÃÃ9ñþÙ8/")"K ''"*"!+>ÿ^>¤/2%#".'#7'7>?'5%737'32>5>D0(@;<6?"4?*AÓ?M6AšRìÿ<@< 0 ÜĆ&8/&5 –ž-$ 0)¥c—Á¢<8IÏn9y— 5(!+ w[?>ÿ^>¤/2%#".'#7'7>?5?%57332>5'>D0(@;<6?"4?*-¿Ú>þè+a6i§ÿ<@< 0 `Z)&8/&5 –ž-$ 0)qZ8gœƒ9óþ÷Nx˜ 5(!+ *h>ÿ¯>S -5% 5-5>þþqþþqͺ¸2‘—º3‘2¸>ÿ¯>S 5-5%5% >þþqþþq‡º3‘2¸þº¸2‘>ÿ^>¤!%#75?'57'5%737''>þ­960n†CÉÚ÷S960n…CÈÚöÄË—‡—3i{y(31§I2OGZzy(20¨I3OFY]I7ç6>ÿ^>¤!%#7'5?5%7%5737'>þÂN6U“Î&ô "þÓ>N6U“Í&óþõ!,q3”E4QsÄÖ5J^X3aTl2rÃÔ5K^W2`Tm¯+ì>ÿó> '.'5>5> Ik¿tt¿kIM–ZI€N9 ?DCCCB$M;D33.>ÿó> %57>7./5>t¿kIM–ZZ–M Ik¿tôCCB$MÿÆ>N%'.'5>5!5!> Ik¿tt¿kI)N–ZZ–N)þ5?DCCBB$L)=CD>)»5>ÿÆ>N54>75.=!5!>t¿kI)N–ZI€N9 Ik¿tþ5CBB$L)>C310L?DCþx5>ÿ>N8%'.'5>5#".#"'7>3232>5> Ik¿tt¿kI)N–ZZ–N)D0%@'94? :$!@*;0 5?DCCBB$L)=CD>)[8/")"K ''"*"!+>ÿ>N954>75.=#".#"'7>3232>5>t¿kI)N–ZI€N9 Ik¿tD0%@'94? :$!@*;0 5CBB$L)>C310L?DCþØ8/")"K ''"*"!+>ÿš>h!&5'.'#&'5673>?%> 5oGo6v^n•qn6b1O% .X4 Nyþî+*: 5Gþé).ö<*M)6OP× >ÿš>h#%#757>?./53&'6>•rm6aY^iC P="&5332653#'73PœØž3WY}3›•Y““Y•o™šn5þÇXyR9ÿl™›l>P= 2#"&546"&5332653H+;<)*;:2œØž3WY}3°;+);;+);¨o™šn5þÇXyR9>P= ##5#53533"&5332653à3€3€pœØž3WY}33vv3‚‚^o™šn5þÇXyR94Hú%!!!!Hýìþâò2þt4Hú%!5!!5!Hýìâþ4Œ24ÿÆH< %!!!!5!HýìþâýíLñ2þvº54ÿÆH< %5!!5!!5!HýìâþýíL4Š3ýŠ5>P#!#!#!P3þT3ðþ#>P#)3!3Pýî3¬3#þðÿÔk. "&462.''3'>5#k±ø±±øƒ„],]„èé\…þóé„~ú°°ú°þê]ƒèè„\.鄌é]„ÿÔk. "&462."%326k±ø±±øƒ “Æ”þþ“dc“~ú°°ú°þêb‡‡b.bˆ‡ÿÔk. "&462&#"4'/'32k±ø±±ø(I[]G¤<¤¤ä¤<<h¤¤G][~ú°°ú°i<<¤}ºG¤¤¤¤GºG ¤¤<ÿÔk."&462&#"%4'326k±ø±±ø(I[j–<Ä<þ˜G]i—~ú°°ú°i<–j]G¤]Gþ˜<–ÿÔk."&4624&#"32"&5462k±ø±±ø„—ij––ji2$&% .!~ú°°ú°þiÔ––Ô–!"ÿÔk.%"&4624&#"32#"&4624&#"2k±ø±±ø„—ij––ji-X=>YX|W,>+,==X~ú°°ú°þjÒ—–Ô–=XW|WX=+V=7.546324&54632>23#"&'"&465"&k±ø±±ø„—ij––jiþé0V V; k  p0UV2 k  o~ú°°ú°þiÔ––Ô–²_ce^  _ce\ÿÔk. %!5!6"&4624&#"32!5!óþ–jx±ø±±ø„—ij––jiLþ–j®.¢ú°°ú°þiÔ––Ô–%.ÿÔk."&4624&#"327!5!k±ø±±ø„—ij––ji[þxˆ~ú°°ú°þiÔ––Ô–é.=? )!5##5#5##5#?ýþ8­8­’­8­å­­­­å­­­­=? )!5!5!?ýþ8þn’þnå­­å­­=? )!!#''?ýþ`þ¾¡É¡P¡j¡¡8¡ÉB¡¡þ¾(¡¡=?)!!$#"&5462?ýþ8þn""!0þ6’þnà0!!">%!#3!þ`88 åååÿÿ> TÀ>Š&!#!5!Šþö8þöLîþî8>Š&)5!3!Šý´ 8 8îþ>”%!#3!”þâ88ååå>” %!#3!!!”þâ88þ 8“> %!#3!#3þâ88þh88åååþã>ˆ %!#3!#3#3ˆþâ88þh88z88åååþãýþ> %!#3!!!#3þâ88þâþh88€€8“¸ÿÓ”%##5#733733#”ÔJ8*Ak82©Cªªþêåbƒ88såãã8 ÿÓ”%!#5#733733#3'#”þâ8*Ak8~]C^^ˆnöÊT€€88s}}8““qÿÓ%!#5#5#7373733þî 8B8 Kk8B8ÑMÜÜå ÙŸD[!!o“þ§DÛÙãÿÓ%!#5#5#73733733#!'#þâ8B8 Kk8B8XyMyy¯oü"€€ŸD[!!o“þ§D}}8r!“$>>ü-5%>þ2þ’ññþYX¬>>ü%%>þ`þ’÷ñöñ ¬þ¨>ÿÆ>> -5%!5!'>þþ2þ’Hðòýˆ5œW«>ÿÆ>> !5!%>þþ`þ’9ò÷ñþy5H«þ©>YÒ¨#"&'!#"&4632!>324&"2ÒbF?] þ ^>FbbF>] ú ]>FüìEbEEbFŒaP<YÒ¨#"&'!#"&4632!>324&"2ÒbF?] þ ^>FbbF>] ú ]>F0EbEEbFŒaP<Yˆ¨ #"&'!5!>324&"2ˆbF?] þý ]>F0EbEEbFŒaP<8P½ #3!5!Pþÿÿ9ÏÑ9ýî½ýÕ+þ9ÇýC4>P½ !5!# #3Pýî9ÏÑ9‰4ýCÇþ9+>P½ !5!#3Pýîÿþÿ9Ñω4’ýÕ+þ9Çÿÿ>P, ªÿÿ>P, «ÿÿ>P= ¬ÿÿ>P= ­*"Öà'7'ÖÖÖÖ™™™™ßßßߢ¢¢EÒ©6 #"&54632©@m–² 373'7@‚))‚j(ii(6||L}MM}9ÿã>$ %"&5462"&5462'773#''7#5L" (!" (tÀ%ÝÝ%ÀÁÁÀ%ÝÝ%À»Áþ Á%ÞÞ%Á8Á%ÞÞ%Á8?/‘}7#"&54632 632#"'%7a   þùäþâå4 & þû ýÚ ÆÅââþ;ã4ÿÞü¦! ' 7ü"þ¾þ¾"Bþ¾""Bþ¾"BB"4ÿÞü¦! 'ü"þ¾þ¾"¦"þ¾"Bþ¾"¦"þ¾>>·732>32&#"#"!5!>O<0Bu%&M;.B ~æþþ­ m"*"…Y")"—92K#.'3>7K5]>' 9sELDggD~›Ž>W¾È#1ÒddÒ12K%#.'#>73KMDggDLEs9 '>]1ÒddÒ1#ȾW>Ž›~4Hú!%!"&5463!!"3!!"&463!!"3!Hþð5IJ4þï+-þâggþÞQouK"„J32K2,>,®”Ê”2vQRu4Hú!#!5!2654&#!5!2#!5!264&#!5!2Hgþâ"KuoQþÞg J4þð+-þï5IfÊ”2uRQv2ù2K2,>*4J>P=!!#4&#"#462#4&"#4632P3WY}3œØžu2:P:2W<=X9XyRþÇ5o™šnþË,)7:&þÔ*>WW>>P=!#"&532653"&5332653ÛW<=X2:P:2uœØž3WY}3>WW>*þÔ)7;%,þËo™šn5þÇXyR9>PÜ!#4&'##46753P3kO8Ok3Šb8dŠ9Kz ýø uPþÇ5g” ¡  •g>ÿò>¤%3##5##5#535#533333#5#ް°(P(°°°°(P(°°(P·88“8"þÞ"þÞ8“““>>ü #"&5462%5% ø,eþþ` ,þÏòñ8ÃÄ>>ü%5-5$#"&5462>þ þ`þ°,÷ò8ÄÃ8ñ ,4‹ý -5% %5% %5% ‹ýûþ\¤þ×ýûþ\¤þ×ýûþ\¤òñ8ÃÄ8òñ8ÃÄ8òñ8ÃÄ4‹ý %5-5 5-5 5-5‹ýû¤þ\þ×ýû¤þ\þ×ýû¤þ\øò8ÄÃ8ñò8ÄÃ8ñò8ÄÃ8ñ>ÿ*>Ø %5% !5!5-5>þþqþþþqRº¸2‘ž4þɺ3‘2¸>ÿ*>Ø 5-5!5!%5% >þþqþþþq º3‘2¸þÇ4þº¸2‘>ÿº>H 5%%5% >þþþ` ò8òýrñò8ÃÃ>ÿº>H %55-5>þþ þ`ð9ñ¬ñ8ÃÃ9ñ>ÿª>X '5>54.'5>?>HiÁwq½lKIk¿tt¿kI )N–ZZ–N)  ??C2EII)ýR$BBCCD?L)>DC=)>ÿª>X '.=54>75.=>wÁiH Kl½qt¿kI)N–ZZ–N) Ik¿tC?>!MFJFšCBB$L)=CD>)L?DC>ÿš>h/5'.'#7&'57&'56?3>5'.'>:wJ\6cRgqYa…©J6:-3V>Oçø2G$;º–+SLU&i8+L2CED4 x  >ÿš>h/5%#754>?54>?.=7367'5&'6>¢€R6BGQ[@&Ln6f=Cp: :zNV6\Oc~e&w’™ ¾?Í¥._M%K b#WL/;9<2!L$;I×ç%^/\4ÿ^H¤%#7#537#!733#!!!!3Hþ”*6*q…!§l*6*r†#þÉ!X¼þÚ‰:ih4Qðih2þv4Qþu4ÿ^H¤%!!!#7#537#53!5!733#HþÉ!Wþ•*6*r†!§»þ¨l*6*r2TLQ4ih4Q4Š2ihþDŠþv4ÿ”H<%!!!733!#7#5Hýìþâþí.D.Ïþÿ.D.ÎLñ2þv…2252254ÿ”H<%5!!5!733!#7#5Hýìâþþí.D.Îÿ.D.ÏL4Š3ý¿225225>ÿ>>)-5% #"'#7&#"'7>327332>5>þþ` D056#DB,&4? :$16$DA-(0 Hðò8ÃÃZ8/+'F#K ''+'F$!+>ÿ>>)5-5#"'#7&#"'7>327332>5>þ þ`D056#DB,&4? :$16$DA-(0 9ò8ÃÃ9ñþÙ8/+'F#K ''+'F$!+>ÿ>N<%'.'5>5#"'#7&#"'7>327332>5> Ik¿tt¿kI)N–ZZ–N)D056#DB,&4? :$16$DA-(0 5?DCCBB$L)=CD>)[8/+'F#K ''+'F$!+>ÿ>N=54>75.=#"'#7&#"'7>327332>5>t¿kI)N–ZI€N9 Ik¿tD056#DB,&4? :$16$DA-(0 5CBB$L)>C310L?DCþØ8/+'F#K ''+'F$!+>ÿš>h -#'5%7377>þë_6g½U6IŸ2ˆH¤p‚îY‡Ö·KþYX@¶—M5>ÿš>h %#773'7'7>þáU6IŸ_6g½`p4Ј÷‡Ö·Kö‚îþüY 5‚—bþ¨@>ÿ^>¤%#7#537'5%737'!'7>þž*6*h|WÓ?M6AÿON2hRĆ:ih4Ûc—Á¢<þ yÅœW1ϰ[?>ÿ^>¤%#7#53773!'/7>þž*6*h|C¿+a6i§ÿON`Z)æ¨:ih4§Z÷óþ÷NxÆH*h}lþ©OE©þ #2#"&5462#"&5462#"&546wþþ³þ³tÒr6 ##"&54632#"&54632#"&54632rþ³þ³trþ ##"&54632#"&54632#"&54632rþ³þ³ÌþŸþŸtrþ #4632#"&4632#"&4632#"&tMMÌþÈþÈ5ÿ«ÒI *5"&632762#"'#"&54?&542>54'ƒ.I) ,5íCcX@• •8‹aW@•  •7ë.J) ,þí5½!/:*D7,E7•  •CUb‰7•  •DTaþÜ!/:*D7þî,#ÿŸ—¶$%32#"&/4737!"&547632!2 1•  IpþÕ ¦  —+n § ©Ò N þÏ>Oœ­!#!œþÞ<^qþÞ^>Oœ­#!5!œ<þÞ^O"<>œ^)3!œþ¢<"^þÞ>œ^)5!3œþ¢"<<"ÿÿl‚Cn4À@HÜ”44'&#"3276632#"'&54##"&547546232³TVwxUUªxvWTýö_ŠˆÂaaˆ‰`aål   l JxTVUWvxªUTbaˆŠ_a`a‰ˆœ ª ª  Lÿ­Ëš"#4>32#"&547&TJkS3GW?"7(!dþîÕþ0ešó‡X'.&#ÿÿ ÿ¬Ÿ™ iëFÀ>œT<%&#"'7>2TZ¤£Z 01NVM11¦ ff **>œT<#".'7327T!'3C%&B3'! Z£¤Z3 $ # ffÿ:2ê2ÚÚ3ææÑþAþAØØÿ:.ê'7.æ3ÚÚ3þ(¿¿7ÿbÐ’#%#&'!!673!2#!!"&5463!2 (bHý¸b(!EéþEÔý q Sj6þ˜Þþ˜6jV=(=þ¹  üø 7ÿbÐ’#&'3!!#67!"43!"&5463!2eE!(bý¸Hb(!EþAý q =Vj6hý"h6jV=(þT  üø 7ÿbÐ’$567&'!!!&5!"&5463!2p=Uo75qW; ý¸ Lý q E!+lk,!EýŠÞý";  üø 7ÿbÐ’$%&'547!!!6!"&5463!2*q57oU= þäHþä ;éý q G,kl+!Evý"ÞýŠEÄ  üø 7ÿbÐ’463!2#!"&5#&/#!7 q ý }ôH~ üø óõõý"ÞLŸ #2ŸSR üà -Ê  73!2=3!5F  4þc Z1V  #ÿóòÂ/;!5326=4&+567'2 &5464.#"326½$þý# Fl-‘ÑÓþÖÒÕÙ5L]H–bT¿ˆ‡¿LþŒ$!!(î  ?vÕ’•ÓÓ—•Ðþ™JwF.l\|‰ÀÀ#ÿóòÂ)5E326=3!&54>4&#"#"&54632'2#"&5464.#"326*/GJA Ä!!þ¯.AA."# P=LZš‘ÑÒ•–ÒÕÙ5L]H–bT¿ˆ‡¿Ò+>!"*³ )I87FL/  +8FµÕ’•ÓÓ—•Ðþ˜JxE/l]{‰ÁÀ#ÿóòÂ>JY%32654&#"532654&#""&546323#"&546322#"&5464.#" 6F):5- ,:'&TCELS #.nUCYJ‘ÑÒ•–ÒÕÙ5L]H–bT¾¿Ú E0+3$5-")  '171K 2!AT;-ÒÕ’•ÓÓ—”Ñþ™JwF.l\|‰À¿#ÿòòÁ#3%;#5326=#533#32#"&5464.#"326Ë ñ/ÁÕBooV‡‡‘ÑÒ•–ÒÕÙ5L]H–bT¿ˆ‡¿Â!!'AþÐ-ÿÒ¥Õ’•ÓÓ—•Ðþ™JwF.l\|‰À¿#ÿóòÂ0<L%32654&#"'67327#"#"'632#"&546322#"&5464.#"3269 (8-#*')s*I5-!%&- .DEZrUAVW‘ÑÒ•–ÒÕÙ5L]H–bT¿ˆ‡¿Û  D1-;2˜l( y$O=BY8*ÕÕ’•ÓÓ—”Ñþ™JwF.l\|‰À¿#ÿóòÂ%1<K4654&#"632#".547632#"&"32654&2 &5464.#" 6Å 3S;NfN8Q)D.W@S4)72('1-&‘ÑÓþÖÒÕÙ5L]H–bT¾¿ê ]5)KL:G]/KJ%wN64(o?/0>=/3=WÕ’•ÓÓ—•Ðþ™JwF.l\|‰À¿#ÿóòÂ)8%"&54>?##5!2#"&5464.#" 6 "4# 8H¶ d] "‘ÑÒ•–ÒÕÙ5L]H–bT¾¿ð0  $I-Ie ""§š4J´Õ’•ÓÓ—”Ñþ™JwF.l]{‰À¿#ÿóòÂ"-9H#"&5467.54632'654&#"'326542#"&5464.#" 6Ê:2eNJY,8&R@8H t*2) (S:D7)(6O‘ÑÒ•–ÒÕÙ5L]H–bT¾¿A-BUE9*: ,!6E6*, /&#$•!(E*71%3©Õ’•ÓÓ—”Ñþ™JwF.l\|‰À¿#ÿóòÂ#/;K%327>54'#"&54632#"&54632"32654&'2#"&5464.#"326P 1U;NgNXln[@T9&2-&)73!‘ÑÒ•–ÒÕÙ5L]H–bT¿ˆ‡¿Ø^4KL:G]€ioŒ4(J=/3=@.0>Õ’•ÓÓ—”Ñþ™JwF.l\|‰À¿#ÿóòÂ&2B;#53265.+567"54632"3254'2#"&5464.#"326>Æ  3b"ÝJF—MF434 ‘ÑÒ•–ÒÕÙ5L]H–bT¿ˆ‡¿Mþ{##  9þ"òu}û~kÃÏÐÏÐÕ’•ÓÓ—”Ñþ™JwF.l\|‰À¿yD!!yü‡D0üy\!!yü‡\`°ÿ8à!3#°00!ü˜ÿ8ø!3#˜``!ü°ÿ8yD!!#°Éþg0D0þ$°ÿ8y\!!#°Éþg0\`þ<˜ÿ8yD!!#˜áþ`D0þ$˜ÿ8y\!!#˜áþ`\`þ<ÿ8àD#!5à0þPDýôÜ0ÿ8à\#!5à0þP\ýÜÄ`ÿ8øD#!5ø`þhDýôÜ0ÿ8ø\#!5ø`þh\ýÜÄ`°y!3!°0™ þ#0°üy!%3!°0™ü%þ;`˜y!3!˜` þ#0˜üy!%3!˜`ü%þ;`à!!5!3àþ °00Ýüà!%!5!3àþ °0ü`Åø!!5!3øþ˜`0Ýüø!%!5!3øþ˜`ü`Űÿ8y!3!!°0™þgÈéþ#0þ$°ÿ8y!!!#3à™þg00\`þ<é˜ÿ8y! #3!!#°`þg0 þ#0þ$˜ÿ8y! 3!!#°0™þ`DÝþ#0þ$ ˜ÿ8y!!!#3øþ``D0þ$é˜ÿ8y! %#3!!#°`þg0ü%þ;`þ<˜ÿ8y! 3!!#°0™þ`\Åþ;`þ<$˜ÿ8y!3!!˜`þÈéþ;`þ<ÿ8à!#!5!à0þP°!üÜ0Ýÿ8à!#!5!à0þP°!üÄ`Åÿ8ø! !3##!˜`0þPDÝýóþ$Üÿ8ø! 3#!5!3à`þh°0DýôÜ0Ýÿ8ø!#!5!ø`þh˜!üÜ0Ýÿ8ø! %!5!3##°þP˜`0ü`ÅýÛþ<ÿ8ø! 33#!5°0`þh\Åþ;ýÜÄ`ÿ8ø!#!5!ø`þh˜!ü(`aÿ8yD!!#!yþg0þPD0þ$Üÿ8y\ #!5!!à0þPà™þ$Ä`0ÿ8y\ 5!!#!5°Éþg0þPD`þ<Ü0ÿ8y\%!5!!#°þPyþg0ü``þ<ÿ8yD#!5!ø`þhyþ$Ü00ÿ8y\ #!5!!ø`þhøþ$Ä`0ÿ8y\ !5!5!!#˜þh˜áþ`0`þ<ÿ8y\!!#!yþ`þh\`þ<Äy!!5!3!yü‡°0™0Ýþ#üy! !!!5!3à™þgþ °0D0`Åüy! !!5!5!à™þ7þP°!þ;`0Ýüy!!!5!3à™ü‡°0\``Åy!3!!5˜`ü‡DÝþ#00üy! !!!5!3øþþ˜`D0`Åüy! !5!3!!˜þh˜`þ0Ýþ;`üy!%!5!3!yü‡˜`ü`Åþ;ÿ8y! !5!3!!#°þP°0™þg00Ýþ#0þ$ÿ8y! #!5!3!à0þP°0™þ$Ä`Åþ#0ÿ8y! !!#!5!3à™þg0þP°0\`þ<Ü0Ýÿ8y! !!#!5!3à™þg0þP°0\`þ<Ä`Åÿ8y! 3!!#!5˜`þg0þPDÝþ#0þ$Ü0ÿ8y! #!5!3!ø`þh°0™þ$Ü0Ýþ#0ÿ8y! !5!3!!#˜þh˜`þ`0Ýþ#0þ$ÿ8y! ##!5!3!ø0þP˜`þ<Ä`Åþ#0ÿ8y! %#5!5!3!!#°þh˜`þg0ü0Ýþ;`þ<ÿ8y! 3!!#!5!3àþ`þh°0\0þ$Ä`Åÿ8y! 533!!#!5˜0™þ`þhDÅþ;`þ<Ü0ÿ8y! %!5!3!!#°þP˜`þg0ü`Åþ;`þ<ÿ8y! 3!!#!5°0™þ`þh\Åþ;`þ<Ä`ÿ8y! #!5!3!ø`þh˜`þ$Ä`Åþ#0ÿ8y! !5!3!!#˜þh˜`þ`0Ýþ;`þ<ÿ8y! %!5!3!!#˜þh˜`þ`ü`Åþ;`þ<ÌyŒ5!!5!!yü‡yü‡ü0À0hÿ8(!3#3#h0000!üéü°ÿ8yŒ !!!!#°Éþg™þg0Œ0`0þlhÿ8yD !!###hþ¯0`0D0þ$Üþ$hÿ8yŒ %263!+!!ø+çoþ¯0`0þû0þlT0ÿ8àŒ #!5!5!5à0þP°þPŒý¬”0`0ÿ8(D ###!5(0`0þ˜DýôÜþ$Ü0ÿ8(Œ %#!=!#˜0þ˜(0ûþ=”0`0ý¬$°Ìy! %3!!!°0™þg™ÌUþk0`0hy! 333!h0`0Q þ#Ýþ#0hÌy! %!373!yýï0`0Qü0UýÚaÅþk0Ìà! %!5!5!5!3àþ °þP°0Ì0`0•(! !5!333(ýØh0`00Ýþ#ÝÌ(! 3!5'!5!3ø0ýØø`þhh0!ý«0a0•°ÿ8y! 3!!!!°0™þg™þgÈéþk0`0þlhÿ8y! 3!!+3ø0Qþ¯0`00!þ#0þ$éhÿ8y! 33!!!#h0`0Qþþ¯0Èéüéþk0`0þlÄÿ8à! #!5!5!5!à0þP°þP°!ü”0`0•ÿ8(! 3+!5!3ø00`0þ˜h0!üÜ0Ýÿ8(! 35!3#!5!ø0ýØh00þ˜˜Èéü$0•þ;ýÜ”0ÿ8yŒ !!!#!5yü‡yþg0þPŒ0`0þl”0ÿ8yD !!###!yþ¯0`0þ˜D0þ$Üþ$Üÿ8yŒ !!!##!5!yü‡yþ¯0`0þ˜˜Œ0`0þlÄþ<”0Ìy! %!5!%5!3!yü‡yü‡°0™Ì0`0•þk0y! !5!333!yü‡h0`0Q0Ýþ#Ýþ#Ìy! %!5!3!)5!3yü‡yþ0Qþþh0Ì0%þk00•þ;ÿ8y!!5!3!!!!#!5!°þP°0™þg™þg0þP°\0•þk0`0þl”0ÿ8y!##!5!333!!#ø`0þ˜h0`0Qþ¯0þ$Ü0Ýþ#Ýþ#0þ$ÿ8y! #!5!3!!!#%5!3˜0þ˜˜`0Qþþ¯0þh0È”0%þk0`0þlÄ`0•þ;°y¨!#5467à0øÑ«îºç0×Èù¼%!!ùýùÈôÿ8ùÿµ!5!ùýùÈ}ÿ8ù2!5!ùýùÈúÿ8ù¯!!ùýùÈwÿ8ù,!!ùýùÈôÿ8ù©!!ùýùÈqÿ8ù&!!ùýùÈîÿ8ù£!!ùýùÈkÿ8ù !!ùýùÈèÿ8š !!šýfšÈèÿ8; !!;ýÅ;Èèÿ8Ü !!Üþ$ÜÈèÿ8} !!}þƒ}Èèÿ8 !!þâÈèÿ8¿ #3¿¿¿Èèÿ8` #3```Èè|ÿ8ù !!ùþƒ}Èè£ù !5!ùýù£}™ÿ8ù #3ù``Èè#Ö³)!ÖýM³³#Ö³)!!ÖýM³ ý³ýmsý#ZÂ)ZüÉœÂ^ÿÆ ü^Â:6þd#ÿòZ³ Zþeþd³ý?Á^ÿÆ ü ý>üüÊœ#ÿòòÁ ‹þ˜hghgþ™Òä 33' Ñ¿Ä?½Å¢¤ykþ’þŠ:<5þÎ#ÿòõÄ "32654&'2#"&546‘‹ÃÀ‰ˆÁÀƒ‘ÒÔ•–ÓÖ¤¾ˆŠÂÁˆ‡Â Õ”•ÔÕ—•Ñ›r"/:CMW&'#5#&'7'&#"'632'654'>7#'>7&47#"'7327%&'#'n? + È ! + Ki  ?! 'þÊ A*=MM;##"& !þñ-6 !ß++ ; HHï!" # ù +2 À   ++þÌ #@#  þóIn ö=#Ö³)!!ÖýM³þ§þƳýmsý#Ö³7!!!Cs ýM³ sým³#Ö³!!!¶ý“ýM³“ý ³#ÿóà !''!™U çYçæZêÃþò®þ쪪®#Ï ''%77'7'žbÏFìæ<ÑgHì°0¶¸>¦ÜÏò¸þó—— ¸›¼Ôz|Ò”7¥n*732654.#"4>327632"'&`*5% Hg$A)If)%4@/N;ë ë2°A?×*B$hG &3+gH3Q- 2ë  ë=MY~??7ÿ”§q2=2>54&#"".546327&54632#"'4&#"32#/I(sPQrsP8Y1 ‹aPBV;Ša8X2 EEbR?W;ECùuOPstOQD!/:*QrsPQr((9F2b‰2²CYaŠ(9F2`GE3²CYaEE¢ stOQr"Š­609EOZ%+!"'"'>7654'#"'67>32#"'.''627&#""32654&%#"&'32%#"&'32Aþx !$ (A¯ZY¯@(ü<<E):8)(99 =$2%,þ/ ,1!7È=^U  C!!D  h))N8()99(':   ÿÿ#Ö³ þ#Ö³#4632327>763#"&'.!!!—3  7z&#IJÂ5 ?ýM³ ý/]­" Oþòc $Wó³ýmsýÿÿ#Ö³+ €‚v*= þÿÿyö: É#z8*;263326767>54.'.#"%#"'32654&#"‰l 46h:4M'5( ,¥2ZÝ™R($ $*1# !' 6 U.+=[.B_®KS]OPq#z8*;"&##"&'&'.54>7>32%327#"&546327l 46h:4M'5( ,¥2ZÝ™üðR($ $*1# !' 6 U.+=[.B_®KS]OPq#…ˆ/*.Xbu„’%2>737'#"&#"&#"3327#'23#"'5>7>737'#"'7'#"&54?6432#"&2632#"'.47"&54632'#"&546Ð4F6#S iÈ |(+$£¢i‹" X6,x 6î!€, .O 6C %2'+ ;$Gþtü?G€eE! ]$&"l `  ”<8 #J ¡1 Z "L .!$ 2Cþð0RÆ #*51  G=2Ra !*  ˆ*" 1  $ ÿ¨É *.V_rŽ#!7#54654'654&#"&#"&#"&#"%5!7#4./&54737'&5477'&546322'546#"&5476324632#"&7#"&54632;0Z "K / # 2Cþñ0RÆ  .# +40  H<2Ra " * ˆ)# 1  # `4F6#S hÇ|)*&£¢j‹" X6-þ—6î!€, ,R ! 6B $2(, <"HŽüTH$eþº"![2 $%"l b  ”<8"J #…ˆ/*.[i}¤%".'#'732632632##"'33275.'.'#'7327'732654/&#"%327654'.#"#"'&#"327>4"327>54&"32654&Û4F6#S iÈ|)*%£¢i‹" X6,þˆ 6! .O 6C %2'+ ;$G#(4G¯''„= !. ]N  (7  ' #J ¡1 Z "L .!$ 2Cþð"Æ  #*51  G!DR  ~% !* A&   Q $ ÿ¨É ,0]j}¤4>7#5'7!##"&5#"'#"'#"&547&!#3>7>757732?654'&'.327>54&'&54?4&#"324'&/.#"3264'./&'&#"326;0Z "L / # 2Cþñ"Æ # +40  H"DR  ~$" * A&  R  # T4F5#T hÈ |)*&¢¢i‹" X6-i7!-Q 6B $2(, <"H"%4þïH$³#'…< !/ ![1N   '7   "J Þ»"_go€#"/.5462#"/7326767632#"'#"'&'#"'"54>767&'#"547&54323254#"3254#"3273254.3  ?ZˆY !  !  !$ C"W0 !'O?R, ?2<6.  "?I2+*%&%&…&%$' {290?HI>&E0(--¾#5  ' ) 75"13 $%  6 +.&)+.&N  VÌI"46462#"&#&'27#"'òn1×Y¥%2$$$ØD\×1a6nEXVKG¹7Z‘ê$%##*$‘U;ª¸,(ÿû¯q&Lm{‡”4>3"&#"&'4>7&%4&'2654.#"'654&+5>2654'7372657#"'#"'4632&#""&6=63&'2.54¨,5**< <* #/K?R$:, IL?*D( NO$4)K-# )< þ¶?Q#  #D?-D"A/SB9Rn8,‡H.:4 /(0(¡ZD1 à Y2A·*D( %1'&2$) HV@("&:T*$CCN,6*%"i=5*!#*> D )#/'þHW;!   !'1R ! $!GDZ/ ) þùm =\µ`$V<#̳7'75#535#53533#3#7#ÏH"j¬¬\\Q\\¬¬I"kQe!H1¶PPPPPPPP!H2Š#̳3##5#535#53533 ¬¬Q¬¬\\Q\ÍæP——PæP––PHÝš"?#"&54632373'7ïz¨Thbs6V=ÀÂŽh^aaONNm¨xwTh#!‹ŒÁCä\\8]99]ÿînúlu4'6.54675#7.5467&'7#>54&'&'"&547&'"5475"&547>77>54' V+!ª dH15$,H$J-AG5 ZZ 5GA-Jfr>(Ge |3Z&l&Z4|ö!+V ô5?Z'< Eþ«3IGS#Lx$!,-J*# ,&X4=Y .. Z=6V,`[;x#zK-gRQ`J   08v$**$v80   L° <'Z?5+HÜ” )#"'&54763!'6'7654.'Âaaˆ‰`aa_Š¿~«`ˆ«TW-]Q3HÆîG3Q\-”ˆŠ_a`a‰ˆaaýܨðî¬BD)FoAnQÉÉPoBoE)þèCÝš ,832654'&#"632#"&546324&#"3262#"&546YCBY\[€Jt@* ‡AZÈþÉoÀÁŒÀÁRD\]C|\Z5J^@œXD_‹ŒÁ‹ŒÁ2&ô 3!5!5!5!5!5!2ôþ ôþ ôþ ddddd2&ô 35+3!5!5!5!^ÈÈdÈÈÈôþ ôþ ddþpddd2&ô 3!5!%35+3'!5!2ôþ ,ÈÈdÈÈÈôþ ddddÈd2&ô 35+335+3!5!^ÈÈdÈÈdÈÈdÈÈÈôþ ddÈddÈd2&ô 7#553!5!5úÈ,Èþ ôþ ddddddôddÈdd2&ô 35+335+3'!5!^ÈÈdÈÈdÈÈdÈÈÈôþ ddþpddÈd2&ô %3+5373+53'!!^ÈÈdÈÈdÈÈdÈÈÈôþ dddÈddÈd2&ô 35+335+335+3^ÈÈdÈÈdÈÈdÈÈdÈÈdÈÈddÈddÈdd CÝšYp…š¯¹Îãø %&'#"54323&'#"543247#"543267&542&5432#"'632#"'2632#"547"54&'&'&'26326326323#"'#"'#"'676767&547&547&5475&547&547&5472654&"7263263263&'67#"'#"'#"67&'&'&'676767&'ƒbF"!  A !! F !"GaBaG!"! F !! A !"!FbB-         + )/  0( $&{       9 /)  (0 @@  !"Ga!"ZN!"! @ !! @ !"!NZ"!aG"!  @ !!: )/ > /) +         {6 0(K )/ -    °   HÜ”)2;4'&#"3276632#"'&54&#"'>32'"&4622"&4632³TVwxUUªxvWTýö_ŠˆÂaaˆ‰`a®*:9,A('AÛ"Ê"JxTVUWvxªUTbaˆŠ_a`a‰ˆþÖ''%--%Ì" ""HÜ”(1:#"'&54763654'&#"32'#"&'726"&4632#"&462Âaaˆ‰`aa_ŠÍTTVwxUUªxv E()E1zQ"±"”ˆŠ_a`a‰ˆaaýéTyxTVUWvxªÊ%++%%ò"" "HÜ”"*632#"'&54327'#"'264&":64&"©_ŠˆÂaaˆ‰`aâ/SQ11675"×""3aˆŠ_a`a‰ˆðBBÆ$"""ÿìË V"32654&'763232+"/"&=&'"&4?&'#"&46;67'&5462675462’PloMNno9G7U T.x x.T U5I  H7U U/w w/U U8G  mONnoMNnŸw/U U7H  I5U T.x x.T U7G  G8U  U/w 8ÿ«ÐI#%#"567>4&'&'432>54.'ÐÔž&GPPG&žÔþ³BUC/0EW?jCDk=*9™¨™7ÿ«ÏI#.464632#"&…BUC/0EW?jCDk=*9™¨™í–¹ 4°4 »7ÿ)æÝH32654&#".5467.54632326546232+"&=#"&46;`*5% HghGIf›^fG68E  fIHg  E86GrQ‚ ‚  ƒ ƒB*B$hGHggþâ ‚J@li@ IffI @il?Uy„  ‚ ‚  7ÿ)æ032654&#".546232+"&=#"&46;`*5% HghGIf›^f€°rQ‚ ‚  ƒ ƒB*B$hGHggþâ ‚JY~XUy„  ‚ ‚  7æð5732654&#"#"'&54675#"&46;546232+`*5% HghGIf†%3@.XA?sQƒ ƒ  ‚ ‚Kx×*B$hGHggH3P- ??YUzƒ  ƒ ƒ  ƒv7¥n4732654.#"4>327#"&46;2"&="'&`*5% Hg$A)If)%4@/N;É’   É2°A?×*B$hG &3+gH3Q- 2É   ‘È=MY~??3ˆ«3>32356732+"=#"&54>54&#"#"3W29=!)ªÄ Ä(Ï 33($ &(=FG:,t[,ÌÉ  ÍÍ eŒ=*3- 0ÿ>«<"&5#"&5467356323+>32;2+"5454&M/B  I I H K!V#Un]Bj^Uš.B4È   H F ¿4&ŽY1ÿF  K%(Js7ÿŒæ|4>732654&#"#"'&54675#"&54?632"/2#"&54`*5% HghGIf†%3@.XA?sQY  { { XKx×  c*B$hGHggH3P- ??YUzýX  {{ XývF  ÿþÿK© m%"264&".54675.="&54?632#"/5#"&54?632"'>=#"&54?62#"' &3+gghG3Q- rRSq 7 7  YB 7 7 BY  87 qRLw??Ò$A)IfhŽhþy%4@/UyŽzT 88 Ccµ 88 µcC 88 TzŽuZXA?7«,%2#!"&546;2#4.#2>ü þO 4@gAM,-LAdB2ˆ9AbT<32#"5654&#"¦  `N8PgHEffEHgO8S[´þU «^‰M5-FdUDDUcF.5MŠtÿñ{Ê9%2>54&#"2#".5467.54322654&54x2O, }VW}~>VEAR+322654&"23267#"&5462#"'&546ÛT;;T;C/54&#""6264&"#O8#R.ÂS“_$33$8N7  NpO6A6¨tu¨6A6NpN77N7\pOƒm9t=zM0bSQ]+'77' 8NN8:}\w4`||`4w\}:8N(7N77N#ÿ>ˆ¹NZ4>7&54&""&54&""&54&#"&4632>32>32>32#"'#"&7654&#"u)]+KjL  KjL  L5 0PP0/PO02S[:Jnœ‰  !% Ò„•U;?_® ,(3ú5KK5þ ú5KK5þ ú5K  0((00((05,+9bI²þÃl   D ‡f-ª7LN7þ$$\ù 17!2#!"&462!2#!&=654&#"!"&463!5468 ûð l’  þß}YZ{þÞ  ’(   Ñ™t  db  t™ÿ‘€¶K#"&54&""&54&""&54&#"&4632>32>32327#"&46;2"&5Xah>OKjL  KjL  L5 0PP0/PO0Fb<0OR: o  L?:ú5KK5þ ú5KK5þ ú5K  0((00((0bFþ%->  o *•k*7#"&546;2"&=#"/#"&4?'&562×y‘   þ†Š ŠŠ  ŠŠ Éy   ‘þ†Š ŠŠ ŠŠ!ÿõ ¶+<"&463!2632#"'.547"&4767>7326754&#"5 µ "Z^z#',„¸ˆ\%&Zg†a v¥+›oþÊ'7C2Km t79Ž   &N0‡pay ™^742i 2Od)þ‡;\4" _H [v;"ÿñ]¾B„%".+".#"#"54632;>?232654'54732".+".#"#"&54632;>?232654'54732¸(C,'0(!#1 8*+9 3KcC(B+(/(!#1 %D.F'2LbC(C,'02$<# &D.F'3K cC(B+(0(!#1 &D.F'3KbÞ#12# +*!#12#I5 ,E`#12#+*!5?5I4+E`í#21#.605@5I5 E`#21#++ 5@5I4,E`!þ·4##"&547>4&'&546323>7632#"'.åya \mm\ ayåya [mm[ ayGj°+  )¨È¨)  +°kk°+  (¨ed¨)  +°a¿’0;GWdo2#"'.54>32474675'53733>>54#"7"3>54&.'6326"3265."32>54C $-ÈÇ!#-% 11)%  %)% 9•)+²1h·*3!YI /+B EegCþ¡$51(}gŒ`+8EÑ 4"*"*O6CCFZ 2$#4 ' %$&&$+, €+;;+VeQ4+(2ö&.22(H Qeþ¤   5ê†$*2Ÿ©±·Àæ%32232=4&#"32>&#"62&544  "32544&5462654&5463265'&54632+&#&52&74654/&5&'&5462654.54626%"3254'"324!"324"3254&.'&'63267&547.y, I{45z;AÂOSWK <À< þºF£;!. 6 !A!"."K‘I®1".!.!@".!6D  œ  þ¨› 63 R‡ˆQ44á-  h@{":!!9#1`r:!!! *%:C*"!)(Œ \ :":8 Š*)!!$,A,($+ !!9s[S @222@ @7?73/b F0&0//‚HW2 .?-’ˆK#';35'575'57335733573%!5%!'#'5#!75'##'5äþ¦fXZnZXfþ@°þ²BpBœA8 D D 8A„±±þ|EgÈM[[MÈgEO''c@@o8778JÿéО)7Cd¡"'632&547"2654"#43254&#"'32767.5#53533#23274&&'&#""326326732632.'.'632327&54654.5467&4632F'OO/1G/7Au*- ,ohpq>""$"" -5;2/A[" ;)B.1@o›G6*41! &_} zL  !17)7Gs"'' u   j  þh G^.<  8.^µ,'++',ð  !¸ <" ?5  0? "? 8"?i: !h?8Z¯OMv72#"547"54632'267&!654'&+.';2673232767>3272!>7#"&'#"'>54'32636¢ ]&0 05J'< '9 i,Q' 8H;)þ]!&#'7  0x61 ìz $¼ þó,[N.Î{$@ )È  #D#(B G æ=[a/%.H&9!1( <&ý%3"/ $¸eL.L!4.54>54/&546=4&#"&5467.547&5462j**e % /±@E D3F3E!EA (N6-G' .  $ ""þè "We#2C"+,!D 1$dW! `¿!1Bm|"#"54.#"327327>54&>32#"4#"326323254675'53733632#"'.'&546322#"'.546?-5&%6,)0=%'WX'&;0§$ 'A>b“(6noä&)% " $(#/24I'%ÊÈ'I341 %-=?'­'J/1L%,'[  W',·$:"P   \(&$%%$#0&D3)6 8^DD3O5)2E<!C, P1ÿÿç…!)1š¤µ%"326373233254'"3247"324!"324"3254&#"&54654&'4/&'&54632654.54632654&5462654&54632654'4632"3254&4#"32?3222¦A<l †þ¾  k' inÈ\}G .!"@!!7!.6!!  @!!. 0½  ª´µ-ANˆ ‚2?22 2?2 þƒA(@W 217* !#-A)-%*  !&8s^2$; !8$2^r9" ! &,)A-!!(?k 7Æ þz !šG#3'575'57335733573%35'35­eNG&o&HNeþ¨ãããGdÇMYYMÇdGÕ""´""IÿâÑš R^g%"3254#'2654+"4.54>7&4632372.'.'>3327&5467535#5##3"3254\3-7d31?%3n'(L&4/ '(1d<G4-;#"B+: !8 l4:E= # 0   *!#9j.&++&.aºM3=T2654#">54'43263632!>7#"5#'.7"265454'#""32ë2%}x )= 9H<)þZ"'$&8  /éSH;  .5.d' $¤%þ&("/(=[œa.%,G(:2) =  %£hZ 1E|N,·dL!&5467.547&5462ÒE E@þUAE E4F2ÆB3#dW# #Vf"2 C!,,!"OÁ,%!5>7#"&54>7#"I! þ !4R5K,FJHGKF-K5Rî5&!  !&5PJ5-J=BkCBjB>J.5J#ÿò“À7.'.5463267632">54&#"#".'&\Qm<+U>U22F=W6EžÄ1='57I. DJF.84?/ 9K‰ŽOY/?VK,6"8T;8pWÃ/F4%KFI_N&/hX[c/398 /!*J"ÿò0Á &'67>7.(¸8F¡!J¼ÁE;——;8-“Á0ù>PÜ<„äé6jµ¶j1°?0É#åÁ5!5>7#"&54632&5462>32#"’ ".F-þ-F/! O&@\S;""']‚]'+;S\@n%%9%./$:#,"(_CA\ 82?ZZ?28 \AC_#ÿò“À>32.'.54632\Y6=W5QTMQm<+U>w0JFT;6phi†BK‰ŽOY/?V"ÿò0Á &'6(¸8F¡!J¼ÁÁ0ù>PÜ<„äé7¶ %#"&46323B,-BB-3"S%..J.-7ò¶"&46323#54'&BZBB-6 ‰T‰&÷þ\%..J.-7mC”88m7™¿#"&4632#"&4632"F0/FF/:#F/0EE0:"kþs&--L-¬“þ'&--L-b7™¿5%#"&46325%#"&4632€þ¢wF/0EE0:"þ¢F0/FF/:#­==þ'&--L-Úþû&--L-¬BÿëpÚ#"577>324&#"326p;W_&( -FNW%'30;b,C|R0Ç þÊ VO=#"#&'57654.'5673;54&'567332>7332673#.+#.#"#&'#'L*J  ! XI" &'N U 0 Q$N#  %- T$Ð  *Q&M/! WQ*  )Ð%S   0 ]¬Ý $(48<'#&'675#&'6735'6737'5#5#'5#5##3355#5#¬`l=3573"o` ""Xu?53<.=k] à7 &‚@@@Ø&7ª0:<ôY'('2ô?;,/8;‚V ,* \~<5®&&û66NNÀÀ66þ¤&&#G«i2>J%632'#'"#"&546323267&'.54632'"32654&"32654&÷&K* $ _kþ^`\eb14(-D2#TE8‘091#.F_":"48%3!%0¾ 0(=7nr &2@*"2#_ ;&"0B*)Œ!1 0þœ!/$*#QŸc3<H32%632 #"'%"&5463267&#"&4632&"3264"32654&ô&_&8<)&þ‡z'8-9þË;Y '. %?.&")%'vŽ(r #(65)/;%A9X76$:*&:þÞ-#'!$#E«g5AM3727#"'%#"&54>7>7.#"#"&54632"32654&"32654&ð1ee\`¢m]"þ÷'I)F."1'55(YER#2D-(44":! 5> 2%#0%  ro6=&/ )*B0"!2 F##2"*@0þ®0!/!f/!*# #±³  *5Ax˜ ·72"&546"32654&2"&46"3264&2#"&547"32654&'26327632 #"/#"&#"#"&547>4.'&546324&546327&#"+"3267327-4654&#";27&#"#"¶$44J55+&%#"$44J44*%%""ó&/  ™8!¢cJ*@%þ»B5[CI¿03R?BQ@#{NS€#9QB=W*F æ/3C.þÛb9DKB63AÁœ8E",1þÏþ¸D43AL?C:^  'Gæ5$%44&%3&&&&²5$%45J3%4%%4%Õ   W _9 'ÂÍ=1~ ,+:LQCS) : *OBQN7%/þº, * ª>C>7CC®h&&Â/1@E6:E 8 #ÿóóÃ@IR%"&#"32654& #"&54632#"&54?4&5467>32#"'67"'6ZEÈÂþôÁ] "LÕ’”Õ×›Qm bD9>%-È 3"7‡ )6¿‰„¿¿„ygšOÒÕ•–ÐD3LÜM RyQ¡ <1Lþ« D!#ÿòó ".=%'>5%7&&#"76322"&5462#"&546"32654'.i£!'‘'þ–C¦ 1)("(;;T;<.‘ÑÓ•–ÒÖ—˜eVËŠÄo,t’V?&u>[nT'L ù¹Ç<)*;<*);Õ“•ÓÔ—•Ðo^~ŒÄÄŠ“d(.#ÿóùÁR4&'"'7'7'7>3765464./3232+32+32+32++76x2sJ3!##!3J$=!% W% '=!1<J Fx]jJ<1!='  %W cv vc  Æ 7  F  cc  F  7 ÅX#‰,!75'#"'!62ý”ÐvÐ;9ÐFÐÐýºÐv,þ]£)þ¯£ Ä¢77¢g£ £g¢77ÿöÂ3m{‰•™746;&54632&'&5.46327>32#"."'5332654'.#"32654/&'376;.'#.#"632>54&#"32654'&'7&'-0&%(& ++( ˜g8W0 •8, 3 % 6)Pe2›R  >L ![%( 8  M</ ôX G §-&ß"#/ f_.&5@oqAA#Yp ,=z•(8E2pT26'n"‹mS ' b % Loi !¢ 4™ B<™| pu* !;4x(cs‚Šš?67>776327#''#"'#"5?267327654/327#";2654&5'#43632'7&"3677654&#"327326547326%#7654R# EL1=U J]& —— \hc*O4Y8í C&B%K Bx;/:|   X¦%>K ' w   <'ìO $xX iÊZ4KA8#`  T; GgŽ8 8! o& 8%(D FF5  ²µ$B Y :!±  # ÏV$^]>2UKO ;CN#3l  *17=2#"&5467#!"''??2654/654'%>7%>7 . 0_­ $þëþN)Q|E!yIÍ#QBFþçnþ†?q+þDož ( *>>Wþû û šˆt‚|þY-%ŠRp/ iÛshàGbý$#ƒ&(-492"5'57!2"%5'%7654/'!!&!654'!!!6jNNeeÍá áþŽRRRöŸŸ(WþaB€þ•„þ|þwD® ¨NOOÍv¬w   ›b_¢_nmW‚îP4Õ()¢L#1l| ",39?2#"&546/763!27/4&+76%654''%.''%.'™- /}•Q)²$ŽþU"Iy!E«%µFBQýòŠþ’ p+þ l ' þb< = ׇš ùåv{‚rÈ*/oQ‰"þ;ïÚÞG ÞÜ#û#‹&E7"&546;32>32#".#"7232675##"&5463235."#"'#";> 8EJ:˜/',5ÏhNì5*$4G-&z'_0'(-_#w8(- =ƒ):8#‹ 2ÂU>CWK)0)xWH„&-&Bb&-&:HI0"#2FK?)0)JE2-G##gªL6E22#".5.#""#"'.5463:32>76#&#"32?64a!8/4S3:W1,7$"2   1%.J?R2'4    !o *$$* HnL*?B:  ;#"&'."M T¸:Z-pþÚQ%,Ý)GŽ4wþf–  7ƒ$ÿò+Â574&54>7>3232767632#"&'&'8    Ýnm  B)4öJ7G k˜!/'   ?'æqW  R#J/;ñ@/3 #×´  ' 7 ×þà ;þáþá; þà;yþâþà;!þß; ;þà #×´ ''7'77×®®®¬¬®®®®¬¬«­®®®®­«®®®ÿÿÿ»<”P#"&'#"&54654&54>767.'&'&5463262676327632>;2<eBX  [rT#  ›(  ,%   n#[·" Š3¢‘ + -#)½kP +U ˜) $ÿò‚ÁN7#"&##".'#'?4"".54654&'67.'6732632>32Q Zy# .:O =   t2$M <&D "   ‚r   #;T hU,•2?­,"[6K¡#ض #3##5#53573##5#535##33535#¬ææ\çç¡çççççÄ¡çç¡ççpç\ææ\çFççèèçç#ç¡èè¡#Ö³ 3##5#535ðææçææ³æçææçæ#Õ² !33)!%!!Ennnþp"þÞ"þÞ"þÞ"þÞnnn#Э !5353!3#%3#ÑÑÑþAîî¿îîîî¿îîÑÑÑ#̳ 33###53Ê[§§[§§³µ[þ]£[#³33##'#'537#3335#5µuLANkV8Z’’’]³GME|þ¢GLu|”]þc]”#÷³ #33###53'33###537#3335#5á[‰‰[ŒŒ2¿‰‰¿ŒŒŒŒ‰‰˜UþžbUʘ¹þžb¹˜‡þžb‡˜#`S1;54&'5!#"732673#54.#!526=+"#;iV[HnF[ Oj,W<[Hþ’F] NkJZSnmS\Gþ‘32SkiN ^Eo#ÿò‘¾  #3#'#7'337/373#/?#ZiÎffÎijÍffÍRR¨RRT?}A=<<==32#"&'#"&546=#"&54632.5462Ö5&'#"&546ƒ#/% 029P:2/ *&(1'99(1''3/  9P:2/3''2'99º0 )'(1'99(1''302:P92/$1!'99'0))2/2:(':#ÿòñÁC%4>=#"&546323.54622>32#".##"& #*#!0,5OM5 0-!!MjM 6$3235#"&547&54632#"'3&4632632#"'#"&547#632"&547.546325##"&'#"&4632$(‰$H&(%$Œ%1!" 8%Œ$$ (6' &$‰%% '&!%'Š&8 "' %&Š4$G $#D%$$ '& $$%% &2##ÿó÷Á!2#"'.'.'&54>7>76‹Ås xÏ C.(ˆ& ;o12KÁ k¸Òi 6v,(P833y* #ÿò÷Á&3#.'5>767>7.'.Ç€zÌ ¾…{½-/agqT2*",)HNÂþÜ œþä¿¿œ >,-??X?#ÿô #''%7632%7&/&547ŸcÑEêé@Óf?  þë3hh#JÒÒE&ðï2Âô¸þó—— ¸Òþû,5þÿÿB ¸¸Hœ›-,#ÿò 3'7'3!''!7#7'7#¡E’z7”—-t›CkÞZùöMÕiXÚ¨=ÇÆF°×'²\¤cc¤\Mþê§þí££§Ìä…Ü‚‚Ü…#ÿóÁ (23'7'372#"/#"'5'&543%7627'7'š-x]"jn%Xt›þÁ;ßâ=ÃfH¿‘5«§2“¾éuG‚MM‚GZœþó“ œîi· qÍttÍq #ÿóà !%'!%''5?%¤_Ýfþÿù`è RNNA¼…ÞÞÔSþ´Ãþî¥þç°°¥bSñbb’0þ䙂þåì0b#ÿóx 3#'''!7#7'7#—{RÕ?×Z…’²ƒVâaQî¾QÒÉKË÷Âõšþýk‚­ãöï#Ƴ7'#5'7'75À¸NÅÅN¸–¹NÅÅN¹³ßv…mn„uÛÛu„nm…vß#°³ #553'77''7 mmÓ6ÒýªÓ6ÒÒ6ÓVÒ6Ó³óóýMóó×z_zþ¦z_z¹z_zþ¦z_z#ʳ7%!'#'7!5'7 ×ê=þÃê× 1Î%åþÇ9娳þ¿ç Ô +ÒåþÅ;åÒ+ Ô çA"ÿñôÂ643274322#"/#"'#"54?%&543%'&5432fÛ´þè­Ñ×±þï´¥þêºÚײþé²Ó× #ÿòöÁ #&),/7'#''7'57'777!'/'7?7'–.Ë|ÜÙu ¼7 .Èxááx¼:+15+Üjl/ÊgÖµ/4+àngþÇÔkØÁÚ{À6 1ÃwáØv½5 3ËyÝík5ÌlÜ·.6'ÕflþËÉoà¹16'Ù#ÿð•Â$#/"/"54?'&54376272ÒÀö66öÀÀö66ùY®PþþP®­PýýQ#ÿùåº5732/#"/#"?#"54?'&54;'&327632êòËË ò+ˆ‰+ìÆÄê+ ‰„È,ŽŽ 0íÃÄï'…,é ¿#ÿùÞ»7''77''Ù§§Ù”‘Ù¨¨Ù‘»Ú“’â©©â’“Ú©#ÿÿõÐ7'''77'7''7G1®}®®}®1Œ2-ƒ-°ƒ¶¶ƒ°-ƒ-2 ¯,‚26ƒ.¯±±¯.ƒ62‚,¯ƒ³³#Õµ/3777!!'''#'7'7'7!5!'7'7'7l!`#j¼Áøú þóúøÁ¼j#`!a$j»Ãúþþïþúûj$aµþóúøÁ½k#c!a$n¿ÅûþþîþûÅ¿n$a!c#k½Áøú#ÿõ À ".8BK#"&54>7>32.54632#".2#"&547&54632"&54o<$*5L&Ç1_#*5L&Ç+H4($Zé+H5'$^­F22$#1U:  994 'ž&#iGW&#"&R³"&WÏ1F22$"DzLIþµ|IJ#ÿò Àoy%4654.'&##"&54>54&54654.546323267>54&5463232>32#".#"#"&"2654&%$   *&9"BNBBNB"9()  #$#%   *(8#BNBBNB#8(* ! %#$=++<+*9w  )0'!$,   ,$!(1( +)>o   (1(!%+   +$!(1( k!)+†+>++ +#ÿý‡¶N%".'&5465#"'&54>7.5476324&5467>3282%@%CMMC$@$3#(>m¢¢mA8)z 6"%F6 ¡(0&")%±j$*"&0(¡†% 22 %}3!( g  h &"|Ž&#53"$Ž|"& g  g (!3 ™$- D™H5&+||+&5#ÿîÌV`%4654"#"&467254#"#"&5463232654.546232>32#"/"3#"."3264&¤ 8%:]T(  Y3 6%8II8A #Y>9H C*7W$5,ICbEE`E#ÿð Á?Rf{¤%#"&54>7#"&54632&5462>32#"'#".7632654&#"?3232654&#"32654.'#"/&#"327/&54323267'#"54?— %6L ++ )FUL5$A2%LlK%1B$5LUF) $L6/  !'6)*6˜^ V&8L7'K„F1&6+",Cš>0-"+# =-&6þÖHZ6&1!UEÓN6&-= #+~!3&6XJ E\ #ÿòòÀ4=Wkƒ—±ÅÝò#"'#"'#"&547.4>7&4632632632%"264&#"&54?'32654/#"&54?'32?'#"&46327'&#"32?'&546327'&#"7'&546327654&#"76327654&#"7632#"/3264&#"#"/32654/ò*?+/SO/*@**>,.QP.*@)þ°&66J55  )1"#1)f< _h02#5.>n "" nj "00" j _!; .5"2/hQ )1"#1)f< _h02"6.>n "" nj "00!j _ < . (#1/hx>-+JaaG +->-+:JaaH+5J55J5Ïm "" mj "00" j_ < .3#1/gR, (1D1(f< _g02"5.>n "" nj "00" j_!< .4"20gR, (1D2(f< _g1#4. #ÿòòÀ  %*/4>2 &5466327#"'7.'%'%&47'>7'"264&‘ÒÒþÖÓÔ“D!#$!EE%&<¥6 þU¥6 ¤ ýé¤ >D 6JD 6QIdeŽdeÀÔ“•ÒÒ”—Ñ ¤ ýé¤ °C 6þ¶C 6RE J EE J ²¤6 þU¥6 `dHGeeŒg!¢Í:AGLSY^&547>32#"&'.547#"'&5467.547632%&#"654%>54&'3267%RRb0(IU[$5€Ÿ¬u 2&fPR/31'IT\$5ž®s 2&ea* F\V þÏ* Fþø!YWþø µC9( KªsW1%17/3#+[i´D(& M©sW1%17.3"+[d0#(ap˜'M‘™GþÏ#(ap™&K“˜I$‹°A7'/'#7'757'7'77''7'7'5'7'37?7'zŒnadc!Œg Z&Z gŒ!ceanŒŒnaec!Œg Z&Z gŒ!cdanXQ708 :k{Q¢D;rr;D¢Q{k: 807QQ708 ;l{Q¢D;rr;D¢Q{l; 807#ÿÿ•µLPTX\`d'4;7377632##"/'/"57'#"/&54?'7'"4?6327577'5'75'7'Ä  „}ˆ„„ˆ}„  „~ˆ„„ˆ~r˜rr…qssr˜rr…qsscK——K˜TDMLDT˜K——K˜TDLMDTvƒC…AA„BdBBA¥ƒC…AA„BcAAB#©A7'/'#7'7''7'7'77''7'7'77'7'37?7'rižc\X42imM"Mmi24X\cžiižc\X42imM"Mmi24X\cžU>"018fš;yx+FhhF+xy;šf810">="018fš;yx+FhhF+xy;šf810" "ÿòï¿ &2?LZi'>7#'&543'32.'7#"52#"&546#"'&54634632#.2#"&5476"&=>321Þ Í ¨Þ Í ¨ Ê wÊ Ú F####L& & e& ' tn‡N-ýùIN-žÊ Ú ‹Ê Ú  Þ jÞ Í ####mˆN-|ýpmˆN-|ƒ% & e% !   #ÿñðÀ *=M]7'7''762"&42'.546"&546763?2#"&'&5/>324632#"&UƢƲÇþ‡Ç8D00D0JF/  K4)F4*4E1-9OŠ#Dý30.7R‹"ByÇþ†ÇÇþ\ÇÀ1"!00DF1-,M‰!Bý10.0Y &@$!BpF/ M3*D0 M4#ÿó¦ÅP7&54632#"'62#"&547'#"&5475#"&54627'#"&546325&5462u…5#%44$%ƒƒH43%#4…F4"#5G…5#%45Hƒƒ #$43%#4…F3F5GxM "22#$5 NN 5%#12"L=#54#>L "31#%5 NN!6%#13"M<$54#> #ÿòôà #-:GQ[g#'&546323#"&547'7632#"&547%57632#"'%#"&546327#"''&546322#"&546” 1 ‹ X#þµ X#lœ  þ]œ  v †#þû †#°&88'(88Þœ þ]œ v †#þû †#¦ 1 ‹ X#K X#‰8('88'(8$ÿòï½a'&546276327632#"/#"/#"&54?&'#"&54?&'#"&463267'&546326q "." m! *™» $$ º›* "m "# m  *™» $$º›* m¨º $$¹š* !m "." m"*™º $$¹š* "m "." n  ™#ÿóFÁ "&546324.#"326¯°Üã±­âäj$hC3 k\zˆ¿¾#׳ 3!5#!!niý¸l*ý÷ ³hýµaR!ýð#׳ )35!#!oý´lHh!ýöMfýµG ýõ#Õ³ !'!!VýÅw3ýî³xýÅs@!ýé#Õ³ )7!!VýÍw;ýî@sýÅWýé#ÿòíÁ ''7'7%7ˆ““•ú ••Å••—þŸ••Á¡••Ä™™•þ¤––Æ••”#h³#hE³ýM³#ò³#òϳýM³#|³!|þ§³ýM³#eÁ4>;#"32632#"&#'=fA W9( %4&#"#"&4632e™|6R( %=T\DIZ u’)# TzTc#yÁ"#"632>;632#"'#"&546>K{&#T2“eL)!>ZX@b.O1D[¤ÁL8PeuN5Z~Xg.9eLp™$zÁ&'3267#"'+'267#"&54632>32_K|&$T2”dJƒ )!>YX@c,O1D[ %:lL9OeuO6Z>?Xf-9eL8N>/#ÿq¹%4<%".54676;573#"'#"&5463232>7#ERx=^K1E. ! %I‚˜ ¤Mxg:8ÿòèÁ.'&547>22#"&466L(%JšJ%6G* 9SS;32.'&5462"&46›( *6B, 0082:'B­9SSvSTÀ"  L?%5%/()6*A?LþNTtTTvR#(k‹&2>2.'.546î/K2b°s!##ZM NZ%#!s‹96$ObuZ+#(@>=A( #+Yt#ÿóyÂ!.54632327&#"#"&5467»NJiI5F(2#23 Z>[8IgJNdb:Hg-HMO!AH*J4?fI;b#ÿóÖÁ9Df#"&54632563232654&54632#"'&54>7.#"654&#"632327632#"&54632Uq;5A""$1 52+" "‚?2 0 uh&8n$ 66N.B$5>5$#C `@{·M;b3! 7.46;32&5463232654'632>54'öj>Mm% 7!L> ( $/^=/.$& #' 58<)%G #  ýQ-2,H/VCM7%+S+ 1)3Z 6" $$.'%4&#!  '/ E*#ÿóò 2 &546#32+!5#"&5‘ÑÓþÖÒÕÎ$7vM "$( ÂÔ“•ÓÓ—”Ñ]H  þø## (#ÿóò 52#"&5464&54632!5#+>54&#"326‘ÑÒ•–ÒÖ[ &%C?su%!ÙIQN2eTDX ÂÕ’•ÓÔ—”ÐÌ 3)8Q.Vc É/'&9$)D0@L>/!#ÿóò L2#"&546#"'632#"&54654&#"32654.'&54>54&#"32654/>32‘ÑÒ•–ÒÕË>1&18>+  bK]y!1( ")"RMF] "*ÂÕ’•ÓÓ—”ÑÓ0:(8/5L !3C]G%8  1$7<4(  .#ÿóò "#2 &546"&=35##3+!5r–´‘ÑÓþÖÒÕxxKíÖ4 þæªÕ’•ÓÓ—”Ñý¾17Mþž"* ###ÿóò :2#"&5464654&#"32654&#"732>7#"'632#"&‘ÑÒ•–ÒÕ*" _F_€cMN1 1*.(5,!ÂÕ’•ÓÓ—”ÑýØ "-?bICX(† ,#~¢6B27M#ÿóò >2#"&5462#"&54632654&#"&5463232654&#"’(15*+6;*‘ÑÒ•–ÒÕG-Z>VrVB[9@5 \F3Q0 oB84AC43ESÕ’•ÓÓ—”Ñþ•)RS4iOAURYx !+9'73326‘ÑÒ•–ÒÕ¥ &yþv! Ê~X%$ÂÕ’•ÓÓ—•ÐýÔ4"ABͺ&% ªqI )$#ÿóò !9'&54632#"&542#"&546>54&#"32654&¬/6, !,AE;+,54&#"327#"&54654&#"…+78V355‘ÑÒ•–ÒÕ‡?]/xbUpXFZ6@5![KC43DA74BwÕ’•ÓÓ—”Ñý“7[[/sgNBRC\w%-;#ÿóòÂ)62"2#"&546"&5#32+35265#"Î||A“ÒÓ•”ÓÔh&D:9  Ü“OX§NR-7LìêLÔ”•ÒÓ”•ÓýÁ®"   þÚ&&.rŠƒNk:#ÿóò %3##532672#"&5464.#"326ˆ%54&#"#54632'2#"&5464.#"326&<=: áþßsG/3)(0=T@BWŽ‘ÑÒ•–ÒÕÙ5L]H–bT¿ˆ‡¿¹-G.'.4 QK.=.-97- ?STÉÕ’•ÓÓ—”Ñþ™JwF.l\|‰À¿#ÿóòÂ(4D"#>32#"&54?32654&+532654&'2#"&5464.#"326†16J<=PDQTCGJ8GW=MD4  d1'+.++-&-œÕ’•ÓÓ—”Ñþ™JwF.l\|‰À¿#ÿóò )##5#53'32#"&5464.#"326K8ÏÏ88——‘ÑÒ•–ÒÕÙ5L]H–bT¿ˆ‡¿2vv24þÌåå¥Õ’•ÓÓ—”Ñþ™JwF.l\|‰À¿#ÿóòÂ(8%254&#"#3#632#"&'72#"&5464.#"326‘`4*#/-öÉ@ASZE8F-0%‘ÑÒ•–ÒÕÙ5L]H–bT¿ˆ‡¿ ‹.8+' 2…,YGLdA8 %."Õ’•ÓÓ—”Ñþ™JwF.l\|‰À¿#ÿóòÂ+7G4>324.#"632#".7"32654&2#"&5464.#"326é64e3 19 L;LS>'+)67*&//‘ÑÒ•–ÒÕÙ5L]H–bT¿ˆ‡¿\Jh1k^Q DSAE\ 2WZ=.3C<15?EÕ’•ÓÓ—”Ñþ™JwF.l\|‰À¿#ÿóò &!#>7#72#"&5464.#"326î8SYDmMþ¢‘ÑÒ•–ÒÕÙ5L]H–bT¿ˆ‡¿H*yÇibã\¬Õ’•ÓÓ—”Ñþ™JwF.l\|‰À¿#ÿóòÂ)5E"&547&54632'"32654&"2654&2#"&5464.#"326KUU‚SZHN<;Iˆ&..%&1.+)46P41&‘ÑÒ•–ÒÕÙ5L]H–bT¿ˆ‡¿×KX%".547632"3254%3##5>72#"&5464.#"326Ý$(*'AŽ..T.*RþÊ)54&#"&5462!5‘ÑÓ•–ÒÖQ 7@=)`IG]X(F++8L%<ÂÕ’•ÓÓ—•Ðýõ*)2H+DXVA  .55+(>"6/.A"ÿóò ;2#"&5464.'654&#"4632#"'632#"547326‘ÑÓ•–ÒÖ6:WB-/R& #-'"' ),)"IRWDH[ÂÕ’•ÓÓ—•Ðþ=!1 E;N ;* ,.)&#(=*&%.U :KT#ÿóòÂ#2#"&546##3353Š{‘ÑÒ•–ÒÖ.KHÙÏRK湕Ւ•ÓÔ—”Ðþk1þÏBuu#ÿóò &2 &5462#"&532654&#"535!36‘ÑÓþÖÒÕšP+(#&GL?LcZJ(*ÒþçGÂÔ“•ÓÓ—•ÐþÎm:>/+=FfPK\_AþçQ#ÿóò 32#"&542#"&54627&#"32654&#">cD'& $/[‘ÑÒ•–ÒÕ‘Lr7;#55 D[R@4. 'x:1-5=.*‚Õ’•ÓÓ—”Ñ  q2kLJf1bIDY)XA#ÿóò 2#"&546!3>75‘ÑÒ•–ÒÕJe_LOÂÕ“”ÓÓ—•ÐkA_Ýeo½„2#ÿóò  62#"&462"&5462#"&546>54&#"32654&Ž $&#$&+,F-+*‘ÑÒ•–ÒÕè$R?@W@R\EF]!'("#+)F)Ó,N11'&-nÕ’•ÓÓ—”Ñþ´/$9KL7H !V@UXA'3#ÿóò 02"&54672#"&546#"&'32>54.#"32€$/.D'&0‘ÑÒ•–ÒÕà MLn79"55E[Q?;'=.*8:1-5›Õ’•ÓÓ—”Ñþ›"'w3lMJg1_IEY#ÿóòÂ(2#"&54'2#"&546#+33"32654äGD"'‘ÑÒ•—ÑÕ5B.0SV¹ QLNR%ƺi[¼Õ’•ÓÓ—”Ñi(#6þëö}ƒyþ#:\z3 #7!5!޳þå³×ý¾Bzþßþáà„#^ºU7%7%{EN¬þ†SþUþëuþ©3p×#Œz'' 7#P‰þwPýâ¸C²ÍβB#^ºU7'%'%'{XpSz¬N^}×q2þªt#§t &'567#k>+ÁÞ°Ôþ…+>þ•pPXTD£ZQ#|˜!"'.546763!'&54632#"&47FþY46§2/7%$ää%&70 +, 2.&%6 þüþö!7L0#{2!55!#}ÛÛýƒjÈÙØÈ#}1!55!#ÛÛý¡Ùן#š !55!'3#'3#'3#6ääþûfLLS--Z²gÀ¿g±±±±±±#aFR 353#5#3#3#3#3#—°ˆVQ‹°aGGZ22[!!^èjN‹#!‰Khþáþáþáþá#hL!55!#ÿõõþëaòòa#Ryb'#Vüª&¬Ù¥bþèøÇÅ #Ryb7  %#&þÚVý$~þ[RùÏÏ #r° #Oü±É°þªþªV"S€`37!5 5!"'.6'5K6R+#_þ¡þÅ:#0 `S=SèéS*06*ã#T€`%5!"#5467>3!5!þÝH-*(4(%;_T Y ãHESè#ÿœ­ 5#35­þö€€ZþB‘Y#FPm !53#5!#Š ™ÿþü” þv]í",ä]#+"ˆ3 #5!!7!!™€ þ÷€þŠvþŠvúˆþÐþÓœ#ˆ ó #+"ˆ3 #5!!7!!—‚ þ÷‚þŒtqþ‹uúˆþÏþÔœ#ˆ ó #e@M5!57!7!!%œ¤þ>þ¥´D;þ¨ž;M¶u½\¸5H¯M§#e@O%'!'5!57%!!Cþ}´]À¢Œþs:þa¨ƒeT»\½v˜Ÿ§L²#,•‹ '5#'3-#3zþÚT¦Røþýøø‹þ¸þé?QUþZòãOþÛ#,•†%5#7357%#3-øR¦T&þžøøþý,iPQ?þëdþáPáï#KHe 5!'7'!7!!7; þíþ2DD=ýþ7D Àeþñþõ`Aƒœ!9„ƒ2µ#KHe%5!7'7!57'!!;ýèDDDÎúºÀý÷D7KZœƒA`þõÖ½¶3ƒ„#Õ²#".'! !67>32ÕØ®2_Y<b8þÈþž)%ŽH¬ëþÞÈ <)x=7&#"467'%67"%.ê}*3FM#1}«þû0yS©þý  i!6O`  7i Ú ÚžÚdCÙw#Ñ>ã&547#53&54!67!%!!&”G27a¡¡þõþ­(PW9þiS>?þ© ã+; K"" "!"!û1D-ÊH3"$à'7.5327.'%&%467%ê}1#(BH4*ý»WPþýtþü ©i7  bM7!þäÛÙÚwÚI"ÿîUÇ%&5467&#">7'&#"%632&54'&(7e*#DI^Ni5S3fM>MMþûTa,ÇÙ@=0F.U )d+ ¢„72WBBÚK 67A#{¤8"!>7&'!;.'>7Xfkþ®O<{R .F=+„ (x—†‰ "ITgIl0›>O" p?žA2¬MY("ÿìUÆ$%&547#"'%32?.'327.547)þý+*aTMM7#"&54632×H%E&) HD32&547&5467L?a<5@&26 2'(=1;nL?M…JLƒL"S!0/!?4&.- //#'5R27Œ Š62O*#•{9$4654+"+"&54?654/&54;2;254&54632#"w!Q(0 ô>;,ò6 $R$%yk"º,  ;  d [ B ' ne#K¤g;7"&54?654/&546;23254&54632#"&54654#"#‚0/  ,1Þ;1+' &” $'%"! '/9K-Z8 $^!'#1N  G#'— $‘'#U F0"ctP 3#>7.'3!5!.5!#>75>K¶ªW>=VZMlÂ8k4ý…þ#Hþm{4f"8LP‚vl‰XYD8qO5t&-%`þÏ-%n9&efXX/".fk‡.?^/7tDrPe62"&46"2654ŒT<V==V&/"!//!"89¼¼Š2þùX2þù?2Ôƒ2Ôb#¿$%67#547>737#".' YVÞO~T[1H" Þ 73noJ:[*Zâ~«™sj»— <**  «sH"Gƒ+:d}k""3>54.".=4>32ô6yjEe£VƒÛ]¥Y@xNÄFLúú62*æƒÝ¢ülq­}dk„ !!#!=!}îþ®Kþ¯î£Kþ ôáKKÕ©Ï' »» ÈÏdýDddî>Ï'7'KÈÈ ¼¼Ïdýdd¼d«nRú v%27&'7>7267654&76632632"'>54&#"#"'#"&547567#".7632746=4&7632>-VQs0Å0"0Ë 2|5 &5 35S. EmDCD9\M^ Q3+Då ' 2"5/A—•V+V DLƒN0q u=  2 +5'1=  %A$8K‚%FFE]*XM6o ! =$ &Yi¨š 727&'7>7267654&7663632#"7>54&#""&/#"&5476747#".'&7632746=4.7632>ß5og:÷981ÿ"D˜> A2 = Bh9% %D5^gŒv_ aD8SM¶ 5##& B%G9}b›lXI&V^¢#` 9ÇO  $@ &6C0 4!! )p:J]¶\-Wr8'J?GŸ(8! "œ-C#"&'63765654&'&'%4.5432676?#".- ee//0/#0& ý–   ;7 $$H%@,+G 5Š1 2 lª/;(  ) O¡ !,-]9-q¡F¥y J#"&'&73654654&'./3$4.543267>2#"&'&y!w%: >> A,J?üÿ %84 Y-.#(WQ  A±. D¼vtJ ) 3JÔ,*s<\+-8N6aÃÜ"/"#"&/4632632'5>54&'"&543KD $  6x,L9';+7cP“JI4ü)* F0,U>?#+[©A1!zU  ßDé¾#0"#".'&54632632#5654&'"&543NBpI# E ¢;4G"@y^ð'#Âa ]@ˆ#:&32d{.}OêßE0®r' Â^-àW#"&'.7632"54>7>7#".'&76;2326?263263232632#".#"#g 7 0H 7"þr!F-–,4H  % f..);¹ ,!'>)q }Jd,&%'d , D6 þ(&+  #  "0 /ª &&% %' wXyzU#"&'.'&632"&54>7>7#".763263263232632#".#""ƒ#A-/$D)þ )U(eŽNf&4 h ò( (fˆ (D-\>+„  NPYz7'1$ .=Ý 5A % ýŒ "2"]ˆ',,U [~$+$ .- 55ªjXß&’.56.#""543763654672>7&5.473727632>32#".'"54332654#"".'#"&563272>7654'#"&76;2O7EPB")&&ýó% $   >GO#z5H[RP,4 $.IP‚W` )"  0  ;&,,  ' þÅ  P!`* 3 (D,*-`EF3 *6y6n# +::)@= Xh®v%.'"56'&#"'43>567274&5.67632632>32+".'"5632654.#"".'#".'&563252>7465&'#"&76c u:  S)=! )Zýn;&)6G *_ $^/.ŽC^pe`5E >,Ua !E1jz 4*  %L-)- 7 a; þu ž7¯ &!;" )V753wVW> 3E11FŒP($J IG= Jƒq²{'‚2654'.'&7616#""3632"54>7#".'&5623263232>7654.7632632#".'&76332654&#"†)@e/C %+ 74ý'5   !    J"P&,-=, 3(UY4!(D#›=!7D%Q2    þï9³…   %'H!Y v A.:ÐX$$0(îV=3 S„cNƒqé{ Aœ#".'&7#".'&62654'.'&7616#""3632"54>7#".'&5623263232>7654.7632632#".'&76332654&#"é $""CP #N%)@e/C %+ 74ý'5   !    J"P&,-=, 3(UY4!(D#«#2 5[%0+õ=!7D%Q2    þï9³…   %'H!Y v A.:ÐX$$0(îV=3 S„cN™6-¯‹23%'#".'&76;237.'.'&563232632>32>32"##".#"32632#".54676323'.'#".'&56326ø ;™( (      ! T"8S0 (]+&2, %/:T/XyuK*‰ YQ!Io6jZ $kg(Ó- 7# !+*œ(    4$€$  K` !((g"'\ .C97`? aE $™6º¯ §#".'&74#".'&7623%'#".'&76;237.'.'&563232632>32>32"##".#"32632#".54676323'.'#".'&56326º  $DDQ "O$ý ;™( (      ! T"8S0 (]+&2, %/:T/XyuK*‰ YQ!Io6jZ $kg(Ó- 7# !7 $14Z&0)ó*œ(    4$€$  K` !((g"'\ .C97`? aE $/R¼®0%#"/.'&547>?>=4&4732¼ k >|D/c0 !%)VL  @l4oo { Jt6,:0 TE !E)5#@=   ,V:vCzv E#".'&7#".'&6#"/.'.54?>=4&672172v $!"DP #N%z`‰$%D‰Lœ#2 5[%0+þn BE 5 &7‡@  A'!@c!  #0Ua0§…Bh2#5>54'#".7632>74.'&6326%>76#"&54654&7632tŸ *8[JVj + M#[;  /#˜ýfL # !&0¦ 39]E?(37iç™' <:  D<5 "R p.9œorB 9e8e„Šñ *KŒzɆ`‡#".'&632#".'&76#"47>54&5#".7632>7.'&632632%>#"54654/4'&632É  $O  C "O$Mx.FRDJ` ' K_=  U •ý` "(<".&$1  ]&0)q*ElCC B^ψ  76  )%C) F w'0Šfo/?D0[50Ð|Ö . Ç‹?0A%2#".'&5463326+"##"5&6727.'.54332632 “^KxE1)-%6FD× -ngKl!šOPCCBIì$/# S'"' !÷( 93  Ç‹Ér>a#".'&632#".'&6322#".'&5463326+"##"5&6727.'.54332632É  $O  C " J $l“^KxE1)-%6FD× -ngKl!šOPCCBI$1  ]&0 )þ$/# S'"' !÷( 93  ÁX¡c'#".'&7632632327.'.'&4326327632+".#"72#"'.54>32326°R¢=5%"# Ý   4 * V O"   TN\( +* DDV-2I"ÁXîÊ#".'&632#".'&6'#".'&7632632327.'.'&4326327632+".#"72#"'.54>32326î $N  P "T %îR¢=5%"# Ý   4 * V O"   TN\( +* DDV-2I"ÿii¤,454&'&543232>76#"&+  +$Mºo.U,O?Y0hNn m  #C¯•FO@ NK&P(:uù‡4H#".'&632#".'&6%4&543232676#"&54654&546Ì $N  P "T %þ‰ ' #FZÎD Y0RU2\EÆ%0 C'/ 'K 3xˆIb4R%3f€bÎ# L#§¥ _3267.#"'2675.7632632#"&+#"7>7#".54>3254'#".'&546‚W,=  #8F„"ø9. 1 P8XAž590V )X'7#.*3' 'CþÛ!$&  ‘›M7OOÞ"š " ,  3@,""q&3: #žY# 6&'?%  4'+ L#§°*~#".'&72#".'&63267.#"'2675.7632632#"&+#"7>7#".54>3254'#".'&546ƒ  $ N  Q  "U $þPW,=  #8F„"ø9. 1 P8XAž590V )X'7#.*3' 'CþÛ!$&  ‘C &/  C '/ $þlM7OOÞ"š " ,  3@,""q&3: #žY# 6&'?%  4'+ f_¦tv%".=47#".'&54627>54.7667>54.763232#"&'#".'&76327467"32632†Vq[*p! 65 D 3 ƒœ 3 iX }+  2 Bp¥ '#*&.’ S_0ZF0/`. "-&F#  H? ƒ1 ^F %X#* 2, |D„ "  f_Ýt ’#".'&74#".'&76".=47#".'&54627>54.7667>54.763232#"&'#".'&76327467"32632Ý  $DDQ "O$þúVq[*p! 65 D 3 ƒœ 3 iX }+  2 Bp¥ '#*&.’ SØ $14Z&0)ý 0ZF0/`. "-&F#  H? ƒ1 ^F %X#* 2, |D„ "  wCGO"&54>76?67"##"&7632623263%$32#".5467” AB­  nB*@  ö &6—: ‘;5œˆ0DD0IQ=Ž”‚þãWÑ  *c~ ==$(W'm')( 3Z>1C! #:_2Pw5 3wC¨ i#".'&7#".'&6"&54>76?67"##"&7632623263%$32#".5467¨ $!"DP #N%ý< AB­  nB*@  ö &6—: ‘;5œˆ0DD0IQ=Ž”‚þãWâ#2 5[%0+ö  *c~ ==$(W'm')( 3Z>1C! #:_2Pw5 3mKŸ2Ll7"546767#".76327654.76327632%"&546746232632"=43>32##"54>7.+"&‰m- =;& \69 ´ 7t[Psn9M 3Ÿþ— t9 =5/4%LIK$ÊMrn%&<?#! W> þÒì'@3 1 4,  5Ù   mKŸ Nhˆ#".'&7#".'&6"546767#".76327654.76327632%"&546746232632"=43>32##"54>7.+"&e  $""DQ  "U $ýum- =;& \69 ´ 7t[Psn9M 3Ÿþ— t9 =5/4%LIó &/ 6Z '/ $ýl$ÊMrn%&<?#! W> þÒì'@3 1 4,  5Ù   ‘U_ÂR"&54>7"#".546327654&632>32>32"43>54&#"G $K' 0 GT- 5 =…Bš4  Rn=d‹5*F5Zˆ’_M8—,e)€^ 701!h !#= ( Jt*$*!`M3b& ‹R;S24~i„|#".'&72#".'&6"&54>7#".'&546327654&7632>32>32"5&3>54.#"  $ N  Q  "U $þ  %P   O $P2 7 Dˆ,>}6  Wt>'OS4cI5aIq=' 'E+;—5 &/  C '/ $þU $qT2 \ !" # Af$% A,[P /3<* #*5¹Yí("&54?>32#"&#"543>765.#"#ù+f}9dx‹e>\€H=BuPe6 &!kPK‹J(:+7$((q»jÐ."&54?2?632#"&#"543>74&#"È:7 'p{gOu:#9CG6RIhT>`yFMQ/? )+1NN'6Z<,  &8d?Wf!'!q»ÄŸN#".'&632#".'&632"&54?2?632#"&#"543>74&#"Ä  $O  C " J $ýU:7 'p{gOu:#9CG6RIhT>`yFMQ?$1  ]&0 )ê? )+1NN'6Z<,  &8d?Wf!'!D]aI@4>7##".'&543767>32#".'&š*>THL )z)bn[   dÕÖm., ª† &"C60rˆw=kIC'+   +    T“k/$(V2/D]°I \#".'&7#".'&64>7##".'&543767>32#".'&°  $""DQ  "U $þ;*>THL )z)bn[   dÕÖm., ª† &"C60rˆ5 &/ 6Z '/ $ª=kIC'+   +    T“k/$(V2/íƒ"Ÿ2467.'.4&3432>32#32632+".í_G P6 ;Æ"c²<Z=j‰"¨"#ÁÙL7>u.-“˜  ß!T %7#AJ'@0*K탣Ÿ L#".'&7#".'&6467.'.4&3432>32#32632+".£ $3& "T %ýš_G P6 ;Æ"c²<Z=j‰"¨"#ÁÙLÎ8%0'/ 'þœ>u.-“˜  ß!T %7#AJ'@0*KŒOˆ¨2>}"54>7#".'&546327654.763276323267.#"724&54>727.7632'&#"#".'#".4>Ì"P*2% W S Ls$R}McvE/1S a(=¢#9:@-  @H6!26* PQ = Z63L"&NR*4‚L 7&*:Q'œ°"Œ4//,PTAW+  +0 760?&D082*! $whoZ3^%#"&54>743232632.#"&7>32+"&676%762#"5654&54654&'&432oÞ~ª  ’62 s :1‡S WCc)#W)=(ýô34 *! 9É6TC& "&'Û   $ %&( T Y²vERrq Sg"<6CŽõ K  X£­‚ ~327&#"67327&'47.'&7667654&7632632#"/#"&54>7632654.#"#"/#"&÷V%KCD95WÊ%5"Es &"&G¿¤$_VP % 1D2x 3Rd6d%8*HN' ,P232654.#"#".'&'G1(G^'<þü1$iœ 4 8  !ì¥.B" 59^Hd,?63F**€ò à5)!!.@28(¬ 5 Äe:$ ,3'`! 6 ?%N/é*FJ)TH! 0QG'* !<>:Q(þô)V.)(O¢…(74&#"#".54>32"6762>54&'P¬ˆ&y¤1#?+Wr¢W“¶" ;'Kßý|†nJˆW3PÓzª -Ø»W][i\=À„%>4&*, “6˜¸)^ Zd\+u‘S‹‘ Z„%327>7&#"%4.'#".'&76327&=4.7632>32#"/#".5462667>76#"&5454&'&5432žK3>- \?&F ,4?E ‘#D 4 )= Uj_Dd /7).F"T„OþM2  ) & +" 3à> 3Y3j $(G!  ' #   ;ÏE *5  >)+$ (5± þ½lE( 7&#"%4.'#".'&76327&=4.7632>7.76'#"/#".5462667>76#"&5454&'&5432Ë $""CýÓK3>- \?&F ,4?E ‘#D 4 M$,>%N>_Dd /7).F"T„OþM2  ) & +" 3ñ#2 5ýË> 3Y3j $(G!  ' # $$ ;ÏE *5  >)+$ (5± þ½lE( 7&#"%4.'#".'&76327&=4.763267#"&54622632#"/#".5462667>76#"&5454&'&5432]&&þ&K3>- \?&F ,4?E ‘#D 4 t)(:)Uj_Dd /7).F"T„OþM2  ) & +" 3N&&ý­> 3Y3j $(G!  ' #)))%  ;ÏE *5  >)+$ (5± þ½lE( 7&#"#".'&54632632327674&546;2F0<,E]m’ANP ‹  m – 8PO87+.9±H&   7|AªF -‰ƒ€%8ˆm>Œca*()!BQ\pfXçv|<8.Oy1‹…ÓTo#".'&632#".'&76#".'#"&54>7&#".'&54632632327674&546;2Ó  $O  C "O$ ** 5$A[g‰=IL!‹e’ ;'F,ªD"   4ô$1  ]&0)þÍv¡ !Ztle7ƒl@Žba0)(!%$#!P7I)8- är=?Vy+‹…®R b2"&546"264#".'#"&54>7&#".'&54632632327674&546;2h)*8))/&&2 ** 5$A[g‰=IL!‹e’ ;'F,ªD"   4)8*))&&þ°v¡ !Ztle7ƒl@Žba0)(!%$#!P7I)8- är=?Vy+yqŽ_d7>7.546=4.7632#".+"4326727.'#".'&7632654'#".'&56Á "$5;Q.1f(!A *L7Äw (B$D®<' 4E<".'–  )Ø L',Š4%5   $(" M7*w  7R-,)= 2 :($* Ÿ$\( CyqŽ_ €#".'&7#".'&6>7.546=4.7632#".+"4326727.'#".'&7632654'#".'&56Q  $""DQ  "U $ýÁ "$5;Q.1f(!A *L7Äw (B$D®<' 4E<".'–  )q &/ 6Z '/ $þ{ L',Š4%5   $(" M7*w  7R-,)= 2 :($* Ÿ$\( CyqŽ_ w2#"&46"264>7.546=4.7632#".+"4326727.'#".'&7632654'#".'&56Ú))))0&&ýº "$5;Q.1f(!A *L7Äw (B$D®<' 4E<".'–  )Í))):(&&þ= L',Š4%5   $(" M7*w  7R-,)= 2 :($* Ÿ$\( C?ú™Ð,"".'&56326232>32#"'.œQEH& >=S%($%!"8šQ PSR²;H;#080 #&>H J®eFož' J#".'&632#".'&632"".'&56326232>32#"'.I $O  P # J %þÀLBD$  :8O$3?$0”RW¹dº#2 A%0 +6@6 *2*6'1rG LÌ`ož <2#"&546"264"".'&56326232>32#"'.µ:)))X&&þ¹LBD$  :8O$3?$0”RW¹d)))&&G6@6 *2*6'1rG LÌ`•‡nC o’%326?&#"&'#"&#"&'"5>3263>32632#"&'#"&54632654'+"&'.>2327&%762#"5454&'&5432qT()I QE1D %ƒ  `)•  & ^  IQBD 08'YS}=1F,$  Zcþ| 89(+'6-  3ð'&%2lV % %  RB(%* "& ,G(>-?Z „ ½WD nnPv0-¥^*L"•‡ÕC %‰¬#".'&7#".'&6326?&#"&'#"&#"&'"5>3263>32632#"&'#"&54632654'+"&'.>2327&%762#"5454&'&5432Õ $""CP #N%ýìT()I QE1D %ƒ  `)•  & ^  IQBD 08'YS}=1F,$  Zcþ| 89(+'6-  3—#2 5[%0+þt'&%2lV % %  RB(%* "& ,G(>-?Z „ ½WD nnPv0-¥^*L"•‡¡C¤2#"&47"264&326?&#"&'#"&#"&'"5>3263>32632#"&'#"&54632654'+"&'.>2327&%762#"5454&'&5432?:())F&þT()I QE1D %ƒ  `)•  & ^  IQBD 08'YS}=1F,$  Zcþ| 89(+'6-  3é):((:&&þ'&%2lV % %  RB(%* "& ,G(>-?Z „ ½WD nnPv0-¥^*L"àoX£ j%32>7&#"7254'".'.7>;&'#"&546;5.'&632>3267.76#".'#"&546E-/> 4KO=±"34I_ )Y1 9Ø j€+ A#=òh,,F}p‹Hm2Sn@Usß,"5' 6` .Q* Q32 e %9  0U/ ""‚5$c 5QNY>3764>;67&#".'&76332632654&76#"/"'4>767&'#"&&ç9#   &ÎL9\#(T4v0) H!.$)F>!L }H.nošw "767&#4632475#"&'"5432?4.7632>3232>54.54632+"#"&#"43676=32'4&#"#"=#"&ê%.++oL8  h!u!?" 4ofN$ z'|p---#$Y9   @c(ABPu[ä 'Mð(!)4  ” V2CA >'D!$+0 # # G4 x"$*-Xx56HNX‚;(5„h%6 ˜TPkžf]673>7&467'&'.'&7667654&7632"1"'47654&'".'+"&4+_7j•TH2!:9)ÏQ] Y  w}(1F`N7O?.Vö—Cz( H5'I?=uŒo_@x.(U?N‚“2H9+ /J$Jf"#((:e>o[%b¿g‹„­k b4i›6Wµ f67'4>7.'&76654.7632#"'#"'32>7654&/6#".547&'& X=%cZÕ?RQ:@K :}C#  I! 0 1>+9GZ/S6! ,- &7a;%HG+Ob-·^^ 0P59 1 '.M&-1* > wY  ;5EQ+BM$ *ZAf'@TE0.\?*C >™T9åU%"'./#".'&57627&546;274&7432#"&#"7632#".'"54332654&#"M, 3+;5   --+/0, 5 G 37#toKZDH5)5 &.A2<1^½NV ndQ)c *  >)(5< "F*(A,/8  +%0S |Ž5BJ‰[%#"'.'&'#".'&54627'.546;274&7632+"&#"7632#"&5632654&#"b  A6 4J+!  77 @ A=:CX @,/! ‘Y;S'ZC‡J*L@M>xë_n' j#€d3W&!4  :5$ FJ  #$B52-*:E*6$.7&'#"&5&54654&54>7&54>32632¢AK#:×/ 9F7) `"H%µ!#` "X%! % * # +E% 0F#$Fïp!5zL†bgM';*-þêQ›/"UPhj Q <(3[_@ / o )]   ‚&+I,L[?V'>@!&HH+·zo~ c67.'"%32654.'654'#"4767&'#"&54654&'&54>7&54>;2632#"Ž\U* %E ;GW%0!u, :N&Š38m J    4 , 7$V*59+ .N2)Mš)3 a¦yc2M) <þ¥cÆ70hV€z~9q=v° >Q(ˆz %(" ¥-7 4[ \pNl #6[9"EM;'þnà H%3265&#"46;24&54654.'.'&32>32#'#".'#"&\H3>F5T^    MLn p-E#v0  /R6¡5GÏD@< )5 >&^%>6 - *! /=B# * 5ÀkAz J7326765&#"4;23&54654.'.'&632>32#"'#".'#"&Ùx6B$QWBÙ %    ^Lh0!•-> ]Å Fh8XoEWãU'D%(v_9n-"'&EH !' >#7^ P& *4 KWA³SO—P#43676&4.632#"&"&5467>7633>32#"543>54&#"s6‰"01 =ž;Ô !  WZ‡@3O, TÓ9aQM-Saš¯ó '`+ þK . `h(!%T4L 34+$3?/~N+ &3N/Be£*MÉ›<"547&=4654.5432>32#7>54&#"U 66s%)(-@,h >Z-% 9/#Ê #rn+5 "$LOho32>54.#"c<>4 § ("8 >!. O6¦* 5Å‘`j·ŽUg,*/Y7D-$H/.~PTÀ, 22)Y )@   -.8# 7á=kXgŒ?3) H4.I()0!+'-MkÕ¤s6565'2674654.76326327>3232?#"&54654&#"#".'&76654'#"5475#".'&54l‘ G%G)  2”&2J7*,@?JG4>5*"@68*' ,'L žÉ;,#" 7 #=%H&( ?8!6QTA$þ÷)J,.]L>ø$)4,772t}K:$U&OyFñR_ ,  »{<_=632#"'43>54.#""&54>7>7#"#".'&63326k+|Ç+¤†d†UP8p–¨$K1^¼5 4ùž ;;¥\'x¦-VYIWN! !ŒP $-Q- 7ì'#2 1Ðe0Ø f%=47#"&/6;6765.763262632"'>5.#""#".'#"547k+6& 0% B &tq1I#L:c5<>(DPfc $¦¯8[4 5F $ ^2!   F e-A6RE"1N.>_f[<6 H&- "ˆbp m%=47#".'&7632>7654&763263223632'47$54.#"#".'#"&54746J)* $ !=  6 //L ,“‹>\+_(’8'L5ƒ{  (  Ϻ6‚3=& ¡ $0~7 ( O }9SDcZ%7oµ"?>%‚jSFB !H'8! j†d?d j%3267.#"'7>767"&54676=".#"#".'&6322632632#"&546;2654.#"!$U%(2%†7&#".6332>>32#"'#6322>32#".#"#".#"#"'"5&54>7&5463232>54.#"#"&§ * &˘²,55SD> .O73C(Pf8RAHP #)63m, !4 %J *%1fL  [ª5=&*+ 0H#';.*;M" Ú   !…Œ$" '{O$[A-@ <  -("# $;: <`&1$ *$ +D  VMz¢u&#"'&5>?#".54632?67.'"5432632>32>32>7.76#".'32632#".546:-K)'   Š(@q7 Ke-X/L# \ #,6T Ÿ\$OL&8%HŸ/&‚ %>‚E `^eb#8”ê8gc;|Î '½ B  !#5´I%(+7 !) $! j;f:x'& < 6%,Œyg{B%".#"#"&54>7654.7632>3232>763‹,9)!_S  5³ 5 œ">)2>,&D='0@Kz)ÿÿºÌŽuÅ|134&6#"47>7"#".'&4332$72632#"7>75&í$&6 \ AMžŠñ '& *C< #`_-SÜ#; #"²*eJÙ½ U@"^ zz€;4.76#"767"#".'&43232$726;2#"67>7&íND)D S`ɯþÑY6”I ) xw=f 48)+Ý62A  _ í' %kP.t&UÚè64&46&'#>767>?5654'5632#"&546c LNC3-šB+>05C    n""/#_9&L  1$@?  6G:˜ |ðK‚>4654&'"47>767>?5654.7632#.54654&{#|`q=¿Q1T :77    é. #G')sG+c  =?3 >T^¢*”(rË| é]4&5.5423234&54#'.'&6322>32#7>7>54&43'.##"#"&46÷ ' >N & H]3+=0PJU1â%6 $  ! !£!10#5A^*!w $= <€zL„Z4&'5.54623234.54&7632>32#"767>=4&##"+"546¸   . Ma.0_y  ;6L;eÖR('þæl#%   t)  $E','Å*!=<+D¡*›%  % N5EºÐH{`'&'4'#".'&63276;2632+"&#3;2#"&##"'##"&/47632672634>546é 6F  J !kåœú[46464&'&5"#".'.63232>;2632##"&#2#".##"'##".'&546374äCV R %!0Wû )* ' -v…_% ?} ;Sf  K ý½)6 _% &  &;C+“    '   ÈeJãQ%4>=4'>7#".'&763274&54654&632>32#"&'&#>-='Pq‹HY^ O¡(B 8‘ 1.[)  b02µ FF32;U4.+Kž}*,F01A É2 P  zaŸ}V#47>7#".'&763754654.7632>32#"&'63&54>=1*O;N2a‹³X“#'  b$ã 1H´=9s2 'ŒJK1IlB;5YÌ™  49/!;>S AÅ,# @9i  WD?Œ]xƒ]"#"&#"'47>7#"&54323763>54&5432>32#".'.'3>5 &…3QZsU9bC:#  J]@ H$\\* L “e&(/-  /;:3, {WF3%OHK@@2 @ *L S"*! b˜ˆV( &E G 59"}j°Œ]ƒ y#".'&74#".'&76"#"&#"'47>7#"&54323763>54&5432>32#".'.'3>  $DDQ "O$ &…3QZsU9bC:#  J]@ H$\\* L “e&(/-  /;:3,û $14Z&0)a {WF3%OHK@@2 @ *L S"*! b˜ˆV( &E G 59"}j°oO•}_"&54632>7'#".'&7632>7./.'&632>32%632"&'.'Ë@ / !.lC,5F  E! =-    H &±f¡1B @9~6O G º7|E  –  * ' 0,    D99  •T    *â=>ê*& oO¨•~#".'&632#".'&6"&54632>7'#".'&7632>7./.'&632>32%632"&'.'¨ $O  P #N%ýs@ / !.lC,5F  E! =-    H &±f¡1B @9~6O G º7(#2 A%0+þoE  –  * ' 0,    D99  •T    *â=>ê*& ã|!tI67&54?54/632>2#47>767"&#"òˆM! #Jc   0.D_>=fPB1)aJ$20CÛ_• E #      sW'#>>&F%F>=998<="5@*&ã|ìt e#".'&7#".'&667&54?54/632>2#47>767"&#"ì  $""DQ  "U $ýWˆM! #Jc   0.D_>=fPB1)aJ$20C &/ 6Z '/ $þí_• E #      sW'#>>&F%F>=998<="5@*&x}–wS6>7654654/37>32#""#"'+4>7&6>?654.732>1j?q 9X:%¤ %"00ƒÁW;é‰(# 5V'O& 1f 6Æ!"2@(W[8[ Ñ6#  &17 #X8%- Ax}ä|,9r6>7654654'%#".'&632#".'&6%37>32#""#"'+4>7&6>?654.732>1j?q 9X:%§ $O  P #N%þ %"00ƒÁW;é‰(# 5V'O& 1f 6Æ!"2@(W[8[ ·#2 A%0+56#  &17 #X8%- A©ç7òA%.#"#"&763672636'"#".'&54276 676326;2#"'Ñ þ»H8 H ⬠'þ </˜+6 òY M/-   þÑT ©çÚ~`#".'&632#".'&72.#"#"&763672636'"#".'&54276 676326;2#"'Ú $N  P " L %¹ þ»H8 H ⬠'þ </˜+6 %0 C'/ 'ýøY M/-   þÑT }tu["&=4&=4'#"&54667&54.76>7>&/632632+"&#">7a 79: G> #c_y*6  ,‹ !8 4!< ,A"‘o   P Q$A&#53 KE [ŽTI/ *_Ma;Z">0}Äzz#".'&72#".'&6"&=4&=4'#"&54667&54.76>7>&/632632+"&#">7Ä  $ N  Q  "U $ýî 79: G> #c_y*6  ,‹ !8 4!< ,A"‘o  &/  C '/ $þ—  P Q$A&#53 KE [ŽTI/ *_Ma;Z">0—vHX7#"&563#"&'&76"./6767™w  N n"S   ! ]~^ma3BØËš õd$ .þŒ2  ,/[ zd)5š—v[X ,9S#".'&7#".'&6#"&563#"&'&76"./6767[  $""DQ  "U $þw  N n"S   ! ]~^ma3BØä &/ 6Z '/ $š õd$ .þŒ2  ,/[ zd)5šx»DC%#".'&'"#'43>767'#"#".'&727>32326324O *Tš l¬jU*W7 S ]U !)+XN]2Ñ4[v2g6ZFnyP2  "   ç333M2x»°½c#".'&632#".'&632#".'&'"#'43>767'#"#".'&727>3232632°  $O  C " J $14O *Tš l¬jU*W7 S ]U !)+XN]2]$1  ]&0 )ýš4[v2g6ZFnyP2  "   ç333M2pdšmi%4654&5#"./632?4&54654.7632>7>2>7&'&/3#&#"32632#".‹ 1M %" M  “#>"o¬) *ZF › þê=>%@9± X‚~Š-ÝbT /  ,* p$'>!!@G!P#  E"œ Ia%@*!   1pdÆm ƒ#".'&7#".'&64654&5#"./632?4&54654.7632>7>2>7&'&/3#&#"32632#".Æ $!"DP #N%þ 1M %" M  “#>"o¬) *ZF › þê=>%@9± X‚~Š-ì#2 5[%0+þ bT /  ,* p$'>!!@G!P#  E"œ Ia%@*!   1¿“9I4&5".'&%4&7432#"547>76ÀA þ&(  M$"lm>dŠJ'%$D 7!5_,3   æ?;fB)E‹‚d|!¿“ßÄ/S#".'&632#".'&72&5".'&%4&7432#"547>76ß $N  P " L %ý1A þ&(  M$"lm>dŠJ'%W%0 C'/ 'D 7!5_,3   æ?;fB)E‹‚d|!èn ˆ-H4.'63>32>7.'&'>5>='#&#&³* ƒ @uv“`T„V. (_EJ4—¹ YBg& -" Z#2"7   !ªÎpU01c\;%&450À+þ§8Ô&>%  $ènß Ni#".'&632#".'&6324.'63>32>7.'&'>5>='#&#&ß $O  P # J %þ$* ƒ @uv“`T„V. (_EJ4—¹ YBg& -" Z#2"U#2 A%0 +   !ªÎpU01c\;%&450À+þ§8Ô&>%  $u|uW"&##"&7>7#".'&546;23267&=4&54654'"5436$7262&632PÕN-?(3@‡Ž  …x 5Ob Fm# }!@œXèOoJK+?og20&  & [)G uÓ®w#".'&632#".'&632"&##"&7>7#".'&546;23267&=4&54654'"5436$7262&632Ó  $O  C " J $2ÕN-?(3@‡Ž  …x 5Ob Fm# }!@œXN$1  ]&0 )þÀOoJK+?og20&  & [)G èzÚ%C#".'.'&372#".'.'&5%4.732"547>76é  M „  .  &Qd^Ea}4) 3 3'# A$y- (  #6Ž"  ë$(Y>)D‚gr4¤x]q$E#".'.'&32#".'&546"547>7654.743ç  a ®  #53 >`‡L6   /f7654.743î $N  P " L %þI  a ®  #53 >`‡L6   /f76?45"#".'&763237376;2#"&"&#"#".'&5432>32  S   (:)A )MZ'  44_tRˆËZTµ0+   G i­ak”þ 06HC%) !>.__>'   þû ,  tñp;Zz#".'&72#".'&6.76#4>76?45"#".'&763237376;2#"&"&#"#".'&5432>32ñ  $ N  Q  "U $þm S   (:)A )MZ'  44_tRˆËZTµ0+   G i­ak” &/  C '/ $ð 06HC%) !>.__>'   þû ,  *RÜs1".'"&54654&54654&'&542Ã,4}Q 6<2LW+s/Q(8èUF º<;Ä1+1; _H 0*R s M#".'&74#".'&76".'"&54654&54654&'&542  $DDQ "O$ ,4}Q 6<2LW+É $14Z&0)þÃ/Q(8èUF º<;Ä1+1; _H 0~y‰tI"&+"476765"#".'&57632>74&54654&/6326322`ÔH8S9‡%”Y) I &oQ  ;a^R) \xPM1€‚<^( ^*5 79C  tŸ¼8"#".'&57632632#"&"#".'&543;232632#"&Auà$m ùzšz ×bd…    ¯T^?‰3!2  ["   … NE".'#"=47$7.76>5#"&/4326;23>7632ö ! 6>”—d-…%M4*Ê'&W³´  &  c’o 5K(q+:JQo?.°*  K8¯)    +q!–x\ˆrb#"&'.76"&76354767&767>7"#".'&763>7632#"&54654&54.5'&ˆU2X*¿ 'Pþ”V+# H3®=>Éy0gö% /Kt\ ¬*!   R ) .Pál þ¤$FL^)%    Ú$D76”/ISb.DiE0$5 -‰€3/S=@-XIR?T<^!v‰Å/#".'&'&?2"57>7674654.732‰ *T<O(4-üïB3B 7L‹98v.Œ>@$CdM J7674654.732· $O  P # J %" *T<O(4-üïB3B 7L‹ì#2 A%0 +þh8v.Œ>@$CdM J7674654.732v&&K:)))k *T<O(4-üïB3B 7L‹&&2)8*)þ18v.Œ>@$CdM J54&732632#"&546=474&'&42ä¼!)=G< F\=CLìfæ\V8î'Y% !+  S!60;O [Ch4K]º³’` ]#".'&72#".'&632>54&732632#"&546=474&'&42’  $ N  Q  " L $ýÎä¼!)=G< F\=CLìfæ\V8ó &/  C '/ $ñ'Y% !+  S!60;O [Ch4K]º³WM"264&2"&4>54&732632#"&546=474&'&42N&&K:)):(þä¼!)=G< F\=CLìfæ\V8?&&3))(:þÀ'Y% !+  S!60;O [Ch4K]¡©&4"#".'&546326?632#47>7654&5&Èþh# _ GåOO ZpL1j@mKG%.   ß+*   # Ûu3.MB^8e#/¡©Ë¸ U#".'&632#".'&632"#".'&546326?632#47>7654&5&Ë $O  P # J %³þh# _ GåOO ZpL1j@mKG%.   K#2 A%0 +Q+*   # Ûu3.MB^8e#/¡©«§F"264.2#"&4"#".'&546326?632#47>7654&5&f&0:())Xþh# _ GåOO ZpL1j@mKG%.   &&):((:Ÿ+*   # Ûu3.MB^8e#/s;˜ )"&/32>;232>32#".#"· "  FZ'I+G"ToŒ‘–! }è <<"=5AbwbS s;˜$H#".'&632#".'&72"&/32>;232>32#".#"] $N  P " L %ýª "  FZ'I+G"ToŒ‘–! }·%0 C'/ '¸ <<"=5AbwbS s;˜@;"264'2#"&46"&/32>;232>32#".#"Ï&&-))))þ "  FZ'I+G"ToŒ‘–! }(&&2(:)):(þ¨ <<"=5AbwbS [ps%…%#".'.'&767>54&7654&546=4'#".'&57632674&54654/.76263632#"&#"#"#"&'&736p&#3—<ýB70W\ect BhU / "Ê Š8  y&< ä&M*2Vg)>d3:y#O8{#@ #(  )0 88" 15 $Š.S% V  [Ž/C£#".'&632#".'&6#".'.'&767>54&7654&546=4'#".'&57632674&54654/.76263632#"&#"#"#"&'&736 $N  P "T %1&#3—<ýB70W\ect BhU / "Ê Š8  y&<  %0 C'/ 'ýÛ&M*2Vg)>d3:y#O8{#@ #(  )0 88" 15 $Š.S% V  [p#7—"264'2#"&46#".'.'&767>54&7654&546=4'#".'&57632674&54654/.76263632#"&#"#"#"&'&736&&-))))&#3—<ýB70W\ect BhU / "Ê Š8  y&< x&&2(:)):(ýT&M*2Vg)>d3:y#O8{#@ #(  )0 88" 15 $Š.S% V  wØŽ<%#".'.6>767&##".'&533>7632‡+-M&š'E4-   þ0Z"  e‹Ý¹4 'LF)+Lï >&5 . +&'##    -    ¡"+f Tþp(9%#"&'&'"56#"&'.=4#"&'.563þ`‰´ 0“:\I-%W9\1"  ,w9Z3LD‰?†W")lK=+%O2  &A #$v’†>&A%#".'#".'&5432%.764&54654&?3#&57>†Î4È 4&$ n /Å:” $ýó #=--[«)-- 2 (V2T‡&\ ,#¥A"À\[Þõzt4".'"'47>7.563>54&7632ý,)3@M^8]‡P*54&'#".'&732$32#"&#"6;2#"&#"32632#".6{®/ 21*b 8! 66?#^=H ùg,­,)^$:/b Si4L:$ ß K ADA$ K].(;!&2BPÉX4ÙN%#"./"&/532632327.'.'&632>7>3'&>767* -C!   r    ?+Ÿ/ $OU ) #;w 2:A^ 17  HL  !W3 + 8  ]Lw+$}Q„qO%#"./#"&5423263232>7.'.'&632>763&>767"6  ”, ?  %" 5.##"&/63262326326;2#"&#"#"&5+ rx   jr  'J6)nk™¢.,,@0X    _G   5 yC–µF"#".'&5763>75>765.##"&'&763263232>32632#"&zÌÚ W&û@ ‹’)  !cu2 0@@7 „N *  ¦$4  'uU  ŠÅÏ[43326?2+"'#"'&#"#"#".'&74327>747#"#".'&763>3656'34'&+"#".'&  , ™FG  ])­,¤L!%dS ?ÃÎ   Hð  $ ¡- %$·-ÑùeZ2$3232+#"'&#"+".'&732767465"&#"#".'&763%676'56'&+"#".'&542Dg   &!˜ ! W&$‰ƒ , Î!ShÚ32 Ciÿ“    -  Ú1/ ¨B7 ÐZ-D".'&542332632#&7>76=&'2"'&/432326°þz q>•Ÿ)Ud†YJnP4+ -5=n4*$5 à_# "mƒG<%#AF8T;5 å "#?zÄt'C4654.7432#"47>54&4654&'&5432"&54&„ 5 2\2E!þá  5Ï%6 #þâK)S$`9vQh)+dS!O  +*` Qx©k'+J632267>7#".54>54&'43#47>54&546Ä . „&sOHy;  ¡% '6:K &  ui>\# \#XaQd  cʇ p l" (3L8, 'agA( #í•T*'63232$7#"&54>ED)nC$EIuM ãp/ f‰0 s" ¬pQ)?,9-Mé¦Í4è5P22+&'&#"+"&5&5&47./&'&4332>32632636?.#"#"'4B¹ D„   M¦LSp%!ýÖ „F#–'  )\Et}—þ¬     oA~78 ,F0ˆ]' ð“ì·?2>76&#"&#""&54654&543263>È @+f8R9%  !TL  7x>Lc¢ vT$!?B (IL=X<8    8  < >­™*GD"#"&#""&=465./43216$7632>76'4#&ÔpB¶  =‚Y 2$2F2^<_B4  ò  IK N   '/Ã?!;7"; *SFW>d?< ¨Rctx232>7.'&767263547#"&763263232674654&?26;2#"622#"&+"&5&'"#"&56326þ9('5 :?qv D   ‰<$2V480B>>ƒ&  e‚9*D  $Ò CH #A ?]% 5 (H   3Ž  pÅãb;kåœú^4&'#'./63232$72632>7>7&#2#".##"'##".'&54637474646æ £' 4?$fAiAW=5F ÿ v…_% ?} ;Sf  K ý=a1 /  @ )W  ;C+“    '   )6 °‹@3M2>72674/#&#"+"#".'&43232>32#&7>7#".'&76|/“e : ‘ÍK 55(³T X|N3k‰¯>)…\"  \…6 )  !&ï…5/D¬0 s±l/#"&'&74366&232676763#"&5326¡" '½  &ØK˜ˆ*Be:Mþ÷-R¡~ &þCV9uîK‚‡-32#"767>=4&##"+"546Ý  $ N  Q  "U $ý,   . Ma.0_y  ;6L;eÖR('þæl#%   / &/  C '/ $§)  $E','Å*!=<+D¡*›%  % N5EÕc*éU#"&#"#47>7#"./632>73654.7632>32#".'.'>7>ó €&FJ^>xƒ/n  1G>  ? lS  ' .0 LawD:$N¥‚ =/ C> I$Np. 8 2 '0ÛJ+Æ}CßE6>?654/32>72+"#"'>?&657>54'7432/0S5U ]\& " Q¹9¡:L):;:(6 š)1As § 1#   %%"GR 4ÿÿ­™Ž"usÅÿÿ¨Rñu"ubçÆÿÿkåŽ"uvÇÿÿ°‹&•#u—ÈÿÿFǵ6yuŸs"&#"#".'&5433>32p ×Omè$:9#‚ŽPw!2  ÿÿÿòܤÿÿÛ¤ÿÿ+ÿò°¤ÿÿ ؤÿÿ ÿò¶°ÿÿ"ÿòÔ¬ÿÿÿøÁ–ÿÿ8ÿò½¤ÿÿÿêˤÿºÿ&ÁÌ567#"&5463232654M-PLVS)52Šþ7jp<>M{<aþçìÿÚ#"&54632'654·   !".>2 RŽ 3&-T822ÿïä¡ 5@"&=46 4&#";26'#3#'#3#5254Ȕ4&+"676äÊÊÊÊ(³}³±~~³ž# x _…/ 1 §ŒC"59<HÉÊŽÉËŽ~³²~~²²ñ+ 𱂠 e"+†3ÿñå£#+323273#.#"326?#"&5466  264&"‹F?2:M@J$2   VjoþóÊÊÊþ⢳ü³³ü€(@cH?^   lVWoþ³ÊÊþâÊ×ü³³ü³%W¡7!54/3#525'%33#"3#525#3#5254&+=M%2 3%M`r„~p)2 3†33 ¡aCþÈ8Caþà þÝþ½3þû ÿÿoФÿˆPò3#88òû–ÿÄÜ'5!<VÜ882ÿìäž .5"&=46 4&#";262#'.+#254+äÊÊÊ¢³}³±~~³þø<=# :}1«GGzÔþâÉÊŽÉþ§~³²~~²²G.;#>L0 4£|®F=ƒ1ÿñ㣠(04>32#.#"32673#"&6  264&"â &@( ," 3?(8CD7/?//+HK]±ÊÊÊþ⢳ü³³üB48* 1!!.YICTD$80-k-ÊÊþâÊ×ü³³ü³%Õ¡##5!###33#³1}+}ˆ2i1GllG1%Q++þ¯5þË|þ½Cþ„5(þÛ´ž #7>7´­«4T"JT=.”pþbþþþW¦ »KoI'(ÿ«\3#(44ü(þÛ´ž .'&3\«­ .=TJ"T4õþþþbp 'IoK» ¦ÿ°Už!#Uþâ7ž7üIîÿ±737Oìüÿ°Tž3!!7þ¬žüI7Éÿµ·ž #4>7ÿ60\Bf0"K­5CU5/ M6ˆÿ«ÿ§74&'5>=3#ÉZabY6&..) )..&6§V„$„Vøê8Y4**4Y8îÉÿº·ž .53·B\06"0fF /5UC5¨ýXˆ6MÉÿ°ÿ§3É6P÷ü Lÿ¨ŸÏ3LSX'ûÙ6þÛž %'7#Ž«­ .=TJ"T4„žp 'IoK»þàþZŽÿ«Â3#Ž44ü6þÛž 636­«4T"JT=.þåpž©þZþà»KoI'ÿ°hž!#!R7þåžü·1ÿ±h317Oìüÿ°hž3!5!17þ¬žü7ÿµÿž #4'&'B\06"0fž /5UC5ýS­ˆ6MÉÿ«º§#54>7.=3ÿZabY6&..) )..&6¯V„$„Vüî8Y4**4Y8êÿºÿž 356765É60\Bf0"žýX5CU5/ M6ˆ#Ž«1=#".#"3##5>5##5>5#53>32632%"347.Ž<{z)Ü+»)Ü+DDljW+J"Bþ”)?¼ #nYt þ¶) .Dþ¶) .D m|''>Q+P1* «8".#"327#5>54&+#5>5#53>32¨ #"5 2?*Ü.HV*Ü*DE ,P5:E> ) A+ 5-þú03(þ·)0C!"5E- &   «%17>5#53>76323267#5>5##".#"35 ,EG-L H 9)×'¼+àE A¼ 79 BH ?ý¨'%Nþ­"Hš4#«GT"327#5>54&#"##5>5##5>5#53>32632#".!"367.1)?<5+Ü/"L5 )Ú*»)Ü+DEljf6_0N$þØ)?½#’>Q+ B þú.!0&þ¶)!-Dþ¶) .D m|33 ( >Q+K3#«3BN!#5>5##5>5##5>5#53>3263232675#".#"'"347.×%¼ 'à/»)Ü+DElj[*?H 6 '” C¨)?¾$%Nþ­$!59þ¶) .D m|**ý¨'³›Ð>Q+J5*!3ÿö¢»]4>7#".#"3273#&#"#"&#"#5332654.5463&54632326?63#327#"5#&˜ , MM,.7!  U.+l**W:M 6<#./CB/T:5I4 H7@ ee3! @#\5© /#66<-"B ‰{$.@5)9H œCI&#-#'@)9A5=4I)2)t þÜT# ,-ÿÿ¹#"ªÀ>ÿÿ½#">Ä>ÿÿ¹#"ªÀ#",8>ÿÿ½#">Ä#",8>ÿÿÿ èH#X@%ÿÿÿ èH#mH%ÿÿÿûèH#"öÿH%ÿÿøV#"’>&ÿÿ'(V""V>'ÿÿÿþâT#"’>(ÿÿÿþÑV#"¸>)ÿÿ0ÿV""L>*ÿÿ0ÿÿ V"">+ÿÿðV#":-ÿÿ=ùw""^@.ÿÿþ§ð4#"ß;/ÿÿåV#"’>0ÿÿK#"’>1ÿÿçW#"¸>3ÿÿ/V""V>5ÿÿìV#"Ú>6ÿÿþ­å3#",88ÿÿØV#",89ÿÿ ÜV"">;ÿÿþ©ã4#"Æ<<ÿÿÿÿÕV#"’>=ÿÿV#",8>ÿÿ ÿÿòV#"ð=?ÿÿ0ÿ½#">Ä*ÿÿø°#&ÿÿå°#0ÿÿذ#9rÿv¸ #%'7%4.'7!"&547'?'7ü455Ñ Bý,79G 4*Ÿ455‘555774Ç3C' @(U°+7O}e*&þ˜7749774rÿv¸ #%'7%4.'7!"&547'?'7ü455Ñ Bý,79G 4*Ÿ455‘555774Ç3C' @(U°+7O}e*&þ˜7749774ÿôÿ|- 7'7'?'7#'!54'”9::t999v9::--4ü 8::::½;;:I:::¢ATJnS f8ÿôÿ|- 7'7'?'7#'!54'”9::t999v9::--4ü 8::::½;;:I:::¢ATJnS f8{ÿ-ëú 5%'7'7'7237# 327#&'&5&546767.#">¡>??Š>??©>??¸ÃrZþ¦–6'O7rÇ%¢£†0-A?‘a6o63""5p??==??=º==>É!?ÑMO#A@&-/2 @=CyIv "}ÿ/ôõ9=A%'7;#.5%237# 327#&'&5&546767.#">'7'7ê433¾ +2((þáÆiYþ©”5)H0n£C¡ ‡--@>`3r43 0;433h433 443>R,Q#?0%y!>ÏLO18)"$0?= CxHt 0&þŽ4433443ÿýÿ¦bÍ %'7'7'7>32!"5%'&#"244à422#333ž "o>cý²Î!T;3333333”443U'M9#LKZÿýÿ¦bÍ %'7'7'7>32!"5%'&#"244à422#333ž "o>cý²Î!T;3333333”443U'M9#LKZÿÿÿgkó '7''7'77>7654'k455466455¡ €16h",0A&!K221G220¨221½EOOñH +7`?65-Wÿÿÿgkó '7''7'77>7654'k455466455¡ €16h",0A&!K221G220¨221½EOOñH +7`?65-Wy˺[04;!654/&/&546?+%"'&5476ŽIj }= [~£Çmk"*ýµN2ØþЪKI y¥A j2‚,ÿûÇ”5"&+%7!654/&/&546?'6ŽÇ€k"*þÎ4}= "_z£2þÐR6n'&"09*$#^N mš=  :O/>j2‚,ƒÿðöÑ-2&#"32632#".547$7&+"546Ê!!"]P ?„YuRv<S 4h^..c_†Ñ  V%vO5#;>"ksb‚S]8A„ÿ­Ñ 126=4#"+&5465476;"&#";2#.'547ri— n*T-m2 . oLoMrfU„[7* C0+ :2M#1@T AH cmV7G'/ÿêÿþK7'7'7#"5!54'­;==º;==--4ü1@879999999’>NEhN `5ÿêÿþK7'7'7#"5!54'­;==º;==--4ü1@879999999’>NEhN `5¿ªî¶2:^e254/7#&'#"'.54>35732654'73263%327523654'636#"'#"5473632654'67&'7–- 7.m c<+"6B*7 ")7-þQ#%[   "Wn-„¢ASbBIKr(&-"M[F+)ëk!Pk"–  )  I%ÿf, (,0N#".'&'7;4&'#"/7327654'7'7'7#"54732654/5473X¢%*‰ïw1($IDBA@49®77µ"`\Ž; ,s7j*( $27Taµ)C9eš?#&ä2q 9723764AX10;21œÕPN77>7¾29—;29—îJ wJ ,ÿïÿÝ7>7'7>7´/:—;/:—™J >J 6ˆù 7>7¾29—îJ 3kÿn'#67'&546324&#"6Û 2"]G5"4" 'ò @$'I #1*   ,ÿïÿƒ7>7´/:—™J X™ú4#"'#"&547332>72654'7ú !   $ó %-   2 šeQ23267#"&#&>54'7›3 $).694/#"07 *$7D)ü{54'7•  *šb¨71U®Yÿ¤«ŒÈ.…;"&'654'7× MWF/»K™,.6.Qbc…V=af~ÿ̽ %'7%4.'7!"&547„444NAý287F 4*665ßAN@)S®*7N} h%$!~ÿ̽ %'7%4.'7!"&547„444NAý287F 4*665ßAN@)S®*7N} h%$!ÿüÿØ? 7'7#!7!54'ûCDDZ-4þñ 7EED¬ASIoS f7ÿüÿØ? 7'7#!7!54'ûCDDZ-4þñ 7EED¬ASIoS f7{Ç'7'74&'7!"&547ACCACCÜ ?ýK47D 2)>BBCCBBCþ”OD='P©)5Kyd%# {Ç'7'74&'7!"&547ACCACCÜ ?ýK47D 2)>BBCCBBCþ”OD='P©)5Kyd%# ÿôÈ*ì'7'7+'!54'–9;;Ê9;;,3û7±::;<;;:ÕBRJoSb7ÿôÈ*ì'7'7+'!54'–9;;Ê9;;,3û7±::;<;;:ÕBRJoSb7Â¸Û !'7'?'74&'7!"&547ô@CC¡@CC°ABBW!Aý777F 3*BBCCBBC7CCBþ8QF?)R­*7N{f&$!Â¸Û !'7'?'74&'7!"&547ô@CC¡@CC°ABBW!Aý777F 3*BBCCBBC7CCBþ8QF?)R­*7N{f&$!ÿþÈ5W '7'7''7+'!54'£===¿<>>===_-4û7£==>@==>;>>=þ½ASIoS f7ÿþÈ5W '7'7''7+'!54'£===¿<>>===_-4û7£==>@==>;>>=þ½ASIoS f7|ÿßë)-237#"327#&'&5&546767.#">'7J¾oX®ïJ6'L5m¼0¢„.-?>^8i54 .<Ò544ë!?fkLR#A?&//1@= DvKv 0'þ}553}ÿ î<%'7%#.';%237#"327#&'&5&546767.#">ñ544N-A%8þDÂv[³öL7 )E,pÍ%¢¥‡0.@@”`]?(5 !"7T5548Yf #! Þ!?flNP48*/01@>!DyJy  !ÿýÿ÷]Ë632!"5%'.#"'7€g,W"[aý·Ê~B•544L5`LJX þ”554ÿýÿ÷]Ë632!"5%'.#"'7€g,W"[aý·Ê~B•544L5`LJX þ”554zÿ4âù)237#"327#&'&5&546767.#">J ÃpY°ðK6'M5rÄ%Ÿ¡…/-@>‘^1s52 4;ù >djKP"@?'-.0?; CwHv  4"}ÿ î:;#.5%237#"327#&'&5&546767.#">~8-( þÛÂv[³öL7(N6oÅ%™¤‡0.@@”`]?(5 !"7…#! P!4+i!?flNP"BA'/:'@>!DyJy  !ÿýÈ^Ë>32!"5%'&#"”0p;bý¶Ë~#Qa&""M8#LJXÿýÈ^Ë>32!"5%'&#"”0p;bý¶Ë~#Qa&""M8#LJXpÿZµÓ(,237# 327#&'&5&546767.#">7'74²jTþ»Š3#G1iÆ–˜+*=:‰X0m1. -8o,++÷;ÃFK <<%;<- ;9BpBn  -$±,,+}ÿí :'7#.';%237#"327#&'&5&546767.#">Ú655r-=, 19þ<Èt\¶ûO7*I0vË$¨¥‰2/BA•c[D*5 ##7¸665ýÜLm B*â"AimOS2;+132B?"F|Jz  #ÿýÈXš'7>32!"5%.#"@200{#9cý¼Ç:B"#Pj110þÅ&„"KI*-ÿýÈXš'7>32!"5%.#"@200{#9cý¼Ç:B"#Pj110þÅ&„"KI*-rÈ«4.'7+"=7~  4"8Ê7 $ O (8hCN`&rÈ«4.'7+"=7~  4"8Ê7 $ O (8hCN`&rȧ '7.'7+"=7/977„  4!7È6 Õ997þ #,&N (7gBM_&rȧ '7.'7+"=7/977„  4!7È6 Õ997þ #,&N (7gBM_&ÿÿÿgY¿76?>54'E €07hSEE%¿EOH ñH 1 ddQ&-WÿÿÿgY¿76?>54'E €07hSEE%¿EOH ñH 1 ddQ&-WÿÿÿgYŽ'7767>54'F8;;7 €+54'F?CC> €+"R C:F&?‹*! k( $Z$e47!"-E'  A/@ h6H5 )0Ž0H8@E7&|ÿßý9254'7+&'#"+.547326764'732=7r5(-)) !$:1+?Y!"5>"R C:F&?‹*! k( $Z$e47!"-E'  A/@ h6H5 )0Ž0H8@E7&ÿúÈ`Ð,2654'7#"'+"'+"'27654'73254'7 "49+-!SÅÞ !L  Q6Q,S$&&&&K5,5+/@7ÿúÈ`Ð,2654'7#"'+"'+"'27654'73254'7 "49+-!SÅÞ !L  Q6Q,S$&&&&K5,5+/@7|ÿâ¹¼=AEI254'7#.'#"+.5473267654'732=7'7''7'7l1',%$";0-#&Œ )!j( $!/11"/11$/11W$c42% !7I,9&?e6F3 ),KE-H8>D7%---:..,“---|ÿâ¹¼=AEI254'7#.'#"+.5473267654'732=7'7''7'7l1',%$";0-#&Œ )!j( $!/11"/11$/11W$c42% !7I,9&?e6F3 ),KE-H8>D7%---:..,“---ÿúɘ2+/372654'7#"'+"'+"'27654'73254'7'7''7'7: 9?01!$[!×ó !%S  7788'788)699 X54'77674#"23276@$&»–%GR8ÔQkA\-?",x:1JTRe‡@Ò 8'!""C[/±oVOILS!45GIHix7Rƒ‚ÿé´Ò(32##"567>54'77674#"23276@$&»–%GR8ÔQkA\-?",x:1JTRe‡@Ò 8'!""C[/±oVOILS!45GIHix7RƒÈMì"#!"'+&53>?;>4'!6Ôo +þ`03//©Á -eS}‰R-K7$ì¹h00F'›}[”D  6!ÈMì"#!"'+&53>?;>4'!6Ôo +þ`03//©Á -eS}‰R-K7$ì¹h00F'›}[”D  6!‚ÿé´©(372##"567>54'77674#"23276'7@$&»–%GR8ÔQkA\-?",x:1JTRe‡@”100Ò 8'!""C[/±oVOILS!45GIHix7…RƒH000‚ÿé´©(372##"567>54'77674#"23276'7@$&»–%GR8ÔQkA\-?",x:1JTRe‡@”100Ò 8'!""C[/±oVOILS!45GIHix7…RƒH000ÿìÈ9ð$'7#!"'+&53>?327>74'!6`100è"+þ`03//©Á#*\ WyT3R|]$À000þËHCh00P .A’vX”C € ÿìÈ9ð$'7#!"'+&53>?327>74'!6`100è"+þ`03//©Á#*\ WyT3R|]$À000þËHCh00P .A’vX”C € ÿùÉ8 6547632#!'%4&#"!6¥V? tf2I=ýÿ :$)bƒÿSEš´3ƒBVQO-';ÿùÉ8$'76547632#!'%4&#"!6».//èV? tf2I=ýÿ :$)bd../þ‚ƒÿSEš´3ƒBVQO-';‚ÿ%†ö$467&'5476;&#";673&'&‚>>W#A8F5D Mšb.xr#ŽMƒiohàqKC4•4K* =91*8$R: CK}FL.A !|ÿl\/;#&'327#"&54>7.#"#6g "&&dƒ†f4JN5NA3J+hPh‹7F> = ' !LLY6rG*@*38yb@wO9  wÿùÉ¡+327+"5&5>3&#"V:e«2®´ü@ _:8W"`63Y­$\M1L_:5I'"%ÿöÇ8%2;#"'+&'723254.#"#5>Z8LH$2JLH=Q_§˜  B( %O>M]]MY>C‚ÿ,€%)467&'=476;&#";673&'&'7‚A:W"A7E4E M_.wp#IdngÛrJÁ011><0J*=90)9$Q:BJyHL-A !b000|ÿl\Ó3'7;#&'327#"&54>7.#"#6Š122 "&&dƒ†f4JN5NA3J+hPh‹7F> =¢221» ' !LLY6rG*@*38yb@wO9  wÿïÉX"327+"5&5>3&#"'7ÞJ9]š.Ÿ¡åû; V43M O8-S’...¤]J0I^63F$"#2001ÿöÇ[ñ#'2;#"'+&'73254&#"#5>7'7c;LJ&2abJ?Rb«“ ˜  Dj111 ($LB\$%#6LN$"0 $#@>9W =1'J¼223€Í+û%/3#%.'67326;2=.5476;23275.''7Výò""S¦)¦)S:L'!..4$T'*122 `>B\$%#6LN$"0 $#@>9W =1'J¼223ÿâÈ>#)#!5732=.5476;2''7".(Sþ÷ÚP5K' -.S1000" !"ýBX?\J/ #"B98/Æ222þì2 !<1ÿâÈ>#)#!5732=.5476;2''7".(Sþ÷ÚP5K' -.S1000" !"ýBX?\J/ #"B98/Æ222þì2 !<1‚ÿÄÏi.<'7'7+&54&54733267654&#""546";27254/Å777f877n$HG[¨Ñ3 8rXmK  _A#) &27777777ÈUF?,8-v`zgA'5/ $K3/p8/ ‚ÿÄÏi.<'7'7+&54&54733267654&#""546";27254/Å777f877n$HG[¨Ñ3 8rXmK  _A#) &27777777ÈUF?,8-v`zgA'5/ $K3/p8/ ÿâÊ9%)#!5732=.546;2''7.#"'7$Rþû×O4I(8*.0//()%!'"‰/00÷=X>ZH. ##7w.Ä220þ§ 3V1220ÿâÊ9%)#!5732=.546;2''7.#"'7$Rþû×O4I(8*.0//()%!'"‰/00÷=X>ZH. ##7w.Ä220þ§ 3V1220yǺý0+%"'&547;!654/&'&54>7´Çm*U/(*ýµN2Ob }= "4!8TtM¾W3)hD@u7´Çm*U/(*ýµN2Ob }= "4!8TtM¾W3)hD@u767„ÇK1kUQ*þÎ4}= "40\w]Rnf›c_N j= 0 -(,0$ÿñÇŠË"+%7!654/&'&54>767„ÇK1kUQ*þÎ4}= "40\w]Rnf›c_N j= 0 -(,0$„ÿjÁ%#"54732765?™>rYõ=.LYHQ#Y%&4/4 ¡UlR$Áa¤KJ4.o¸&)’@0¬þé„ÿjÁ%#"54732765?™>rYõ=.LYHQ#Y%&4/4 ¡UlR$Áa¤KJ4.o¸&)’@0¬þéÿóÆú… '?6'Ò((-+lN\ …‚ þyJPMmÄÿóÆú… '?6'Ò((-+lN\ …‚ þyJPMmÄþ®7n%"&54732#'&#".'54>32&Pkd8$GF1=  ?(l_/&A"G'>$òƒ?0ƒ¡%þ®7n%"&54732#'&#".'54>32&Pkd8$GF1=  ?(l_/&A"G'>$òƒ?0ƒ¡%³­®2"/+5>3254/3%UMC/- 8ee"/()*4®z8= (L -,¾"4!³­®2"/+5>3254/3%UMC/- 8ee"/()*4®z8= (L -,¾"4!yÿŸ¡ú '7265&'7#"'"&547¹;::ƒ(:*HP8 ˆiÃ777ýòQlœ `G¬NF^/jg\aI9“yÿŸ¡ú '7265&'7#"'"&547¹;::ƒ(:*HP8 ˆiÃ777ýòQlœ `G¬NF^/jg\aI9“ÿôÈK°'7#!'!54'=>>E-4þæ 68v:::´>E-4þæ 68v:::´B;e ' (s HD"WJ g(‚ɇº%"&'#&547&547;%3267.'ggY K£ßJ,>^þGD5  ¡ÉU‚MGU^ &&þ¯VHï" -$Cÿô¼ë *&'#727&'47'62654''654'a³#fXXfS‰T3Ö8• F3_‚&0Q`뮿2B2 ROL0U§0%.þLV^S/m?7 c9"(/ÿîÿÝë*23#+"&/#737>324.#"3>654&#z0%ÜÜ .F' + ¿» ))*;   77‹:@W:”'" M='MQ6eM}A;^"  ;W13¤œ)3?IÿƒÆ#%#&=476;+5>76547.#"3232Jc**3 Dj;l5w=-" - % ÇH>9 ¡Ur…K E6J7*g51fIÿƒÆ#%#&=476;+5>76547.#"3232Jc**3 Dj;l5w=-" - % ÇH>9 ¡Ur…K E6J7*g51fz»f”(/>7'4&547767'&'"#"&5432>54'¸*D<  /6;h±z/44qAJ6-¶\É07 (4K“}i6+[1PÔM 74.¥³ß2>{Äã’%#"5'#"'6764';%&+'ã0i -\F¡6¦y”x*%þÚhwdhŤb¯>5:U ]Ÿw‹pµ5¥ØÊ#ÿòòÁ 354>54&#"34632#3 Ø#*#8#*#H=‰5#.$,888þ˜hgÄ0 2#,8"7A’/2'þÊA{hgþ™ÿÙÿÚœc"%->&54>&'&5!2632#!#".54657674&'"32>_`  #a ?þó\r]Bl>*C7·Ñ';Cœ$L*+c$/UIWP#, #A þän18D"1:,.?««3H0)Ÿ+ '$"1 ;Qÿ~;¹"&5473327èUB7!8y'* %‚ha¾´Î“‡Vþý´0#"&5463232=332654.=3ú('wZJ^#&8  .5(>T+*S-R@?L)GX<1)(  '>2*C7DyRlþI´9C#"&547.5463232=332654.=3264&#"ú('B@C13BJX#&8  .5(>T+*S 4"#"-R@?L)J-I1CC1#:0)(  '>2*C7DyRlüÙ#2#"þƒ´;J_#"&547.5463232=332654.=32654&+2>54'#"&'ú('QST=>R)$1#&8  .5(>T+*S,,%  C*2(1*(-R@?L)T- \AYTB?& +)(  '>2*C7DyRlüé  u# " %6$ #. ÿŪ!533þéÄS;#ÂFÿ÷e¶/923##".546;.#"#4&#".54632632=#"@s –“H:)7P;@')3Q+"*? t7LlRd%(R"A(?¶eP*d|87;K95+$þÉ.?*?2lQ €A]GGþË1‰(ÿEÍ\!2#"54654#"#"'46323276‘" .8>c3  /-R9\" ¹þÎPÈ.  ÆoÇKÿöbZ8CJR]%2#"&547##"'#"&546;4632>54&#"'>322654&+'4&#"325#32=#"×>MQ@5H TER'!A7LRU%N?+@ + D41'2O!4?$,5 /$.*22 &¤8,+44*fã?"bþE9:PX=4f€PPS=H1Vk,G4OQ!$*#,"80#L6>Ê1% 2X;Ë:PM=I=Rµ@ %`UMÿõq\LXa"&547&#"#4&#"#4&#"632#"&54>32632632654&#"'>322654'264&"*3XnKs>70SA3'3SS,¥->2B?5@N $7\;TE5\Z59\1.0'6 9.*De$,8#D# üÿ&'@()— w=jaQ>m- þ¾5@( þ¾,)5ÉGP=;HiT$FJ8$ONKL%+' ' 39$þgL?f=l=(3 -H1.H0Mÿö[6A#"'&547&#"#4&#"&54632632654&#"'6322654'«)4U?5&"sF*4S,#A+(v†pRh%1UC+1#3!*aik'/8#D)—!wH#"&547&#"#"&54>7326=4>32654&#"'6322654'°!,%4 C708"98O70$3!(bib+5l?ŽhQk_YE„`3M>1IaRB8;R'"#,&Qk$þh?Hr5We:8Nÿõ\'22#"&547&#"&54632654&#"'62654&'w*D+]PB9Jp0Nf_uƒa?+1'4j&- f,\39(5Tv_sWGƒ[vTs;HŒkŒ$,'RýÙJ<'aTc1@KÿøÂ29DO2#"/3254&+53254+#"'#"&547634632#4&#"325#32=#"ª#07;@)!6,CTER'!A:IC!hN?.B E8,+4)fâ?"b#+1*% !3!!'fPPR>T Vk0F7:PM=P (1"µ%( $`UGÿ_þ¿@GOY%#!"3!!"&5463!2654&+532654+#"'#"&546;4>3232%4&#"325#32=#"Æ 3)þ/Tý¬,66,Ã"-#A/TEQ("@8KTP( ;(EVZ30þþ7-+44*fã "?"bš,%, %G3*+; !$ $RcCCC69,43 \I),w1C?5A4@“. #%QBKÿ À3:CM2#"&54632&#"32654&+#"'#".546;4632#4&#"26=#26=#"mCY´šXkv_]M+4H'Yb~›<1WFS"'B&+N1KO@BWH6,*4\.6À3‘$(\+ÿwW~—)"$/%"nASb{QQ>)?6VkkVÕTA#=J0'UJ)9EÿFçÃ<C\dnx‚2#"'#"&547&#"#54&#"#"&5467#"&546346324&#"2654&##"'632632#'%3265#2654'32=#"2654'&jW@/ $IC5/@M#$.G"!M 0 6BE% 3CUoK=*=B7(0*3%0FQCN%F/5R þÙ2'(9¹(%PB-6(CQ"5*,JPYc>32'654.#"32#".547##"'#"&546;46322654&+'4&"3265#26=#"x *+5!^GE}1[(2$ 2U iT@4#4 /TER'#?:IUZN?$8—'!*#>2Ç9V44*'?Ã^'"b(3L&DD_hNt.H(K?7Q:G+>42f€PPV:H1Vk +<&Ñ8*4@<Ñ9QN*#Q4?>2:H0SFS&!A9JTXä%)#>*¿8,+44*fã?"bTm-G5Ã(+B;"!<6F 3+"C45(8  E92654&+'4&"325#32=#"vYuOLETý4üq.88.·J>)#&J/UnB9CA3.I&SFQ("@8KTT$M@%:0F&+"4‹9V44*fã "?"bÄKx K0K!(G5V55$!+30 -'Q,:.5@CN.WjCCC6:,E]%5F`þª' ") h°2A?4=6C˜4 #%QGKÿ/ÄNZait2#".54>32&"32654&#"2#".54>5##"'#"&546;46323>2654&+'4&#"325#32=#"?fŠÂ >N7bUSK?'jI\"–fT3È8,+44*fã?"bÄ®…¤Ð"" ¬ŒtšP97Q:G+?4  %JI.PPR>H1Vk#.=#Psþl8*4B:Ñ:PK?H@Pµ= $`U@ÿ$¢·P^dnx2#".54732>54&#"32#".547##"'#"&546346323>2654&+'4&"325#32=#"»hMxÁ|_¢u\:'bT!êt±e@\L1RZUE+"4 -SCR$A9GSsL>#77 )*4!U$!)!=Ã9R3! d¾Ÿ "= a·ˆm=ooQ2/BITO(~sdj§Å/GcW/UpI>6OC;)<4 (e|NNQ54&#"32#".547##"'#"&546346323>2654&+2654.#"4&"325#32=#"»hd+.*" #3 ¬_¢u\:'bT!êt±e@\L1RZUE+"4 -SCR$A9GSsL>#77 )*4!U$!)!=Ì6"(þ’9R3! d¾Ÿ "= a·ˆm£g A&"2 *"  4/BITO(~sdj§Å/GcW/UpI>6OC;)<4 (e|NNQ54&#"32#".547##"'#"&546346323>2654&+'4&"2654&#"2654'#"&'325#32=#"»h{9>#4*"6 r”_¢u\:'bT!êt±e@\L1RZUE+"4 -SCR$A9GSsL>#77 )*4!U$!)!=Ã9R3B""d.21$#-þ ! d¾Ÿ "= a·ˆm¶k T/*> "+ &/BITO(~sdj§Å/GcW/UpI>6OC;)<4 (e|NNQ@'0ŽH?C1&!'2ETER'!A:IRU%N?%:E8,+44*fã?"bu&;0%&/5./&5(-˜T57I/3'4&f€PPV:H1Vk#.=#:PM=I=Rµ? %`UKýüÀ)08Cp{2#"/32654&+#"'#"&546;4632#4&#"325#32=#"2#"&547&'73254+"&54632&#"3264&#"H?C1&!'2ETER'!A:IRU%N?%:E8,+44*fã?"b703<! .B*6&KS>@'0:DT0$C#6-?#!#$ÿT57I/3'4&f€PPV:H1Vk#.=#:PM=I=Rµ? %`Uþ’09D*?16! &5(-$&;0%&þÊ-&--%KýêÀ)08Co|‘2#"/32654&+#"'#"&546;4632#4&#"325#32=#"2#"&547&'73254+"&54632&#"32654'#"'2>54'#"&547H?C1&!'2ETER'!A:IRU%N?%:E8,+44*fã?"b708?-# 4H6.&KS>@'0:DT0$C#6-$ ", 3&#/ÿT57I/3'4&f€PPV:H1Vk#.=#:PM=I=Rµ? %`Uþ–/;$G$5 G4A$&5(-$&;0%&þü   P#!  '"4 & 0Kþ¼À)08Cn2#"/32654&+#"'#"&546;4632#4&#"325#32=#"2#".54732654+"54632&#"3H?C1&!'2ETER'!A:IRU%N?%:E8,+44*fã?"bù0-.#N.:0%#!KýÿÀ)08Cw„2#"/32654&+#"'#"&546;4632#4&#"325#32=#"2#"&547.54732654+"54632&#"32>54&#"H?C1&!'2ETER'!A:IRU%N?%:E8,+44*fã?"bù0<34! /A$P_8,65M+4?zK-.#N.:0%#!þÐ "-%KýèÀ)08Cv„—2#"/32654&+#"'#"&546;4632#4&#"325#32=#"2#"&547.54732654+"54632&#"32654'#"'2654'"&547H?C1&!'2ETER'!A:IRU%N?%:E8,+44*fã?"bù0<:9 4"4H0LV8,65M+4?zK-.#N.:0%#!ÿ   P." 44 &".KþÁÀ)`goz„2#"/32654&+#"'#"&546;46322'654&#"#54&#"#54&#"632#"&54>3263264&#"325#32=#"2654#"H?C1&!'2ETER'!A:IRU%N?%:A7Pb$H-&>)!>&(d&!/0#+3 67C!9DP8,+44*fã?"b" +ÿT57I/3'4&f€PPV:H1Vk#.=#þóVCm*-V5>Ѷ)ÓÅ*t&4+'1F63J'0.+- :PM=I=Rµ? %`Uþ42Fþ¿À)ekt~‡’2#"/32654&+#"'#"&546;46322"&547&#"#54&#"#54&#"632#"&54>3263264&"325#2654'32=#"3254&#"‹H?B2&!'4CTER'!A;HRU%N?%:2EZ6X7D!,>, >," 0 (#.,#,6'0# >.%=:%.?9V44*fÃm!1@!þ (?"b/+ÿT56J/3'4&f€PPU;H1Vk#.=#þîfK8DC7P5 Òµ&!ÓÄ!, &:)&.D7+D%11.,9QM=I=Rµ þ4"'L.4E!)ž+:`UþB"1Oþ\iÀ+y‡’›¥2#"/32654&+#"'#"&546;46324632632632#"'732>54'#"&5467&#"#54&#"#54&#"632#"&4&"325#2654'32=#"3254#"Ÿ&8 B2% (2ETER'!A:IST%M@%:ýò_B=0"=9$(=S$9;dD)(+1!7 5,'3=)1%#?+ >&) / %"/1,4É9V44*fÃQ 0þ!(?"b;)(ÿ,,6J/2(4&f€PPV:H1Wj#.=#þ:Pf11..L X5Md# ?*C;H8,6C&#Ò¶'!ÔÆ*,&9*-'Dý9QM=I=Rµþ"&+%-$$Ÿ*;`UþA!23Gÿø›ÂAMS\e2'654&#"#".547&#"#5&+#"'#"&5463>322>3262654'%4&"325#32=#"Àbyk/L]L^K<%5 Y%>W)J>G#84AOdD8(:   eO6/2G$,JW"þ™0J+-$W§Ž)5T†f‘MC}Zp \yPn-C5M qBÓÐ g~LLR?I1Vi.K.NzþwH6lHNm #*Ê8MF?J;R° ,5.^RKÿ]…ÂQ[air"3!!"&5463!2654&#"#"&547&#"#5&##"'#"&546;>322>32632#'2654'%."327#32=#"§+Þü"1+3)ñIWXI!^K<5HY': ) 8'F$85?NMC9s ]J1-.>arfM¡$,JV8þ¯/J,-#V§!5T!M<&(;hRQlLgC]\@iB %7,§¤ =>%??F4=*IW¡Dg}fay<.\;B[6.ª0>=1?2D“ 4#/NEKÿ]‹ÁhryŠ2#!"3!!"&5463!2654&+532654&#"#".547&#"#5&##"'#"&546;463232>3262654'%.#"327#32=#"»=Y(DE`MüÍ0Ûü%,45+ùRG %%'HP+^K<%5 Y(0!*J>H" 64ANOE8!3"&0 /10E$-KV8þ¯1$%,-#W§"5T¿-$ 4&'B8K!M6,*9<&24"#9LgC]&9-jA @,§¤ Wi??E5=*GY%4,A#þ¶;/[3232>3262654'%4&#"325#32=#"Ædy²™Xm½\F50:mVs‹`O^K< #-Y%7^)K=G#83BOdC9!4 eO6/2G$,JW"þ™1$&*-$W§Ž)5TŸ‚®Ö,%G# ·q• [zRm$P7~N iKÔÑ g~LLS>I1Vj"+@  OzþvI6lHNm #+Ê:LI=J;R°<5.^RMþȯÂ_ƒ–ž§%#".54632.#"32>54.#"#".547&#"#5&+#"'#"&5463>322>326322'654&#"#54#"&546326'2654'%4&#"325#32=#"¯½¢AL4]yC' P;?XZC=a:%'M5^K< #-Y#7^)J>G#83BOdC9!4  eO6/2:!;A.þÏ&% #"%$,JW"þ™1$&*-$W§Ž)5T^¶à 2!6GB '/#&--G^X.;kg= [zRm$P7~N iKÔÑ g~LLS>I1Vj"+@  Oz/LƒþÁ' + ;% &ÃI6lHNm #+Ê:LI=J5.^RIÿ*Â[elu%>32632# 4>7!2>54&#"#".5467&#"#5&+#"'#"&5463463222654'%.#"3265#32=#"¼gO7.2:\AB #9_{²lý€/- [¤›…ËsHt?ZK<%5 4*#,@ *J>G# 62DNfE8(: !#.F[.þ©0$1-$#5¨Ž6TùM|PPj(JTHD/³#4i4jv¸`Z/FbW0_‚ W~Po.C6:m% -A4ÔÑ e€LLR?J0Tl.K.ÊJ5nFQj3EÊ;K=IJ32632".547# 4>7!2>54&#"#".5467&#"#5&+#"'#"&5463463222654'2>54&#".#"3265#32=#"¼gO7.2:\ABb,4*"#*’åý€/- [¤›…ËsHt?ZK<%5 4*#,@ *J>G# 62DNfE8(: !#.F[. *+ý«0$1-$#5¨Ž6TùM|PPjšhC("3 3" ?³#4i4jv¸`Z/FbW0_‚ W~Po.C6:m% -A4ÔÑ e€LLR?J0Tl.K.ÊJ5nFQj3EþÜ  î;K=IJ7!2>54&#"#".5467&#"#5&+#"'#"&546346322>32632%2654'264&'"2654&'#"&=.#"3265#32=#"¤ ( U>+> ˆÅý€/- [¤›…ËsHt?ZK<%5 4*#,@ *J>G# 62DNfE8(: !gO7.2:\ABþ›#.F[.Î.!V7'#8+-/)þ0$1-$#5¨Ž6Tj4 >U$5*$"/³#4i4jv¸`Z/FbW0_‚ W~Po.C6:m% -A4ÔÑ e€LLR?J0Tl.K. M|PPj¸8J5nFQj3Eþ×,z:( 5 588 (;K=IJ ?(. 9'(1KUK:7&$ÿT57I/3'4&f€PPV:H1Vk#.=#:PM=I=Rµ? %`UòWB>K*Z+Fѵ&!A0\#.hCX10Kþ»À)08Cgq2#"/32654&+#"'#"&546;4632#4&#"325#32=#"2#"&547&#"#54#"&5463262654'H?C1&!'2ETER'!A:IRU%N?%:E8,+44*fã?"bÔCZ5,*7D *97'4MYK74'-m6B#ÿT57I/3'4&f€PPV:H1Vk#.=#:PM=I=Rµ? %`UòiJ7ED6R6 ѵHC3Z!-hAZ0/þü)"O.4E#,KþXÀ)08C€Š2#"/32654&+#"'#"&546;4632#4&#"325#32=#"4>32632#"'732>54'#"&5467&#"#54#"&264'H?C1&!'2ETER'!A:IRU%N?%:E8,+44*fã?"b5 0& 4',;R0<9bH&& !3; 6+&2>+>",98  NZx"=%ÿT57I/3'4&f€PPV:H1Vk#.=#:PM=I=Rµ? %`Uþt.B 0.KT2Kf '0# P&$5 .>"9:PM=I=Rµþ¹).gM<$6TN] %`Uý“P." ,+ '".§JÿDšÂ18AK2#"$54732>54&+#"'#"&54;4632#4&#"325#32=#"=IÚ¬ÆþüVF„v’;ni?0&(UEQ'#?:I‡DM@$9F9+2,5)f£ "?!cQB‡£Ù¡˜k"nyŽZP5gG+9f€PPR>yUl ,;'9QV4I54&+#"'#"&54;4632324&#"325#2>54&"32=#"E#2 1"1CF\ÆþüVF„v’;ni?0&(UEQ'#?:I‡DM@$9B=Iþò9+2,5)fÂG.#2#þ3 "?!cU>* "*C1 Ù¡˜k"nyŽZP5gG+9f€PPR>yUl ,;'QBr9QV4I54&+#"'#"&54;4632#4&#"325#2654.#"2654'#"'32=#"=Ir%2 >*?R3BÆþüVF„v’;ni?0&(UEQ'#?:I‡DM@$9F9+2,5)fÂ,%D+75%C#þ& "?!cQB†T$.-8&Y=% Ù¡˜k"nyŽZP5gG+9f€PPR>yUl ,;'9QV4I,#N@,5_F:D=?V90I8NaH:+Z5:a"':PM=I=Rµ? %`Uþ #&C6%NOKþÀ)X_gr~‡2#"/32654&+#"'#"&546;4632"&547&=4&#"#"&5463232654'4&#"325#32=#"264&+"'2654'H?C1&!'2B TER'!A:IRU%N?%:_*5:B\B-6,#N@,5_F:D=?V90I8NaH:+Z5:a"':PM=I=Rµ? %`Uýb-&--%ª#&C6%NOKýë À)\ckv„™¢2#"/32654&+#"'#"&546;4632#"&547&=4&#"#"&5463232654'4&#"325#32=#"2654'#"'2654'#"&547'2654'H?C1&!'2B TER'!A:IRU%N?%:_*6C$ 4H93,#N@,5_F:D=?V90I8NaH:+Z5:a"':PM=I=Rµ? %`Uý“  P." ,4 '!/É#&C6%NOMÿøÓÂ8=IOXc%>73!5654&+#"'#".546;46323235"&54632"54&4&"3265#26=#"ÛI} ýƒR) TER'#E-<BN:N?$8*=K$»GUF9.C¤H\‡( þ9V44*'?Ã]'6- Ù•9þG!P&4f€PP@>.EVk +<&P75!T>7CQ] ÐX–b( -r"…9QN73##".547!5654&+#"'#".546;46323235"&54632"54&264&"4&"3265#26=#"ÛI} E/ "*þPR) TER'#E-<BN:N?$8*=K$»GUF9.C¤H\‡( Ù2##2#ýÙ9V44*'?Ã]'6- Ù•9þG,3A 2!*!P&4f€PP@>.EVk +<&P75!T>7CQ] ÐX–b( -r"þ"4""4V9QN73#"&547!5654&+#"'#".546;46323235"&54632"54&2654'#2>54'#"&'4&"3265#26=#"ÛI} )+TzS.þtR) TER'#E-<BN:N?$8*=K$»GUF9.C¤H\‡( Ë&$!$(+3&1EýÒ9V44*'?Ã]'6- Ù•9þG!>BYW?A#!P&4f€PP@>.EVk +<&P75!T>7CQ] ÐX–b( -r"þ! !X 0%" &4"! 0-¹9QN73#"&54632&#"327675&=!5>54&##"'#"&546346323235".5463273"544&"265#32=#"ø#ec >4J/Vk#.=#?J5?*3EXTP/I–g2- w>Š9QM=H@PTa= $`UMþ¾ÓÂ8qv‚ˆ‘›¦%>73!5654&+#"'#".546;46323235"&546322'654&#"#54&#"#54&#"632#"&54>3263267"54&4&"3265#2654#"26=#"ÛI} ýƒR) TER'#E-<BN:N?$8*=K$»GUF9.Cs6O`F0' :) ":'*l +/"*2 67D !8FhH\‡( þ9V44*'?ÃJ-þ…'6- Ù•9þG!P&4f€PP@>.EVk +<&P75!T>7CQ] þúVCm**[3DѶ +ÔÅ+.)&0F53K&21./6X–b( -r"…9QN73!5654&+#"'#".546;46323235"&546322#"&547&#"#54&#"#54&#"3632#"&54>3263267"54&2654'4&"3265#3254&#"%26=#"ÛI} ýƒR) TER'#E-<BN:N?$8*=K$»GUF9.CZCZ8(,6G#.:"("9.#,*",*#,4(:.=0$>;$.„H\‡( ü#5B#ý®9V44*'?Ãë.þ¸'6- Ù•9þG!P&4f€PP@>.EVk +<&P75!T>7CQ] þ÷eM9BE5Q6 Ó¶-ÔÅ"' .8*&-D75N#330.9X–b( -r"ýb#)P/5I"+9QN73!5654&+#"'#".546;46323235"&546324>32632632#"'732>54'#"&54>7&#"#54&#"#54&#"632#"&"54&2654'4&"3265#26=#"3254&#"ÛI} ýƒR) TER'#E-<BN:N?$8*=K$»GUF9.Cýæ&/# ?.">:$(=T";9cD)% (=> 4+&2.4,:)!!:.$#2 )"-$)3,¾H\‡( ­ #ýð9V44*'?Ã]'6- -,Ù•9þG!P&4f€PP@>.EVk +<&P75!T>7CQ] þB+D&3300L U7Oa %5.J#;G7, !,!+Ò¶")ÔÆ"1 .:(4KX–b( -r"ýa'-) %%9QN73!5654&+#"'#".546;46323235"&54632"54&4&"3265#26=#"4632!7354&'4#"6ÛI} ýƒR) TER'#E-<BN:N?$8*=K$»GUF9.C¤H\‡( þ9V44*'?Ã]'6- ï9T‘þâ½&¡-/*2,AmÙ•9þG!P&4f€PP@>.EVk +<&P75!T>7CQ] ÐX–b( -r"…9QN73!5654&+#"'#".546;46323235"&54632"54&4&"3265#26=#"4632##"&547#7354&'4#"62654'#ÛI} ýƒR) TER'#E-<BN:N?$8*=K$»GUF9.C¤H\‡( þ9V44*'?Ã]'6- å9T‘&A/1?&o½&¡-/*2,Am.&11%Ù•9þG!P&4f€PP@>.EVk +<&P75!T>7CQ] ÐX–b( -r"…9QN73!5654&+#"'#".546;46323235"&54632"54&4&"3265#26=#"4632#".547#7354&'4#"6264&#"2>4'#"&5477#ÛI} ýƒR) TER'#E-<BN:N?$8*=K$»GUF9.C¤H\‡( þ9V44*'?Ã]'6- ê9T‘*3$%3c½&¡-/*2,Am%') )/' Ù•9þG!P&4f€PP@>.EVk +<&P75!T>7CQ] ÐX–b( -r"…9QN..>"¾).gM<$6TNÀ$P '< ,+ '".§ Mþ,ÓÂ8=IOXc…™%>73!5654&+#"'#".546;46323235"&54632"54&4&"3265#26=#"4>32#".54632&#"326=#7354&#'"654&ÛI} ýƒR) TER'#E-<BN:N?$8*=K$»GUF9.C¤H\‡( þ9V44*'?Ã]'6- ó,-’CV38J5B;7N;)ó¼#$(¦30,_(t Ù•9þG!P&4f€PP@>.EVk +<&P75!T>7CQ] ÐX–b( -r"…9QN%$bPB!5?tS[!Kþ¿À)[bju2#"/32654&+#"'#"&546;46322654'7#"&=4&#"#54#"&546326324&#"325#32=#"H?C1&!'2B TER'!A:IRU%N?%:T"*Q^?5/A,,9: LWI57&!7/A&z8,+44*fã?"bÿT57I/3'4&f€PPV:H1Vk#.=#ýë=/b$*x?M@2190ѵI .b$-u?O0/A08)2:PM=I=Rµ? %`UKþÀ)biq|‡2#"/32654&+#"'#"&546;46322654'7"&547&=4&#"#54#"&546326324&#"325#32=#"264&#"H?C1&!'2B TER'!A:IRU%N?%:T"*Q^58B\B18,,9: LWI57&!7/A&z8,+44*fã?"b#!#$ÿT57I/3'4&f€PPV:H1Vk#.=#ýë=/b$*xS'A1??1;! D190ѵI .b$-u?O0/A08)2:PM=I=Rµ? %`Uýb-&--%Kýë À)fmu€¢2#"/32654&+#"'#"&546;46322654'7#"&547&=4&#"#54#"&546326324&#"325#32=#"2654'#"'2654'#"&547H?C1&!'2B TER'!A:IRU%N?%:T"*Q^6A$ 4H=5,,9: LWI57&!7/A&z8,+44*fã?"bï  &4)'"0ÿT57I/3'4&f€PPV:H1Vk#.=#ýë=/b$*xT&#I.G4F$ B190ѵI .b$-u?O0/A08)2:PM=I=Rµ? %`Uý“  P." ,4 '!/Kþ+À)w~†‘2#"/32654&+#"'#"&546;46322>54'7#"&54632&+"32>5#"&'.#"#54#"&54>326324&#"325#32=#"H?C1&!'2B TER'!A:IRU%N?%:G DZ%>;!=S`811*VR+>!:.6."97BNZ /% 5'!60BT8,+44*fã?"bÿT57I/3'4&f€PPV:H1Vk#.=#ýä 2"V&L’C_-251F:W6Ò¶H:=Z!+m-B 0/O> Y:PM=I=Rµ? %`UKþ¼À)AW^fq2#"/32654&+#"'#"&546;46322'654&#"&54&2'654&#"&544&#"325#32=#"H?C1&!'2ETER'!A:IRU%N?%:|L+A7+-8H [ó|LA$A7+-8H [a8,+44*fã?"bÿT57I/3'4&f€PPV:H1Vk#.=#þëRD$0) !L0;<1V*iEVRD@K !L0;<1V*iEk:PM=I=Rµ? %`UKþ À)Jbiq|ˆ2#"/32654&+#"'#"&546;4632#"&547'654&#"&54632%2'654&#"&5464&#"325#32=#"2654&#"H?C1&!'2B TER'!A:IRU%N?%:v*.B./A@A6,-8H [V?>Lþ*>L*(@6,-8I [V+8,+44*fã?"b %!"$ÿT57I/3'4&f€PPV:H1Vk#.=#ýà >%1?@0G!L0;<1V*iDWRDGÝRD.G"K1:>/V*iEV:PM=I=Rµ? %`Uýb$.-&Kýë À)Mcjr}ŠŸ2#"/32654&+#"'#"&546;4632#"&5467'654&#"&5462$2'654&#"&544&#"325#32=#"2654''2654'#"&547H?C1&!'2B TER'!A:IRU%N?%:k.3$ 4H4A7+-8H [W|Lýî|LA$A6,-8H [‰8,+44*fã?"bï#&4)'"0ÿT57I/3'4&f€PPV:H1Vk#.=#ýß F(.G4/9 !L0;<1V*iEVRDHÞRD@K !L0;<1V*iEk:PM=I=Rµ? %`Uý“ # P." ,4 '!/Mÿ6Ã/;G2!3##"&547#5654&#"632#"&5462>54&"%2654&#"7^‰VS&%A31C&ôebI)A$ ,=2CB6>KÛ#2#þ:!)' *&ÃzdkX—þG"41CC13#JtPi"/>)HS<:HeS~˜ý· ""+µ.%#0-$'.MþþÃ/<NZ2!3##"&547#5654&#"632#"&5462654&#"2654'#"&'%2654&#"7^‰VS/.U<=S1ÆebI)A$ ,=2CB6>K°%$,64%".EþS!)' *&ÃzdkX—þG%BDWTBD(JtPi"/>)HS<:HeS~˜ýÓX9)$ (2( 0-ñ.%#0-$'.Mÿ Â<H233#"&54632&#"3265!5654&#">32#"&5462654&#".cŠSîS/YDht^IHG"$}W"aBþ®a_I(A% +!4B6>AM%"'"((†ÂV—þ;8J;,# &#[cHjQp".=)+\31PeTsžþn8%2.#9Iÿ_°Á>2#!"3!!"&5463!2654&#"#"&546732654&546ñ6O(59VþÈ9 ñþ0;1:G]A4"3VJRhQ<2F& $<Y¿'?B#`JP(H:+#:tYE\GN$HVmXMf YC$: 9?5?OIÿb·ÄK2#!"3!!"&5463!254&+532654&#"#"&54>7326='546þ*D' AAcOþ¯9þ0;294}($46/)[FOj 2)3E /%,4`¿& 9#F;I$H:+#:T"0$+ !7<'TGYlZ-L,Z?-B =4W:FHÿÇÂ72#"54632&#"32654&#"#"&54>732=4>ø\s¼šÐnWmK(.$4 J=[M§€§×T"" ")µ–hŽØMh€`2JC5>1K`¨#/QAMþÈÎÀ@b%#".54632.#"32>5#"#"&54732=4>322'654&#"#54#"&546326ÎɤAL4]xD' O;?XZCAe='}%/ZCUe|fI54&#"#"&547326=462'654&#"#"&54732=46N_ =-$3 J6%<ZCUe|42I<%8a}5?bP-";;/8DUD-%9C¿u_9KC6w-%Y1>e*.=RCi1)P3@Q64AMþX±À+e2'>54&#"#"&547326=462+"3!!"&46;2654&#"#"&546732654&546N_ =-$3 J6%<ZCUe|42I<%8at$5 8&Í$$Hþ¸ (( ·-<)"6>,4G.1#.2"&<¿u_9KC654&#"#"&547326=462+"3!!"&546;254&+532654#"#"&5467326='46N_ =-$3 J6%<ZCUe|42I<%8as@:((@6Ý$$Qþ¯ '' ÊQ D8;05F1."/ %?¿u_9KC654&#"#"&547326=462#"5432&#"32654&#"#"&546732=46N_ =-$3 J6%<ZCUe|42I<%8ae;N{f‹ƒE6%5LQOa1';<+7E*5!' /(:C¿u_9KC654'#2>54&'#".=ÕwXËþ¶ÆS+7V= +$7þv›JM&7/Ue|42I<'6RC’SéBT#c*%&0 ("83%!,  *ù[nþñ—þG+H>U8#G,¡U¦B,D!{f¢FSLSdU.SSd·FÓVF6¾þ* [+( 76!-"  #MÿAÂMU%4632!!3#".54>32&#"326=!5#54#"#"&547326=463237"!5&ÕwXËþ¶ÆS‹£ \b7P?`F6B'iO:z[ýã›JM&7/Ue|42I<'6RC’SéBT#ù[nþñ—þGvv &" VX¡U¦B,D!{f¢FSLSdU.SSd·FÓVF6¾IÿóÇÄC2#"/32654&+532654&#"#".54>732?> 2L%LRbJ%$ 1#;3)#".(>",A(<377! =+'5G5a#9:Ä,& CO732?>264&" 2L%LR8:A3"2  1#;3)#".(>",A(<377! =+'5G5a#9:N4""4"Ä,& CO@&"C1C+! ' <%+&8,2)KYK,C!/\?7G@9?+Ma‘;9Q)ý»"4""4IþþÇÄKYk2#"&547/32654&+532654&#"#".54>732?>2654'+2654'#"&' 2L%LRCBU<=S0 1#;3)#".(>",A(<377! =+'5G5a#9:: +72'$.EÄ,& COG&$PDWUAB)<%+&8,2)KYK,C!/\?7G@9?+Ma‘;9Q)ýÒX:($ $6) 2+HÿDãÃL#".5432&#"32654&+532654&#"#"&54>7326=4>32Ò9/y<@]5D.˜W-"=Q9GVC6&&-9/60LZBSg >.$4 J=4'$1K`KI77P)MHÿëñÃk#"'#"&54>54&#"##532654&#"#"&54>7326=4>323265332>54&'u;A+4'I2T>8H)2)"& %& &:L=GW+&(D(! 0 5617!2" 1(Cþë;3%J1LaHÿDòÃs#"&547&'#"&54>54&#"##532654&#"#"&54>7326=4>323265332>54&'2654&+"u;AGH 1"1C4&T>8H)2)"& %& &:L=GW+&(D(! 0 56* Ã!‚IoDO "*C1$871)#*% BMOL_z`3W9# eQ/F!@JI3L'>17!2" 1(Cþë;3%J1Laýß* HþüñÃp}"&547&'#"&54>54&#"##532654&#"#"&54>7326=4>323265332>54&'2654'+2654'#"&'u;AYWTzS7%T>8H)2)"& %& &:L=GW+&(D(! 0 5617!2" 1(Cþë;3%J1Laýë( X9)" '3( #. NÿÃs#".54632&#"3265#"'#"54>54#"+532654#"#".546732676323265332>54'ŠD35eN8C/mP'U(3mI$eP1B[4j…(1(H4/I'& ?:1G F:k 2"') –@O7- "P3BL'!%6 kÃ@tle…k1" '" vk1HTY0*)3QttQ5N?H„'Wz.9&XeÍ90H,%#1'Dþê1<)=2tSLÿ(|Ãh%3254'7#"$54732>7#&'#"&54>54+5;254&#"#".546732>763232653ˆ!'k~ô’çþÌb `ÚQƒ_/ \5i6P)0)HG$6*O<1G F:k*" %%)N;P7/['P5@M¥*C®Š9O©vÁlð¿†eRw©Ï6$FT)00*EpdMi6O>H„'Wz.D Ja{"B;.H/"A"/(DLþñ}Ãu~#"&547#"$54732>7#&'#"&54>54+5;254&#"#".546732>7632326533254'7264&#"&9*" 0FŠ¢çþÌb `ÚQƒ_/ \5i6P)0)HG$6*O<1G F:k*" %%)N;P7/['P5@M!'k~Ž2""$&>."3 B4Hð¿†eRw©Ï6$FT)00*EpdMi6O>H„'Wz.D Ja{"B;.H/"A"/(Dþê*C®Š9O©‡þô#2"!4Lþ|Ãr•%3254'7"&547#"$54732>7#&'#"&54>54+5;254&#"#".546732>7632326532654.'#2654&'#".=ˆ!'k~†:@U|TsyçþÌb `ÚQƒ_/ \5i6P)0)HG$6*O<1G F:k*" %%)N;P7/['P5@M/.&A+7'#8'# $':¥*C®Š9O©¥s V1=VU>+ð¿†eRw©Ï6$FT)00*EpdMi6O>H„'Wz.D Ja{"B;.H/"A"/(Dýr y:( 5 6& & +7Hÿ÷ÓÅ=2'>54.#"#4&#"#"&5467326=4626 Pw :*"/ 0(!2S9+-CVEOjR/#1 /(#4hš8;Å„e3D?7<*2L%5=þìD .@KaO`}c\u6<,2L%?KMRg67Gÿö<Å9E2#"&547&#"#4&#"#"&54>7326=463262654&'=þrI:4`k27CHÿbÃÂTa4632632#"'7327654&'#"&54>7.#"#4.#"#"&54>732652654'PbO\8G^ŽI[WMLg;8('X=?7+M@7Q E0 H5/IS& )C\EPd ;*#1-# %;O2%3!0)ET77s‚LpML*JIa?R -:[mUF4?-)08þÝ:":CkK_|d3HB6<,5N#ISšBDF& 7&1?Fÿ÷Â+72!5>54&#"#"&54>732654&5&546354.'.m„þy^^)!+?bGPa ;*m@2.9}²KFê.%)ÂhÝNO'-@2\Rh|f4F@7J]O? Na¯Ds;Õ*>)Fÿ;Â6BJ2##"&547#5>54&#"#"&54>732654&5&546354.'264&".m„!!A31C!À^^)!+?bGPa ;*m@2.9}²KFê.%)4""4"ÂhÝ /0DC1/ NO'-@2\Rh|f4F@7J]O? Na¯Ds;Õ*>)þ"4""4FþþÂ6BOa2##"&547#5>54&#"#"&54>732654&5&546354.'2654&#"2654'#"&'.m„.,U<=S/“^^)!+?bGPa ;*m@2.9}²KFê.%)%$,64%".EÂhÝ&?DWTBD&NO'-@2\Rh|f4F@7J]O? Na¯Ds;Õ*>)þ3X9)$ (2( 2+GÿGJÂ52#".54732654&#"#"&5467326=46–3J&\µtr±[G#@¿—•¼D7*=`DPb<8"07B6+8cÁ-JK'jµrq´jƒhXqż‹M_9,…BYucH†#r@F\<0oL_GþéKÂ?J#"&=#".54732654&#"#"&5467326=4632264&#"í%9A31CJTr±[G#@¿—•¼D7*=`DPb<8"07B6+8cI3J&s##("1>.0DC1 q´jƒhXqż‹M_9,…BYucH†#r@F\<0oL_-JK'–þë"4"#"GþŠLÂBNa"&547#".54732654&#"#"&5467326=46322654&#"2654'#"&'Ì%.TzS 4;r±[G#@¿—•¼D7*=`DPb<8"07B6+8cI3J&DY&%'%*85$1 *(U 8%AZUAq´jƒhXqż‹M_9,…BYucH†#r@F\<0oL_-JK'U¢¿X9)" '3 # #. Mþ½±À+S\2'>54&#"#"&547326=46#"&=4&#"#"&5463232654'2654'N_ =-$3 J6%<ZCUe|42I<%8a’*C4/>,#N@,5`E:D=?V90I8NaH:+Z5:a"ð#&C6'LOMþ³À+[gp2'>54&#"#"&547326=46#"&547&=4&#"#"&5463232654'2654&+"'2654'N_ =-$3 J6%<ZCUe|42I<%8a’*5:B./A-6,#N@,5`E:D=?V90I8NaH:+Z5:a"þf&.-…#&C6'LOMýë»À+^l€‰2'>54&#"#"&547326=46#"&547&=4&#"#"&5463232654'2654'#"'2654'#"&547'2654'N_ =-$3 J6%<ZCUe|42I<%8a’*6C$ 4H93,#N@,5`E:D=?V90I8NaH:+Z5:a"þ—   P." ,4 '!š#&C6'LOLÿ;OÂ19A%4632!!3##"&547!5#5654&#"&5463237"!5&264&"ÛwXËþ¶ÆS A31C þTîI7(+4,;UEF]$véBT#s4""4"ù[nþñ—þG#.1CD0.#¡,H.9B76#2XHYYJ4'ÒVF6¾ýê"4""4LþþIÂ08EW%4632!!3##"&547!5#5654&#"&5463237"!5&2654&#"2654'#"&'ÛwXËþ¶ÆS,.T=>R1þ‚îI7(+4,;UEF]$véBT#\%%+72'1 Eù[nþñ—þG&‚ZUAD(¡,H.9B76#2XHYYJ4'ÒVF6¾þX9)$ %5"! 2+HÿxÂHO23467632!!3#"&54>32&#"325!5#5654.#"&546"!4ü $1(#-0J8O1 þ±ÕSþñF'@@ WQ#L02DU*ÂýÓøI&2D8Dc7OC(Â"<&3(Mh"&.LQ9—þLè.&¾¡+IB3= 2XHX*]@6ÓLþÈGÂBbj%4632!!3##"&54632.#"3276=!5#5654&#"&5463232'654&#"#54#"&546326"!5&ÛwXËþ¶ÆSÅ_z}_xD' Q;QFWFjKLýàîI7(+4,;UEF]$vD% #HBT#ù[nþñ—þG{©L+6GB (:$/HIf¡,H.9B76#2XHYYJ4'þ²$% ;;% % VF6¾LþºGÂ&.T%4632!!3!5#5654&#"&5463237"!5&2'654&#"#54&#"&546326ÛwXËþ¶ÆSý”îI7(+4,;UEF]$véBT#s6H)?(. 9'(1KUJ;7&%ù[nþñ—þG¡,H.9B76#2XHYYJ4'ÒVF6¾þUWB$-) *Z+Fѵ&!A0\#/gAZ10Lþ»GÂ&.R\%4632!!3!5#5654&#"&5463237"!5&2#"&547&#"#54#"&5463262654'ÛwXËþ¶ÆSý”îI7(+4,;UEF]$véBT#YCZ6+*7D+97'4MYJ86%/k 6B$ù[nþñ—þG¡,H.9B76#2XHYYJ4'ÒVF6¾þUgL7ED6R6 ѵHC3Z!-hAZ0/þü)"O.4E$+LþXGÂ&.jv%4632!!3!5#5654&#"&5463237"!5&4>32632#"'732>54'#"&5467&#"#54#"&2654'ÛwXËþ¶ÆSý”îI7(+4,;UEF]$véBT#þ² 0%5&,;R0<9_K&& (: ; 6+&2>+>",98  NZx"$%ù[nþñ—þG¡,H.9B76#2XHYYJ4'ÒVF6¾ý».B 0.KT2Ih ':0P&"!4Og&aÆDZ-þ±ÌSKxÓŠ®þâ¥$)#š ¢äýâÙI@.1<5C 45ñ*<)Á[D2+ý(R_F—þ>'FP9&ˆï’?_=7V9€ÎsÖ ¡+J-9;1F 0Y-C!)236ÓIþròÂKT`23432!!3#"&547#"$&54673 =!5#5654&#"&54>"!42654&#"Og&aÆDZ-þ±ÌSL3 2"4B‰Ç­þâ¦$)#š ¢äýâÙI@.1<5C 45ñ*<)f2""Á[D2+ý(R_F—þ>bB8- #*F0 )‡ð’?_=7V9€ÎsÖ ¡+J-9;1F 0Y-C!)236Óý!!!6IþòÂIRau23432!!3#"&547#"$&54673 =!5#5654&#"&54>"!42654.'#2654&'#"&=Og&aÆDZ-þ±ÌSw67U>=Uy¨­þâ¦$)#š ¢äýâÙI@.1<5C 45ñ*<)3.A+7'#8+-/)9Á[D2+ý(R_F—þ>|GQ.>UU>-$‡ð’?_=7V9€ÎsÖ ¡+J-9;1F 0Y-C!)236Óý  y:( 5 588 )9Lÿ;+ÂHP[2#".547&/3254&+532654&#"#4&#"632#"&54>326264&"%2654&#"zGbBJ86A3"2   8U29'$.717/ASS,¥-?1AD93262654'+2654'#"&'%2654&#"zGbBJ=FTzS/ 8U29'$.717/ASS,¥-?1AD932632#4&#"3265#';54#"26=#"v=J(# #'%(/ %/! !?/ '. B.0H)I@\D7.$:5*.7ä6+$?'H&"cI<%9 /F!28X0 1#" :'I)-" "PMkS9L>GI>SdS Ž )'c%þÃ,4UT)HÿøÂ5<DNY%#"/324+5324+#"'#"&547&54>3263232%4&#"3265#';54#"32=#"Ë$>1:H:H'20P)#?:IBD .(G%OEV7…þÿ8,+44*'?æ9)$?4?"bˆ##* ! ^"FD`.PPR>P@ 2 PPnSD^:PM=H@PTal*'c!Ü $`UHÿd¿AHOZe"3!!"&5463!254+53254+#"'#"&547&54>3263232#4&#"325#'";5432=#"´8Sý­1;<0“}6*/EZ;P)#?8KBD96G%O%:@|/5P;|7-+44*fÃ_.$"$„?"b 'B1()9:0(-dWCCC6D5%0 CC%4>,*,9%1C?5<4E˜‘!SÔ%QGMÿÂ:@JU^2#"&54632&#"32654&+#"'#"&547&54>32632#4&"';54#"32>5#32=#"nE]³—D’w\[B(0>"^T+r‰5,UEP)#?:IBD .(G%O.A E9V4¦9)$?.¥5)&1ã(?"br[}š,#.“m@Ue|PPR>P@ 2 PP/I29QN32#"&546326326322654&+53254'$264&#"+,SE(, AH(/0**%.41ES@KF:K ;(6]2*"L:\4% .!/=$ 9F£„a948dB'yF^ý— + &D@.32þÍ>&& %â ?$9E:!L 4211/$þÂ-E'>5$F #-^`?s" !/<.)M;!3bP€—NMF4?Ý) '.7;!h;=L-H1.HLÿ;oÃer…Ž%#"&547&/3254&+532654&#"#4&#"#"&5467&#">32#"&546326326322654&'%2654&+53254'$264&#"+,42A31C AH(/0**%.41ES@KF:K ;(6]2*"L:\4% .!/=$ 9F£„a948dB'yF^„4"& þ= + &D@.32þÍ>&& %â ?$A"!?0DC1- :!L 4211/$þÂ-E'>5$F #-^`?s" !/<.)M;!3bP€—NMF4?þv" ‹) '.7;!h;=L-H1.HLþù{Ãdn”%"&547&/3254&+532654&#"#4&#"#"&5467&#">32#"&546326326322654'#2>54'#"&'%2654&+53254'$264&#"+,;GS|R8 AH(/0**%.41ES@KF:K ;(6]2*"L:\4% .!/=$ 9F£„a948dB'yF^ž.)(C&0 5$"./þB + &D@.32þÍ>&& %â ?$D##TCXV@I):!L 4211/$þÂ-E'>5$F #-^`?s" !/<.)M;!3bP€—NMF4?þˆ% $v+'  '3) Có) '.7;!h;=L-H1.HJÿ7Ú¹)1233##"&547!532654&#"#&54>264&"=CQ7ëS"$B21C$þ4Ó+7$)#* + 974""4"(R>I-—þG"3/ED03""?/"80! $. þS#2##2Jþýܹ)5H233##"&547!532654&#"#&54>2654&#"2>54'#"&'=CQ7ëS,0S>=S2þ]Ó+7$)#* + 9.%C&0 3&1 /(R>I-—þG&BCXUAD)"?/"80! $. þmw+(  %5"! CJÿ9×¹%-233!5>7!532654&#"#&54>5#=CQ7ëRþ<9[8 þCÓ+7$)#* + 9oJ&#(R>I-—ý€ .9."?/"80! $. þ7¡):JþzÛ¹3;F233##"&547!5>7!532654&#"#&54>5#264&#"=CQ7ëR!! .B!þ÷9[8 þCÓ+7$)#* + 9oJ&#°#!#$(R>I-—ý€!.*?1.! .9."?/"80! $. þ7¡):©-&--%Jþaà¹4<G\233##".547!5>7!532654&#"#&54>5#2654'#2654'#"&547=CQ7ëR"+-# $5 +þÿ9[8 þCÓ+7$)#* + 9oJ&#œ"&4)+1(R>I-—ý€%8$5 -# 7& .9."?/"80! $. þ7¡):z P." *)  '$,JþÊÞ¹R\233!532654&#"#&54>2#"&547&#"!532654#"#&546323&54>2654'=CQ7ëSýrÓ+7$)#* + 9.+B5,%2H4@>þ€‡0 0(*7r&Di%B(R>I-—þG"?/"80! $. þÏ(:2=J:.V< J5M' '; (1;)*5E#>3þþ(.I5@ )JþjÚ¹nz233!532654&#"#&54>#!"3!!"&5463!2654'#"&5467&#"!532654&#"#&546323&54632'3254'=CQ7ëSýrÓ+7$)#* + 9Â@4þB$$5ýË&&ž0>> 1)$/<'+0B>þµc#,%'7o%OI-—þG"?/"80! $. þ3D&  A-B 2<3$,3>1A!.  &-!%.6:F? )%I$JþjÚ¹u233!532654&#"#&54>46322#!"3!!"&5463!254#5254&##"&547&#"!532654&#"#&546323&2654'=CQ7ëSýrÓ+7$)#* + 99MI-—þG"?/"80! $. þL;G-)/)'!!6&!'3?0)S7)C -  ',F .%'2F#Jþ4عu233!532654&#"#&54>4632#"&54632&#"32>54&'#".5467&#"!532654&"#&546323&2654'=CQ7ëSýrÓ+7$)#* + 9IQAN(0BkV1``(51%#7A+@ #4+#:*/!2 #þ¦n *3 )6 r(»V(R>I-—þG"?/"80! $. þ/CYK T@Y}  '@A"H '&.& #G<  -'4*)&8-5%& I3Jþ}عir233!532654&#"#&54>4>32#"&54732654'#"&547&#"!53264&#"#&546323&73254=CQ7ëSýrÓ+7$)#* + 9£ .@,,žuƒµ@9¤zg. *$K ( .þùK "*Z©0$'(R>I-—þG"?/"80! $. þN %.>E)Uo‰hO7 ;?\riM22B3%O.+E!,& +.!$/^*=I%Jýÿì¹t}‹233!532654&#"#&54>#"&547#"&54732654'#"&547&"!53264&#"#&546323&54>32'32542654&+=CQ7ëSýrÓ+7$)#* + 9•-:(G0'‡±@9¤zhŽ. *#K<( .þùK "*Z' @+-w+$' (  (R>I-—þG"?/"80! $. ý–.)+702 ŠgO7 ;?\riM10D3%O,,D",& +.!",9%6 >E)Mª.=I"þ®" "Jýëì¹{„§¬233!532654&#"#&54>4>32#".547#"&54732>54'#"&547&"!53264&#"#&546323&732542654''32654'"&57?&=CQ7ëSýrÓ+7$)#* + 9·' @+-J B2!2 "ƒµ@9¤z5I;*. *#K<( .þùK "*Z©+$' $297 &:&)?(R>I-—þG"?/"80! $. þN%6 >E)S6 %+?& ‰hO7 ;?\r&D+10D3%O,,D",& +.!",a.=I"þ."7  :“Hÿ‰À[i"3!!"&54>3!2654.'#"&54>7&#"!532654&#"#&546323&547632632#'2>54'»!$Óü-,<$ ÖO_$/ &O;?N2##/J72_ý¼Ë#,("#, +H;=U2¸<@?Z\Cgƒf{% &&+0GJ:)* iN)B% AIVweL+I. =;Lx;">-(5/$3!2>54&+532>54&+#"&54>7&#"!532654&"#&546323&54>3262654'µ^{HJP:ü§Úü#*.+$),- ) TC"S<9K"7+%<5L#_ý¼Ë"-(D- +H;AQ2¸< .O1g=p"*@G1{PC@(C4GI 0% & (%7#! ,4ATOp^A.N0$1G8x;">-*3.%=IY=D,Ti4A5$Jþ«UEK4^71@Lÿ1Â_m%4632#".54>32&#"32>54.'#".54>7&#"!532654&#"#&546323&2654'ß‚cz@Ji­‚ `e4K@SM99+#[f'7V4" +QD&7 E3$J5M#8+ýà®8*"#* + P3>W2²>%#0),Õi„r{dµ %)>TO(,8. 9Zy':-+>090F75m"U #11% E:O?A8VDM:;/.(JKÿvÄPZ%4>32#"$&547327654'#"&5467&#"!532654&#"#&546323&2654'j&T9u4MR†äŠœþý˜s 71$䬅UL92BQ9*5C-(Uþ#ˆ7-& * 6?9K*£2(TÝCS9p Jg¥YoÊ~Œg8cC ×Y`“Y%,)Y{YGL_2?8H: &J(,%0#2NR=@6RAL8B)J2oKþÌyÄ]gs#"&547#"$&547327654'#"&5467&#"!532654&#"#&546323&54>32%2654'2654&#"#++*" 4B}œþý˜s 71$䬅UL92BQ9*5C-(Uþ#ˆ7-& * 6?9K*£2&T9u4MRþõ(TÙ "("M @%"3 F0 6oÊ~Œg8cC ×Y`“Y%,)Y{YGL_2?8H: &J(,%0#2NR=@6RdCS9p Js-L8B)J2oþÛ$"""KþgzÄ[epƒ#"&547#"$&547327654'#"&5467&#"!532654&#"#&546323&54>32%2654'2654.'2654&'#"&=ø2PW<=Ukyœþý˜s 71$䬅UL92BQ9*5C-(Uþ#ˆ7-& * 6?9K*£2&T9u4MRþõ(T—.:V7'#8+-/)tO=@SU>'&oÊ~Œg8cC ×Y`“Y%,)Y{YGL_2?8H: &J(,%0#2NR=@6RdCS9p J‘KL8B)J2oþÍ.y:( 5 588 (Hÿ0(Ånw%2#!"3!!"&5463!2654'#"&547'#".54;2654&#"#54&#"632#"&54>32>32+"32>2654#"324#"ƒG^SBþ*9gý™/<:1²;L^8*)7 vp.14ÏÇ@M<03'S?3>! (&"-7,?7p0Y -C jzÏD:W)“£.3þY**™B61B ;.#$,.%?$(1-" B0 -!‚?4->D? O/7% 9 #8,(>7&7-:_4,>>‰//.f%MþܹÀ~ˆ‘%2#".54732>54#5254&##"&547'#"&54>;2654&#"#54&#"632#"&54>32>32+"32>2654#"324#"E[**=VkNC„jD\"S?b‚z>UmJEN9#9)2. $'D@",PGW2«AVC)5$S?4=!(%.#*9,A5p0X AXv™6G2$#@8@e.3þm**–?2% (/K) Fj¯n}| qkb™\< <)6(3!#.>>""1H7.:I63,DFO.8% 8(77-)> 7N=M[(!0 .. ¦!//*4fMÿ ?Åqzƒ%2#".54632&#"32654&'#"&547'".546;2654&#"#54&#"632#"&54>32>32+"32762654#"324#"yWo¯‹;F0kWpC8.K4D[#p‹/-6,)7 ŠB3 apÉ>O2:4&S?3>!(&.#.6,?7p0Y CUnYÛ'9 +#4†ˆ+.3þO**”aLc{"#,'nX-L$(1,#H7'! .KH4%=:< @.8% 9(77-(>7T=FX"AA„ //.fMþÈ@Åxœ¥®%2#".54632.#"32654.'#"&547'#".54>;2654&#"#54&#"632#"&54>32>32+"32762'654&#"#54#"&54632672654#"324#"y8Q+nf€AL4]yC' P;+7$[Br! 6,*6 Šg: #+(BC$É;R<07"S?3>!(&.#-7,?7o1Y @XpWÛH=-!6†…&% #"Q.3þO**”57~VO 2!6GB '$&-”m$6 $(1.!I6 /"3 E7,6;W@.8% 9(79+(>7Q@GW5!AAþá& + ;% %› //.fMÿólÅž§°¹%2"&547'#"&546;2>54#"#54&#"632#"'#"&54;2>54&#"#54&#"632#"&54>32>32+";2>7>32>32#"'#"32?62654#"324#"324#"*:8T6 ,%7.Q+6H}iµ@>f2'SG,=! (%.#0šsŠOUK©á(=7/ZS?3>!(&.#.6,?7o1Y .C {fËzu9Q›mE-@2p0X *A ~…#?`R@:f A !.3þF** ý]**¨5'(1.! 2(5?7#bBA O7/% 8(7U\D<(^"1*'0† S.8% 9(77-(>7$4*GV843O\*,> 7 /(XC,)#:„//.%ffJÿN(Ũ°¹Ã%2#!"3!!"5463!254'#"&547#"&546;2>54#"5#4'&#"632#"'#"&54;2>54#"#54&#"632#"&54>32>32+"3267654632>32+"32>2654#"3254#"3254#"—>SZDþX//Dý¼`7)n›=0(&0 a^/8EsXŸ54WMLH4 $#4)—izqq§Á44WLM+75 # *(1(:/a+ P&: ¹ËA,o_y?[Fa+O2ˆŠHPJ0&+þ##ýš$$®;1;F!5J$,Z1#(2,$ C-4+:F2$_|4]=$94,[[?3Cb4&_€ 4BE$#! )78-*? 5 /( @+c_>T5 ' [?,==‡,X*01101LÿDÅ´¿ÈÖà232#!"3!!"&5463!254#5264&+#"&547#".54;2>54#"#4'&#"632#"'#"&54;2>54#"#6=4&#"632#"&54>32>32+'";7>54>32>2654#"3254#""3267#"&%3254#"H*/ ƒ ª(-%þ4% ýö%01$¹&) 31'&0 UM / ·ž %-VNLG5 # *(>`ŽKzx¬½45WMM+85 # *)1(90a+L&: ¸yzEmIŒa<'81a+O'*þ™""#‘+8A-%/8üô##Å 8%q D*)9- ((!"!'3-# A." ‚ +_|\=$#! (8OP73E`4&_€ CD$$! )79,*> 5 /( 6@7P[%(>5þX&,, 01µ(.m „"01"Lÿ0Ű¹ÂÌ%2!".54632&#"32>54'#"&547#"&54;2>54#"#4'&#"632#"'#"'&54;2>54#"#54&#"632#"&54>32>32+"32>7>32>32+"32$2654#"324#"324#"15 þñ5A-jTRC7(4mF)HE)D1'%1 6h=3,SÈŸ#5 WMMH5 &!4)ft½%»¬44VML*84 # *(1'80a+N2ƱzST_­a&."`,L'; Ų/=,"'+þ€##ý­##© >,ù") -W=F##(2,$>#4(ƒ$ _| \=$94,S_B9+]4&_€44DC$#! )79,)=5 '  3$Wx6#75!0'›$v‚ --+#b"bLÿóÂÕŸ«µ2'654&#"#"'&5467&#"#4&#"632#".547!#"&546;2654&#"#54&#"632#"&54>32>32+";2>?>32>3262654'2654&#"%324#"Ój…6'1YfU#nWA@)$9/*.CyZy ]zRl>6E9p% 3*þÔ,2+i_H<<))$;;Ú5,+:T0$6::O7/% 8 #9+(<5!K=If%0K0*0P3 þqK6nJPo3G')&1-$=þ%fJÿœ¸¢¬¸ÄÌ%#".5467'654&#"#".5467&#"#4&#"632#"&547+"&46;2>54&#"#54&#"632#"&54>32>32+";2>?>32>326322654'2654&#"%2654&#"324#">-1" "*0 WeQ"lV?(< :,(-;Q:&N_ +6o-E2DRq]ð$,-#|?nDA pVK1F88B7g‚þ‡(3Ub54"+$"ý<$!&"(#ýF**D'- 2"+6 BvYu ZxPj-A47p" 1*þÛ%1*h[F"3)C;W^ :U*4V866#57:M&=$ &(&)8*': 3 I;Ja*&=#+1YO,# ŠezH6kIPk2EÇ$!""Á7$1,#; "!dJþŸ©´ÉÕÝ%#".5467654&#"#".5467&#"#4&#"632#"&547+"&46;2>54&#"#54&#"632#"&54>32>32+";2>?>32>326322654'2654&#"2>54'#"&'%2654&#"324#">%&S<*> O3JeQ"lV?(< :,(-;Q:&N_ +6o-E2DRq]ð$,-#|?nDA pVK1F88B7g‚þ‡(3Ub5ò*B)1%# #-8ýg$!&"(#ýF**?(54.#"#54&#"632#"&54632632+"32?6322654#"324#"×ê¹Îþài!]˜…©ñQ.$:)*6 !€i+ #+hUÉ,2"*)4'SA3:#(%/"*9hR`;1UFUkSå0.'2K†QDLbè.4þP** f‰ë¬Š~"mvžiZx($%1H,( D+ 05A 7$* KC@,;& 8(77-AN57K>CS ' !>"N@//.f%Fþ˜×¿xŽ˜%2#"&547#"$547327654&##"&547'#".546;2>54.#"#54&#"632#"&54632632+"32?62654#"264&+324#")LbOG 2"4BTbÎþài!]˜…©ñQ.$:)*6 !€i+ #+hUÉ,2"*)4'SA3:#(%/"*9hR`;1UFUkSå0.'2K†Q .4™!! #ýÐ**˜N?Q@N #*F0묊~"mvžiZx($%1H,( D+ 05A 7$* KC@,;& 8(77-AN57K>CS ' !>"Ž//.þÕ#2"#Df%Fþ?׿w€Š•©%2"&547#"$547327654&##"&547'#".546;2>54.#"#54&#"632#"&54632632+"32?62654#"324#"2654&'"2654&'#"&=)LbA33:U|TLGÎþài!]˜…©ñQ.$:)*6 !€i+ #+hUÉ,2"*)4'SA3:#(%/"*9hR`;1UFUkSå0.'2K†Q .4þP**.*A(:'#83%/):˜N?4X R/=VU>1& 묊~"mvžiZx($%1H,( D+ 05A 7$* KC@,;& 8(77-AN57K>CS ' !>"Ž//.f%ý¬ #y8* 5 5!-8 ,6LÿEÝÀWco#".547&'#"&=4.#"#".5467&#"&546326323265332654.'264&+%2654'X*9 GEE/ "*E0.RB_:-(lUD)< 9/-M^^!kwb?4.MJX<)"?S2):N 3#4""ýU)5We(À@D3sD K3A 2!  ALaLa :2ZzRl.B6;n% nW~?Mjƒ`M]LD,#Dþì4>iM-94ýâ"4"‰K6oIPo #,LþþßÀUbt€#"&547&'#"&=4.#"#".5467&#"&546326323265332654.'2654'2654'#"&'%2654'X*9 VXU<=S,4'.RB_:-(lUD)< 9/-M^^!kwb?4.MJX<)"?S2):N 3#) %)92'#/EýN)5We(À@D3‚B`DWW?A'3LaLa :2ZzRl.B6;n% nW~?Mjƒ`M]LD,#Dþì4>iM-94ýï% X8*$ %5) 2+öK6oIPo #,MÿÞÂht#".54>32&#"327#"'#".5&4.'&#"#".5467&#"&54632632265332>54'2654'y$AK‰e58CDZa'6SO,? Yý()5We(Á&zCnz<!(Ù%KK&90T"3(ZzRl-B67q& ,@7„HU–_€RH"RŠ+#Dþìq+A3YfþK6oIPo #,LþÈìÀo‘%#".54632.#"32>54'#"'#"&='.#"#".5467&#"&546326323265332654'72'654&#"#54#"&546326%2654'ì,Fa_4AL4]zB' P;@WZCAg9% 5LU9.RD]<5&lXA)< 9/+N]^!kwb?4.M.C"fFS2)>Ju';þÈ&% #ýß)5We(na—\; 2!7FB '/#%./AR;8MLbG4>7'&'#".'4&#"#".5467&#"&546326323265332>54&'2654'r%.þ´õ¦þô—17'502éHQQ$N$-I%8 *@# ]N:%5 /*&ATU _jU7.1;?NU#-LD'8 4+ý#.KV"ÂAD'¼øpÆzHh=7`B¤Æ.EH&9/‡nZxSl.C67n' u?ƒHY”`WC"R‰*"Dþìo.D74aþ–J5lHNm #+PþþÝÃkwƒ#"&=#"$&546732>7'&'#".'4&#"#".5467&#"&546326323265332>54&'72654&#"%2654'~,3F/0Fš¿ þ÷ 17'502éHQQ$N$-I%8 *@# ]N:%5 /*&ATU _jU7.1;?NU#-LD'8 4+ %.s ""ý•#.KV" B(4BA5SiÇ€Hh=7`B¤Æ.EH&9/‡nZxSl.C67n' u?ƒHY”`WC"R‰*"Dþìo.D74a AD'‹þö$"*"óJ5lHNm #+Pþ™ÞÃn|œ#"&547#"$&546732>7'&'#".'4&#"#".5467&#"&546326323265332>54&'72654&'"2654&'#"&=2654'V(; U>=U ‹Ÿ¢þö17'502éHQQ$N$-I%8 *@# ]N:%5 /*&ATU _jU7.1;?NU#-LD'8 4+ %.ž #(:,8+-/)8ýÅ#.KV"B%2(>UU>32#"&54632>326322654'264&"%2654&#"ÿ))D01C2GpU$mX@)< 9/*0CS-$ -F%/!4B6>AMŒrk-J)>58CkŽþy&3Wa5$2##2#ý%%"'"(( =%3AD0.6 PWZ{ [|Rl.C5:q# 5(þÔ,(#.?&)\31PeTx™M#*†l]=J7oILs3G¸"4""48%2.#9MþûSÂPZez†2"&54>7654&#"#".5467&#"#4.#">32#"&54632>3262654'2654&#"2>54'#"&'%2654&#"XkŽZ\S|R!1%FpU$mX@)< 9/*0CS-$ -F%/!4B6>AMŒrk-J)>58K&3Wa5þ,%%C*3&1/ý6%"'"((†laZaCXV@); PWZ{ [|Rl.C5:q# 5(þÔ,(#.?&)\31PeTx™M#*þtJ7oILs3G£u" " &5$ Fõ8%2.#9Eÿø‘ÄDO[233!53654&#""&547&#"#4&#">32#"&54763263262654'2654&#"ýVj_àSýןjJ8NNh@M&/SI63L&.!/F5>@OJH`_F$V.#)? )F",*þO'&!)(Â}_}E—þG":„KgInCRNCsA 2(þË,(6.I8)SA0LlOqRNONþ¾8/a-U*.:P/%$/.#9Eÿ;•ÄOWbn233##"&547!53654&#""&547&#"#4&#">32#"&5476326326264&"%2654'2654&#"ýVj_àS$(A31C)þ’ŸjJ8NNh@M&/SI63L&.!/F5>@OJH`_F$V.#)74""4"þ¬ )F",*þO'&!)(Â}_}E—þG51CC15":„KgInCRNCsA 2(þË,(6.I8)SA0LlOqRNONý½"4""4ß8/a-U*.:P/%$/.#9Eþþ›ÄN[ny…233#"&547!53654&#""&547&#"#4&#">32#"&54763263262654&#"2654'#"&'2654'2654&#"ýVj_àS'1TzS3þ»ŸjJ8NNh@M&/SI63L&.!/F5>@OJH`_F$V.#),%$+72'1 *(þ– )F",*þO'&!)(Â}_}E—þG&CAZTBF(":„KgInCRNCsA 2(þË,(6.I8)SA0LlOqRNONýÔX:($ $6"! #. B8/a-U*.:P/%$/.#9MÿÊÂiu2!3#".54>32&#"326=!53>54&#"#"&547&#"#4&#">32#"&54632>3262654'2654&#"RgZS.IU=N4bVlB=j"\H6u‘ý²ø+0D7" N 8%2?Z(0SJ2-F%+!4B6>AMŒrh0 ;+8()G#*@9 #þL%"'"((ÂvXr^—þ /5& $ !&_N"%e2LeNf-6%M;bT1)þË,(5#.?&+\31PeT{–M5þ¾9.T4 U+*+P8%2.#9Pÿø=Âfs~Š2#"'&547&#"!53>54&#"#"&547&#"#4&#"632#".54632>326323&5462>54&'%2654'2654&#"w/J) H;5"`.C 2%ýì´#,;/ C 3#,9N(#M>-DV'6- 8/$5 |e[*-2"#/F^LË6p•X'ý¾$73þŠ,"""Â*;H6Zy7.:ƒZ/E74l &c6HeMe,6%M7&#"!53>54&#"#"&547&#"#4&#"632#".54632>326323&547632632#!"3!!"&54>3!2654.'#"&%2654'2654&#"%2>54'[45#/J72_ýÞ´'(;/ C 3#,9N(#M>-DV'6- 8/$5 |e[*-2"#/F^LÔ<@?Z\Cgƒfý5!$µüK,<$ ¸O_$/ &N<=Pýö$73þŠ,"""6% &&+1¦5X( =;Lx;"$r(HeMe,6%M54&+532>54&+#"&54>7&#"!53>54&#"#"&547&#"#4&#"632#".54632>3263232&54763262654'%2654'2654&#"Y]|HJQ9üϲüK).:*ü),,!) SD"S<9K"-!%<5L#_ýè´#,;/ C 3#,9N(#M>-DV'6- 8/$5 |e[*-2"#/F^L3^7<@?Zf> r"*@G1ý¦$73þŠ,"""PC@(C4GI 0&,< ($7#! +5ATPo^A%C+$$0G9x;&c6HeMe,6%M32&#"32>54&'#".5467&#"!53654&#"#"&547&#"#4&#"3>32".54632>326323&7327654'2654'2>54&#"ÀqZl9A\™r;J4POKF70(OQ(0K. ,'I<"2 EE$8.D +-ý­ÛO;/ C*# .7N(#M>,ES ), 9^<{e[*6$2"#0I[Mä5Ã&$sýÊ$7!& þ} !"Ôe‰r_޶ % !)>TM'6_5X|(:.=k 5/E7)q &LmIeMf,@ N32#"&547'#".54>;2654#"#54&#"#"&547&#"#4&#">32#"&54632>3263262654#"%2654'2654&#"L-7%ßÊ)B'-aHc.*;9*(8 ;…E0 "*(BB"µ2^e3&S?35$(1#0CSJ2-F%.!4B6>AMŒrk-J);$'3r.˜-4þz**þ%"'"((à 8'Ÿ $!)!2%"-&D&#4 B0b9<-@.8 E #9+/&5(þÔ,(5#.?&)\31PeTx™M#*55þ\//.Ú"??É8%2.#9Mÿ:)Ñž©µ%#!"3!!"&57>3!2654&'#"&547#"&546;2>54#"#54&#"#"&547&#"#4&#">32#"&54632>32632632+"32>322654&#"%2654'2654&#")T4þS..5ýË*8)!“-H3'8-)7 _g05BwYÉ $-e7"S?35$(1#0CSJ2-F%.!4B6>AMŒrk-J);$'3r.l-7%XJý-I(.fMh/BZÕ ! þ~**þ%"'"(( 921%', 7")2'<.6,=J 0!b>T@.8 E #9+/&5(þÔ,(5#.?&)\31PfSx™M#*55 8'HW%*!%-%I;ð"??É8%2.#9Mÿ<Ø¡¬¸%2#!"3!!"&5463!254#5254##"&547#"54>;2>54#"#54&#"#"&547&#"#4&#">32#"&54632>32632632+"32>762654#"%2654'2654&#"€fV '2ýë))[ý¥)33)ÿ%.'P8-)7 -E!A2‡FV1¶*> e7"S?35$(1#0CSJ2-F%.!4B6>AMŒrk-J);$'3r.l-7%‚]º3HP&OGQ.1þ“**þ%"'"((™8&  0%:5$ '$*<$)2'/s.:* b>T@.8 E #9+/&5(þÔ,(5#.?&)\31PfSx™M#*55 8'GX1'4)4!‰/*.é"??É8%2.#9MÿóUÂgs€Œ2'654&#"#".5467&#"#4&#"#".547&#"#4&#"632#"&54632632632>3262654'!2>54'2654&#"bl‡{1WlQ nUD)< 80'3JSF9(k ?+': a(0CSI3-F%-< "*F-@N‹sSE1VC,2Je:I9=,7N(5We"ýõ(X-02þ) &&!).•eHDt]z ]zOo.B67r% 5?þë 2#"&54632>32632>3262654'2654&#'%2>54'2654&#"bkˆN2DbC.)? )E+!nTE(< 80'3JSF9+k$4+': a*2ASI3Qa .B2 0!AMŒrl,K)D+:Bi6>1B'4K(5We"ù4"" ,ý$. X+21þ*$#&!).½cVW 6.1CD0&@ MP1=2" ]zRl-B77r% 5?þë 7654.#"#".5467&#"#4&#"#".547&#"#4&#">2#"&54632>32632>3262654'2654&#"2654'#"'%2>54'2654&#"bkˆW`"+ =T0"F )E+!nTE(< 80'3JSF9+k$4+': a*2ASI3Qa .B2 0!AMŒrl,K)D+:Bi6>1B'4K(5We"Û,%"D,65%C7ý$. X+21þ*$#&!).½c]Ze%: W?(: PU1=2" ]zRl-B77r% 5?þë 54&+"&54>32&#"32654&"6HT>;A3"2 t==o6-.5a:J(O7‚D5i?L) k4""4"?5J)!E1C+! $!?9 ''F4/.G80)"þƒ"##KþþÓÀ.;N2"&547&'732>54&+"&54>32&#"32654&'#2654'#"&'6HTJKTzS+`1=o6-.5a:J(O7‚D5i?L) ^$$,63&"/*(?5S'"WAZUA@'49 ''F4/.G80)"þ– !X:($ &4' #. Kÿ…çÀ3"#"&54632&#"32>54/.54632&L@JbM`-IK(IjYDX<-><;/10cl%0r]‚H=•8'MWE5L'.& 0*' 6%] <(FUE5Aÿ?¿+Q%2#"&54632&#"32654'#"&4632&#"32'654#"#465654#"&546326NYm¨IabK^5Z2EJ5`zŠi=R`qJ=€’T$  ôaOt‘9/-;62&!,r\…HnU:4^Jþà    '   Gÿ>ÙÂ4%#"&'532654&+53254&+"&54632&#";2ˆ7Sa?wi5B9!ðÊx/#w:Ip^zG7g@O%e31 8'(B7+)1D*G4BOG70'# /!TGþ‡ÙÂ>K%#".547&'532654&+53254&+"&54632&#";22654&'#ˆ711A3"1 ~4i5B9!ðÊx/#w:Ip^zG7g@O%e31n ( (# 8'/#<1C)" &'7+)1D*G4BOG70'# /!Tþ+ ,#Gþ@ÙÂ;FY%"&547&'532654&+53254&+"&54632&#";22654&"2654'#"&'ˆ7HBTzS1c,i5B9!ðÊx/#w:Ip^zG7g@O%e31Ÿ%&$,65$"/*( 8'>$PAZUAD( 7+)1D*G4BOG70'# /!Tþœ%X:(" '3' #. JÿönÂ,%2#"'&54732654&#"+"54632&#"327ÍGZq\ŒgdTB¦vAR.5·o\|G7g9Zw ýK7=HRTogOBU^Ž.&"uHUG7/lJÿEoÂ7E%2#".547&'&54732654&#"+"54632&#"3272654&#ÍGZ67E/ "*‹abTB¦vAR.5·o\|G7g9Zw ,2#" ýK7;$!B3A 2!"RSmgOBU^Ž.&"uHUG7/lþŒ"! JþþsÂ5BT%2#"&547.54732654&#"+"54632&#"3272654&'2654'#"&'ÍGZGLU<=S(I‡`TB¦vAR.5·o\|G7g9Zw $,62'#/EýK7E$"WDWUA='A}NgOBU^Ž.&"uHUG7/lþ™ !X9)$ $6) 2+MÿTÀ(4%#".547#"&546322>54&#"264&+Ì0E/ ") _€yad‡û1<*bGHa"I¢2## 4 6-3A 1"{afˆhcH!H0Id`G3>+–"4"MÿÀ&6H2"&547.5462>54&#"2654&+2654'#"&''d‡`aTzS"*<.!yQ1<*bGHa"IŽ&! +72'1EÀhwCeBYW?6' -O2fˆþn!H0Id`G3>+’X8*" %5"! 2+MÿEØÂJR#".547&'#"&=74&#".5463232653327654&'264&"W)8 KE/ "*E12YHa5!(0 6.*; qK7\G-50S(.5*.G)2##2#À@D0tE33A 2!" BLePSG>%M354'#"&'W)8 ^\S>=S.5%2YHa5!(0 6.*; qK7\G-50S(.5*.G) &0 3&1 EÀ@D0†CbCXU‚)5LePSG>%M35#"'#".54754#".546323265332654&'N:K»¬`€|[oF5c"_Z%@i=)3?e(3T86!S:Op*: gS8CX'6SOBRB1Â&~EîÎ*!*#"$5?2'KK*R9‡fJyLCC1e3TU`G+#DþìqcJ7qMþ½ØÂ@v#"'#"&=74&#".5463232653327654&'2>54'7#"'#"&=74#"&54632326=3W)8 "/:)S92YHa5!(0 6.*; qK7\G-50S(.5*.G)  KV .%7%!:3>7 JZI4,6.#:À@D08X1 MLePSG>%M354'7"&547&'#"&=74#"&54632326=3264&+W)8 "/:)S92YHa5!(0 6.*; qK7\G-50S(.5*.G)  KV<=B\B+!:3>7 JZI4,6.#:C#!!$À@D08X1 MLePSG>%M354'7#"&547&'#"&=74#"&54632326=32654'"'2654'#"&547W)8 "/:)S92YHa5!(0 6.*; qK7\G-50S(.5*.G)  KV=F$ 4H7!:3>7 JZI4,6.#:2 L4)'"À@D08X1 MLePSG>%M3%M3,6'/(‘ . MþÙÂ@~‰”#"'#"&=74&#".5463232653327654&'2"&547&'#"&=4#"&54632326=33267#"&5462654&#"264&#"W)8 "/:)S92YHa5!(0 6.*; qK7\G-50S(.5*.G)F'1C?B\B&# %M3,6'/(‘ . þà-&--%MýëÝÂ@‚›¯#"'#"&=74&#".5463232653327654&'2#"&547&'#"&=4#"&54632326=33267#"&5462654&#"2654'#"'2654'#"&547W)8 "/:)S92YHa5!(0 6.*; qK7\G-50S(.5*.G)F'1DH$ 4H1" %M3,6'/(‘ . ï P." ,4 '!MþÆØÂ@HT[#"'#"&=74&#".5463232653327654&'4632!7354&'4#"6W)8 "/:)S92YHa5!(0 6.*; qK7\G-50S(.5*.G)‹9T‘þâ½&¡-/*2,AmÀ@D08X1 MLePSG>%M2%M254'#"&5477#W)8 "/:)S92YHa5!(0 6.*; qK7\G-50S(.5*.G)9T‘*3 4"4H3c½&¡-/*2,Am", )'"0& À@D08X1 MLePSG>%M2 $,G4>"¾).gM<$6TNÀ P#!  ,4 '!/§Mþ,ØÂ@bmv#"'#"&=74&#".5463232653327654&'4>32#".54632&#"326=#7354&#'"654&W)8 "/:)S92YHa5!(0 6.*; qK7\G-50S(.5*.G)‹,-’CV38J5B;7N;)ó¼#$(¦30,_(t À@D08X1 MLePSG>%M2%$bPB!5?tS[!KÿIfÃK".547327#"'#"&=4&#".546323265332654'7[y½sKi!dEi¯pâ‘\22VFe3" (0"G(*: qM7YH.6-S4+8Kj|þÛ·1Mjh7|tck0X[B*vJK`L\J?$I0PgDI4b{TaWNC9Cþì3?cOˆ:`Œ±ÛKÿ iÃXa#".=#".547327#"'#"&=4&#".546323265332654'7264&#"+.C1"2 …¡y½sKi!dEi¯pâ‘\22VFe3" (0"G(*: qM7YH.6-S4+8Kj|‹4""' B%1C+! =1Mjh7|tck0X[B*vJK`L\J?$I0PgDI4b{TaWNC9Cþì3?cOˆ:`Œ…þý#2##2Kþ©gÃYfz#"&547#".547327#"'#"&=4&#".546323265332654'72654&#"2654'#"&'ë"-U<=Ss€y½sKi!dEi¯pâ‘\22VFe3" (0"G(*: qM7YH.6-S4+8Kj|µ. C,64%"0 )6 8%DWUA(1Mjh7|tck0X[B*vJK`L\J?$I0PgDI4b{TaWNC9Cþì3?cOˆ:`Œ¢ò" v9)" &4)  MÿFÂKVb2#".547&'#"&=4&#".54632326533265##"&5462654&#"2>4.#";HQ((E/ "*\D3XIa4"8Mo*; jS//E+6.S!0';`*)1@E=")' &$  $$ÂmWˆM ?#3A 2! ONiVEKAkO…8BG2`ƒ'M5HSH;Aþè$5 cr&"R;7KÞ.")1/J1þ¦.!6!MþþÂKVdv2#"&547&'#"&=4&#".54632326533265##"&5462654&#"2654&+2654'#"&';H"aS>=S&G73XIa4"8Mo*; jS//E+6.S!0';`*)1@E=")' &$ %%+72'17ÂmW0R7 fCXUA<& @NiVEKAkO…8BG2`ƒ'M5HSH;Aþè$5 cr&"R;7KÞ.")1/J1þ²X9)$ %5"! %9MÿÁXd2#"&54632.#"3265#"'#".554#".546323265332>5##".5462654&#"yS8´®B”}[lM=M%!`V+wž;Zp,1\/F#S:Op@FgS7EU)5SL9,A! *#3 @G!**!'&Áq|íË+!(% ‚i6LL&?B#>‡fKxL&|Db‚7YWZH-%@þé7D'CD&#4(4KÝ.#;( ,7HÿA’Á f%2654&#"".5473 7#"'#"&574&#".54632326533265##".54632 +*#%'þÉzPb"]Bf‹„E‹!$`?5XL]2"*/ 1#(.hRBQ /!GSN8FU#E "+C154'#"&54>7&#"#4&#"#4&#"632#".547626326322654'%4&#"326ý”g@4$$3@4$dNA8K >($S?5T?3'5SI5,F$-<2D7+5DJGÀF6\X6=](B)#6(þÚ#,%1 -ýR%")$%'lu–, "2W5u"-6XlSB%6-$E:þÂ5@(þ¾,(6$/A$IV>4,@M+wPMONJK*! !.RkH:D, 9&-@NKGa_F3Ze0@Ql+# E !K'ü¯ &%!).©0 %/4," 3/) ")5'þÎ5@'!þ¿,(5$/@$H ?*1LfSuPNOMZZK<$*!&y/H0.#$2Hÿ;†Äiq|%2#"&547&/3254/&5463232654&#"#4&#"#4&#"632#"&547632632632#"&#"326264&"%264&#"&3-61A31C?& 1_`=q=8#G D9C[SA3'3SJ5,E$-< "*5>@NKGa_F3Ze0@Ql+# E !K'2##2#üð &%!).©0 0!>0DD0)4," 3/) ")5'þÎ5@'!þ¿,(5$/@$H ?*1LfSuPNOMZZK<$*!&þÖ"4""4/H0.#$2Hþþ†Äht†‘%2"&547&/3254/&5463232654&#"#4&#"#4&#"632#"&547632632632#"&#"3262654'#2654'#"&'%264&#"&3-@=TzS+( 1_`=q=8#G D9C[SA3'3SJ5,E$-< "*5>@NKGa_F3Ze0@Ql+# E !K'.$ %)92'17üù &%!).©0 6%LBYUA?( 4," 3/) ")5'þÎ5@'!þ¿,(5$/@$H ?*1LfSuPNOMZZK<$*!&þí! X9)$ %5"! %9ò/H0.#$2Oÿ+Áiv%2# $5467!2>54/&546322654&#"#4&#"#4&#"632#"&54632632632#"&#"2654&#"rTXo¶¹bþÙþ˜47*92M[£›\=q=2)CE1EaSA0)4SH4Pa +>+9 /!6XŒrk./Y54/&546322654&#"#4&#"#4&#"632#"&54632632632#"&#"2654&+2654&#"rTXLG 2"4B“ÁþÙþ˜47*92M[£›\=q=2)CE1EaSA0)4SH4Pa +>+9 /!6XŒrk./Y54/&546322654&#"#4&#"#4&#"632#"&54632632632#"&#"2654&'"#2654&'#".=2654&#"rTXs4;U|TЦþÙþ˜47*92M[£›\=q=2)CE1EaSA0)4SH4Pa +>+9 /!6XŒrk./Y/#!íÂDe=9^A¡Å-W=. 6(5 $!-3)þÍ5@( þ¿,*3i_I<<))Ucz˜MM; ["2(<!þj #y:( 5 5' & +7„9$3-$$$Lþ’KÂ>J[g74>32632632'654&#"#4&#"#4&#"632#"&2#"&5462>54.#"2654&#"L$8\:i0/Xj/*SN:A 3)+hK;'3S@2&6SS,¥-> !*E4>LêOfcNL`]? '.  & 5MLýÐ,(*&°%HJ8#OMHJ=Df3U6 A‹Rf-$þÂ3B)þ¾,)5ÉG =*:HjlcOIfcGOhþÊ 7$2H89Nr,#'0-$'.Lÿõ™ÃVb%#"'#".=4&#"#4&#"#4&#"632#"&5476326326323265332654'74&#"326™bIL2+M-7&.%*M7,!,N<.&="'6,<9.:E>BbC:*WS*'M%þ¾,(2"/:*FS>:HlRdRWJKHJ^JrD;*"Cþí3%þ¾,(2"/:*FS>:HlRdRWJKHJ^JrD;*"Cþí3<²#2# ‹+#$.+#%-LþùÃ_k€Œ%2654'7#"&547&'#".=4&#"#4&#"#4&#"632#"&547632632632326532654&+"2>54'#"&'%2654&#"ú2AgyUYU<>R9(+M-7&.%*M7,!,N<.&="'6,<9.:E>BbC:*WS*'M%þ¾,(2"/:*FS>:HlRdRWJKHJ^JrD;*"Cþí3<¦v+'  '3#  "ú+#$.+#%-Qÿ™Áx„#".54632&#"32>7#"'#".'&54#"#4&#"#4&#"632#"&546326326323265332654'2654&#"%(4%@aE =<%mQNF0*8O]+?, '4W%-I"7KRL5- !#M>-'= '5/;:.;D{f]**M]*!K0<M#-MC6Jgû²,!$'Á#JJ+_„h< !*% 9.,!HH", a†ZþÙ2A "þ¾,'4#->%G_1;HgSvœKKHH5WV]F*"CþìnhGlSþŒ%($1.!"1IþÞjÂny#"$&5467!2$7#"'#".'&54#"#4&#"#4&#"632#"&546326326323265332>54.'2654&"ò6BÄþ¢äßþ—Ó+6%0)öÕ$Õ+J+*K"8KQM6-6M>-D^'6&31'9E|e^))M_* K~+;$-MC&7 !# û³+ 4%'Á%A›éz{æ”G`HAV9ÏziW QI"- [†ZþÙ1B!$þ¾,&5qSG==7.fT{–JJGG·NFK+!Cþìn+?3>-- þŒ%($1-"$/IþÞmÂz…#".'!"$&5467!2$7#"'#".'&54#"#4&#"#4&#"632#"&546326326323265332>54.'7264&#"2654&" %; 1!+9Ôþ¶ßþ—Ó+6%0)öÕ$Õ+J+*K"8KQM6-6M>-D^'6&31'9E|e^))M_* K~+;$-MC&7 !# 6Bs !("û­+ 4%'-=0 "+10€{æ”G`HAV9ÏziW QI"- [†ZþÙ1B!$þ¾,&5qSG==7.fT{–JJGG·NFK+!Cþìn+?3>-- %A–þë$0##"%($1-"$/Iþ{nŠ¡¬2#".547!"$&5467!2$7#"'#".'&54#"#4&#"#4&#"632#"&546326326323265332>54.'72654.'2>54&'#".=2654&"Ý)5$$5* +$ ÌþÝßþ—Ó+6%0)öÕ$Õ+J+*K"8KQM6-6M>-D^'6&31'9E|e^))M_* K~+;$-MC&7 !# 6Bµ.:A&0 ("8 +"!, 8ûÝ+ 4%'_ @V? 8#f{æ”G`HAV9ÏziW QI"- [†ZþÙ1B!$þ¾,&5qSG==7.fT{–JJGG·NFK+!Cþìn+?3>-- %Aºþ÷/y+'85 ""  (:s%($1-"$/Kÿ÷ÃÀ_ky2#"'#".'&54#"#4&#"#4&#"632#".54632632632326533265#".5462654&#"2>54&#"G1K)R8`)&V*?JRM5-!-M>-DV'6- 9/$4 {f^))M^* K1<L2M@35Q!8(49?$#!û{!#'À]m+RQ1II"4(a…YþÙ1A'þ¾,&4g]F"3+:G$<;u›JJGG5WV[F7;þé1F]mC>;8FÚ-!:(*6´!%/+#$/MÿIâÀsŠ•%#"&547"#"'#".'&54#"#4&#"#4&#"632#".546326326323265332>7#".54>32'2654&#"2654&#"%2654&#"~'= 00B `)&V#7KRM6,7M>-DV'6&307$5 |e^))M^* K2<L4M@3&8 !:- 1'#3 k##"!3&%û]+ #''B$Šz+#:(+4þ—,´%($1-D1IÿðÀ{ˆ” %#"'53264'#"&547&'#".'&54#"#4&#"#4&#"632#".546326326323265332>5#".54>32'2>54&#"2654&#"%2654&#"t2JdK9,$A)8 -#(7Y%$X#7KQM6, !#M>-EU'6- 8/$5 |e^))N^* K~L$.L?4&8 !9, 1'3Ik $" û‰!"#' H:DSA09X )-/$(CJ!-\…ZþÙ2A "þ¾,'4jZG#3+:H%;<z—JJGG»zF6<þè0H'AA"C"3+5,^l‘€" <(*6þ§ ¥7$1/ $/KÿÅÁ|ˆ”2#"&54>32&#"32>5#"&'#".'&54#"#4&#"#4&#"632#".5463263263232653325#".5462654&#"2654&#"G$4 ,HqLXlDR.WG1Pqq>b;'6_*L&V"8KRM6,7M>-EU'6&307$5 {f]**L^*L2<L 1M@3{5- 9@##" ûz+"#'Á-LO+U€oG(.&% ("%.%!4FA"N("J"- \…ZþÙ3@!$þ¾,'4h\G==2Q%;<vœKKHH5WW[F7<þè2E³,#4*:FÛ- ;(+4µ%(%0/ $/Lþ¼KÂ>s‰74>32632632'654&#"#4&#"#4&#"632#"&2'654&#"#54&#"#54&#"632#"&546326326%2654&#"2654#"L$8\:i0/Xj/*SN:A 3)+hK;'3S@2&6SS,¥-> !*E4>Ll6O`F0' :) ":'*k +./"*2fDE 9E ýC,(*&F-°%HJ8#OMHJ=Df3U6 A‹Rf-$þÂ3B)þ¾,)5ÉG =*:HjsVCm**[6AѶ +ÔÅ+.6)&0G4`U21./C,#'0-$'.þ¶76Lþ½KÂ>|†’74>32632632'654&#"#4&#"#4&#"632#"&2#"&547&#"#54&#"#54&#"3632#"&54>3263262654'2654&#"3254&#"L$8\:i0/Xj/*SN:A 3)+hK;'3S@2&6SS,¥-> !*E4>LICZ5+,6G#.:"("9.#,*!-$),4(:.=0$>;$0j"5B$ý,(*&Ý .°%HJ8#OMHJ=Df3U6 A‹Rf-$þÂ3B)þ¾,)5ÉG =*:HjteM7DE5Q6 Ó¶-ÔÅ"' .:( 3E65N#330.þý#)Q.5I"+G,#'0-$'.þí4LþYYÂ>‘žªµ74>32632632'654&#"#4&#"#4&#"632#"&4>32632632#"'732>54'#"&54>7&#"#54&#"#54&#"632#"&2654'2654&#"3254&#"L$8\:i0/Xj/*SN:A 3)+hK;'3S@2&6SS,¥-> !*E4>Ló&/# ?.">:$(=T";9cD)% (=> 4+&2.4,:)! :.$#2 )!.$)3,W #ý;,(*&¾,°%HJ8#OMHJ=Df3U6 A‹Rf-$þÂ3B)þ¾,)5ÉG =*:Hjþ×+D&3300L U7Oa %5.J#;G7, !,!+Ò¶")ÔÆ"1 .:(4K '-) %$H,#'0-$'.þë(5 Mÿ÷­Á1=HQ>32!4&#"#4&#"632#"&546326322654&#""654&354#"TFÜþ"H5#8SH4Ob +>!2 5?AMŒr 5( 4]?PýÁ$#'"(#é . ¹)sQNú¡F[42þö·3A &þ¾,(5i_I"3+2OeS{— MBþ¯9%2.#=[#9;°ƒ‹%3hEsF–å1MÿA³Á;DOXd>32#"&547!4&#"#4&#"632#"&54632632354#'"654&2654&"%2654&#""TFÜCbC þäH5#8SH4Ob +>!2 5?AMŒr 5( 4]?PQNú¡F” . ¹)z4"!6!üÃ$#'"(#[42þö·-1CD0.3A &þ¾,(5i_I"3+2OeS{— MB^EsF–å1#9;°ƒ‹%3ýü"##2†9%2.#=Mþþ·Á<EP]p|>32##"&547!4&#"#4&#"632#"&54632632354#'"654&2654&#"2654'#"&'%2654&#""TFÜ.8U<=S:þÿH5#8SH4Ob +>!2 5?AMŒr 5( 4]?PQNú¡F” . ¹)m%)92'"/ 0üÄ$#'"(#[42þö· GDWUAJ"3A &þ¾,(5i_I"3+2OeS{— MB^EsF–å1#9;°ƒ‹%3þ "X8*$ $6( &)ð9%2.#=Iÿ\øÄ I%2654'%#!"3!!"&5463!2654&+"#"&5467&#".54632632v*4We5«bHþl?#9ýÇ3>?2j8KgU nSB@P<,0IY*5!>.v_;37F6V3" s;1]=D\.8f_‚'J5,+5kMYlMgGWTF1` `H&^"g+Xx 1A;Dÿ\óÆ S%2654'%#!"3!!"&54>3!2654&+532654&#"#"&5467&#"&54632632r*4Vf6©I>þJ>>4ýÌ0B 0!eH>(-7@C5lU@?Q/:(HZ_!kxX<75dÍ Kx<0Z>EY.8#xBfEA³LþÈ,Ã@co2#".54632.#"32654&#"#".547&#".54763262'654.#"#54#"&546326'2654'{—˦AL4]xD' O;@WZCœx`7nWB)< h)L`_!38DE_6.1 &%  #V)5We(ÃΙµß 2!7FB '/#%.Æœ‰º \zRl,B6}Q rU}>%vB^GGý²' , ;% 'ÀI9oIQo #,GÿøÄNXa2'654&#"#"&5467&#"#4&#"#"&5467&#"&5463263263262654' 2654' l‰,"1Zt]nSB@P:/!3KSL9lSB@P9/+'?% ^!k}]B04;k@1g5-9P*4Xe6ýêT4WeÑh,L3 Bu]{ \{UgfQ9q$B5þë @0-_vn_nRCAO:/!3KSJ;lRCAO9/+'?% ^!kyaA14;k@1g5-9@r…9oBÈV3XeþJ+3We4P*I4+-6h]r \{QkhO;o$B5þë 9O ZzQkhO9q$ /:-€=K’cˆ\[‹q=[‡I7mKPo3FI7oIPo4EGÿÄnw2#!"3!!"&5463!2654.+532654&#"#"&5467&#"#4&#"#"&5467&#"&54632632>3262654'2654',e‰RP-D5ü_"#Zû¦1?@0_JZ$! &%^C7nRCAO90!5ISK:lRCAO71+'?% ^!kyaA14;k@N:5-;}V3XeþJ+3We4ÃN?G))K0E I6),7E:$/ ,B,:\{QkhO9o&D3þë :N ZzQkhO9m( /:-€=K’cˆ\<þtI7oIPo3FI7oIPo4EHÿÁdp|2#"&54632&#"32>54&#"#".5467&#"#4&#"#".5467&#"&5463263263262654'!2654'"pŠ/GbX0Y|GZO0"U"\}%CK6#pV$nUD)< 9/ƒSE9&lUD)< 9/,0I#_!j{]>57Di6$~%48Q*4We(þ)5We(Ážwb•T5,$'+.I‚Ug ]yRl-B69q$ tþë ;J[yRl,B6:o% ,?7„HW”a~[ZþsJ8nJQo #,I9nJQo #,HþÉ<Á$™¥2'654.#"#54#"&546326".54632.#"32>54.#"#".5467&#"#4&#"#".5467&#"&546326326326322654'!2654'ú&%  #"?N5]yC' O;?X<-3Pt; .T6+nUD)< 9/ƒSF8"lWB)< 80*0I#_!j{]>57Di6$~'28LtœÇæ*4We(þ)5We(‹' ,  ;% &¬ 3#7FB '/#*?gj8JhT< \zRl-B6:o% tþë 8MZzRl,B69n' ,?7„HU–a~[ZÖž¯ÕkK7nJQo #,I9nJQo #,Kÿ=Á\fr2# $54732>54&#"#".547&#"#4&#"#".547&#"&54632632>3262654'!2654'1`vT؉þìþ­[%R7ùFˆ’lFeP_K<%5 ZlL<1]N:%5 Z!@TU!_mR8./<]/ B29#2F".KV.þP#-KV#ÀŠi6gmR4Þ¹ytgk£¾/JyNWu ]yPo.C6|Q rþë :IZxSl.C6{Q t?…FW•a~V9þwH6kINm2EI5lHNm "+KþùÁgq~Š2#".547# $54732>54&#"#".547&#"#4&#"#".547&#"&54632632>3262654'2654&#"%2654'1`v]+0F/#2 Úþìþ­[%R7ùFˆ’lFeP_K<%5 ZlL<1]N:%5 Z!@TU!_mR8./<]/ B29#2F".KV.é2"! ýŠ#-KV#ÀŠi‡e B&4B*" AÞ¹ytgk£¾/JyNWu ]yPo-B7|Q rþë :IZxSl.C6{Q t?…FW•a~V9þwH6kINm2E÷## ÕI5lHNm "+Kþ™Áeo}‘2#"&547# $54732>54&#"#".547&#"#4&#"#".547&#"&54632632>3262654'2654&'"2654&'#"&=2654'1`vC?3NU>=Uƒºþìþ­[%R7ùFˆ’lFeP_K<%5 ZlL<1]N:%5 Z!@TU!_mR8./<]/ B29#2F".KV.×  #(:,8+-/)8ý˜#-KV#ÀŠiMŽ4N|UU>!/Þ¹ytgk£¾/JyNWu ]yPo-B7|Q rþë :IZxSl.C6{Q t?…FW•a~V9þwH6kINm2Eÿ   [7+#5588 (:[I5lHNm "+Iÿ÷ÕÃ2<E2!5654&#"#"&5467&#".5463263235462654'"!54&[sý|RfK$nSB?Q:.,L`_!47wb=63Hd~CrýÌ*4We6Æ=L#UÃvbë@lYy ]ySjeR9r# qV}>$wAh†‰ÌIáViþrH9nJQo6CYWEÏŸ[qIÿEÛÃ?HT^2##".547!5654&#"#"&5467&#".546326323546"!54&2654&'#%2654'[s E/ "*!þ=RfK$nSB?Q:.,L`_!47wb=63Hd~Crj=L#U4"ýR*4We6Ãvbë-3A 2!-@lYy ]ySjeR9r# qV}>$wAh†‰ÌIáVi5WEÏŸ[qýû"!!ŠH9nJQo6CIÿßÃ=FSeot2##"&547!5654&#"#"&5467&#".546326323546"!54&2654&#"2654'#"&'%2654'#632[s$.U<=S1þbRfK$nSB?Q:.,L`_!47wb=63Hd~Crj=L#U &&)92'#.7ýY*4We6îÃvbë!@DWW?D"@lYy ]ySjeR9r# qV}>$wAh†‰ÌIáVi5WEÏŸ[qþ"X8*" %5( &8ñH9nJQo6C5MÿØÁ[bn2#".54632&#"3265!5>54.#"#".5467&#"&54632632354>54#"%2654' .J, 4lMAL3x`RG!)M&ZJ6\eýº)*%K1$nUD)< 9/+0I#_!j{]?43Hb&>C¬—‹þ )5We(Á,;7þø#??&!+#Rhh:>G1 ]yRl,B63263262654'H9B-0++iJ>&3S#5+nSB@P9/!Nc_!k*14%:69@gI9þ\T4WeÅ1bA1S6" ?‘Rb,%þÂ&7 ]zRjeR;m&…F|?M‘0O2$!!LNþoG9nJPo5HÿôVÄ[e%#"/3254.'&5463232654&#"#4&#"#"&5467&#"&54632632632#"&#"326322654'VU`O0 *]dHe .9# L =?B[SU@,#nTA@O9/#Mc^ k[<6=CvO?„Qi+$ D M%*7ý%+4Xd4V';5+-/) 04(þÍ?L\{VggP=m$ƒF~?K–gƒ!#^ZI=#,'-EH9nJQo4EHÿcDÀlv%#!"3!!"&5463!2654&#""#"546323254&#"#54&#"#"&5467&#".54632632632#"&#"32636322654'DDNý @#„ü|4>@2Ä6?'  Y3) L (H;AUSW5*$nSA>R:.!Db(7 &FvYB1?>kSE}Ri%*8 ?M 1.ý-+4Xd5^)>)B1()9# Q")&!(-!þþè>6MhGXTF0_ ^J)Z_IYmNLG3) ' K C/ 41**3   r/% B (C4F\SW5*$nSA>R:. 0=))6 &wYB16MhGXTF0_ !I2)Z-D(ZlNL6-& &!n`Ãr|%2#".54>32&#"32654&#"&54>7654&#"#4&#"#".5467&#"&54632632632#"&#"2654'½.C" "8`@2 \O3(M $'ZZ_LM4-*A-9C1E`SY76nVA)< 9/,0I#^ k{^>5;R7i?8D/\;."ýé)6Xd5‡00-2#!!#H74632632632!54.#"#"&5467&#"&%354#'"654&2654'Mwa;87=nJLïþ-*3& % nTB@O80!$Ja^!j RMú¡F@/º+þ*4We6Òh‰ ZZþõ·í)A%]yTigP32&#"3265!54.#"#".5467&#"&546326326354#'"654&2654'ŒEb4r_6OC\I6G&dP54&#""&5467&#"&54632632)6W`0&ÃþúN.MÞ§LxI0wC#!nT‚O9/#!2J!c&jX9:@;kŽ:XŽ5H:oIMs7Cíâ·wi\k™À"7IH&r’\zUhhO;o$0F:‚>K‘k… ­{+X\E-Kþ×¥ÄFPZ#".547#"$54732>54&#""&5467&#"&54632632%2654'264&#"O)-C1"2 P[ÃþúN.MÞ§LxI0wC#!nT‚O9/#!2J!c&jX9:@;kŽþr)6W`0)4""*E ?&1C*! â·wi\k™À"7IH&r’\zUhhO;o$0F:‚>K‘k… ­{H:oIMs7Cþæ"4"Kþ¦ÄFP]r#"&547#"$54732>54&#""&5467&#"&54632632%2654'2654&#"2>54'#"&'3,T=>R ??ÃþúN.MÞ§LxI0wC#!nT‚O9/#!2J!c&jX9:@;kŽþr)6W`0.%C*2'1  /` 6%AZUA# â·wi\k™À"7IH&r’\zUhhO;o$0F:‚>K‘k… ­{š6H:oIMs7Cþäw# $ %5"! &)LþÁ Ã-7_h2'654&#"#"&5467&#"&5463262654'#"&=4&#"#"&5463232654'2654' t5'1VqSnSB@P9/&0H#^!k‚X:84M*5We2J*C4/>,#N6%+6^G:D=?V/:I8NaH:+Z69a"ð#&C6%NOLþ  Ã-\ft}2'654&#"#"&5467&#"&546326"&547&=4&#"#"&5463232654'%2654'2654&'+'2654' t5'1VqSnSB@P9/&0H#^!k‚X:84Ò*.=A^A&9,#N6%+6^G:D=?V/:I8NaH:+Z69a"YH8oIPo4Eþ$"+&¦#&C6%NOLýë Ã-`jxŒ•2'654&#"#"&5467&#"&546326#"&547&=4&#"#"&5463232654'%2654'2654'#"'2654'#"&547'2654' t5'1VqSnSB@P9/&0H#^!k‚X:84Ò*8G$ 4H<8,#N6%+6^G:D=?V/:I8NaH:+Z69a"YH8oIPo4Eþ:   P." ,4 '!ž#&C6%NOGÿöêÃJT%2654'7#"&=4&#"#4&#"#"&5467&#"&54632632>32%2654'@4Hp ~bRES?) #*SJ4%lSBAO80%0I$_!k}]:81Jb=#6I[7ý_*4W`22iM†;H¢c~`QMRF 2!þë :K[ySjhO>l$1G=}?Mg‰ [ hUEKCH9nJLt6CGÿEêÃVcm%2654'7#".47.=4&#"#4&#"#"&5467&#"&54632632>32264&+%2654'@4Hp ~BB 2! "*?8?) #*SJ4%lSBAO80%0I$_!k}]:81Jb=#6I[7@4"" ýA*4W`22iM†;H¢u@ I "* 1Da>MRF 2!þë :K[ySjhO>l$1G=}?Mg‰ [ hUEKC©#2# ‰H9nJLt6CGþûêÃQ^pz%2654'7"&547&=4&#"#4&#"#"&5467&#"&54632632>322654&'"#2654'#"&'%2654'@4Hp ~VTTzS5_?) #*SJ4%lSBAO80%0I$_!k}]:81Jb=#6I[7. 'C,65$"..ýV*4W`22iM†;H¢‡>]AZUAH''€MRF 2!þë :K[ySjhO>l$1G=}?Mg‰ [ hUEKCŸ "v9)" (2) @úH9nJLt6CHÿóÁw%4&'7#".54632&#"32>5#".=4&54.#"#4&#"#".5467&#"&54632632>3232>2654'ÆE5 ‡#8MgB>P6x`rC8b&WZ$In?' .Z&9 ).LSE9&lUD)< 9/-0I#_!j{]>57Di6=1&=$ $)?üµ)5W`3â:l!i‘>_\C9# *#/A;!:&9/W %,6>þë ;J[yQr/D7=m$ ,?7„HW™a~[#, )83B6-*=4›I9nJLt4FHþÈÁ"’œ2'654.#"#54#"&546326".54632.#"32654'#"&'254&#"#4&#"#".5467&#"&54632632>3232654'72654'Ó&%  #DN5]xD' P;?XXAy¢.RDY<(.LSE9$lXA)< 80,0I#_!j{]>57Di6X%*7+ ,8Bp (;,DaXý)5W`3‹% , ;% &­ 2!7FB '/#%.†n(g?QZL6>þë ;J[yTo/D7>l$ ,?7„HW™a~[2) ?,\). gL‹<Ojp=^ŽR3lI9nJLt4FGÿöØà U^h2!535462654'7#"&=4&#"#4&#"#"&5467&#"&54632632>32"!54&2654'\uýÙ‘pþŽ4Hp ~bRES?) #*SJ4%lSBAO80%0I$_!k}]:81Jb=#6I[7 @P#Qû*4W`2Âzbæ"âWgþpiM†;H¢c~`QMRF 2!þë :K[ySjhO>l$1G=}?Mg‰ [ hUEKC]YFιRbþ¦H9nJLt6CGÿEãÃbkv€2##".547!535462654'7#"&=4&#"#4&#"#"&5467&#"&54632632>32"!54&2654'#%2654'\uD0 "*þ™‘pþŽ4Hp ~bRES?) #*SJ4%lSBAO80%0I$_!k}]:81Jb=#6I[7 @P#Q"/-#û%*4W`2Âzbæ,3A 2!,"âWgþpiM†;H¢c~`QMRF 2!þë :K[ySjhO>l$1G=}?Mg‰ [ hUEKC]YFιRbýú"0 1!¬H9nJLt6CGÿçÃ_hsˆ’2#"&547!535462654'7#"&=4&#"#4&#"#"&5467&#"&54632632>32"!54&2654&"2>54'#"&'%2654'\u-TzS0þ»‘pþŽ4Hp ~bRES?) #*SJ4%lSBAO80%0I$_!k}]:81Jb=#6I[7 @P#Q&%&%*2'1 /ûK*4W`2Âzbæ"AAZUAB&"âWgþpiM†;H¢c~`QMRF 2!þë :K[ySjhO>l$1G=}?Mg‰ [ hUEKC]YFιRbþ X# " %5"! &)óH9nJLt6CGÿØÃ%pyƒ2##"&54>32&#"3265!535462654'7#"&=4&#"#4&#"#"&5467&#"&54632632>32"!54&2654'#AD)ÿ_6OC\I6G&dPl$1G=}?Mg‰ [ hUEKC]YFιaSþ¦H9nJLt6CGþºêÃJpz%2654'7#"&=4&#"#4&#"#"&5467&#"&54632632>322'654&#"#54&#"&546326%2654'@4Hp ~bRES?) #*SJ4%lSBAO80%0I$_!k}]:81Jb=#6I[7K6H)?(. 9'(1KUJ;7&%ýG*4W`22iM†;H¢c~`QMRF 2!þë :K[ySjhO>l$1G=}?Mg‰ [ hUEKCHWB$-) *Z+Fѵ&!A0\#/gAZ10KH9nJLt6CGþ»êÃJnx‚%2654'7#"&=4&#"#4&#"#"&5467&#"&54632632>322#"&547&#"#54#"&5463262654'2654'@4Hp ~bRES?) #*SJ4%lSBAO80%0I$_!k}]:81Jb=#6I[7+CZ6+*7D+97'4MYJ86%/k 6B$ý*4W`22iM†;H¢c~`QMRF 2!þë :K[ySjhO>l$1G=}?Mg‰ [ hUEKCHiJ7EC7S5 ѵHB4Z!-hAZ0/þü)"O.4E$+OH9nJLt6CGþXêÃJ†’œ%2654'7#"&=4&#"#4&#"#"&5467&#"&54632632>324>32632#"'732>54'#"&5467&#"#54#"&2654'2654'@4Hp ~bRES?) #*SJ4%lSBAO80%0I$_!k}]:81Jb=#6I[7þŒ 0%5&,;R0<9bH&& (: ; 6+&2>+=",98  NZx"$%ýq*4W`22iM†;H¢c~`QMRF 2!þë :K[ySjhO>l$1G=}?Mg‰ [ hUEKCâ.B 0.KT2Kf ':0P&32354&'4#"62654'À9T‘þâ€4Hp ~bRES?) #*SJ4%lSBAO80%0I$_!k}]:81Jb=#6I[7a&¡-/*2,Amý0*4W`2Òc]°xliM†;H¢c~`QMRF 2!þë :K[ySjhO>l$1G=}?Mg‰ [ hUEKC®).gM<$6TOH9nJLt6CGþ êÃJTfqxƒ%2654'7#"&=4&#"#4&#"#"&5467&#"&54632632>32%2654'4632##"&547#7354&'4#"62654'#@4Hp ~bRES?) #*SJ4%lSBAO80%0I$_!k}]:81Jb=#6I[7ý_*4W`2b9T‘&C-/A&o½$$'¡..*2,Am.&11%2iM†;H¢c~`QMRF 2!þë :K[ySjhO>l$1G=}?Mg‰ [ hUEKCH9nJLt6Cþùc]°x`@A/0¾?$#gN;$6TNç$2 2$GýëëÃJTiu|†šœ%2654'7#"&=4&#"#4&#"#"&5467&#"&54632632>32%2654'4632##"&547#7354&'4#"62654&"2>4'#"&5477#@4Hp ~bRES?) #*SJ4%lSBAO80%0I$_!k}]:81Jb=#6I[7ý_*4W`2p9T‘*3 4"4H3c½&¡..*2,Am& %()'"0& 2iM†;H¢c~`QMRF 2!þë :K[ySjhO>l$1G=}?Mg‰ [ hUEKCH9nJLt6Cþùc]°x"> $,G4>"¾).gN;$6TOÁ $P '< ,4 '!/§Gþ,êÃJTs~ˆ%2654'7#"&=4&#"#4&#"#"&5467&#"&54632632>32%2654'432#".54632&#"326=#7354&#'"654&@4Hp ~bRES?) #*SJ4%lSBAO80%0I$_!k}]:81Jb=#6I[7ý_*4W`2j’CV37H7C;7N<(ó¼#$(¦30,_ t 2iM†;H¢c~`QMRF 2!þë :K[ySjhO>l$1G=}?Mg‰ [ hUEKCH9nJLt6C㢱€JM6:¾ >%$bQA (1tS[!QÿHìÁ q%2654'#".5473267#"'.'&#"#4&#"#".547&#"&54632632>3232>54'ß#.KR+À151Z{¶o‘ÜPi%^ 1Qj™\—ÀbZ  09M<0]K=%5 Z!4aY$_jU9,1;\/ A3AR3 "&c7H6lHLo2EŠ2j9&,UXJ:!2Noi=speo =E:8&/DL$j=5þë :IZxRm-C6{Q eN€KW•^V8fN WK$H0ˆ?QþþñÁq}‡#"&547#".5473267#"'.'&#"#4&#"#".547&#"&54632632>3232>54'72654&#"%2654'—%5*" 2D‘Í‘ÜPi%^ 1Qj™\—ÀbZ  09M<0]K=%5 Z!4aY$_jU9,1;\/ A3AR3 "&c$15Š2""  ý #.KR+=-"3 D2 =2Noi=speo =E:8&/DL$j=5þë :IZxRm-C6{Q eN€KW•^V8fN WK$H0ˆ?2j9&ƒþ!! 6ÑH6lHLo2EQþ˜ðÁp{“"&547#".5473267#"'.'&#"#4&#"#".547&#"&54632632>3232>54'72654&'"2654&'#".=2654'j(/!U|T„±‘ÜPi%^ 1Qj™\—ÀbZ  09M<0]K=%5 Z!4aY$_jU9,1;\/ A3AR3 "&c$15ž!"G("8&$ $'#ý#.KR+C<&=VU>("-2Noi=speo =E:8&/DL$j=5þë :IZxRm-C6{Q eN€KW•^V8fN WK$H0ˆ?2j9&¤ì%.[02 75' & *\H6lHLo2EYÿB%Á#12##".547!3354>54#"2>54&#"T9T*!A3+9 ýüTÛ&?CΗŒÖ# Á)DE$ë,1C20,¹þjá6N'þbŸÇ˜Î "+Yÿ"Á$1C2##"&547!3354>54#"2654&#"2654'#"&'T9T*)- >*?Q/þ)TÛ&?CΗŒ¨&%%+74&0 8Á)DE$ë&?-7&V?B(¹þjá6N'þbŸÇ˜Î‹W:'" %5# )8MþºÝ :2!33546"!54&2'654&#"#54&#"&546326 \uýqT¥ps@P#R 6H'$?(.!9"(1KUJ;7&$Âycæ¹þiâWg3YFιSaþ[WB,F *Z+Fѵ 'A0\#.hAZ10Mþ»Ü 09C2!335462#"&547&#"#54#"&546326"!54&2654' \uýqT¥p‰CZ5,*7D *97'4MYK74'-%@P#R6B#Âycæ¹þiâWgþ(iJ7ED6R6 ѵHC3Z!-hAZ0/¥YFιSaýW)"O.4E#,MþXæ Q\2!33546"!54&4>32632#"'732>54'#"&5467&#"#54#"&2654' \uýqT¥ps@P#Rþ@ 0& 4'+",98  NZx/)Âycæ¹þiâWg3YFιSaýÁ.B 0.KS2Ih ':0P&J^`2!33546"!54&4632##"&547#7354&'4#"62654&#"2654'#"&5477# \uýqT¥ps@P#R®9T‘*3$ 4H3c½&¡..*2,AmL4)'"V Âycæ¹þiâWg3YFιSaýŸc]°x">.G4>"¾*-gN;$6TNÀ P." ,4 '!xMþ,ß 7BK2!33546"!54&4>32#".54632&#"326=#7354&#'"654& \uýqT¥ps@P#Rª,-’CV37H7C;7N<(ó¼$%&¦+8,_(t Âycæ¹þiâWg3YFιSaýÃ1D ±€KL5;¾@&"bHJ!5?tS[!Mÿ=íÁ3;2#"&547&/32654&+532654&#"&546264&"23K"KO5>A31C-1;G4+*4==2M](“4""4"Á .% @K:* G0DD0#7)"'2,)"$/yfO` rL{’ýÀ"4""4MþöçÁ1>RX2"&547/32654&+532654&#"&5462654&+"2654'#"&'7"#6323K"KOJMTzS3 -1;G4+*4==2M](|"%+75$1*Á .% @KJ(!XBYW?F(7)"'2,)"$/yfO` rL{’ýÍX9)" '3"!  "½MÿFö¿:%#"&54632&#"32654&+532654&#"&54>32{54.#"&54>32'2'654&#"#465654#"&546326UqtYq?% U+IDS32á:F'K+$M*?B4554A?299/:<0>i&,GJ&I_T/-Q(*X'1?!#!("/$"+/,"!0orIf {CKn9H5H A(T3Mþ‡ãÁBM%#"&547&/32654&+532654&+532654&#"&54>322654&"(*02A31C0$M*?B4554A?299/:<0>i&,GJ&I_T/-q+#2#$30#=0DD0' ?!#!("/$"+/,"!0orIf {CKn9H5H A(Tþ¯""!MþEäÁAOb%"&547&/32654&+532654&+532654&#"&54>322654'+2654'#"&'(*>AR~Q2$M*?B4554A?299/:<0>i&,GJ&I_T/-›, )"G3&1 +'39#QAZW?F' ?!#!("/$"+/,"!0orIf {CKn9H5H A(TþÁ&  %X02  &4"! $. KÿîÁH%#".54632&#"32654#523254&#"53254&"&54>32„,/P_h8C/mO9K$&7pL$RHÏ „DT ‹;V@ & .N217&ã 7!d@>M!&"A+N'W1%#P#++FI&If {C$EJ6# 0 GMþŒõÁIn#".54632.#"32654&+53254&+57654&#"&54>322'654#"#465654#"&546326õ”s.:(]EZ1 A$/@A2UjaM03 …KL8`C-+@ & .N2:pA-.P\æ l‡ 3"8EB #0"&-hM@N*W3"# A!-+FI&If {C$EJ6#A3G# 7!d®" %#  .% $Iÿó‚ÂN#"'#"&54>54++53264&#"&546323265332654.'÷+< oSX;mLF=0906++/0(HY(}d>R? N6NXKS8+:J 3$ÁAG7c}M40#"!, B(|eMb qMx•>2< !J <Cþë2>fM/;4IÿF‚ÂYd#".547&'#"&54>54++53264&#"&546323265332654.'264&+÷+< GDD0 "*J0mLF=0906++/0(HY(}d>R? N6NXKS8+:J 3$2##ÁAG7r> J3A 2!  @40#"!, B(|eMb qMx•>2< !J <Cþë2>fM/;4ýá"4" !Iþú‚ÂVbv"&547&'#"&54>54++53264&#"&546323265332654.'2654&#"2654'#"&'÷+< \[S|R0;(mLF=0906++/0(HY(}d>R? N6NXKS8+:J 3$%%$,65$".*ÁAG7ƒ=aCXV@B)540#"!, B(|eMb qMx•>2< !J <Cþë2>fM/;4ýéX:(  '3(  "Iÿ„Âm#".54632&#"3267#"'#"&54>54++53264&#"&546323265332654.'÷.=Q8WEB3:6`‰rt:]X;mLF=0906++/0(HY(}d>R? N6NXKS8+:J 3$ÁDK1-%LgX* *% %uŽOM40#"!, B(|eMb qMx•>2< !J <Cþë2>fM/;4IþÇšÂd‡%2654'7#".54632.#"3265#"'#"&54?654#"532654&#"&54632326532'654.#"#54#"&546326Ð?Ox™2KPDN6]zB' O;?XY?‡>_X;lLF=(I(K-+01'HY({f>R?/ #'NE^S6@&%  #"4fM39þã8msU7 2"7FB '/F1¹™OM30/ !#,#!(‚_Mb oOt™@0< $  1#Cþë1?¿% , ;% %Iþº‚ÂNs#"'#"&54>54++53264&#"&546323265332654.'2'654&#"#54&#"&546326÷+< oSX;mLF=0906++/0(HY(}d>R? N6NXKS8+:J 3$6H -%?(. 9'(1KUK:7&%ÁAG7c}M40#"!, B(|eMb qMx•>2< !J <Cþë2>fM/;4þAWB1>*Z+Fѵ&!A0\#/gCX10Iþ»‚ÂNr|#"'#"&54>54++53264&#"&546323265332654.'2#"&547&#"#54#"&5463262654'÷+< oSX;mLF=0906++/0(HY(}d>R? N6NXKS8+:J 3$CZ6+*7D+97'4MYK74'-m6B$ÁAG7c}M40#"!, B(|eMb qMx•>2< !J <Cþë2>fM/;4þAgL7ED6R6 ѵHD2Z!-hAZ0/þü)"O.4E$+IþX†ÂN‹–#"'#"&54>54++53264&#"&546323265332654.'4>32632#"'732>54'#"&5467&#"#54#"&264'÷+< oSX;mLF=0906++/0(HY(}d>R? N6NXKS8+:J 3$þn 0& 4'++>",98  NZx"$%%ÁAG7c}M40#"!, B(|eMb qMx•>2< !J <Cþë2>fM/;4ý§.B 0.KT2Kf '0# P&;L9.3A,"˶H 2!Y#-(\ +'!IþÆ‚ÂNVbi#"'#"&54>54++53264&#"&546323265332654.'4632!7354&'4#"6÷+< oSX;mLF=0906++/0(HY(}d>R? N6NXKS8+:J 3$€9T‘þâ½&¡-/*2,AmÁAG7c}M40#"!, B(|eMb qMx•>2< !J <Cþë2>fM/;4ý…c]°x¾).gM<$6TNIþ ÂN`ls~#"'#"&54>54++53264&#"&546323265332654.'4632##"&547#7354&'4#"62654'#÷+< oSX;mLF=0906++/0(HY(}d>R? N6NXKS8+:J 3$v9T‘&C-/A&o½&¡..*2,Am.&11$ÁAG7c}M40#"!, B(|eMb qMx•>2< !J <Cþë2>fM/;4ý…c]°x`@A/1¾*-gN;$6TOè$2 2&IýëÂNdpwƒ—™#"'#"&54>54++53264&#"&546323265332654.'4632##"&547#7354&'4#"62654&#"2654'#"&5477#÷+< oSX;mLF=0906++/0(HY(}d>R? N6NXKS8+:J 3$v9T‘*3$ 4H3c½&¡..*2,AmL4)'"V ÁAG7c}M40#"!, B(|eMb qMx•>2< !J <Cþë2>fM/;4ý…c]°x">.G4>"¾*-gN;$6TOÁ P." ,4 '!xIþ,ƒÂNp{„#"'#"&54>54++53264&#"&546323265332654.'4>32#".54632&#"326=#7354&#'"654&÷+< oSX;mLF=0906++/0(HY(}d>R? N6NXKS8+:J 3$x,-’CV37H7C;7N9+ó¼$%&¦+8,_(t ÁAG7c}M40#"!, B(|eMb qMx•>2< !J <Cþë2>fM/;4ý©1D ±€KL1?¾@&"bHJ!5?tS[!Jÿ? Á^#"$547327#"'#"54?654+53254&#"&54>323265332654&'§9@þýËéþáVQÖ¹‘)h bJ:iJþê Ám{#"&5465#"$547327#"'#"54?654+53254&#"&54>323265332654&'2654&#"§9@\,/ 2"3Cg|éþáVQÖ¹‘)h bJ:iý’" "Jþ… Áoy#"&547#"$547327#"'#"54?654+53254&#"&54>323265332654&'72654&'2654&'#"&=š(/!7#=USféþáVQÖ¹‘)h bJ:i"%ˆH³ö #.y9)%358&( +7Jÿ<hÁ3"&546732654&+532654&#"&54>32yˆ§ .sVK>3551?:@N`"( !3T6Rg[^AEÄÚ¹Ni;\x¡Ê]9;P0E&'@`t; @~&FH5!U>Q*7fU?EJþ™hÁ=K2#"&547#"&546732654&+532654&#"&54>2654&+¬Rg[^JGA31C  ˆ§ .sVK>3551?:@N`"( !3T{ "$ÀU>Q*7f\AO0DD0Ú¹Ni;\x¡Ê]9;P0E&'@`t; @~&FH5!ý+#!JþJiÁ;FY2#"&547.546732654&+532654&#"&54>2654&#"2654'#"&'¬Rg[^bcS>?Q!‚ .sVK>3551?:@N`"( !3T=.%C)95$1*(ÀU>Q*7fmBfAZW?6'Ú±Ni;\x¡Ê]9;P0E&'@`t; @~&FH5!ý""w6," '3"! $. MÿEçÀ:B%#".547&'#"'&54>732>5332654.'7264&"›2E/ "*H48PJ9; <*#*0B9(,S2*9M0"&,ˆ4""4"& 7-3A 2! EM@Dc4F?o732>5332654.'2654&+#2654'#"&'a&,\\T=>R06'8PJ9; <*#*0B9(,S2*9M0"%&%+75$1*À 6R0ˆAbBYV@D'4M@Dc4F?o5#"'#"'&54>73265332>54'7®Oy}Lc:4SjS"*MJ-7NX57PK9; >.",2I;'4S1!,3#j/<:agè4&!"%1aC9KL?Db2IBn>Ob.!Cþì>4%K1@$Xb3'i—N"MþÈÀKp".54632.#"32>7#"'#"'&54>732>5332654.'7'2'654.#"#54#"&546326©@N6]xD' O;?XN9Kp>)]CV98PU63 <*#ZC8)*S2*:L0"OX.G`[&%  #"þÈ 2!7FB '0"%05Ls[97MMMKCY4E@BˆOb + :þì3?hP+94Îw\’X9­% ,  ;% &MþºáÀ.S#"'#"'&54>732>5332654.'2'654&#"#54&#"&546326a&,nQV98PJ9; <*#*0B9(,S2*9M0"6H'$?(.!9"(1KUJ;7&$À 6R0g‚MM@Dc4F?o732>5332654.'2#"&547&#"#54#"&5463262654'a&,nQV98PJ9; <*#*0B9(,S2*9M0"CZ5,*7D *97'4MYK74'-m6B#À 6R0g‚MM@Dc4F?o732>5332654.'4>32632#"'732>54'#"&5467&#"#54#"&2654'a&,nQV98PJ9; <*#*0B9(,S2*9M0"þe 0& 4'+",98  NZx/)À 6R0g‚MM@Dc4F?o732>5332654.'4632!7354&'4#"6a&,nQV98PJ9; <*#*0B9(,S2*9M0"‰9T‘þâ½&¡..*2,AmÀ 6R0g‚MM@Dc4F?o732>5332654.'4632##"&547#7354&'4#"62654'#a&,nQV98PJ9; <*#*0B9(,S2*9M0"9T‘&C-1?&o½&¡-/*2,Am.&11%À 6R0g‚MM@Dc4F?o732>5332654.'4632##"&547#7354&'4#"62654&#"2654'#"&5477#a&,nQV98PJ9; <*#*0B9(,S2*9M0"9T‘*3$ 4H3c½&¡-/*2,Am.0&4)'"0& À 6R0g‚MM@Dc4F?o.G4>"¾).gM<$6TNÀ o." ,4 '!/§Mþ,áÀ.P[d#"'#"'&54>732>5332654.'4>32#".54632&#"326=#7354&#'"654&a&,nQV98PJ9; <*#*0B9(,S2*9M0"…,-’CV37H7C;7N<(ó¼$%&¦+8,_(t À 6R0g‚MM@Dc4F?o73265332654&'7áµåJ"EÈ›«z'%Z05QSm 4),gG:'5SQAOA'|ã¸ç¦ƒhZsÍ„KJ…a3U5 @‘Oe+#Cþìr`IQel¬ÐGþápÀEQ#".5465#"&547327#"'#"&54>73265332654&'72>54&"%7 2!"2 OYµåJ"EÈ›«z'%Z05QSm 4),gG:'5SQAOA'|‹.!6!9>- "*+!   禃hZsÍ„KJ…a3U5 @‘Oe+#Cþìr`IQel˜þù $$ Gþ†pÀBM_%4&'7#"&547#"&547327#"'#"&54>7326533262654&"2654'#"&'@A'|~#,U<@P >9µåJ"EÈ›«z'%Z05QSm 4),gG:'5SQAOr&%&%+72'#//ÛQelµi 7%DWW? 禃hZsÍ„KJ…a3U5 @‘Oe+#Cþìr`þŒX9)" $6) @Jÿø%Ã+6"&5467&#"#4&#".54632632'2654&'“AQ:0/3@S5!

7&#"#4&#".54>326322654'"­q:7&)_=8aPB9J E1'a6CS5!5*. 2#): "/;*P;@\)9:[WþØ'-(1"/mn*QJ_€-:ZsVF2?.F3)þË=304R,:5>D38X0 JH1$„JMÿøÄ?%#".54732&#"32654&#"#4&#".54>32632ø«Œ=I3ËSJ&;KpI6m„bM&1S5"3+.3%(."/;*P:ˆ¥%J2/?S6-=L 6.)7pXU:EV4R1 Ðx&% #"þÊ 3"7FB '/#"1Ä¡7db;-$þÂ3326326~$:Wf6¼e‹q1WlN!$mSB@O80/3BS3" *#4%*: !/9+Q;>Y9/;5=DmKPp5DŽ‹mŠJEmS‘[{RkgP=m$-%þÂ=3 &D+):5?E37W0 JJ GÿeôÄJT%#!"3!!"&5463!2654&#"#"&5467&#"#54&#".546326326322654'ôrTý‚6@üÀ72;.KL\hR!mSA?Q,<14@S5!6ME1'/lNR9BW4243!2654&+532654&#"#"&5467&#"#54&#".546326326322654'üN@ýB6Füº/: -‹E:"#Wj"mSA?Q,<12BS5!5NE1;KlNR9BW424FHe0!=þx*4Wf7p4@)@0' #3 9,'@= MgGWUE'`%%þõè2+TB?W eGVk=<.-#+8;1]=B^-9HÿÂPZ%#".54632&#"32654&#"#"&5467&#"#4&#".546326326322654'Å£!Y\{[YK+Z~[$z–p]#mSB@O803*GS3" *#4%*: sPQ;:X#J6Euþk$:Wf6 Õ $!+'½‹v– [{SjgP=m$&+þÂ=3 &D+):5?E3eƒJI­ß=DmKPp5DHþÉ'Â_ƒ".54632.#"32>54.#"#"&5467&#"#4&#".54>32632632'2'654&#"#54#"&546326'2654'¿>N4]zB' N<@W%8,?c;' 0V7"mQD@O8012?S4!)< 2$*: &S9Q;:X'F8C|š3O!&% #"^*4Wf4þÉ 3#7FB (/#$+CZT+LgS; [{QliN=m$,%þÂ=3-A6-93?E3DS9JIÓ›5fkQ3¬% , ;% %ÀG:nJPp3FJÿCœÂIS".54732$54&#"#"&5467&#"#4&#".54632632632'2654'yžü•Z!Q"ÝÐ rR mSB@O80.4@S5!5*.)"*: sPQ;D3eƒJJŠl²×òG:mKPp4EJþÿœÂZdqu2#".5465#".54732$54&#"#"&5467&#"#4&#".5463263262654'2654.#"'6£qˆ]$5 2! "*Š®žü•Z!Q"ÝÐ rR mTA@O80.4@S5!5*.)"*: sPQ;" "!Šl†b<- "* 1" ?`»zxpbh¡Å±][{UhfQ=m$.$þÂ=305R*F,>D3eƒJJþsG:mKPp4Eò$#$qJþ¤œÂV`k}2"&547#".54732$54&#"#"&5467&#"#4&#".5463263262654'2654&"2654'#"&'£qˆ€$,TzS {žü•Z!Q"ÝÐ rR mTA@O80.4@S5!5*.)"*: sPQ;D3eƒJJþsG:mKPp4EùX:(" (2"! @Hÿ÷ÚÃ?"!54&'2!5>54&#"#4&#".546326323546!=L"TZ]qýO,2N6&3S3" *#4%*: sPQ;8NRl\ÆrŽWEÏŸ]o5vbë*x54&#"#4&#".546326323546"!54&2>54&" ]qC1"2 þ ,2N6&3S3" *#4%*: sPQ;8NRl\Ærj=L"T #2#Ãvbë,1C+! +*x54&#"#4&#".546326323546"!54&2654&"2654'#"&' ]q.TzS1þ0,2N6&3S3" *#4%*: sPQ;8NRl\Ærj=L"T&%&%+74%"./Ãvbë"‚ZUAC%*x32&#"325!5654&#"#4&#"&54632632354>54#"$:S*„…54&#"#4&#".5463263235462'654&#"#54#"&546326"!54& H†ÃŽBL3}_xD' Q;,A ZCv•ýŒ,2N6&3S3" *#4%*: sPQ;8NRl\Ær&% #~=L"TÃy_ÿ{© 2!6GB (%.št*xP 3#): lWP;7ÂJ79#"I:J :.&(2,*$,+#þ¿<3hM,;5?E3c†JHIÿ;ÞÄDL2#"&547&/32654&+532654&#"#4&#".546326264&"0GaCI:9A31C -*3?3%(7/:0/@S2">P 3#): lWP;7‚2##2#ÂJ79#"IC$!C0DD0* :.&(2,*$,+#þ¿<3hM,;5?E3c†JHý½"4""4IþùìÄDPe2#"&547"/32654&+532654&#"#4&#".5463262654&#"2>54'#"&'0GaCIBPU<>R4 -*3?3%(7/:0/@S2">P 3#): lWP;7%:*5$"/ÂJ79#"IH$!YDWV@G':.&(2,*$,+#þ¿<3hM,;5?E3c†JHýÏ"X$ " '3(  "IÿÂM%#"&54>32&#"32654.+532654&#"#4&#".54632632C‹eJŽ)CD#n?'3RzB1|„ :)""9DH:3DS2"=Q3%): mVP;9oOiS:( +KL,(  &Wq%'4;/2>.!þ¿=3gO*<5?D3c†JHNAL<*COÿ?‚ÂH2#"$54732>54.+532654&#"#4&#".546326ÅReTZ.G`Y-Êþò[&Yï·Rs7*# 221>C71@S3!U"@T5T3! ܯ‰ma}’Á 53$5 78()2+"þ¿<4hO*;4@E3c„JGOþ¯‚ÂPb2#"&547#"$54732>54.+532654&#"#4&#".5463262654.#"#ÅReTZGGB21C;?Êþò[&Yï·Rs7*# 221>C71@S3!U"@T_:N/ED0 ܯ‰ma}’Á 53$5 78()2+"þ¿<4hO*;4@E3c„JGý4##Oþa‚ÂP\p2#"&547#"$54732>54.+532654&#"#4&#".5463262654&'2>54'#"&'ÅReTZa`S>=S!-Êþò[&Yï·Rs7*# 221>C71@S3!U"@To=dCXW?+!ܯ‰ma}’Á 53$5 78()2+"þ¿<4hO*;4@E3c„JGý:X+'  &4$ $. IÿõîÂH#"'#"&=4&#"#4&#".546326323265332654.'h*: nST:-\BWA-)32&#"32>5#"'#"&'&54#"#4&#".546326323265332>ÂD2‘.E_R,Ya_YkQ>\&YV)4\V33fd)2T?Ps)8S,#+@ v>HnTf'(b.D".:(6S%*,? æ8m`õR~G, %6$ & 9nLWJJW:TŸ.#þÂ0@,@3pP(zD`„II*?2/[b+$Cþì+F,A3Lÿ3õÃ\#".547! 7#"'#".=4&#"#4&#"&54632632326533254.'~9>Q|Ï„mµ~a9$ ,')UPp*U+'K)3#9'* M+2IhwdKC5*I,7&2) .M!€/#Á%ŒI8inQ4 4LO]Q*i]R[þw” =H ?+eUJ"" þÂ;2dMƒ8L—]ŽHF"K4k7A*">þì,1£-?9LþêõÃhs#"&5465#".547! 7#"'#".=4&#"#4&#"&54632632326533254.'2654&#"~9>]$5 1!4BŠÆmµ~a9$ ,')UPp*U+'K)3#9'* M+2IhwdKC5*I,7&2) .M!€/#2"",Á%ŒI“b>, "+F0 = 4LO]Q*i]R[þw” =H ?+eUJ"" þÂ;2dMƒ8L—]ŽHF"K4k7A*">þì,1£-?9ýŒ!!Lþ‡õÃhrˆ#"&547#".547! 7#"'#".=4&#"#4&#"&54632632326533254.'2654&'2654&'#".=~9>‡1S7#=U¦mµ~a9$ ,')UPp*U+'K)3#9'* M+2IhwdKC5*I,7&2) .M!€/#", :A)9-8'#!, ;Á%ŒI²iN@ ,#V=$"- 4LO]Q*i]R[þw” =H ?+eUJ"" þÂ;2dMƒ8L—]ŽHF"K4k7A*">þì,1£-?9ý€ #/y9)%35& "  +7IÿöþÄ62'654&#"#4&#"#4&#".546326326?Rm!3,'kK=&3SC2(2S2">P3B*: oTR:4^Y69Ça3V5=’Ne,$þÂ4A)"þÂ;4hL2p?E4e…ONIIHÿôF D%2654&'"&5467&#"#4&#"#4&#".54632632632¤(0/$h98AP91/,GSB3'3S2">P3%*; pSS:6\Y6EY`FIR4?68kQl5E=gQ:p&'-þÂ5A*"þÂ=3iM);5@D3e…NNJJLOoTmIÿaÊ U%3254'#"'7327654&'#"&5467&#"#4&#"#4&#".54632632632R,#W8Rxq;7')^=89-RB;F`>.VA9SB3'3S2">P3%*: lVS:6\Y6AVtQ[Z¤2r׋``YOx¾hØžOc2þÂ5@.þÂ1?gJ:k(|E`„MMIIýp$0#""Fþ…“ÁP_v2#".547#"$&54732654&#"#4&#"#4&#".5463263262654.'2>54&'#".=ÒWjKA(1"U>*4$ l€£þø›-)+ò’ÆûK=2,SA12+S-"?UB3=JoSg'.Xm.'{ " $-8+-!+ 9Á‚gT 9=(>U ?,")r׋``YOx¾hØžOc2þÂ5@.þÂ1?gJ:k(|E`„MMIIýb [*%358"  )9Iÿõ-Ä(02!4&#".546326354#4&#"6O(HE)þ+3!=Q3%*: pTU6DÂRMû¢FH, iµÄ8oM·<4gO*;5@E3e„TV£EuD–å1<%3½©ƒIÿB2Ä*3;F2##"&547!4&#".546326354#4&#"62654&#"O(HE)B21Cþï3!=Q3%*: pTU6DÂRMû¢FH, iµI>* Ä8oM·,/ED0,<4gO*;5@E3e„TV£EuD–å1<%3½©ƒþà*+Iÿ6Ä*3;GY2##"&547#4&#".546326354#4&#"62654&#"2654'#"&'O(HE)%.T=?Q1î3!=Q3%*: pTU6DÂRMû¢FH, iµA&%&)92'1 7Ä8oM·"ABYW?C%<4gO*;5@E3e„TV£EuD–å1<%3½©ƒþô"X8*" %5 # %9Mÿ1Á2;C746323632#".54632&#"326=!4&#"&%354#4&#"6MnTl!2‚Ü€‹AM5…bXJ 6G+ac(vQþ_,#A+(v‡UNQú¡FH*"iµÝ`„SSþö·Ša ",^`0@92FmU^ÏFoI–å1<$4½©ƒJÿ%ÃÁ9CK2#".546732>5!4&#"&5463236354+4&#"6è7=,Otd#b¤qX4 (.*ZCg‹„DThGþc.!?Uu…oRm!4ÍPNöœFG,!i¶Á #9bAÙ3N&2HLYK(Ff>gpV‡R4 E.0@gJwK^Š`„SS FqG–å0=%3½©ƒJþÅÁDNVb2#"&547#".546732>5!4&#"&5463236354+4&#"62654&#"è7=,AC 2"4B 82b¤qX4 (.*ZCg‹„DThGþc.!?Uu…oRm!4ÍPNöœFG,!i¶b "$+Á #9bAÙ>0K #*F0 2HLYK(Ff>gpV‡R4 E.0@gJwK^Š`„SS FqG–å0=%3½©ƒþ1$"! Jþ?ÆÁCMU`u"&547#".546732>5!4&#"&546323632354+4&#"6264&'2654&'#".=b')U|T'b¤qX4 (.*ZCg‹„DThGþc.!?Uu…oRm!47=,PNöœFG,!i¶ .P:'#8'#!+ £@*=VU>2'2HLYK(Ff>gpV‡R4 E.0@gJwK^Š`„SS #9bAÙN‘FqG–å0=%3½©ƒþ7,y8* 5 6& "  +IÿFrÃ3"&54732654&#"#4&#"&54>32632õµ÷A$:Ù ®PA&3S3!+3#v…!/:*P;:KSnѺâ²gVj™Ç°‹Yw,%þÂ<4%K0‘1C¦6V0 JK“u¨ÍIþÒrÃ?K2#"&547#"&54732654&#"#4&#"&54>3262654&#"±Sn^+0F/0FELµ÷A$:Ù ®PA&3S3!+3#v…!/:*P;:y4!! Óu™h A'4BB4â²gVj™Ç°‹Yw,%þÂ<4%K0‘1C¦6V0 JKýV## 2IþsrÃBNd2#".547#"&54732654&#"#4&#"&54>3262654.'"2654&'#"&=±SnD=1MU>+> 45µ÷A$:Ù ®PA&3S3!+3#v…!/:*P;:P.+A)9("8&/)9ÓuV™4O<=V$5*(# â²gVj™Ç°‹Yw,%þÂ<4%K0‘1C¦6V0 JKýNz9)858 )9Mþ¼[6NY#"'&547&#"#4&#"&54632632654&#"'6322'654&#"&5472654'«)4U?5&"sF*4S,#A+(v†pRh%1UC+1#3!*ai—|L+A7+-8H [ƒ'/8#D)—!w54'#"&547'«)4U?5&"sF*4S,#A+(v†pRh%1UC+1#3!*ai>9II98J-A7+-8H [V?>LL'/8#D)@.+,"*#$—!w32&#"32>5!5654&#"&546ù3J"&>Oê?O6)BC"K?-Dv:D13þJH071A5Dd*(:07,–þ7Ô '&P9-R&?@5C#3XK\KþÈ ¹<\2!33#".54632.#"326=!5654&#"&5462'654&#"#54#"&546326ù)A$&8TÅBL3}_zB'T9,A WFhþQH071@4Dc8&% #")'1# 7,—þG{© 2!6GB )$/h -M&?A5B$5WK\þL' ;;% %Kþ¾ ¹>2!3!5654&#"&5464632&#";2#"'73254+"&ù)A$&8TýýH071@4DcU:DU/$C#6-?70N1V,&KS>@(/)'1# 7,—þG -M&?A5B$5WK\þb&;0%&05./&5(,Kþ ¹GR2!3!5654&#"&5464632&#";2#"&547&'73254+"&264&#"ù)A$&8TýýH071@4DcU:DU/$C#6-?7098B./A,1&KS>@(/#!$%)'1# 7,—þG -M&?A5B$5WK\þb&;0%&0=>1??16 &5(,þØ-&-&$Kýë ¹IVj2!3!5654&#"&5462#"&547&'73254+"&54632&#"32654'#"'2654'#"&547ù)A$&8TýýH071@4Dcï70;=-# 4H7,&KS>@(/:DU/$C#6-  %533/)'1# 7,—þG -M&?A5B$5WK\þE0>!D$5 G4?"&5(,%&;0%&ÿP." '"#& '".Kþ¾¹FP2!3!5654&#"&5462'654&#""&547&#"&5463262654'ù)A$&8TýýH071@4DcÂL_Q$:H7F8V5C. ?HU;'$#3&8A")'1# 7,—þG -M&?A5B$5WK\þÆaFZ0 .H=S=O7FD6P6 .'R* 3`EYþû',F04G#+KþW¹U_2!3!5654&#"&5462#!"3!!"&546;2654&+""&547&#"&5463262654'ù)A$&8TýýH071@4DcÍITB0þø((vþŠ"**"í$1C7  G9T6B/:AIO>(!"2!7A")'1# 7,—þG -M&?A5B$5WK\þÄUFAT3$$D3:F2D099-F+?.F 'P;OÜ&:),;$KþX¹^h2!3!5654&#"&5464632632#!"3!!"&546;254&+532654#""&547&#"&72654'ù)A$&8TýýH071@4Dc¨P:+!$@ˆ./*0þá''sþ ,#)êWL-E8V5C/:@HÅ!7B")'1# 7,—þG -M&?A5B$5WK\þB;IS$.#73%0;!: 1C/::-?/>/G %&9)-9$Kþ-¹Wa2!3!5654&#"&5462#"&54632&#"32654&#"#".547&#"&54>3262654'ù)A$&8TýýH071@4Dc¸Q`j@LO=?6$9QQOaG< F7.$. C1>?H&7-$/#8@*)'1# 7,—þG -M&?A5B$5WK\þÄvYj‡0u\Ne3262'654#"#54#"&54632'2654'ù)A$&8TýýH071@4Dc­Qd…nN.6%*:@'ThO?$I:+(E3>>G%. $! .#9C )'1# 7,—þG -M&?A5B$5WK\þˆew” &$.+‚h[z=Q6H,# R6K8S) 2`%; þz ' ˆ/'H15I !$Kþº¹B2!3!5654&#"&5462'654&#"#54&#"&546326ù)A$&8TýýH071@4Dcí6H -%?(. 9'(1KUJ;7&%)'1# 7,—þG -M&?A5B$5WK\þÁWB1>*Z+Fѵ&!A0\#.hBY10Kþ»¹@J2!3!5654&#"&5462"&547&#"#54#"&5463262654'ù)A$&8TýýH071@4DcÍCZ6V6D+97'4MYJ86%/k6B$)'1# 7,—þG -M&?A5B$5WK\þÁiJ7EC7S5 ѵHB4Z!-hAZ0/þü)"O.4E$+KþX"¹Xc2!3!5654&#"&5464>32632#"'7327654'#"&5467&#"#54#"&2654'ù)A$&8TýýH071@4Dc8 /&5&,;R0<9bH'% <)$; 6+&2>+>",98  NZx"#')'1# 7,—þG -M&?A5B$5WK\þ'.B 0.KT2Kf 50=P&( #ô -M.7B4B$5WJ]Kþ>¹CO2!3##"&547#5654&#"&54632!5!5654&#"&5462654&#"ù)A$&8T*C-1?)ù/$*$/@4"1  þBH071@4Dcù..#-)'1# 7,—ýD20@B.2 2'*!+#:/@( "ê -M&?A5B$5WK\ýQ!"-#Kþ¹ERf2!3##"&547#5654&#"&54632!5!5654&#"&5462>54&#"2>4'#"&547ù)A$&8T(3-# 4H3ì/$*$/@4"1  þBH071@4Dcà %(!'41)'1# 7,—ýD%>$5 G4>% 2'*!+#:/@( "ê -M&?A5B$5WK\ýz P '< 4"' (".KþZ ¹O2!3#"&54632&#"3265!5654&#"&5463235!5654&#"&546ù)A$&8U`=+fU53*,L:Kþ4/$ *#.AdAlJJ)2½6)'1# 7,—þG -M&?A5B$5WK\þÃO@›4%)",#:1=<1$’9E&:+…g;HKþ¹GP\2!3!5654&#"&5462##"&547!5654&#"&54623546"354&2654&#"ù)A$&8TýýH071@4DcÕ>K)C-0@)þà/$ *#.AdAlJJ)2½6&.#$)'1# 7,—þG -M&?A5B$5WK\þÃO@›31?A/34%)",#:1=<1$’9E&:+…g;Hþx$"-%Kýë¹LU`t2!3!5654&#"&5462##".547!5654&#"&54623546"354&2654'#2654'#"&547ù)A$&8TýýH071@4DcÕ>K%3-# %3þê/$ *#.AdAlJJ)2½6.$&4350)'1# 7,—þG -M&?A5B$5WK\þÃO@› <$5 .< 4%)",#:1=<1$’9E&:+…g;Hþ©  P." '"#& '!/Hÿ+›Á/2!3# 47326=!5654&#"&546ŒL^$9PpžKþ[PAfžg[ºþQG8.3?4Dc*YJ;(–þ@:b3§}r_o@h]?%V8.N/9B3D"2YL[Hþ¯¥Á=K2!3#".547# 4732>=!5654&#"&546264&+"ŒL^$9P:DB2"2 /4ýè[PCk«qJX<þQG8.3?4Dcð## "*YJ;(–þ@?. J/E+!  “}r_o=aY;# 4".N/9B3D"2YL[ýÉ#2# "Hþ\¢Á;FZ2!3#"&547# 4732>=!5654&#"&5462654&"2>54'#"&'ŒL^$9PY`T=?Q ýè[PCk«qJX<þQG8.3?4DcÂ%&$*2'1 E*YJ;(–þ@N5eAZW?.#“}r_o=aY;# 4".N/9B3D"2YL[ýÊX# " %5"! 2+KþÁ¹EO2!3!5654&#"&546#"&=4&#"#"&5463232654'2>54'ù)A$&8TýýH071@4Dc *C4.?.!N6%+6_F0N=54'ù)A$&8TýýH071@4Dc *77C-1?04.!N6%+6_F0N=54'2654'#"&547ù)A$&8TýýH071@4Dc *CA-# 4HH3.!N6%+6_F0N=.c$+w>N@31)?&ѶH5'b$-u@O0.@18(3Kþ¹Vd2!3!5654&#"&5462654'7#"&547&=4&#"#54#"&546326322654&'+ù)A$&8TýýH071@4Dcô!+Q^08C-0@+7"'"9: %&MWK39$"6.A(#&-$)'1# 7,—þG -M&?A5B$5WK\ý¼>.c$+wN' @1?A/6"E1)?&ѶH5'b$-u@O0.@18(3§$$ 0%Kýë¹Xdy2!3!5654&#"&5462654'7#"&547&=4&#"#54#"&54632632264'#"'2654'#"&547ù)A$&8TýýH071@4Dcô!+Q^5;-# 4H.c$+wS&#E$5 G4E$ ?1)?&ѶH5'b$-u@O0.@18(3v$ P-# '"#& '!/Kþ+¹g2!3!5654&#"&5462654'7#"54632&#"32>5#"'&'&#"#54#"&54>32632ù)A$&8TýýH071@4Dcâ$0DZ&>; X4G'F4R+>!:^ 6"97'NZ .& 6&!61A)'1# 7,—þG -M&?A5B$5WK\ýºC1U'L’D_,2 341€J1Ò¶H," Z!+m-B 0/Q4.#"#ù)A$&8TýýH071@4Dc:"(ZN'& 0!0 :A¡½=9«³U, 6<:9.(KXI<2%!7p!0K  %)'1# 7,—þG -M&?A5B$5WK\þ2OBYb< 5 %$  ‚kPA:C[nK,# F/¿¦B=&[(g=J+*`I%*þú, !Kýë¹ixŒ2!3!5654&#"&5464&'7"&547#".547327#".=4&#"#54#"&546326323262>54&#"2654'#"&547ù)A$&8TýýH071@4Dc<(U`$9DbD1;8jj@:6¥†¨S&1 2976,&HTE9/$ 3k("g  .'"#'.)'1# 7,—þG -M&?A5B$5WK\þ<G?Qj95*,=<-# .\?J=7>UgG2.A,²›=9#U&`9E('YE#4è I0 -%  &KÿEÍÃ,5@2##".547!5654&#"&546323546"!54&2654'#óYvE/ "*þH8.1A4D`MJc%¬rm=O#S #//"Ãvbë,2B 2!,-O.:B4B$5WK[ZJ9)âVi6WFΠ[pýü#0 1"KÿÎÃ*3>R2##"&547!5654&#"&546323546"!54&2654&"2>54'#"&'óYv ,T=?Q/þ-H8.1A4D`MJc%¬rm=O#S %&$*2'1EÃvbë#?AZW?A&-O.:B4B$5WK[ZJ9)âVi6WFΠ[pþX# " %5"! 2+KþÀÂÃDMS\e2!5654&#"&5463235462#"/32654&+#"'#"&54634632"!54&4&"325#32=#"óYvýGH8.1A4D`MJc%¬rÊ0**#!*8.5)'0783+Z 3=O#SA%6 "A}j (?Ãvbë-O.:B4B$5WK[ZJ9)âViý¬7F2 # !!CS227(0!7HWFΠ[pýâ%3/)1&6t#=7Kþ¿ÂÃNW^en2!5654&#"&5463235462#"/3254+53254+#"'#"&54634632"!54&4&#"325#32=#"óYvýGH8.1A4D`MJc%¬ré #G"*8.6*(/6O4*'27=O#S=-  A}k (?Ãvbë-O.:B4B$5WK[ZJ9)âViý¬ 6!CR226)27G73WFΠ[pýâ/(/(8Ngi  CT447(0 9F.% WFΠ[pýä&54'5 %(x5# ?9Kþ¾ÇÃ@I2!5654&#"&5463235464632&#";2#"'73254+"&"!54&óYvýGH8.1A4D`MJc%¬r':DU/$C$5-?70N1T.$MS>@'0F=O#SÃvbë-O.:B4B$5WK[ZJ9)âViýÈ&;0%&/5./&5(-&WFΠ[pKþÃÃ@NWb2!5654&#"&5463235464632&#";2#"'73254+"&2#"&46"!54&264&#"óYvýGH8.1A4D`MJc%¬r ;CT0$C#6-?61N1V,&KS>@'0µ*=*>=&=O#S"# #Ãvbë-O.:B4B$5WK[ZJ9)âViýÈ&;0%&/5./&5(-„:-&:Z:ªWFΠ[pü¿"4"+"KýíÏÃKTa{2!5654&#"&546323546"&547&'732654+"&54632&#";2"!54&2654&#"2>54'#"&547#óYvýGH8.1A4D`MJc%¬rÔ./IrI%C$%L"1>@'0M1U/$C(1-?+$=O#S$+ & -  $Ãvbë-O.:B4B$5WK[ZJ9)âViý)H'5MM56% $&(.#4-0% & $%‡WFΠ[püè[$ % !, ,+Kþ¾ÂÃ(Q[2!5654&#"&546323546"!54&2'654&#""&547&#"&5463262654'óYvýGH8.1A4D`MJc%¬rm=O#S:L_Q$:H7F8V5C. ?HU;'$"2'8A"Ãvbë-O.:B4B$5WK[ZJ9)âVi6WFΠ[pþbaFZ0 .H=S=O7FD6P6 .'R* 3`EYþû)*F05F#+KþWÂÃ(`j2!5654&#"&546323546"!54&2#!"3!!"&546;2654&+""&547&#"&5463262654'óYvýGH8.1A4D`MJc%¬rm=O#S*IT@2þø((vþŠ"**"í%0C7  G9T6B /:AIO>(!"2!7A"Ãvbë-O.:B4B$5WK[ZJ9)âVi6WFΠ[pþ`UF>W3$$D39G2D/:9-F+>/F 'P:PÜ&:)-:$KþXÈÃ(is2!5654&#"&546323546"!54&4632632#!"3!!"&546;254&+532654#""&547&#"&72654'óYvýGH8.1A4D`MJc%¬rm=O#Sþ¶P:+!$@ˆ./*0þá''sþ-, êWL.E8V5C/:@HÅ!7B"Ãvbë-O.:B4B$5WK[ZJ9)âVi6WFΠ[pýÞ;IS#.#73$';!%: 1C/::-@.>/G %&:(-9$Kþ-ÂÃ(cm2!5654&#"&546323546"!54&2#"&54632&#"32654&#"#".547&#"&54>3262654'óYvýGH8.1A4D`MJc%¬rm=O#S?Paj@LO=?6$9QQOaG< F7.$. C1>?H%.! $/#8@*Ãvbë-O.:B4B$5WK[ZJ9)âVi6WFΠ[pþ`wXj‡0u\Ne32632#"'732>54'#"&5467&#"#54#"&2654'óYvýGH8.1A4D`MJc%¬rm=O#Sþ7 /&5&,;R0<9bH&& (: ; 6+&2>+=",98  NZx"#'Ãvbë-O.:B4B$5WK[ZJ9)âVi6WFΠ[pýÃ.B 0.KT2Kf ':0P&KþËÃ(S`2!5654&#"&546323546"!54&233##"&547#5654&#"&5462>54&#"óYvýGH8.1A4D`MJc%¬rm=O#Sì"1 Ç;%! 0@$£/$*$/B* .$%Ãvbë-O.:B4B$5WK[ZJ9)âVi6WFΠ[pþ ( # þÝ0*A/0 1#*!+#:1>þº "&$KýõÉÃ(S^r2!5654&#"&546323546"!54&233##".547#5654&#"&5462654&#"2654'#"&547óYvýGH8.1A4D`MJc%¬rm=O#Sì"1 Ç;-5H3 %5›/$*$/B0A!'(!0Ãvbë-O.:B4B$5WK[ZJ9)âVi6WFΠ[pþ ( # þÝ&?4G.?& 1#*!+#:1>þße') 43 (".KþÆÂÃ(0<C2!5654&#"&546323546"!54&4632!7354&'4#"6óYvýGH8.1A4D`MJc%¬rm=O#S­9T‘þâ½&¡-/*2,AmÃvbë-O.:B4B$5WK[ZJ9)âVi6WFΠ[pý¡c]°x¾).gM<$6TNKþ ËÃ(;GNY2!5654&#"&546323546"!54&4632##"&547#7354&'4#"62654'#óYvýGH8.1A4D`MJc%¬rm=O#S­9T‘&A/1?&o½&¡-/*2,Am.&11%Ãvbë-O.:B4B$5WK[ZJ9)âVi6WFΠ[pý¡c]°x0/AA/0¾).gM<$6TNç$2 2$KýëÉÃ(>JQ]qs2!5654&#"&546323546"!54&4632##".547#7354&'4#"62654&#"2654'#"&5477#óYvýGH8.1A4D`MJc%¬rm=O#S­9T‘*3H3 %3c½&¡-/*2,Am%535/' Ãvbë-O.:B4B$5WK[ZJ9)âVi6WFΠ[pý¡c]°x">4G.>"¾).gM<$6TNÀ P." '"#& '".§JÿPÄ:C2#".5473265!5654&#"&54623546"!54&€^rOn‡^ 5itg_D(d*bGn’‡D©ÚýŒH8/2@4Dc–`%­oM>M#TÄx`þü4R, +FX{I…wk|VˆQ5aP-O.:C2B$3XL[ZI9*áTk5[BΟZrJþ“QÄFOY2#".547#".5473265!5654&#"&54623546"!54&264&#"€^rCD*" #2 rl5itg_D(d*bGn’‡D©ÚýŒH8/2@4Dc–`%­oM>M#T2""*Äx`þüA4L"3 *"  +FX{I…wk|VˆQ5aP-O.:C2B$3XL[ZI9*áTk5[BΟZrýK#2"Jþ=RÄEN\q#".547#".5473265!5654&#"&5462354632"!54&2654.'#2654&'#"&=é"GW<+> cW5itg_D(d*bGn’‡D©ÚýŒH8/2@4Dc–`%­oW^rÚ>M#T #"G'#83%/)+(£ G=@S$5*0% +FX{I…wk|VˆQ5aP-O.:C2B$3XL[ZI9*áTkx`þüSú[BΟZrýL%[02 5 6!-8 %0 KþÁÐÃIR[2!5654&#"&546323546#"&=4&#"#"&5463232>54'"!54&2654'óYvýGH8.1A4D`MJc%¬rÒ*C4/>,#N5&+6^G:D= QU=O#Sì(E%Ãvbë-O.:B4B$5WK[ZJ9)âViþ, ,1"@RA60.>?V.;I8NaH:+Z /!a"±WFΠ[pý_#&C6%NOKþÐÃQZgp2!5654&#"&546323546#"&547&=4&#"#"&5463232>54'"!54&2654&#"'2654'óYvýGH8.1A4D`MJc%¬rÒ*:5A/1?32,#N5&+6^G:D= QU=O#S &- %Ý(E%Ãvbë-O.:B4B$5WK[ZJ9)âViþ, ,1"W(!>/AA/=!!D0.>?V.;I8NaH:+Z /!a"±WFΠ[pü´$! $«#&C6%NOKýëÐÃW`mvŠ2!5654&#"&546323546#".547&=4&#"#"&5463232>54'"!54&2654'#"''2654'2654'#"&547óYvýGH8.1A4D`MJc%¬rÒ*?>$ %D0,#N5&+6^G:D= QU=O#S  "Ö(E%%535/Ãvbë-O.:B4B$5WK[ZJ9)âViþ, ,1"\'#G..L"!C0.>?V.;I8NaH:+Z /!a"±WFΠ[püâ   !}#&C6%NOÍ." '"#& '".KþºÎÃR[2!5654&#"&5463235462654'7#"&=4&#"#54#"&54>32632"!54&óYvýGH8.1A4D`MJc%¬rÃ!+Q^@4/A"'"9: %&MW-% 7&"6.A'7=O#SÃvbë-O.:B4B$5WK[ZJ9)âViý">.c$,v?M@31)?%ѶH5'b$-u*> 0.?28(3¨WFΠ[pKþÎÃZcq2!5654&#"&5463235462654'7#"&547&=4&#"#54#"&54>32632"!54&2654'#"'óYvýGH8.1A4D`MJc%¬rÃ!+Q^9/=*+=,7"'"9: %&MW-% 7&"6.A'7=O#S".  !Ãvbë-O.:B4B$5WK[ZJ9)âViý">.c$,vX$8-::-8E1)?%ѶH5'b$-u*> 0.?28(3¨WFΠ[pü¸#0  $KýßÒÃ\er‡2!5654&#"&5463235462654'7#"&547&=4&#"#54#"&54>32632"!54&2654'#"'2654'#".547óYvýGH8.1A4D`MJc%¬rÃ!+Q^6: 8%6LE)"'"9: %&MW-% 7&"6.A'7=O#S #V: & "-Ãvbë-O.:B4B$5WK[ZJ9)âViý">.c$,vS'&F&. K7M&!91)?%ѶH5'b$-u*> 0.?28(3¨WFΠ[püÚ   #[;*# ! %5*Kþ+ÄÃ(m2!5654&#"&546323546"!54&2654'7#"54632&#"32>5#"'&'&#"#54#"&5462632óYvýGH8.1A4D`MJc%¬rm=O#S $0DZ&>; X4G'F/R+= !:]  6"97BNZKl&!61AÃvbë-O.:B4B$5WK[ZJ9)âVi6WFΠ[pýVC1U'L’D_,2 341€J1Ò¶H:=Z!+m@Z0/QLA$A6X9H [VT=O#SÃvbë-O.:B4B$5WK[ZJ9)âViþ'RD@K !L0;<1V*iEVRD@K !L0;<1V*iEV£WFΠ[pKþÈÃCYbn2!5654&#"&5463235462#"&547'654&#"&54622'654&#"&54"!54&2654&#"óYvýGH8.1A4D`MJc%¬rÃ+<*> A6,-8H [W|L(þ|LA$A6,-8H [ð=O#S,#"+Ãvbë-O.:B4B$5WK[ZJ9)âViý#<+&:-+!L0;<1V*iEVRD@.RD@K !L0;=0V*iEùWFΠ[püÂ## KýãÉÃD[do„2!5654&#"&5463235462#"&547'654&#"&54632%2'654&"&546"!54&2654#"2654'#"&5475óYvýGH8.1A4D`MJc%¬r«%7 .&7K8A7+.7H [U@>Lþ,>L*(A6X9H [U¯=O#S.V:" 8 *Ãvbë-O.:B4B$5WK[ZJ9)âViý$ .&&8 L6D' !L0;<1V*iEVRD@ÖRD.G!L0;<1V*iEV£WFΠ[püÞ .[;*#% %'3*KÿB Ã=GR233##"&547#5>54.#"#4.#"632#"&5463262654&"%2654&#"eTdUìIB21CÔ#? 6%)8S40¤-;/>=2>K…j\C4o2##2#ýh$%&'Ás`€H—þG,/ED0,mQ44-!þ¿,$. ÉHR<;IkRuQOýÅ#""†.#%1.H1Kÿ Ã=HZe233##"&547#5>54.#"#4.#"632#"&5463262654&"2654'#"&'%2654&#"eTdUìI!-U<@P0®#? 6%)8S40¤-;/>=2>K…j\C4_%&$)92'2Eýc$%&'Ás`€H—þG"ADWW?B&mQ44-!þ¿,$. ÉHR<;IkRuQOýÙX8*" %5!" 2+í.#%1.H1MÿÁOZ%33#".54>32&#"3265!5654&#"#4&#">32#"&54632>322654&#",.4öS ;iJBN5eb%?I)N'gP54.#"#4.#"632#"&5463262654&#"2'654&#"#"&54732=46eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4þ´$%&'ê4@bP-";<.8DUD&,9CÁs`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþn.#%1.H1EM?w-%Y1>e*/54.#"#4.#"632#"&5463262654&#"2+"3!!"&546;2654&#"#"&546732654&546eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4þ´$%&'á$5  & Í$$Hþ¸'!( ·/:)"6?+4G.1"/;!<Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþn.#%1.H1E++'>"20"L9.:` -4H;*H :+6-*#+4KþZÿÃ2=233!5>54.#"#4.#"632#"&5463262654&#"2+"3!!"&546;254&+532654#"#"&5467326='46eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4þ´$%&'à@:((@6Ý$$Qþ¯ '' ÊQ D8;05F? #.<"?Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþn.#%1.H1F=$-'02(#6!8?70:H;6B  ;*5.#:'/Kþ-ÿÃ2=n233!5>54.#"#4.#"632#"&5463262654&#"2#"5432&#"32654&#"#"&546732=4eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4þ´$%&'—vN{f‹ƒG4%5LQOa1';<+7E*5!' 0':Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþn.#%1.H1CmVo8*vaE\2FTA&] :*/@k1Kþ½ Ã2}…‹–233!5>54.#"#4.#"632#"&5463262+"32632#"&547'#"&546;2654&"#54&#"632#"&5463264#"32$4#"3%2654&#"eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4Œ !*?JŸ$'.¾$%%  X]#%A8“&1"4 6,( %#H6?$""þÚþ$%&'Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþ,)$;"L " ) #++##$9D .(+6#$ô‡DDÊ.#%1.H1KþAÿÃ2—Ÿ¥°233!5>54.#"#4.#"632#"&5463262#!"3!!"&5463!2654'#"&547'#"&54;2654&#"5#54&#"632#"&54>32>32+"3274#"32$4#"3%2654&#"eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4Tb<6,þÊ&&–þj '!&'2>%%NJ(%ˆƒ1,' ;6*") $$31K :+ EQ‰#0:ê""þàþs$%&'Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOýn-"!+'!)   + *V/)W 4%.&$/ $$ (>—DDÃ.#%1.H1KþNÃ2‘š ­¸233!5>54.#"#4.#"632#"&546326232#!"3!!"&5463!254#5254+"&547#".54;2654#"#4&#"632#"&54632>2654#"'4"2"3267+&%2654&#"eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4z &(WoþÑXþ§!!#/!2  k yi9933+#  L@ 3 ­..2&+m"ý¿$%&'Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþ4 , L-  &  LV #?R I.-/2.#þè  –!! 7Iù.#%1.H1Kþ'Ã2›£©´233!5>54.#"#4.#"632#"&5463262#"&54632&#"32654&'#"&547'#"&546;2654&#"#54&#"632#"&54>32>32+"3264#"32$4#"3%2654&#"eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4u9Jt\$_P0H.%3O(+K[%. ˜()&@J…(5!';7*!( $32I <,8G<'1Ó)!!þÙþy$%&'Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOýk@3AQI;0  R410"(N *%%,%#.$7(09V9—DDÃ.#%1.H1Kþ¼ Ã2Yd233!5>54.#"#4.#"632#"&5463262#"/3254&+53254&#"&546%2654&#"eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4‡>5/1@6E+$I))DSýq$%&'Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþ-=(/%7 )/ /GJ4?K3Q`A.#%1.H1Kþ Ã2cr}233!5>54.#"#4.#"632#"&5463262#"&547'62654&+53254&#"&5462654&'+2654&#"eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4‡>5/1/1C-/A8 ++$I))DSK&" $ýB$%&'Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþ-=(/0!;1?@0B  # /GJ4?K3Q`þP$"%&ñ.#%1.H1KýëÃ2hvŠ•233!5>54.#"#4.#"632#"&5463262#".547'632654&+53254&#"&5462654'#"'2654'#"&5472654&#"eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4‡>5/1.:-# %E -+$I))DS<  &4350ýV$%&'Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþ-=(^$D$5 .L"  $ /GJ4?K3Q`þ P." '"#& '!/.#%1.H1KþPÃ2lw233!5>54.#"#4.#"632#"&546326#"&5432&#"32654&+532>54&#"&54>32%2654&#"eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4ï($Q.0(Rq5$<&-72(% $*)4>*:DüÅ$%&'Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOýÐ4O$5 .  2+'3#! )4="6=K388!5s.#%1.H1KþÀ Ã2Wb233!5>54.#"#4.#"632#"&5463262654'7#"'#".547326=32654&#"eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4ˆ%1JUJ58%$5 %-\<,#%:!ýF$%&'Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOý+C4V$0gDU11 @,l,+Z3? ϶!(C.#%1.H1Kþ Ã2cq|233!5>54.#"#4.#"632#"&5463262654'7#"&547&'#".547326=32654.'+2654&#"eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4ˆ%1JU::,<%$5 %-\<,#%:!4" -ýd$%&'Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOý+C4V$0gW+A&<+1 1 @,l,+Z3? ϶!(¢"  .Â.#%1.H1Kýß Ã2bn‚233!5>54.#"#4.#"632#"&5463262654'7#".547&'#".547326=32654'"'2654'#"&5472654&#"eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4ˆ%1JUB@M5&8 G$5 %-\<,#%:! ,V: &*#-ý§$%&'Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOý+C4V$0g]*%L8J .&P$ 1 @,l,+Z3? ϶!(… # *[:+# !65+é.#%1.H1Kþ8 Ã2=}233!5>54.#"#4.#"632#"&5463262654&#""&5432&#"32>5#"'#".547326=332>54'7eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4þ´$%&'•6N…@'"7F230$3/'"77()F ( &@DÁs`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþn.#%1.H1þ "/ !@-'22@*n*)]6?Ö¶L9+U*:BEd3KýòÿÃ2r“ž233!5>54.#"#4.#"632#"&546326#".54632.#"32#"'#".547326=332654'2'654#"#54"&546322654&#"eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4ƒ4:1_B<;S>N.6%*:2'¾ B%7'$6%5 [;%,/6"'2JW( ý¤$%&'Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþ'ˆO-VT4 &$.+ -*33%7,m+,Y-H϶!+F4X$þ ' Ô.#%1.H1Kþº Ã2=b233!5>54.#"#4.#"632#"&5463262654&#"2'654&#"#54&#"&546326eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4þ´$%&'è6H -%?(. 9'(1KUJ;8%%Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþn.#%1.H1EWB1>*Z+Fѵ&!A0\#.hBY10Kþ»Ã2=ak233!5>54.#"#4.#"632#"&5463262654&#"2#"&547&#"#54#"&5463262654'eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4þ´$%&'ÈCZ5,*7D+97'4MYJ86%/k$6B$Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþn.#%1.H1EiJ7EC7R6 ѵHC3Z!-hAZ0/þü#(O.4E$+KþXÃ2={‡233!5>54.#"#4.#"632#"&5463262654&#"4>32632#"'732>54'#"&54>7&#"#54#"&2654'eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4þ´$%&') /&4'+",98  NZx"+ Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþn.#%1.H1ß.B 0.KS2Ih ':0P&7#5>54.#"#4.#"632#"&5463265#%2654&#"eTdUìIþ)8\7 ¯#? 6%)8S40¤-;/>=2>K…j\C4©h%#ýò$%&'Ás`€H—ý€ /:-mQ44-!þ¿,$. ÉHR<;IkRuQOýž¡(:Ð.#%1.H1Kþ| ÃFNZe233##".547!5>7#5>54.#"#4.#"632#"&5463265#2654&#"2654&#"eTdUìIE/ ")þç8\7 ¯#? 6%)8S40¤-;/>=2>K…j\C4©h%#É#$ "ýC$%&'Ás`€H—ý€,3A 1"- /:-mQ44-!þ¿,$. ÉHR<;IkRuQOýž¡(:Ÿ"!+"o.#%1.H1Kþ; ÃDLWju233##"&547#5>7#5>54.#"#4.#"632#"&5463265#2654&"2>54'#"&'2654&#"eTdUìI",S>=S.î8\7 ¯#? 6%)8S40¤-;/>=2>K…j\C4©h%#›%&)(+3&3/ý{$%&'Ás`€H—ý€#@AZW?A' /:-mQ44-!þ¿,$. ÉHR<;IkRuQOýž¡(:Œ%&X 0%$ &4"! A´.#%1.H1Kþ¼ÿÃ2=z233!5>54.#"#4.#"632#"&5463262654&#"2#"/3254.54>323254&#"&54>32#"&#"326eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4þ´$%&' %593-(1C0;02/%-E/0&7 ,+3 Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþn.#%1.H1ú!)  ! FP.ES+2J%!  JÿÃMY233# $546732>5!5654&#"#4&#"632#".5463262654&#" JcXæIBe„x;þìþ¯(1(ZJs»w}Í}þ½gI<'3SJ4%=&-@1A?4.,Šf^H6þ® %( !',ÃgS‚d–þC5U2! é¿NuBkŠ2^aF-(N4XGX+$þ¿,(6**4GO=;I'L2yžPPþm-#%0/"%/Jþš—ÃXgs#"&547# $546732>5!5654&#"#4&#"632#".54632632332654&#"2654&#"N2 2"3Cq’þìþ¯(1(ZJs»w}Í}þ½gI<'3SJ4%=&-@1A?4.,Šf^H6\JcXæIl " ýQ %( !',„8, #*D2 é¿NuBkŠ2^aF-(N4XGX+$þ¿,(6**4GO=;I'L2yžPPgS‚d–þCLÏ$"  O-#%0/"%/Jþ?˜ÃUcx„"&547# $546732>5!5654&#"#4&#"632#".54632632332654.'"2654&'#".=2654&#"&7;U|Tjwþìþ¯(1(ZJs»w}Í}þ½gI<'3SJ4%=&-@1A?4.,Šf^H6\JcXæI— !P:'#8'# $'ý¼ %( !',Ÿ T0=VU>1(é¿NuBkŠ2^aF-(N4XGX+$þ¿,(6**4GO=;I'L2yžPPgS‚d–þC_À[8* 5 6& & +w-#%0/"%/KþÁ Ã2Zcn233!5>54.#"#4.#"632#"&546326#"&=4&#"#"&5463232654'2654'2654&#"eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4Ÿ*C4/>.!N5&+6_F0N=>Qý*E%þS$%&'Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþ. ,1"@RA60.>?V.;I8Mb54.#"#4.#"632#"&546326#"&547&=4&#"#"&5463232654'2654&#"'2654'2654&#"eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4Ÿ*::C-/A37.!N5&+6_F0N=>Q&."$á*E%þS$%&'Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþ. ,1"X'C1?@0>J0.>?V.;I8Mb54.#"#4.#"632#"&546326#"&547&=4&#"#"&5463232654'2654'#"''2654'2654'#"&5472654&#"eTdUìIþm#? 6%)8S40¤-;/>=2>K…j\C4Ÿ*?>$ 4HD0.!N5&+6_F0N=>Q "Ö*E%òL433ý$%&'Ás`€H—þGmQ44-!þ¿,$. ÉHR<;IkRuQOþ. ,1"\'#G.G4K#!C0.>?V.;I8Mb;254#"#"5463232654&#"&4>32#"&#"32636š#Bfä(!>þÂ.? /¢^= O W9#A R(´*.A9D}8 C %LÃ3$pE5' %K,K'"!/½;XjlT/ K6!  JÿÁV%#"&5467327654+53254&'&5463232654&#"&54>32#"&#"32632a‚bŸÃ(%&*@lD@8H"ÙuZ[R=2) N E1³*/@97Q%8;$K'&:M`ß·Y{>6nT-W^G-9*102(0 !-áFivIAc9# "2('%'$,2Jÿ À\%2#"&54>32&#"32654.#""#"&5463232654&#"&54>32#"&#'"&#"376s%0'n†H…3L@@7/-:O]#MS73 .!*G7 :H:Ã) 1D=!32#"&#"32632'2'654#"52#474654#"&54626MjaOt8"h5.I8czF8 2 % I8 60'5>V))6hH.@4%E*4%&5HWŸY  , þË2(+41- #hV=L(&(070-JG&H`vO0VQ0">&7/+cJm‚ƒ(     6ÿ#•ÃK%2#"&54732>54&#"&546323254.#"&54>32#"&#"æ^Q "6a>›ÂF*I§€6N$;E=/.&E > 7%86 /,IJ':T',#J U8+>2$Ý´¢j_’™Æ#3('<'*-:< !1`BQZ 32#"&#"264&+æ^QEFE/ ") ›ÍF*I¯ƒL`;E=/.&E > 7%86 /,IJ':T',#J n4"# U8T>M3A 1"Û¶¢j_’œÃQ<'<'*-:< !1`BQZ 32#"&#"2654&'2654'#"&'æ^Q[\U<=SšÂF*I¯ƒL`;E=/.&E > 7%86 /,IJ':T',#J ]&(%(:3&$-EU8e=cDWW?3%ر¢j_’œÃQ<'<'*-:< !1`BQZ ,E/ "*ókiJ % 9 "ÿ@SFI &e«u#//" $8dA¶-2B 2!,›Š¢,/6  gp36 4Ý…{þì#0 1"MÿÂ'/9L2##"&547#5463!54&+4&#"62654&"2>54'#"&'%5>,$-U32#"&4632.#"326=!54'%354&#'"654&H+<5ÝdƒMroQ([ E "UI-[=þ8,-üBUC&0°0ÏI)°}‹&2IþÙÂ+O^f2##".54632.#"3254'!5462'654#"5#465654#"&546326!54&+4&#"6!~aˆp7E/dI]6 F$3D 1&¹þ‘k_  d!'+ÿ@SFI'e«§¤*:r† 5$6HB!"/#%ì ›ŠýÇ$$ %#2  -% !$—0*+%( gp18&.Ý…{Mþº #G2!546!54&+4&#"62'654&#"#54&#"&546326!7>.þNk³ % 9 "ÿ@SFI &e«g6H> ?(. 9'(1KUK:7&$ $8dA¶ž‡¢,/6  gp36 4Ý…{³WB>K*Z+Fѵ&!A0\#.hCX10Mþ¼  #GQ2!546!54&+4&#"62#"&547&#"#54#"&5463262654'!7>.þNk³ % 9 "ÿ@SFI &e«Y=R2'&3?*52#0GRD31#*c 1=" $8dA¶ž‡¢,/6  gp36 4Ý…{´hJ7DC6Q6 Ï´GC2Y!-gBW//þþ#'N.4D",LþX  #^j2!546!54&+4&#"64>32632#"'7327654'#"&54>7&#"#54#"&2654'!7>.þNk³ % 9 "ÿ@SFI &e«Ö% )#-?''4L9 .!. *"% 0"-+2=F%  $8dA¶ž‡¢,/6  gp36 4Ý…{þ³-C 0.K K=Le 5/>P&54&#"#4&#".546326Rl[öIþk+3N6(1S3!=Q 3#): lWQ:7Ã}]vO—þG*u>SG,$þÂ;4gN-94?E3d„IIIÿBÉÃ;H233##".547#5>54&#"#4&#".5463262>4.#"Rl[öI A3"1 Ø+3N6(1S3!=Q 3#): lWQ:7‡  Ã}]vO—þG.0D)" .*u>SG,$þÂ;4gN-94?E3d„IIýÃ.+,IÿÇÃ9DV233##"&547#5>54&#"#4&#".5463262654&"2654'#"&'Rl[öI$-T=>R0­+3N6(1S3!=Q 3#): lWQ:7Z%&$+73&"/EÃ}]vO—þG$@AZTBC&*u>SG,$þÂ;4gN-94?E3d„IIýØX:(" &4' 2+MÿÍÁB233#".54>32&#"326=!5654&#"#4&#"&546326"Sm^ûNq’?O7f` Q>&R;Qe'g<þ¯aK7#;S,#?Uv†oSf'(Á„`iQ–þF…e & "El]fNg&+þÂ0@hIpRk{`„IIJÿ KÂG233#"$&546732>5!5>54.#"#4&#".546326µRk[æNІ±¡þûš)2*#‰æŽX³~þÄ*3 6&'1S3!20-$þÂ<4hO*;4@D2e„JJJþšQÂVb#".547#"$&546732>5!5>54.#"#4&#".54632632332654&#"2*" #2 jv¡þûš)2*#‰æŽX³~þÄ*3 6&'1S3!20-$þÂ<4hO*;4@D2e„JJ}]wN–þEF×$" #Jþ?RÂTat#".547#"$&546732>5!5>54.#"#4&#".54632632332654.'"2654&'#"&=Þ8 \_¡þûš)2*#‰æŽX³~þÄ*3 6&'1S3!20-$þÂ<4hO*;4@D2e„JJ}]wN–þEXÉ%[8* 5 6!-8 +I¬Ã&082!54>32>354+4&#"6%354+4&#"6Ìc}ü(BC$4D>3OuMRúŸFI+ jµþ¥NQúŸFI+ jµÖz³¿Jl6 ?,,1!¦FnJ–æ3;%4¶±}FoI–æ3;%4¶±IÿA¹Ã(0;EM2#"&547!54>32>354+4&#"6264&#"354+4&#"6Ìc} CbC!ýW(BC$4D>3OuMRúŸFI+ jµz$$ +þ32>354+4&#"62654&"2654'#"&'354+4&#"6Ìc}%0U<@P3ý€(BC$4D>3OuMRúŸFI+ jµM%&$)92'2EþfNQúŸFI+ jµÖz³!BDWW?F"¿Jl6 ?,,1!¦FnJ–æ3;%4¶±þúX8*" %5!" 2+ÛFoI–æ3;%4¶±Pÿ²Á*3;DL2#".4>32&#"3265!5&>76326354#4&#"6%354#4&#"6ÎouCM44MBX82:*ef&U^üÜ/{©+#úLSú¡FI*!jµþ¥LSú¡FI*!jµÁ|Ž·†f ,! TkŽ%D99>‹‹ GmJ–å49%3¶°‚|GmJ–å3:%3¶°EÿE–Â+274>32#"&5473265!354&+4#"6ã+;6Ý‘iœ»B$?¢†Nmþ” #5 ù?REGBj¬Ë<\4 þö»OiÛ´†gZy˜¼G4!- .2 –ku26N¬°{EþŸ™Â)9@O74>32#"&547"#"&5473265!354&+4#"62654&#"ã+;6Ý@C*" 0F œ»B$?¢†Nmþ” #5 ù?REGBj¬k""Ë<\4 þö»M1K#3 B4Û´†gZy˜¼G4!- .2 –ku26N¬°{þG!!$EþIšÂ+;BNb#".547+"&5473265!54>32354&+4#"62654&'"2654&'#"&=2 $U>+> +›¸B$?¢†Nmþ”+;6Ý— #5 ù?REGBj¬@!")9,8+-/)8— 6!=V$5*>+Û´†gZy˜¼G4Ê<\4 þö»`…- .2 –ku26N¬°{þH [9)#5588 (:MþÁ  0@HQ2!5462654'7#"&=4&#"#"&54632!54&+4&#"62654'!7>.þNkæ 0KY=2+;5I1$'4YB6@ % 9 "ÿ@SFI &e«l&A" $8dA¶ž‡ý(>1a"*rBPC40:2?V-.þNkæ:KY97B./A:-5I1$'4YB6@ % 9 "ÿ@SFI &e«w#!$%È&A" $8dA¶ž‡ý(69a"*rZ'A1??1C!C0:2?V-54'#"&547!7>.þNkæ:KY?;-# $5 3(5I1$'4YB6@ % 9 "ÿ@SFI &e«\ »&A"ú", 3&#/ $8dA¶ž‡ý(69a"*ra$$D$5 -# -: !?0:2?V-54&#"2654&#"327.54&#"Æ)*CbC  8*7€œVEK,@T*?ŒWmL%Xþ¼!-7-.>Dø"# #ýð0`A1D1#&16 >$1CD0 •sSoVV*=4Mx]nBN{vG4:)@UT54&#"2654&+2654'#"&'327.54&#"±+;TzS-*7€œVEK,@T*?ŒWmL%Xþ¼!-7-.>DË& %(:3&3Eþ0`A1D1#&1% A6BYW?3% •sSoVV*=4Mx]nBN{ˆ54:)@UT32&#"32>7#"'#"&5463263232654'>54&#"%327.54&#"¾9,0N{R>G3.JG#RH52›Š>\4! F7*7{¡VEK,@T*?ŒWmLÇ!-7-.>DþÏ}i /F/%&1À1µIEncB& !*#$5OE*a xSoVV*=4Mz[nBþ“4:)@UT32'>54&#"%327.54&#"4&"325#32=#"!WmL%XŠn8*7€œVEK,@T*?Œ¬0*+" !*8.5)'0782*Z Â!-7-.>DþÏ0`A1D1#&1è%6 "A}j (?"x]nBN{n“ •sSoVV*=4M³7#$1 # !!CS227(0!:EË4:)@UT54&#"%327.54&#"4&#"325#32=#"!WmL%XŠn8*7€œVEK,@T*?ŒÐ #G"*8.6*(/6O4*'2Ë!-7-.>DþÏ0`A1D1#&1ñ-  A}j (?"x]nBN{n“ •sSoVV*=4M³ 6!CR226)27G73Ë4:)@UT54&#"%327.54&#"2!"&5473254&+532654&+#"'#"&54634632#4&#"325#32=#"!WmL%XŠn8*7€œVEK,@T*?Œ@!-7-.>DþÏ0`A1D1#&1V-$%þû–ÉA;°á" +8.6+'/9M3*-.&" Cl*A"x]nBN{n“ •sSoVV*=4M4:)@UTNgi  DS447(0 9F.% &54'5 %(x5# ?9Oþ.À!/?ry‚‹%2654'7#"'#"&54632632'>54&#"%327.54&#"2#"&54632&#"32654&+#"'#".546;4632#4&#"26=#'32=#"!WmL%XŠn8*7€œVEK,@T*?Œ@!-7-.>DþÏ0`A1D1#&15,#86Oþ¹À!\jz…Œ“œ%2654'7#"'#"&546326322'654&#"32#".547##"'#"&546;46323>'>54&#"%327.54&#"2654+'.#"327#32=#"!WmL%XŠn8*7€œVEK,@T*?Œl ".%S$=?. 6 A;$*) 8.6)'1994**##,ž!-7-.>DþÏ0`A1D1#&1½1'{# !A~k(?"x]nBN{n“ •sSoVV*=4M6 9$SG6I6G/(%6!420BT227(0!9E0 )7N4:)@UT54.#"32#"&547##"'#"&546;>326'>54&#"%327.54&#"2654&+'.#"327#32=#"!WmL%XŠn8*7€œVEK,@T*?Œq>T,04( .% " ' 3#+, (/8.6+'08:3** #(!-7-.>DþÏ0`A1D1#&1¢(" !A~k'?"x]nBN{n“ •sSoVV*=4M69*&'&- (1*% .&(1A2CS227(.#9E/"€N4:)@UT54&#"%327.54&#"#"&54732654&+532654#"32#"&547##"'#"&546334632>32'4&+326'.#"327#32=#"!WmL%XŠn8*7€œVEK,@T*?Œ@!-7-.>DþÏ0`A1D1#&1Á’§Ö3/Çš|¢I0@ ,,*#,2*/'#,43 /&Q  K?9J"%½#«9n`#7"x]nBN{n“ •sSoVV*=4M4:)@UT54&#"%327.54&#"!WmL%XŠn8*7€œVEK,@T*?Œ,7"•9þQ‹%1 4 !-7-.>DþÏ0`A1D1#&1"x]nBN{n“ •sSoVV*=4Ms5+- þÝ(9$ $1‹4:)@UT54&#"%327.54&#"2654&#"!WmL%XŠn8*7€œVEK,@T*?Œ,7"•9#=*+=#þî‹%1 4 !-7-.>DþÏ0`A1D1#&14"" "x]nBN{n“ •sSoVV*=4Ms5+- þÝ/-::-/(9$ $1‹4:)@UT54&#"%327.54&#"2654#"2654'#"&547!WmL%XŠn8*7€œVEK,@T*?Œ,7"•9$4 /%&8 4ï‹%1 4 !-7-.>DþÏ0`A1D1#&1.V:,")$-"x]nBN{n“ •sSoVV*=4Ms5+- þÝ'A&8 /%A'(9$ $1‹4:)@UT54&#"%327.54&#"2654'!WmL%XŠn8*7€œVEK,@T*?Œ^L_Q$:H7F8V5C. ?HU;'$#v!-7-.>DþÏ0`A1D1#&1™&8A""x]nBN{n“ •sSoVV*=4M3aFZ0 .H=S=O7FD6P6 .'R* 3`EYK4:)@UT54&#"%327.54&#"2654'!WmL%XŠn8*7€œVEK,@T*?ŒiITB0þø((vþŠ"**"í$1C7  G9T6B/:AIO>(!"y!-7-.>DþÏ0`A1D1#&1!7A""x]nBN{n“ •sSoVV*=4M5UFAT3$$D3:F2D099-F+?.F 'P;OM4:)@UT54&#"%327.54&#"2654'!WmL%XŠn8*7€œVEK,@T*?Œ¼P:+!$@ˆ./*0þá''sþ ,#)êWL-E8V5C/:@H|!-7-.>DþÏ0`A1D1#&1Ÿ!7B""x]nBN{n“ •sSoVV*=4M·;IS$.#73%0;!: 1C/::-?/>/G %&4:)@UT54&#"%327.54&#"2#"&54632&#"32654&#"#".547&#"&54>3262654'!WmL%XŠn8*7€œVEK,@T*?Œ@!-7-.>DþÏ0`A1D1#&1êQ`j@LO=?6$9QQOaG< F7.$. C1>?H&7-$/#8@*"x]nBN{n“ •sSoVV*=4M4:)@UT54&#"%327.54&#"2654'!2654'!WmL%XŠn8*7€œVEK,@T*?Œ~=RG5D6@/'&.=*1,!>/'%/<$17>I5%"@$<—!-7-.>DþÏ0`A1D1#&1Á"3:þã#3:"x]nBN{n“ •sSoVV*=4M4_E\/ -K=R=Q7EB7R6 ,#·¯(2:R7ED5R676R+ 0bDW<;L4:)@UT54&#"%327.54&#"2654'2654'!WmL%XŠn8*7€œVEK,@T*?Œ„LAD2ýæ%%ýs$#þ':@4 =.&$.:!*3,% <1#%-9)3:BI4# ">+&8œ!-7-.>DþÏ0`A1D1#&1Æ/7þÓ /7"x]nBN{n“ •sSoVV*=4M8Y7B^61#)K97C-K.;;,K' %š“!)-I/;;-J(>-M %Y:H12P4:)@UT54&#"%327.54&#"2654'2654'!WmL%XŠn8*7€œVEK,@T*?Œ 03)ýÈ(†ýz (P &,##;.%$,9!*1." :.H,8 !8@F4"!;,$8#8.Mþ·!-7-.>DþÏ0`A1D1#&1»-6þ×-7"x]nBN{n“ •sSoVV*=4MŒ 8'41 $;',' -I/;;,G*$›”"*-J/;:.J) /K 'W:J32'w4:)@UT54&#"%327.54&#"2#"&54632&#"3254.#"#"&547&#"#54&#"#".547&#"&5463263263262654'!2654'!WmL%XŠn8*7€œVEK,@T*?Œ@!-7-.>DþÏ0`A1D1#&1AP&B@$7ET(7,16Hœ 2! @2'"/< L0(! ?2'"< $17=F7# !&= H !/!3;'þÛ!3;'"x]nBN{n“ •sSoVV*=4M4:)@UT54&#"%327.54&#"2'654&#"#54&#"&546326!WmL%XŠn8*7€œVEK,@T*?Œ@!-7-.>DþÏ0`A1D1#&16H -%?(. 9'(1KUJ;8%%"x]nBN{n“ •sSoVV*=4M4:)@UT*Z+Fѵ&!A0\#.hBY10Oþ»À!/?bl%2654'7#"'#"&54632632'>54&#"%327.54&#"2"&547&#"#54#"&5463262654'!WmL%XŠn8*7€œVEK,@T*?Œ@!-7-.>DþÏ0`A1D1#&1ÿCZ6V6D+97'4MYJ86%/k6B$"x]nBN{n“ •sSoVV*=4M4:)@UT54&#"%327.54&#"462632#"'732>54'#"&5467&#"#54#"&2654'!WmL%XŠn8*7€œVEK,@T*?Œ@!-7-.>DþÏ0`A1D1#&1`Nj&,;R0<9_K&& (: ; 6+&2>+>",98  NZx"#'"x]nBN{n“ •sSoVV*=4M4:)@UT54&#"%327.54&#"233!5654&"&546!WmL%XŠn8*7€œVEK,@T*?Œ@!-7-.>DþÏ0`A1D1#&1="1 Ç;þ«/$<+$/@"x]nBN{n“ •sSoVV*=4M4:)@UT54&#"%327.54&#"233##"&547#5654&"&5462>54&#"!WmL%XŠn8*7€œVEK,@T*?Œ@!-7-.>DþÏ0`A1D1#&1="1 Ç;%! /A$£/$<+$/@, .#%"x]nBN{n“ •sSoVV*=4M4:)@UT54&#"%327.54&#"233##".547#5654&"&5462654&"2654'#"&547!WmL%XŠn8*7€œVEK,@T*?Œ@!-7-.>DþÏ0`A1D1#&1="1 Ç;-5-# %5›/$<+$/@&0A!'40"x]nBN{n“ •sSoVV*=4M4:)@UT54&#"%327.54&#"233#"&4632&#"3265!5654&#"&546!WmL%XŠn8*7€œVEK,@T*?Œ@!-7-.>DþÏ0`A1D1#&1?"1 Ò002(iV43*+L/"54&#"%327.54&#"4632!7354&'4#"6!WmL%XŠn8*7€œVEK,@T*?Œ@!-7-.>DþÏ0`A1D1#&1r9T‘þâ½&¡-/*2,Am"x]nBN{n“ •sSoVV*=4M4:)@UT54&#"%327.54&#"4632##"&547#7354&'4#"62654'#!WmL%XŠn8*7€œVEK,@T*?Œ@!-7-.>DþÏ0`A1D1#&1r9T‘&C-1?&o½&¡-/*2,Am.&11%"x]nBN{n“ •sSoVV*=4M4:)@UT54&#"%327.54&#"4632##"&547#7354&'4#"62654&#"2654'#"&5477#!WmL%XŠn8*7€œVEK,@T*?Œ@!-7-.>DþÏ0`A1D1#&1r9T‘*3-# 4H3c½&¡-/*2,Am&4350& "x]nBN{n“ •sSoVV*=4M4:)@UT$5 G4>"¾).gM<$6TNÀP-# '"#& '!/§Oþ,À!/?^is%2654'7#"'#"&54632632'>54&#"%327.54&#"432#".54632&#"326=#7354&#'"654&!WmL%XŠn8*7€œVEK,@T*?Œ@!-7-.>DþÏ0`A1D1#&1v’CV37H7C;7N<(ó¼#$(¦30,_ t "x]nBN{n“ •sSoVV*=4M4:)@UT%$bQA!(1tS[!Oÿ9À'5<L%2654'73!5>7&'#"&54632632'>54&#"5327.54&#"!WmL%X`5þ3Q**7€œVEK,@T*?Œ@!-7-.>Dõ*7#6#þ·0`A1D1#&1"x]nBN{„KïYC •sSoVV*=4M4:)@UT7&'#"&54632632'>54&#"5327.54&#"2654&'#!WmL%X`5 *" "1 þîQ**7€œVEK,@T*?Œ@!-7-.>Dõ*7#6#þ·0`A1D1#&1ò2#"x]nBN{„Kï+"2 )" +YC •sSoVV*=4M4:)@UT7&'#"&54632632'>54&#"5327.54&#"2654&#"2>54'#"&'!WmL%X`5,S>=S.õQ**7€œVEK,@T*?Œ@!-7-.>Dõ*7#6#þ·0`A1D1#&1Ô.%%C*3&3E"x]nBN{„Kï&?CXW?A)YC •sSoVV*=4M4:)@UTH2#"/2654&+532654&#"#"&547&#"&5463262654'5:W'KQ4!(F)' !!%7A<6lSB?Qi $M`^!jua>8>W(6V\. /% :$S (! 44&#*-."$8\wSjeRvTrV}?Lgˆ$$þrI9lHIs7CJÿ4›ÂAK2#"$54732654+53254.#"#"&547&#"&5463262654'ÌXsCGvn“ÇþíO E쯇±7%%- 4#=6lTA@Pi!"N`^ kua?8K%#".54632&#"32>54'#"&546;&#"&546322654'&#"]”x7@+fQO=.@kk>Z.SD9D[I0V3@+bw„aŒ9#ê+5;J"V‡´  *!&';cg9Fa|NAMjL(V:y<Jk‡ˆ%#%!!,P;@Y/"3MÿEÓÁ$/2!!3##".547!546"!54&2654'#^uþ²ÔSE/ "*þDsv@U(Pæ#//"Á‡j/—þG,2B 2!,Ðl…0UC6%N[ýø#0 1"MÿÔÁ"-A2!!3##"&547!546"!54&2654&"2>54'#"&'^uþ²ÔS ,T=?Q/þksv@U(P¼%&$*2'1EÁ‡j/—þG#?AZW?A&Ðl…0UC6%N[þ X# " %5"! 2+JÿöÁ-474632!!3#".54>32&#"326=4&5!"!4J[j^þ²S6`M@L4bVKF&R%YZ$QOý¨åNC)Ãy…Š•–þB@O: % (*:Q–_>6ÓMþÀÒÁ4=CKT2!!3!5462#"/32654&+#"'#"&54634632"!54&4&"325#32=#"^uþ²ÔSý…s¸0*,!!*8.5)'0784*Z þè@U(P¥%6 "A}j (?Á‡j/—þGÐl…ý®7#$1 # !!CS227(0!6I"UC6%N[ýÞ%3/)1&6t )#=7Mþ¿ØÁ=FMU^2!!3!5462#"/3254+53254+#"'#"&54634632"!54&4&#"325#32=#"^uþ²ÔSý…sÝ #G"*8.6+(/6O4*%3þÞ@U(P¯-! A}j(?Á‡j/—þGÐl…ý® 6!BS226)27G64"UC6%N[ýÞ/(2%9Ngi  CT447(0 9F.% &54'5 %(x5# ?9Mþ.ÉÁIPYb2!!3!546"!54&2#"&54632&#"32654&+#"'#"&546;4632#4&#"26=#'32=#"^uþ²ÔSý…sv@U(Pè,"86Iþ¹×ÁGP[bir2!!3!5462'654&#"32#"&547##"'#"&546;46323>"!54&2654+'4&#"325#32=#"^uþ²ÔSý…s|-B S$=?. 6 A;*$+)8.6+'1994**# $+÷@U(P~1' …% !B~k(?Á‡j/—þGÐl…þ+&7,SG6I5H/(%6&/S!CS228'0!9E0 )8¥UC6%N[ýT<*&‰%27 1'5s3%=6=þ½èÁXalszƒ2!!3!5462#"/3254+57>54&#"32#"&547##"'#"&546;>326"!54&264&+'.#"327#32=#"^uþ²ÔSý…s’>T,04( .% 7' 3#+*"(/8.6,'08:3** #”@U(Pt(" !A~k'?Á‡j/—þGÐl…þ+8+''&- (1*%! .&(1A2AU227(.#9E/!€¥UC6%N[ýT0! $,‰&16!1'5s3&=6Kþ&ÑÁbkry‚2!!3!546"!54&#"&54732654&+532654#"32#"&547##"'"&546;>32>32'#3254'4.#"325#32=#"^uþ²ÔSý…sv@U(PX°€Æ.*¸„l” B2'## '.%*B'./)"I  M.0G!Ï& ™03bV 1Á‡j/—þGÐl…0UC6%N[ýTPo§SM?OiT>&L(%0#)1@3 CQ//6)."8E}?A?2,=N57 "%T1)1p1";5MþºËÁ:2!!3!546"!54&2'654&#"#"&54732=46^uþ²ÔSý…sv@U(PÞ5?bP-";=-8DUD&,9@Á‡j/—þGÐl…0UC6%N[þYN>w-&X1>e*/54'#".547^uþ²ÔS'8I97K8ó‹%1 3&-6"•ý½sv@U(PÑ$.+-! "-$Á‡j/—ý'&E5MK7E&(9$ %06*/Ðl…0UC6%N[üê.[$ % , %5+Mþ¾ÕÁ8AK2!!3!5462'654&#"#"&547&#"&546326"!54&2654'^uþ²ÔSý…sjL_Q$:H7F7,+5C. ?HT<'$!Ê@U(PV'8A"Á‡j/—þGÐl…þ.aFZ0 .H=S/F 'P;O¤UC6%N[ý€&;(-:$MþXØÁPYc2!!3!5464632632#!"3!!"&546;254&+532654#"#"&547&#"&"!54&2654'^uþ²ÔSý…sUN<+!$@ˆ./*0þá''sþ5#)êW L.E7,+5C/:@H!@U(Pa!7B"Á‡j/—þGÐl…ýª9KS#.#73#0;!: 1C09:-@.>/G %}UC6%N[ý„&:(-9$Mþ-ÑÁPZ2!!3!546"!54&2#"&462&#"32654&#"#".547&#"&54>3262654'^uþ²ÔSý…sv@U(P§Paj?MM~6$9QQOaG< F7.$. C2=?H%.! $/#8@*Á‡j/—þGÐl…0UC6%N[þ\wXj‡.0u\Ne.;08*"!)6 '*' 7*"!)5 ?07@/#95÷@U(Pw,-3á-3Á‡j/—þGÐl…þ._F]/ -L?Q>Q7FD6U4 -"¹±(2;R7FC7R7@CT* 0cEW==¢UC6%N[ýW.'I15J#./'I15J$-MþUÉÁgpzƒ2!!3!5462#!"3!!"&5463!2654&#"#"&547&#"#54&#"#"&547&#"&546326326326"!54&2654'2654'^uþ²ÔSý…s.: +þ.6ýʺ#0.65(! '2 $,+ 3) '1 $,29>.6& 1ö@U(PŽ)0þè((0Á‡j/—þGÐl…þ(1<"/9'60$%K80I-I.;8.K'$™“'"-H/::-J'<.M $Y9H12¨UC6%N[ý~!&A%(B%( B$*@MþTÊÁqz„Ž2!!3!5462#!"3!!"&5463!254&#퀆&#"#"&547&#"#54&#"#"&547&#"&546326326326"!54&2654'2654'^uþ²ÔSý…s)B')-#þ#0ýÐ$"ÃE !(3)'1 $+' 2' &0"/17;/5$ 1õ@U(Pˆ'/ÿ(/Á‡j/—þGÐl…þ)'.7&51$$;$,' -I/;9/G*%š”"*-J0::.J)?/L 'W;I32§UC6%N[ý"&B#)@'(!B%*A(MþÛÈÁ)22!!3!5654&#"&546323!546"!54&^uþ²ÔSþ­/$*$/B2!2 Çý¾sv@U(PÁ‡j/—ý) 1#*!+#:1>' #Ðl…0UC6%N[Mþ'ÑÁ6?L2!!3##"&47#5654&#"&546323!546"!54&2654&'#^uþ²ÔS&! /A%¡/$*$/B2!2 Çý¾sv@U(Pè&%Á‡j/—ý)0*@` 1#*!+#:1>' #Ðl…0UC6%N[üÒ$&$$MþÕÁ:COb2!!3##".547#5654&#"&546323!546"!54&2654&#"2654'"&547^uþ²ÔS(5$ %5ž/$*$/B2!2 Çý¾sv@U(PÓ &4)>*1Á‡j/—ý)&?..@% 1#*!+#:1>' #Ðl…0UC6%N[üõ P." ,* &$,MþPÉÁ9B2!!3# 4732>=!5654&#"&546323!546"!54&^uþ²ÔSzVþž>5“©DEþä/$+$.@42?Éý»sv@U(PÁ‡j/—ý5G SL@Gjt &2%*")";2=<0$Ðl…0UC6%N[MþØÁDMZ2!!3#".547# 47326=!5654&#"&5463235!546"!54&2654&+]vþ²ÔS0?25(3 *þ¼ ”ŠQnþä/$ *$.@42?Éý»sv@U(PÓ4"+Á…l/—ýY,DK-*ÿ * !w]&2%*")";2=<0$ÒÐl…0UC6%N[üª# MýéÓÁCLVk2!!3#"&547# 47326=!5654&#"&5463235!546"!54&2654'2>54'"&547^uþ²ÔS:DC02@ þ¼ ”ŠQnþä/$ *$.@42?Éý»sv@U(PÛ&,$'&<& ?Á‡j/—ýY0K/CD.)ÿ * !w]&2%*")";2=<0$ÒÐl…0UC6%N[üÐ & 'Q ," (' $0)Mþ¼ÉÁ7@2!!3!546"!54&2!5654&#"&546323546"354&^uþ²ÔSý…sv@U(PÇ>Kþ4/$ *#.B12AlJJ)2½6Á‡j/—þGÐl…0UC6%N[þ[O@›3%)"+";1=<1$’7G&:+…g;HMþÑÁBKW2!!3!546"!54&2##"&547!5654&#"&546323546"354&2654&#"^uþ²ÔSý…sv@U(PÄ>K)B.0@)þà/$ *#.B12AlJJ)2½6&.$%Á‡j/—þGÐl…0UC6%N[þ[O@›31?@033%)"+";1=<1$’7G&:+…g;Hþx$"&$MýëÙÁGP[p2!!3!546"!54&2##".547!5654&#"&546323546"354&2654'#2>54'#"&547^uþ²ÔSý…sv@U(PÉ=L%3 4" %3þê/$ *#.B12AlJJ)2½6.$", 3&#/Á‡j/—þGÐl…0UC6%N[þ[O@› < $,.< 3%)"+";1=<1$’7G&:+…g;Hþ©  P#!  '"4 '".MþÁËÁ?HQ2!!3!546233#5>54&#"#54&#"632#"&546326"!54&3254&"^uþ²ÔSý…s 4?6”-ü'1 4+g &'&'/SB:*!^@U(Pà($Á‡j/—þGÐl…þ3M@W.þÛF8:2ÕÇ#†05)(0E8Ni65UC6%N[ý¨26!MþØÁKTaj2!!3!546233##".547#5>54&#"#54&#"632#"&546326"!54&2654&#"$3254&"^uþ²ÔSý…s 4?6”-+25(3 +e'1 4+g &'&'/SB:*!^@U(Pí!"þM($Á‡j/—þGÐl…þ3M@W.þÛ5K-*5F8:2ÕÇ#†05)(0E8Ni65UC6%N[ü´$+ #ô26!MýêÓÁR[f|…2!!3!5462363233##".547#5>54&#"#54&#"632#"&546326"!54&2>54#"2654'#"&5473254&"^uþ²ÔSý…s 4?6; 4-*2H3 %2?'1 4+g &'&'/SB:*!^@U(PÒ+/(84'"*)þe($Á‡j/—þGÐl…þ3M@W.þÛ$@4G.@$F8:2ÕÇ#†05)(0E8Ni65UC6%N[üÚ,*W8($ '!34 "%26!MþÆÈÁ+22!!3!5464632!"!54&354&'4#"6^uþ²ÔSý…sè9T‘þâr@U(Pì&¡-/*2,AmÁ‡j/—þGÐl…ýmc]°xËUC6%N[ýó).gM<$6TNMþ ÑÁ!*6=H2!!3!5464632##"&547#"!54&354&'4#"62654'#^uþ²ÔSý…sè9T‘%A/1?%nr@U(Pì&¡-/*2,Am.&11%Á‡j/—þGÐl…ýmc]°x0/AA/1ËUC6%N[ýó).gM<$6TNç$2 2$MýëÏÁ$-9@L`b2!!3!5464632##".547#"!54&354&'4#"62654&#"2654'#"&5477#^uþ²ÔSý…sè9T‘*3H3 %3cr@U(Pì&¡-/*2,Am%535/' Á‡j/—þGÐl…ýmc]°x">4G.>"ËUC6%N[ýó).gM<$6TNÀ P." '"#& '".§MþÁÖÀ 7AJ2!!3!54#"&=4&#"#"&5463232>54'"!542654'~_þ²ÔSý…)*C4/>,#N5&+6^G:D= QþÌ)<(`(E%Àˆ—þGÍóþ/ ,1"@RA60.>?V.;I8NaH:+Z /!a"º136ÑýV#&C6%NOMþÛÀ >HV_2!!3!54"&547&=4&#"#"&5463232>54'"!542654&'+'2654'~_þ²ÔSý…)*38B\B,5,#N5&+6^G:D= QþÌ)<(¢# .%ç(E%À‡Ž —þGÍóþ/ ,1"S'B1??17" G0.>?V.;I8NaH:+Z /!a"º136Ñü®-& 0$¨#&C6%NOMýëÖÀ EO\ey2!!3!54#".547&=4&#"#"&5463232>54'"!542654'#"''2654'2654'#"&547~_þ²ÔSý…)*??$ %D1,#N5&+6^G:D= QþÌ)<(„ !×(E%%53&#/À‡Ž —þGÍóþ/ ,1"]%$G..K"!D0.>?V.;I8NaH:+Z /!a"º136ÑüÙ   !}#&C6%NOÍ." '"4 '".LÿBÓÁ,8233##".547#5654&#".5462654&#")\{SÌSB2"1 ÈkZBFT+ )7z™ +##ÁyÊ\—þG,/E)" +NcL_bJ'51!AD/d†ýÅ+ "#LÿÔÁ*4H233##"&547#5654&#".5462654&"2>54'#"&')\{SÌS%-T=?Q/ kZBFT+ )7zX.%&C*2'1EÁyÊ\—þG"AAZW?B&NcL_bJ'51!AD/d†ýÙv# " %5"! 2+HÿÌÀ9233#"5432&#"32>5!5>54.#".546*^rQÐS 1V9ÖÖG912-< þÅ09/0HV>$$,{Àp_uX–þG 9@.KJ%&'6?."i:*>bKEW 5P.f†Iÿ/cÁ2233#"$5473265!5>54.#".546ÈaqQÌNµ‡ÎþðXHñ·jþÊ19?+CZA#(7€Ás^tX–þC^pæ¿€m_q¤ÈPB$j700]NFZ@C0jIþ›lÁ<I233"&547#"$5473265!5>54.#".5462654&#"ÈaqQÌN?HCbC04ÎþðXHñ·jþÊ19?+CZA#(7€!" Ás^tX–þCM5O1CD0 æ¿€m_q¤ÈPB$j700]NFZ@C0jý$#+IþOmÁ=J\233#"&547#"$5473265!5>54.#".5462654&#2654'#"&'ÈaqQÌNV`U<>RÎþðXHñ·jþÊ19?+CZA#(7€e# $,65$#/EÁs^tX–þC[8eDWV@+"æ¿€m_q¤ÈPB$j700]NFZ@C0jý&X9)" '3) 2+LþÁÖÁIR233!5654&#".546#"&=4&#"#"&5463232>54'2654')\{SÌSþvkZBFT+ )7z°*C4/>,#N5&+6^G:D= Qý(E%ÁyÊ\—þGNcL_bJ'51!AD/d†þ. ,1"@RA60.>?V.;I8NaH:+Z /!a"ð#&C6%NOLþÛÁP^g233!5654&#".546"&547&=4&#"#"&5463232>54'2654&'+'2654')\{SÌSþvkZBFT+ )7z°*38B\B,5,#N5&+6^G:D= Q# .%ç(E%ÁyÊ\—þGNcL_bJ'51!AD/d†þ. ,1"S'B1??17" G0.>?V.;I8NaH:+Z /!a"þh-& 0$¨#&C6%NOLýëÙÁVcx233!5654&#".546#".547&=4&#"#"&5463232>54'2654'#"'2>54'#"&547'2654')\{SÌSþvkZBFT+ )7z°*=@ 4" %B2,#N5&+6^G:D= Q ", 3&#/Å(E%ÁyÊ\—þGNcL_bJ'51!AD/d†þ. ,1"[&#I $,.J"!E0.>?V.;I8NaH:+Z /!a"þ“   P#!  '"4 '".Í#&C6%NOLÿ9ÌÁ&.233!5>7#5654&#".5465#)\{SÌSþ>9[8»kZBFT+ )7z´J%#ÁyÊ\—ý€ /9.NcL_bJ'51!AD/d†ýž¡(:Lþ}ÓÁ5=J233##".547#5>7#5654&#".5465#2654&'#)\{SÌS*" "1 þ9[8»kZBFT+ )7z´J%#®#"ÁyÊ\—ý€+"2 )" + /9.NcL_bJ'51!AD/d†ýž¡(:ž###"Lþ<×Á08CW233##"&47#5>7#5654&#".5465#2654&"2>54'#"&')\{SÌS(T=AO+×9[8»kZBFT+ )7z´J%#‡%&$*3&3EÁyÊ\—ý€&32632#!"3!!"&5463!2654&'#"&5467&#"#"&54>732652654'[$;>"sJ]=?ZDý‰" üí.?<-9>SL6PA;OPM-H8C[HRb >+'5!/' $:%,8S17Q)\FE_]zI6(*:lMF` 7kA\KIOe~_7HC:@,2J!BJ‡D7G; G:1@IÿÉÃ]g3!!"&5463!2654#5254&##"&54>7&#"#"&54>732654>32632#!"3254'|#üë,=15ƒ#/WXV>"U?:L 2++A.:[HQc =,&5 9'0.(O6gKA W:ý€"¡5)I AF†K9)G-%N(K.?7@_|\E+K1 6:F'IOe~_8H@9@.2>*Uz"@=$KTDA# /%:21D}M>OMÿÔÀUb%#".54>32&#"32654.'#"&5467&#"#"&54>732654>326322654'ÔÞ¦AN53L@dD8D=QK7‚°<(N>8JHF!L<9ZIQc =,&5!/' 0.(O7oF g}þ—$,)8*sÄ!"$¦„#;.'03]~]H?oBg‰Nf~_8H@8A-2I"Uz"><$Y‡®K>A8)5"-=Jÿö^ÃEP233!532654&#"#"&547&#"#"&54>7326=4>3262654'×I\còSý¤“FUC6@@0*6H+.5TEUg =,&5I;#7+6'22)B.4D¾wXˆE™þD#kXLc7d>SS>YAXJSSd`7JB8@+Ld:DN.J) þÏ15U00U*-JÿCfÃO_j233#"&547!532654&#"#"&547&#"#"&54>7326=4>3262654.+"2654'×I\còSCbCþf“FUC6@@0*6H+.5TEUg =,&5I;#7+6'22)Z"*þ{.4D¾wXˆE™þD-1CD0+#kXLc7d>SS>YAXJSSd`7JB8@+Ld:DN.J) ýÉ#  15U00U*-JÿgÃP[mx233##"&547!532654&#"#"&547&#"#"&54>7326=4>3262654&"2654'#"&'2654'×I\còS$-U<@P/þ“FUC6@@0*6H+.5TEUg =,&5I;#7+6'22)0%&$+72'#/Eþœ.4D¾wXˆE™þD#@DWW?B&#kXLc7d>SS>YAXJSSd`7JB8@+Ld:DN.J) ýÛX:($ $6) 2+L15U00U*-IÿÃ_i%!3#".54>32&#"3265!53>54&#"#"&547&#"#"'&546732674>76326322654'8+S~š@K46N=PJ ]4JI5lUý¨÷.9L?@@0+5H. *YDR63R>w 9'3%0V?%)?RgþÆ$4D õ;x–þGov  %b\#h9Ng7d9OM;YA$HO8LhE?TG…&V|/:'RU+,?6t¶6'U00U'6Jÿö…Ã[fq%4632#"&547&#"532654&#"#"&547&#"#"&54>7326=4>326323&2654&'%2654'ÂudaFCPB8Jo#Od_ý´“FUC6@@0*6H+.5TEUg =,&5I;#7+6'22)?I\cå<'1%f0ý.4Dßf{QL`XtWG„ZpTy:#kXLc7d>SS>YAXJSSd`7JB8@+Ld:DN.J) wXˆETB@F>TTc2@Y15U00U*-JÿhÆ‘œ3!!".54>3!2>54.'#"&54>7&#"532654&#"#"&547&#"#"&54>7326=4>32632!&547632632#!"%2654'%2654':ûü+--+Ü>V);'&O;=P1#%-4L#_ý–“FUC6@@0*6H+.5TEUg =,&5I;#7+6'22)?I\c<@?Z\Cf€ý*¯)#&SS>YAXJSSd`7JB8@+Ld:DN.J) wXˆETi[CCC€i~`|R2S:X42AX15U00U*-JÿGÓ¨2#!"3!!"&54>3!2654&+532654&+#"&54>7&#"!532654&#"#"&547&#"#"&54>7326=4>326323&54>3263254'2654'l]z@DM9ü«Ôü%/ ) `&#% (Q: 'Q@9L1(%4*C&_ý´“FUC6@@0*6H+.5TEUg =,&5I;#7+6'22)?I\cå< -R3_D¹-&M"A=ý½.4D|YC<"`.8$I?. $&*!<*./@BMUs`F*H0 %"/:*y:#kXLc7d>SS>YAXJSSd`7JB8@+Ld:DN.J) wXˆETi1B7&HÓ2CˆJ:QK15U00U*-JÿÇ”Ÿ%4632#".54>32&#"32>54.'#".54>7&#"!532654&#"#"&547&#"#"&54>7326=4>326323&2654'%2654'¿fxB>T!­‚ _f4K@SM99+"\f'7V4" 1&RC %/ E3&HK547,ý¶“FUC6@@0*6H+.5TEUg =,&5I;#7+6'22)?I\cä>%#0#2 ,ý’.4DÕh…r Q^3޶ %)>TO(=I 9Zy D/+>09:8O7k #kXLc7d>SS>YAXJSSd`7JB8@+Ld:DN.J) wXˆEXDM:82 4$(JW15U00U*-MþºÃ-R\2#"&547&#"#"&54>7326=462'654&#"#54&#"&546326'3254&'iPA8Px(*4G[HRb >+'5!/' $:iÆ6H'$?(. 9"(1KUJ;7&$7?MlÔtVnWG„`"`GIOe~_7HC:@,2J!BJCZiþ'WB,F *Z+Fѵ 'A0\#.hAZ10¼:8{(lWMþ»Ã-Q[e2#"&547&#"#"&54>7326=462#"&547&#"#54#"&546326'3254&'2654'iPA8Px(*4G[HRb >+'5!/' $:i¦CZ5,*7D+97'4MYK74'-?Ml}6B#ÔtVnWG„`"`GIOe~_7HC:@,2J!BJCZiþ'iJ7EC7R6 ѵHC3Z!-hCX0/¼:8{(lWýÛ)"O.4E"-MþX"Ã-hr}2#"&547&#"#"&54>7326=464>32632#"'7327654'#"&5467&#"#54#"&3254&'2654'iPA8Px(*4G[HRb >+'5!/' $:iÞ /&5&,;R0<9bH'% <)$; 6+&2>+>",98  NZ9?Ml?"#'ÔtVnWG„`"`GIOe~_7HC:@,2J!BJCZiý.B 0.KT2Kf 50=P&7326=464632!3254&'354&'4#"6iPA8Px(*4G[HRb >+'5!/' $:i'9T‘þâ4?Ml‰&¡..*2,AmÔtVnWG„`"`GIOe~_7HC:@,2J!BJCZiýkc]°xà:8{(lWþy*-gN;$6TNMþ Ã->HT[g2#"&547&#"#"&54>7326=464632##"&47#3254&'354&'4#"62654&#"iPA8Px(*4G[HRb >+'5!/' $:i'9T‘$C-/A#k4?Ml‰&¡..*2,Am-&-"$ÔtVnWG„`"`GIOe~_7HC:@,2J!BJCZiýkc]°x`@A^à:8{(lWþy*-gN;$6TNé$"-&MýëÃ-BL]do„†2#"&547&#"#"&54>7326=464632##"&547#3254&'3632354&'4#"62654&#"2654'#"&5477#iPA8Px(*4G[HRb >+'5!/' $:i'9T‘#/-# 4H/b4?Ml‰&N  ...*2,Am&4350& ÔtVnWG„`"`GIOe~_7HC:@,2J!BJCZiýkc]°x&:$5 G4:&à:8{(lWþy*-gN;$6TNÀP-# '"#& '!/§Mþ,Ã-7Ydm2#"&547&#"#"&54>7326=463254&'4>32#".54632&#"326=#7354&#'"654&iPA8Px(*4G[HRb >+'5!/' $:i[?Ml7,-’CV37H7C;7N<(ó¼$%&¦+8,_(t ÔtVnWG„`"`GIOe~_7HC:@,2J!BJCZiþã:8{(lWþG1D ±€KL5;¾@&"bHJ!5?tS[!Hÿ11ÂLY4>32#".547327654'#"&5467&#"#"&54>732652654'ò&B+–HR0-ý͘÷e!Z‚Ú†Ävfa NA7Jh>$aC4YFOh :*$2 -&':)$&0 "ÿ07'p >;P‘ºgÀz{tcok¥WbTon&*3_t`DHdIieQc|d4FB6>/0I#R]¬T3G) 7%,GHþÍ1ÂWdq4>32"&547#".547327654'#"&5467&#"#"&54>732652654'2654&#"ò&B+–HR0-W**CbCb˜÷e!Z‚Ú†Ävfa NA7Jh>$aC4YFOh :*$2 -&':)$&0 "Ö+* #ÿ07'p >;PrY @$1CC1 %gÀz{tcok¥WbTon&*3_t`DHdIieQc|d4FB6>/0I#R]¬T3G) 7%,GþÜ 4"Hþr1ÂZgt†4>32#"&547#".547327654'#"&5467&#"#"&54>732652654'2654&#"2654'#"&'ò&B+–HR0-{-S>?Q Oa˜÷e!Z‚Ú†Ävfa NA7Jh>$aC4YFOh :*$2 -&':)$&0 "¨%$+73&1 Eÿ07'p >;PŒ^ 6%CXW?!gÀz{tcok¥WbTon&*3_t`DHdIieQc|d4FB6>/0I#R]¬T3G) 7%,GþÕX:(  &4"! 2+MþÁÃ-U_h2#"&547&#"#"&54>7326=46#"&=4&#"#"&5463232654/3254&'2654'iPA8Px(*4G[HRb >+'5!/' $:iä*C4/>-"N5&+6_F:D=>Qy?Ml„)E%ÔtVnWG„`"`GIOe~_7HC:@,2J!BJCZiþ, ,1"AQA60-??V.;I8MbH:+Z69a"Ê:8{(lWýá$%C6'LOMþÃ-]gs|2#"&547&#"#"&54>7326=46#"&547&=4&#"#"&5463232654/3254&'2654&#"'2654'iPA8Px(*4G[HRb >+'5!/' $:iä*;9B./A46-"N5&+6_F:D=>Qy?Mlw$!$%à)E%ÔtVnWG„`"`GIOe~_7HC:@,2J!BJCZiþ, ,1"Z&B1??1=! H0-??V.;I8MbH:+Z69a"Ê:8{(lWý3&.&$®$%C6'LOMýëÃ-_iwŒ•2#"&547&#"#"&54>7326=46#"&547&=4&#"#"&5463232654/3254&'2654'#"'2654'#"&547'2654'iPA8Px(*4G[HRb >+'5!/' $:iä*9F-# 4H=7-"N5&+6_F:D=>Qy?Mlm &4350Ð)E%ÔtVnWG„`"`GIOe~_7HC:@,2J!BJCZiþ, ,1"X'!M$5 G4G"J0-??V.;I8MbH:+Z69a"Ê:8{(lWýd   P-# '"#& '!/Í$%C6'LOMþºÃ-R\e2#"&547&#"#"&54>7326=462#"&547&#"#"&54732=46'3254&'3254'iPA8Px(*4G[HRb >+'5!/' $:i¢Da5-'6L7?.6CbQ;9G?MlN&.!BÔtVnWG„`"`GIOe~_7HC:@,2J!BJCZiþ'`N8J:0U=25/7APBr+"^92V+;G¼:8{(lWþ$$"KH&6MþcÃ-q{†2#"&547&#"#"&54>7326=464632#!"3!!"5463!2654'#"&5467&#"#"&54>732653254&'3254'"iPA8Px(*4G[HRb >+'5!/' $:iC4O0+?5*þ£$$·þIF)5+57 *0".=')!,>.0:%# +(!"q?Ml 0 #%ÔtVnWG„`"`GIOe~_7HC:@,2J!BJCZiýÆ-7<C61@*7'=+A,G1(+8'5+"+:D:(= <)*4(!J:8{(lWþF"J# $MþÃ-7‰’2#"&547&#"#"&54>7326=463254&'#!"3!!".5463!2654#5254&##".54>7&#"#"&54673265462632%3254'iPA8Px(*4G[HRb >+'5!/' $:i[?MlÀ`þY'  ý÷" 0¨9:7+9)", # ,%,;06A)5P +!:ˆ27326=463254&'#"&54>32&#"32654.'#"&5467&#"#"&5467326546326322654'iPA8Px(*4G[HRb >+'5!/' $:i[?Mlê“m*g#5(B-'*_VYq, 3*&/7&2(%L3H/ ERï)*ÔtVnWG„`"`GIOe~_7HC:@,2J!BJCZiþã:8{(lWþg‚ rS"/!! =S?.3B,EY5BQA'^#b=58QD;;Zr7#-#9#)Mþ7Ã-7s|2#"&547&#"#"&54>7326=463254&'32=432#"&54732654'#"&5467&#"#"&547%3254iPA8Px(*4G[HRb >+'5!/' $:i[?MlþÛ<@uc0/D©…šÌB;±Œz™@4*%0F'BN:/7BY,!v/)03ÔtVnWG„`"`GIOe~_7HC:@,2J!BJCZiþã:8{(lWþH;7s€JI7326=46#".547#"&54732654'#"&5467&#"#"&54732=4323254&'32542654&#"iPA8Px(*4G[HRb >+'5!/' $:i#(7* #1:‘À>8¬s=1(".A&T$ 97326=46#".547#"&54732654'#"&5467&#"#"&547325'4323254&'32542654&#"#2>54'#".547iPA8Px(*4G[HRb >+'5!/' $:i'*@. / #¬82šrf‚7+$)8$6B3&-8JA37dS(+ì?Mlj5)+ *.  %#ÔtVnWG„`"`GIOe~_7HC:@,2J!BJCZiüø :!,=& {cA> 5;UjZB:3>3%(3'n,4A6Z"N0-^h<( M¹:8{(lWþ$"=H'þØ $J# ! ' KÿE¥À;AKV%>73##".547!5654&#"&5463235".54>3273"542654'#“S‡E/"1 þ.H8.1A4D`MJc%À/9( 6&B2·e5·þ¿' ñ#//"ד7þG,2B)" ,-O.:B4B$5WK[ZJ9)?* #+RT# _%O –g*<. w>þ#0 1"Kÿ£À9?ITh%>73##"&547!5654&#"&5463235".54>3273"542654&"2>54'#"&'“S‡#-T=?Q0þWH8.1A4D`MJc%À/9( 6&B2·e5·þ¿' Ä%&$*2'1 /ד7þG"@AZW?A&-O.:B4B$5WK[ZJ9)?* #+RT# _%O –g*<. w>þX# " %5"! AMÿ¤ÃLR]%>73#".54>32&#"326='!5654&#"&5463235".54>3273"54“=¥0\H@L4bVJ</C#\G8LKý±H8-2A4BaNK]$À/9(.% B2Æu7Æþ°' Ù‡Jþ1@4 % %193ESEU]F:)?*#4 WU K"Q –f). w>KþÀ¤À.TZdjr{%>73!5654&#"&5463235".54>322#"/32654&+#"'#"&546346323"544&"325#32=#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2·0*+"!*8.4)'0784*Z *e5·þ¿' °%6 "A}j (?ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# þ–7#"3 # !!CS227(0!6IÉ%O –g*<. w>ýæ%3/)1&6t )#=7Kþ¿ À.]cmt{„%>73!5654&#"&5463235".54>322#"/3254+53254+#"'#"&546346323"544&#"325#32=#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2Ò #G"*8.5*(/8M3+%3*e5·þ¿' °-  A}k (?ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# þ– 6!CR226)26H55É%O –g*<. w>ýæ/(/(8v}…Ž%>73!5654&#"&5463235".54>3273"54232#!"3!!"&5463!254+53254+#"'#"&54;464&#"325#32=#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2·e5·þ¿' y.9;A#$<þ³ ‰þw#$)4# +8.5*%1l3c%""Ck*Aד7þG-O.:B4B$5WK[ZJ9)?* #+RT# _%O –g*<. w>þh=00+5 /%'$5B,,,#C0;k -0+ ,a 5,Kþ.¥À.`fpw€‰%>73!5654&#"&5463235".54>322#"&5462&#"32654&+#"'#".546;46323"54.#"26=#'32=#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2ª,ýå)/0(Œ5, '1>#86Kþ¹¥À.gmw„‹’›%>73!5654&#"&5463235".54>322'654&#"32#"&547##"'#"&546;46323>3"542654+'.#"327#32=#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2w-B S$=?. 6 A;*$+)8.6+'1994**# $+Oe5·þ¿' … 1'  " !A~k(?ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# í&7,SG6I5H/(%6&/S!CS228'0!9E0 )8L%O –g*<. w>ý\<#‰&17 1(4s3$=6Kþ½¥À.y‰•œ£¬%>73!5654&#"&5463235".54>322#"/3254+57>54&#"32#"&5465##"'#"&546;463263"542654&+'4&#"325#32=#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2|+> ,04( .% - !43#+0(/8.6+'08:4+* #Ãe5·þ¿' j($ !B~k'?ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# í$ &'&- (1*%#.&/*A2CS227(.#6H/!€L%O –g*<. w>ý\" $,‰$36!1(4s3%=6Kþ`™À.4>ˆ“š£¬%>73!5654&#"&5463235".54>3273"542#!"3!!"&5463!254&+532654&#"32"&57##"'#"&54;46323>2654&+'4&#"325#32=#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2·e5·þ¿' Ñ:M43eþ ##Yý§%%ÊZ  28I +3->07/5*%1n3*Z  \.#\&"#Ck *Aד7þG-O.:B4B$5WK[ZJ9)?* #+RT# _%O –g*<. w>þk1(&2Q/$$:"6 %#*,49F,,+$D.=k/>áDt ,/)!.d5/Kþ*¦À.qwŒ“š¤%>73!5654&#"&5463235".54>322#"&54632&#"32654&#"2#".547##"'#"&546;>323>3"542654+'.#"327#32=#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2tC\€j'gQ=66.$R6RbC5II9%)$8.6+'08<3*Y# Cye5·þ¿' ‚ 0(z" !@~k'?ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# ïsXkŠ q[MbW$6!5)# DS227(0!:E5KN%O –g*<. w>ýX= 8‰'15#1(4t3 =7KþG¡À.\blrzƒ%>73!5654&#"&5463235".54>322#"&54732>54&+#"'#"&54;46323"544&"325#32=#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2´'3rƒ«:.VL`?Z/8.6+&1Z+4+Z -e5·þ¿' ¬$8 !A|k'?ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# þ”5,YljfFJN\;435%DS227)P6IË%O –g*<. w>ýä&20(1(4t%&=7Kýî£À.ioy‡˜¢%>73!5654&#"&5463235".54>322"&547#"&54732>54&+#"'#"&54;46323"544&"325#2>54&+32=#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2´'3FH?b? ¯:.,>L89<- 8.5*&1Z+4+Z -e5·þ¿' ¬%6!!A|Ä - %þì'?ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# þ¤/'K0D(:9)}_Z>@F*C%3!;I,,.&G0?o»%O –g*<. w>ýô"++",#.f þÇ   60 Kýï¡À.lr|ƒ‹›¥¹%>73!5654&#"&5463235".54>322#".547#"&54732>54&+#"'#"&54;46323"544&#"325#2654&#'32=#"2654'#".547“S‡ýpH8.1A4D`MJc%À/9( 6&B2¸&0X(/ 1!"1  |¤8,WHV%CB'5,1("1V)1(U 'e5·þ¿' µ"!>v   ú&<æH2 %" ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# þ¬,$Q/8! %$ %vWR;8DO0' 7&8D))+#C-;h³%O –g*<. w>ýü*,)!*_ þ÷ ê2-þª& *   Kþ¾¥À.OU_%>73!5654&#"&5463235".54>324632&#";2#"'73254+"&3"54“S‡ýpH8.1A4D`MJc%À/9( 6&B2:DT0$C#6-?70N1V,$MS>@'0§e5·þ¿' ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# þ²&;0%&05./&5(-Ñ%O –g*<. w>Kþ¥À.X^ht%>73!5654&#"&5463235".54>324632&#";2#"&547&'73254+"&3"542654&#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2:DT0$C#6-?7098B./A,1$MS>@'0§e5·þ¿' ó&.$%ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# þ²&;0%&0=>1??16 &5(-Ñ%O –g*<. w>üµ$"&$Kýë¦À.^dn{%>73!5654&#"&5463235".54>322#".547&'73254+"&54632&#"33"542654'#"'2654'#"&547“S‡ýpH8.1A4D`MJc%À/9( 6&B2ª70;=$ %7-$MS>@'0:DT0$C#6-Le5·þ¿' Ý  %533/ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# þ•0>"C..@!&5(-$&;0%&Ê%O –g*<. w>üæ P." '"#& '".Kþ9§À.4>m%>73!5654&#"&5463235".54>3273"544>32&#"#"&54632&#"32654/.“S‡ýpH8.1A4D`MJc%À/9( 6&B2·e5·þ¿' *8C%a:.Yl:K=H>K*9Q:?C/#0//#?6LS %ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# _%O –g*<. w>ýñ,95)I;CjD$+! ='I/Kþ£À.4>l%>73!5654&#"&5463235".54>3273"542#"&54632&#"32654+"&54632&#";2'654#"#465654#"&54632“S‡ýpH8.1A4D`MJc%À/9( 6&B2·e5·þ¿' ÆEX‡f=KQ9K+G(7:,LbnT0CL[t;1fu@ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# _%O –g*<. w>ýÏH;Xl+#!-)% UEe7(*?,'G7Ø     Kþ¼¢À.Y_i%>73!5654&#"&5463235".54>322#".54732654+"54632&#"33"54“S‡ýpH8.1A4D`MJc%À/9( 6&B2£0<19?_.8,65M)6?zK-.#N.:0%#!Í%O –g*<. w>Kþ¢À.`fp{%>73!5654&#"&5463235".54>322".547.54732654+"54632&#"33"542654'#“S‡ýpH8.1A4D`MJc%À/9( 6&B2£0<0.-* +-Ua8,65M)6?zK-.#N.:0%#!Í%O –g*<. w>ü¿$0  +Kýê¥À.cis—%>73!5654&#"&5463235".54>322#"&547.547;63654+"54632&#"33"542654'+2>54'#"&547#“S‡ýpH8.1A4D`MJc%À/9( 6&B2˜0<.<-$ 4G)O[8,65M =?zK-. (#N.:0%#!Í%O –g*<. w>üâ   +V*&$ '!4.)Kþ†™À.4>JW%>73!5654&#"&5463235".54>3273"542#"&5462>54&#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2·e5·þ¿' yNgiHKa]? &. K75MLד7þG-O.:B4B$5WK[ZJ9)?* #+RT# _%O –g*<. w>þ^cOMbbHOhþÊ 8%8MHpOKþ§À.HNXkw%>73!5654&#"&5463235".54>322#"&547#"&5463233"542>54.#"2654&#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2±3025,<Hd]KNg e5·þ¿' Y0 8&5M 8Â#+#"ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# ýùIK<+_KOhbP6-f%O –g*<. w>ý( & &0!I7'1!v# #"Kýí¡À.IOYcpŠ%>73!5654&#"&5463235".54>322#"&547#"&546323"542654#"'2>54&#"2>54'#".5“S‡ýpH8.1A4D`MJc%À/9( 6&B2Œ&. K79IIc]KNg:e5·þ¿' Ò$.¢&7 K75MLñ+ && $ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# þ 8%6LM5 `JOhcO#!G%O –g*<. w>üì.(< .&8MHpO—$ % !!  +Kþ¶£À.gmw%>73!5654&#"&5463235".54>322'654&#"#54&#"#54&#"632#"&54>3263263"542654#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2“ %-ZB,%7% 67d '*)#'/24@6BYe5·þ¿' Í +ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# ç C.q,,_9BÚ½!-ÜÍ!‡08*'3H84M)4301F%O –g*<. w>ýW:8Kþº¦À.jpz„%>73!5654&#"&5463235".54>322#"&547&#"#54&#"#54&"632#"&54>3263263"542654'%3254&#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2‡ý]%)R18J#,5%6KþW¯À.|‚Œ—¡%>73!5654&#"&5463235".54>324>32632632#"'732>54'#"&467&#"#54&#"#54&"632#"&3"543254'3254#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2þk"2)7(53"6H41T=$  %-53 ,.--#2(2(>,"')%-Le5·þ¿' › ,  þB&%ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# þ^6N$4301M Z5Lf B,K%F>8XM+%Õ¹(#×É" 2"/:),(D9%O –g*<. w>ý¡%U, +1'56KþÙšÀKQ[%>733!5654&#"&546323!5654&#"&5463235".54>3273"54“S‡þ«/$*$/B2!2 ÇýªH8.1A4D`MJc%À/9( 6&B2·e5·þ¿' ד7þJþÝ 1#*!+$91>' "-O.:B4B$5WK[ZJ9)?* #+RT# _%O –g*<. w>Kþ#£ÀY_iv%>733##"&547#5654&#"&546323!5654&#"&5463235".54>3273"542>54&#"“S‡(! /A'¥/$*$/B2!2 ÇýªH8.1A4D`MJc%À/9( 6&B2·e5·þ¿' ó .$%ד7þJþÝ1*A/2 1#*!+$91>' "-O.:B4B$5WK[ZJ9)?* #+RT# _%O –g*<. w>üÖ "&$Kþ¡À[akvŠ%>733#".547#5654&#"&546323!5654&#"&5463235".54>3273"542654'#2654'#"&547“S‡*1$%1–/$*$/B2!2 ÇýªH8.1A4D`MJc%À/9( 6&B2·e5·þ¿' Ø  &4) )1ד7þJþÝ%:..;$ 1#*!+$91>' "-O.:B4B$5WK[ZJ9)?* #+RT# _%O –g*<. w>ý ! !P." ,+ &$,KþM™À\bl%>73#"&54632&#"325!5654&#"&546323!5654&#"&5463235".54>3273"54“S‡š;VV43*+LQeþá/$*$/B2"1 Ìý¦H8.1A4D`MJc%À/9( 6&B2·e5·þ¿' ד7ý Œz4'*"+#:3<' $-O.:B4B$5WK[ZJ9)?* #+RT# _%O –g*<. w>KþR™ÀY_i%>73# 4732>=!5654&#"&546323!5654&#"&5463235".54>3273"54“S‡zVþž>5“©DEþä/)+$.@42?Éý§H8.1A4D`MJc%À/9( 6&B2·e5·þ¿' ד7ý5G SL@Gjt &2$*")";2=<0$-O.:B4B$5WK[ZJ9)?* #+RT# _%O –g*<. w>Kýí£À.flvƒ%>73!5654&#"&5463235".54>322353#"&547#"&547326=!5654&#"&5463"542>4.#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2V2?É77BA/0@Œ¼>5Ÿ~Qoþä/$ *$.C>e5·þ¿' ó  %%ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# þã7. Óî/C,<<,!s`LG>?M^)!.")'!6/8|%O –g*<. w>ü›."!Kýë¤À.kq{‡›%>73!5654&#"&5463235".54>32#".547#"&547326=!5654&#"&546323533"542654&#"2654'#"&547“S‡ýpH8.1A4D`MJc%À/9( 6&B2½7-# %-‚¥70ŽsIdÿ+"&*;-.9µ1Ne5·þ¿' Û%535/ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# þ :0$5 .:$cRB=47BQ#(!!/(1/'µÌ2B%O –g*<. w>üæ P." '"#& '".Kþ¼™À.NT^g%>73!5654&#"&5463235".54>322!5654&#"&5463235463"54"354&“S‡ýpH8.1A4D`MJc%À/9( 6&B2{>Kþ4/$ *#.B12AlHxe5·þ¿' Þ)2½6ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# íO@›3%)"+";1=<1$’6HL%O –g*<. w>þ=:+…g;HKþ¤À.Z`js€%>73!5654&#"&5463235".54>322##"&547!5654&#"&5463235463"54"354&2654&#"“S‡ýpH8.1A4D`MJc%À/9( 6&B2{>K#-*,<#þÓ/$ *#.B12AlHxe5·þ¿' Þ)2½6!"ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# íO@›/'3 <+03%)"+";1=<1$’6HL%O –g*<. w>þ=:+…g;Hþ$+ #Kýí¡À.[akt~‘%>73!5654&#"&5463235".54>322##"&547!5654&#"&5463235463"54"354&2654#"2654'"&547“S‡ýpH8.1A4D`MJc%À/9( 6&B2{>K,6 8%7J6þ÷/$ *#.B12AlHxe5·þ¿' Þ)2½68-2*:%P%,8ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# íO@›"= #*E1="3%)"+";1=<1$’6HL%O –g*<. w>þ=:+…g;Hþ¢ ))R5&  211&5KþÆšÀ.6<FRY%>73!5654&#"&5463235".54>324632!3"54354&'4#"6“S‡ýpH8.1A4D`MJc%À/9( 6&B29T‘þâÎe5·þ¿' ù&¡-/*2,Amד7þG-O.:B4B$5WK[ZJ9)?* #+RT# þUc]°xr%O –g*<. w>ýû).gM<$6TNKþ À.BHR^eq%>73!5654&#"&5463235".54>324632#".547#3"54354&'4#"62654&#"“S‡ýpH8.1A4D`MJc%À/9( 6&B29T‘!'-* +-'|Îe5·þ¿' ù&¡-/*2,Am 6!ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# þUc]°x 1'3 2'1 r%O –g*<. w>ýû).gM<$6TNê$+  Kýé£À.DJT`gq„†%>73!5654&#"&5463235".54>324632#".547#3"54354&'4#"62654#"2654'"&5477#“S‡ýpH8.1A4D`MJc%À/9( 6&B29T‘(1 6J5 1]Îe5·þ¿' ù&¡-/*2,Am-1*74,5+78 ד7þG-O.:B4B$5WK[ZJ9)?* #+RT# þUc]°x&< #-,$ =%r%O –g*<. w>ýû).gM<$6TNÅ +*V8'! '!!'2'8ËTÿ;Ã@FQ%>73# $54673265!5654&#"&5463235".54>3273"54&9§©zŠþÿþÇ-0*$å›Ôý¬G:+1A3B`NK]$Á09(.% uÊt7Êþ«' Ù„Nþ5p<+ñÎAhA1:2ESEU]F9*?*#4 ®(P#P –f). w>TþšGÃOU`m#".547# $54673265!5654&#"&5463235".54>32>733"542654&#"þ0 2"#3 hmþÿþÇ-0*$å›Ôý¬G:+1A3B`NK]$Á09(.% u9§Kt7Êþ«' þ"##ƒ 8+ #*+" ñÎAhA1:2ESEU]F9*?*#4 ®(„Nþ5BŒ#P –f). w>ýV#!" TþCCÃJP[i~"&547# $54673265!5654&#"&5463235".54>32>733"542654.'"2654&'#".=Ø38U|TXSþÿþÇ-0*$å›Ôý¬G:+1A3B`NK]$Á09(.% u9§Kt7Êþ«' Î,P:-8'#!+ œQ/=VU>0&ñÎAhA1:2ESEU]F9*?*#4 ®(„Nþ5Tž#P –f). w>ýV[8*%36& "  +LÿE×ÃDQ#".547.=4&#"#4&#"&5463263232654.'2654&#H9S>AE/ "*8ND-)+S8"3',2%‚nOU91TDd<05A 4&6+* #À~fn;J2B 2!$ WGKWK )þÂ<5,1J,?;E°_yKI`KU>P_I0?7ýà "LþüÖÃ?L_#"&547.=4&#"#4&#"&5463263232654.'2654&'"#2>54'#"&'H=OQSS>=S50=D-)+S8"3',s‚nOU91TDd<05A 4& .&C&0 3&1 EÀ|d9]CXUAH'T=KWK )þÂ<5,1JˆFE°_yKI`KU>P_I0?7ýë $v+'  %5 # 2+IÿÝÃT%2654'7#"&54632&#"3265#"&'&'&#"#4&#".546326329Ig†-G}R[}|_^>0@(cu‘L+CR P+5S3# )# 2$*: pRQ;2RIb52gLiTbí.UbH/)"!-!Žt%+jWP6]yC' O;?X(;2|™0RI`q3/S0*'9 s‚lQU91TJ^l6@y0L&3N‚&&%  #þÈ 3#7FB '/#$¼‹?bK'Æ:þÂ3>)<1™5E°Z~KIcD%¹]K˜6t’F7jrT7­' , ;% &LþÀÖÃ8^dlv#"&=4&#"#4&#"&5463263232654.'2#"/32654&+#"'#"&5463>32#4&"325#32=#"H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&O0*+"!*8.5+'0782*X0%6""A}j(?ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ýÆ7#$1 # !!AU227(0!:E%32&1&6t ) =7Lþ¿ÖÃ8gpw€#"&=4&#"#4&#"&5463263232654.'2#"/3254+53254+#"'#"&54634632#4.#"325#32=#"H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&n #G"*8.6*(/6O4*%30 ! A}k (?ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ýÆ 6!CR226)27G64 2%8P_I0?7þ>=00+5/''$5B,,,#C0;k!,/+ ,a !5,Lþ.×Ã8ipy‚#"&=4&#"#4&#"&5463263232654.'2#"&5462&#"32654&+#"'#"&546;4632#.#"26=#'32=#"H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&B-;mp7JPz6"0*(?Sc& 9/5*:'.05+*:2!!;#{!Ž&;ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ýÅO9Dt ]F+5AP33/308GE:)/0(Œ5, (0>#86Lþ¹×Ã8ny€‡#"&=4&#"#4&#"&5463263232654.'2'654&#"32#".547##"'#"&546;46323>2654+'4&#"325#32=#"H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4& ".%S$=?.(1A;*$) 8.6+'1993+V# C1' …% !B~k(?ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þC 9$TF6I5H;%6&/20CS228'0!9E~4Jþù$<*&‰%27 1'5s3%=6Lþ½×Ã8Œ“š£#"&=4&#"#4&#"&5463263232654.'2#"/3254+57>54&#"32#"&547##"'#"&546;46326264&+'.#"327#32=#"H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&+> ,04( .% - (8! 3#+0'08.7+'08:4+* ##(" !A~k'?ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þC$ &'%. (1*%#'.&0)B1CS227(.#6H/!€þù0! $,‰&16!1(4s3%=6LþVÔÃ8ƒŽ•¦#"&=4&#"#4&#"&5463263232654.'2#!"3!!"&5463!254&+532654&#"32#"&57##"'#"&54;46323>2654&+'4&#"325#32=#"H-= ^PGbD-)+S8"3',s‚nOU91TDd<05A 4& 9N43eþ ##Yý§'&ÊZ 1!X+,&*"*%7/6,&0n3*Y ]/#\%"#Ck*AÀDP9_u`MKWK )þÂ<5,1J…IE°_yKI`KU>P_I0?7þA1(&2Q/"$:#"&,*$);%9F,,+$D.=k/>áDt ,/)#,d "5/Lþ*ÔÃ8{†”ž#"&=4&#"#4&#"&5463263232654.'2#"&54632&#"32654&#"2#".547##"'#"&546;>323>2654+'.#"327#32=#"H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&C\€j'gQ=66.$R6RbC5IG;%)$8.6+'08<3*Y# C 0(z" !@~k'?ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þAsXkŠ q[MbW%5!5*" DS227(0!:E5Kþ÷= 8‰'15#1(4t3 =7LþGÔÃ8fmu#"&=4&#"#4&#"&5463263232654.'2#"&54732>54&+#"'#"&54;>32#4&#"325#32=#"H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&L(2rƒ«:.VL`?Z/8.5)&1Z+3*Z 1#!!A|k'?ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ýÄ7*YljfFGQ\;435%BU227)P:E%30(1(4t% =7LýîÕÃ8qwš#"&=4&#"#4&#"&5463263232654.'2"&547#"&54732>54&+#"'#"&54;>32#4&"325#2>54&+32=#"H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&L'3FH?b? ¯:.?^J&GE* 8.4)%2Z+3*Z 1%6!!A|Ä $ %þì'?ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ýÔ/'J1D(:9)}_Y>>H5L# ;):K--/%H1>o"++",$-f þÈ$   60LýìÔÃ8u}†–Ÿ³#"&=4&#"#4&#"&5463263232654.'#"&547#"&54732>54&+#"'#"&54;463232'.#"327#2>54&#'32=#"2654'#"&547H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&S(, 0 1B y 6+;WE#B@'5*2'"/T(0(S '$/§;t ñ%;ãF0$'ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ý 9 $;+$wXT;=A2H! 8&5H**-#C/:i-$Q¢  -)!,`þ÷ ì&3-þ§%+# !LþÏÔÃ8[e#"&=4&#"#4&#"&5463263232654.'233!5654&#"632#"&546"3254&H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&¥?Z6¥9þÝCA.!0 ("-%+)2U,/ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þWS@E8 þÜ0K5C1#/6)!6C7TcŸ65LþßÃ8kx‚#"&=4&#"#4&#"&5463263232654.'233##".547#5654&#"632#"&5462>54&#""3254&H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&¥?Z6¥9&! !0 &CA.!0 ("-%+)2U, ."þð,/ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þWS@E8 þÜ2*) 20K5C1#/6)!6C7TcþV "-. 65LýøÔÃ8kw‹•#"&=4&#"#4&#"&5463263232654.'233##".547#5654&#"632#"&5462654&#"2654'#"&547"3254&H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&¥?Z6¥9-7 4" %7mCA.!0 ("-%+)2U ?!'&#0ë,/ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þWS@E8 þÜ#@ $,.@#0K5C1#/6)!6C7Tcþ|P') 44 (#-565Lþ¾ÔÃ8Y#"&=4&#"#4&#"&5463263232654.'4632&#";2#"'73254+"&H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&b:DT0$C$5-?70N1V,&KS>@'0ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ýâ&;0%&05./&5(-LýüÕÃ8ep#"&=4&#"#4&#"&5463263232654.'2#"&547&'73254+"&54632&#"3264&#"H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&8703<! .B*6&KS>@'0:DT0$C$5-?#!$%ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ýÅ09D*?16! &5(-$&;0%&þÊ-&-&$LýæÔÃ8gt‰#"&=4&#"#4&#"&5463263232654.'2#".547&'73254+"&54632&#"32654'#"'2>54'#"&547H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&8708? 4" %6.&KS>@'0:DT0$C$5-$ ", )'"/ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ýÅ0;$G $,.?&&5(-$&;0%&þü   P#!  *4 &".Lþ¼ÔÃ8c#"&=4&#"#4&#"&5463263232654.'2#".54732654+"54632&#"3H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&10<19?_.8,65M)6?zKP_I0?7ýÂ3#!*,?7D6+7>-.#N.:0%#!LýÿÔÃ8lx#"&=4&#"#4&#"&5463263232654.'2#"&547.54732654+"54632&#"32654&#"H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&10<34! /A$R]8,65M)6?zKP_I0?7ýÂ3#0"<*@01!h:D6+7>-.#N.:0%#!þÐ$"&$LýèÔÃ8lz#"&=4&#"#4&#"&5463263232654.'2#".547.54732654+"54632&#"32654'#"'2654'#"&547H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&10<:9H3 %0LV8,65M)6?zKP_I0?7ýÂ3#3$C4G.=$d8D6+7>-.#N.:0%#!ÿ   P." 43 &"Lþ¾ÔÃ;eo#"&=4&#"#4#"&54>;263232654.'2'654&#"#"&547&#"&5463262654'H/>^PGb>3)+SZ3',s‚,@4o%1TL\4'6@6'L_Q$:H7F6-+5C. ?HU;'$"2'8A"ÀFO1_u`MUES )þÂ;J,1J™5E°>\+KIhVU44`H,A;þFaFZ0 .H=S^PGbD-)+S8"3',s‚nOU91TDd<05A 4& ,@"B0þø((vþŠ"*)#í#2C7  G8+*6B .;AIN?(!#3!7A"ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þD12?V3$$C49G3C/:9-F+@-G 'P:PÜ&;(-:$LþXÔÃ8z„#"&=4&#"#4&#"&5463263232654.'4632632#!"3!!"&546;254&+532654#"#"&547&#"&72654'H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&þâN<+!$@ˆ./*0þá''sþ5#)êW L.E7,+5C/:@HÅ!7B"ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ýÂ9KS#.#73#0;!: 1C09:-@.>/G %&:(-9$Lþ-ÕÃ8s}#"&=4&#"#4&#"&5463263232654.'2#"&54632&#"32654&#"#".547&#"&54>3262654'H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4& Paj@LO=?6$9QQOaG<F8-$. C2=?H%.! $/#8@*ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þDwXj‡0u\Ne3262'654#"#54#"&546326'2654'H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&Qd†m<N.5%*:@'ThN@$I9,(E2?>G%. $! 9"9C,ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þAˆex“ &$.+‚hZ{=Q5I,# R6K8S) 2`%; þz  ' 1%G24J,%LþLÔÃ8q{#"&=4&#"#4&#"&5463263232654.'2#"&54732>54.#""&547&#"&5463262654'H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&G^7mK­5!3‘l>Y.*$ G8V5C/ACGU;)"*;"7>ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þDpS$GG,”yNG54.#"#"&547&#"&54632632'2654'2654&#"H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&W#(=/.> ~§3 2j;W-" E8)*3A-/AFQ<&"'(D\ÿ!6;­",-#ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ý 7)<9,†lG?8>Zp15"7 6H2?<2G29*M$ /U=ReJ]#*!@+-B 'è)#LýòÔÃ8ˆ”©#"&=4&#"#4&#"&5463263232654.'#".547#"&54732>54.#"#"&547&#"&54632632$2654'2654&#"2654'#"&547H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&Q*, 0 +8 y 0/„h:S*6(B5('2>(3 ?CO8!$'%BWþô0 3:ª !#1 #%-ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ý9" $,*${dA;2;Sg.0:;2B/98-C-.+E$ *O:J]E`+&:)(?Ü C&,, &LÿöÊà CL2!53546#"&=4&#"#4&#"&5463263232654.'"!54&ù\uýדpþ¤/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&ê@P#RÂycæ"âWgFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7YFιSaLÿEÕÃPYd2##".547!53546#"&=4&#"#4&#"&5463263232654.'"!54&2654'#ù\uE/ "*þ—“pþ¤/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&ê@P#R "//#Âycæ,3A 2!,"âWgFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7YFιSaýú"0 0#LÿÒÃNWdv2##"&547!53546#"&=4&#"#4&#"&5463263232654.'"!54&2654&#"2654'#"&'ù\u%-T=?Q0þÀ“pþ¤/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&ê@P#R%%")92'1 EÂycæ"ABYW?B&"âWgFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7YFιSaþ "X9)" %5 # 2+LÿÊà Yb2#"&54632&#"3265!53546#"&=4&#"#4&#"&5463263232654.'"!54&ù\ut˜b|“KXI7F‹_'{^þ“pþ¤/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&ê@P#RÂycævu-$ -"%a^"âWgFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7YFιSaLþºÔÃ8]#"&=4&#"#4&#"&5463263232654.'2'654&#"#54&#"&546326H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&"6H -%?(. 9'(1KUK:7&%ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þAWB1>*Z+Fѵ&!A0\#/gCX10Lþ»ÔÃ8\f#"&=4&#"#4&#"&5463263232654.'2#"&547&#"#54#"&5463262654'H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&CZ6+*7D *97'4MYJ86%/k6B$ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þAgL7EC7R6 ѵHD2Z!-hAZ0/þü)"O.4E$+LþXàÃ8v‚#"&=4&#"#4&#"&5463263232654.'4>32632#"'732>54'#"&54>7&#"#54#"&2654'H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&þw /&4'+",98  NZx"+ ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ý§.B 0.KS2Ih ':0P&^PGbD-)+S8"3',s‚nOU91TDd<05A 4&À!2 Ç;þ«/$*$/BÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ýû' $ þÝ 1#*!+$91>Lþ"ÕÃ8bn#"&=4&#"#4&#"&5463263232654.'233##"&47#5654&#"&5462654&#"H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&À!2 Ç;%! /A$£/$*$/B*"!$%ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ýû' $ þÝ/*A^ 1#*!+$91>þº.-&$LýÿÔÃ8eq†#"&=4&#"#4&#"&5463263232654.'233##".547#5654&#"&5462654&#"2>54'#"&547H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&À!2 Ç;-5 4" %5›/$*$/B %&)'"1ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ýû' $ þÝ&? $,.?& 1#*!+$91>þß P ' ,4 '$,LþZÔÃ8n#"&=4&#"#4&#"&5463263232654.'233#"&54632&#"3265!5654&#"&546H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&¾+Ò002+fU54),L:P_I0?7þ  #þÜ(:  ?;4)*"+";2=Lþ`ÔÃ8e#"&=4&#"#4&#"&5463263232654.'233# 4732>=!5654&#"&546H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&½2?É7u[þž>5“©DEþä/) *$.@ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ýû;1& þÙ2J SL@Gjt &2$*")$92=LýîÕÃ8s#"&=4&#"#4&#"&5463263232654.'2353#"&547#"&547326=!5654&#"&5462654&#"H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&¼2?É78A! /A »>5žPpþä/$ *$.?)"!$%ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þ7;1&ãÿ4!G*A/"{gRMAFRe-#2%*")";2=þJ.-&$LýëÔÃvƒ˜3#".547#"&54732>=!5654&#"&5463235#"&=4&#"#4&#"&5463263232654.'2654'2>54'#"&547H/>-$BJ 4" %! Šº>5€(G=þø/) *$.?52?µ.@GbD-)+S8"3',s‚nOU91TDd<05A 4& ", 3&#/ÀFO1[;ÿ>" P $,./$|fRMAFRe &3$*"+#:2=<0&Î)`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7üÆ  P#!  '"4 '".Lþ¼ÔÃ8W`#"&=4&#"#4&#"&5463263232654.'2!5654&#"&54623546"354&H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&>Kþ4/# *#.BbBlJJ)2½6ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þCO@›3$)",";1=<1$’7G&9,…g;HLþßÃ8bkw#"&=4&#"#4&#"&5463263232654.'2##"&547!5654&#"&54623546"354&2654&#"H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&>K)B./A)þà/# *#.BbBlJJ)2½6&."$ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þCO@›41?@043$)",";1=<1$’7G&9,…g;Hþx$"-&LýëâÃ8eny#"&=4&#"#4&#"&5463263232654.'2##"&547!5654&#"&54623546"354&2654'#2654'#"&547H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&>K%3$ 4H3þê/# *#.BbBlJJ)2½6.$ L433ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þCO@› <.G4< 3$)",";1=<1$’7G&9,…g;Hþ©  P-# '"#& '!LþÆÔÃ8@LS#"&=4&#"#4&#"&5463263232654.'4632!7354&'4#"6H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&9T‘þâ½&¡-/*2,AmÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ý…c]°x¾).gM<$6TNLþ ÕÃ8JV]g#"&=4&#"#4&#"&5463263232654.'4632##"&47#7354&'4#"62654'#H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&9T‘&A/0@&o½&¡-/*2,Am6%11ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ý…c]°x1/A@`¾).gM<$6TNç%2 2LýëÔÃ8P\co„†#"&=4&#"#4&#"&5463263232654.'4632##".547#7354&'4#"62654&#"2>54'#"&5477#H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&9T‘*3 4" %3c½&¡-/*2,Am", 3&#/' ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ý…c]°x"> $,.>"¾).gM<$6TNÀ P#!  '"4 '".§Lþ,ÔÃ8Zen#"&=4&#"#4&#"&5463263232654.'4>32#".54632&#"326=#7354&#'"654&H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&},-’CV38J5B;7N;)ó¼#$(¦30,_(t ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ý©1D ±€KL6:¾ >%$bPB!5?tS[!Mÿ1bÃH#"$5473 7#".=4.#"#4&#"&5463263232654'Ü=IIoºvìþÚ[$V Öœ%#.C 11$:S6#MþŒgÃTcu#"&547#"$5473 7#".=4.#"#4&#"&5463263232654'72654&#"2654'#"&'ê &U<=Sh‡ìþÚ[$V Öœ%#.C 11$:S6#54'2654'H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&C*C4/>,#N5&+6^G:D= Qý(E%ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þF ,1"@RA60.>?V.;I8NaH:+Z /!a"ð#&C6%NOLþÕÃ8jx#"&=4&#"#4&#"&5463263232654.'#"&547&=4&#"#"&5463232>54'2654&'+'2654'H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&C*49A/0@-6,#N5&+6^G:D= Q# 2%ç(E%ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þF ,1"R) A/A@08! H0.>?V.;I8NaH:+Z /!a"þg-% 3$©#&C6%NOLýëÔÃ8o|‘š#"&=4&#"#4&#"&5463263232654.'#".547&=4&#"#"&5463232>54'2654'#"'2>54'#"&547'2654'H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&C*=@ 4" %B2,#N5&+6^G:D= Q ", 3&#/Å(E%ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þF ,1"[&#I $,.J"!E0.>?V.;I8NaH:+Z /!a"þ“   P#!  '"4 '".Í#&C6%NOLþºÔÃ8k#"&=4&#"#4&#"&5463263232654.'2654'7#"&=4&#"#54#"&54>32632H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&3!+Q^@4/A"'"9: %&MW-% 8%"6.A'ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ý<>.c$,v?M@31)?%ѶH5'b$-u*> 0.?28(3LþÕÃ8s#"&=4&#"#4&#"&5463263232654.'2654'7#"&547&=4&#"#54#"&54>326322654&'+H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&3!+Q^08B./A+7"'"9: %&MW-% 8%"6.A'$#-%ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ý<>.c$,vN'A1??17!E1)?%ѶH5'b$-u*> 0.?28(3§-& 0$LýëÔÃ8x„™#"&=4&#"#4&#"&5463263232654.'2654'7#".547&=4&#"#54#"&54>326322654'#"'2>54'#"&547H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&3!+Q^5; 4" %P_I0?7ý<>.c$,vR'$D $,.E$!>1)?%ѶH5'b$-u*> 0.?28(3v 0P#!  '"4 '".Lþ+ØÃ8‚#"&54.#"#4&#"&5463263232654.'2654'7#"54632&#"32>5#"'&'&#"#54#"&54>32632H,< _OI`.%3/S*0'9 s‚lQU91TJ^<05A 4%+$0DZ";>$X4G'D5R+>!:^4$97'NZ .& 5'!61AÀBK8_ubK`l!:þÂ,E)<1™5E°Z~KIeFU=Q_I1?8ý:C1V&L’@\02 251€J1Ò¶H," Z!+m-B 0/Q^PGbD-)+S8"3',s‚nOU91TDd<05A 4&ƒ0ZHŒaO~L2=9­Ž´T-6 :9'/KXI<3$ 8=3$*$ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ý¤7H K`,QN/#5HC"XG@IdyS )'6MÒ¶H;1b$-pCR0/?+Q("=LýïÖÃ8ˆ™#"&=4&#"#4&#"&5463263232654.'4&'7#".547#"&547327#".=4&#"#54#"&546326323262654&#"#H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&ƒ1ZN'& 0!0 :A¡½=9«³U, 6<:9.(KXI<3$9p%0K.-%ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ý²4@ BYb< 4 %%  ‚kPA:C[nK,# F/¿¦B=&[(g54&#"2654'#"&547H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&…(U`,1 2"1D1;–¶:6¥†©R&1 (976,&HTE91" 3k("g  $1"#'.ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ý¼G?Qj9<" &=,# xfJ=7>UgG2/A ,²›=9#U&`9E('YE'4è I' -%  'Lþ¼ÔÃ8Mc#"&=4&#"#4&#"&5463263232654.'2'654&"&54'2'654&"&546H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&+|LA$A6X9H [µ>LA$A6X9H [VÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þARD@K !L0;<1V*iEVRD@K !L0;<1V*iEVLþ ßÃ8Wmy#"&=4&#"#4&#"&5463263232654.'"&54>54&#"&5462$2'654&#"&542654&#"H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&Y-,A^A%+%7+-8H [W|Lýî|LA$A6,-8H [,&-.$ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ý@ >%/AA/(04+0;<1V*iEVRD?ÕRD@K !L0;=0V*iEþ´$#!&LýëÝÃ8]u€”#"&=4&#"#4&#"&5463263232654.'#"&547'654&#"&54632%2'654&#"&5462654&"2654'#"&547H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&> !)$ 4H?A7+.7H [V?>Lþ,>L*(A7+.7H [UÐ$L433ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7ý7 3".G4G$!L0;<1V*iEVRˆÚRD.G!L0;<1V*iEVþ…P." '"#& '!Lþ;×Ã8Zp#"&=4&#"#4&#"&5463263232654.'2#"&547 654&"&546#2'654&#"&546H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&': Æ—™Ë@9¹©@^9G ZSö9Ne@5,/:H [TÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þG':1|•˜TIBKl…‚j.>:1N,9XFXT?b:+B2=;0M-9XEYLýìÜÃ8N~‰#"&=4&#"#4&#"&5463263232654.'2'654&#"&546!2#"&547#"&54732654&"&5462654&#"H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&þé;Le@5,09H [T€': Z(+7*/A>@Ç@9µ‡­@^9G ZSY.!%%ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þGM7W6';+94,G'3P@N#4,iC 7 ),9+ŠqJC:E]|u`)84,H&3P@Nþ1(!2!LýëÔÃ8Nƒ“©#"&=4&#"#4&#"&5463263232654.'2'654&#"&546#".547#"&54732654.#"&546322>54.+2654'#".547H/>^PGbD-)+S8"3',s‚nOU91TDd<05A 4&þö7I`=4)*9E VO’-39+"3 7<’À=6«‰¤& -6D VPA&8 ‡   $1 "" .ÀFO1_u`MKWK )þÂ<5,1J™5E°_yKI`KU>P_I0?7þFG5S2%8)52)@'2I54&#"&546323&5462#¾#?Aü¿,H‚#Rl ,7(AxL8þ@(!7,0=5D\KIa&æMŽÌ•KIaM/T3:tx]3P, pQH^ E-6=.G!2[FVSE7.Eji†–rnLKJþýúÀM3!!"&5463%26544>54&#"!5>54&#"&54623&54632#"}!Cü½0=>/}.?7*$/ UB\rM7þ@(!8+0=5D\–_&æM’w`‚I]5ýQn*R<04C?#"';(&-RFÿÞÂE2#"54>32&#"3 4.#"!5654&#"&546323&546òk.EbX2Ö'@@ wN+8Y3B~ 44GV:0þ4D_NLb&êDr¨…\‹P1K$'K@^/[K>M/K$'1S3!:IeþXH073>4D_M*B$&ëJeSQ97ƒb3U5 =‘Qb+$þÂ<2aHH/K&:B2F!3XH_'0# 7,OuaxHHLÿùïÄ=H2#"&5467&#"#4&#"!5654&#"&54623&5463262654&'g†Q@AQ:0.2CS7+8J5þvG8-2@4C_–d%×AnRU9E¦(0,(g7ÃtRgfR>n$.&þÂ0=`OJa/K+6A4E"4XK[ZI:)FueJIþs<1,}!Ql6DKÿccÃTa%4632632#"'7327654&'#"&54>7&#"#4&#"!5654&#"&546323&2654' jWL7@\:i"\Vr=5'(_=87+RC;F!=((b5BS'DP]þvG7-1C5D`LKd&×K,/)'2!,é^|IH>4~Mm*QG`?Q -dMB/K,5B4C#2YJ\YJ6,O32#"&4632&#"326=!5654&#"&546323354+4&#"6 /X@äbA••AOB'M&XU)_BýgH8-2A4BaNK]$ '7'*úŸFI*!jµÇ:VG%þöåhO,>+%KP#-O-;>193ESEU]F;*'CF''–å2;%3¶°‚JÿaÃ;2#".54732654&#"!5654&#"&546323&546yd„þîàšù’[NÏÀïZCDV@1þPG7-4@4D`LJd&áDräw¼åoч„p `r±ÛÁœWxcJB]/J+7D2B$3XL[YI:*Aoi…Jþ×cÃKZ#".=#".54732>54&#"!5654&#"&546323&546322654&#" $6E/ ")x§’òŽ[NÇe¡bAZCAY@1þPG7-2B4DcIJd&áDs\c…r#$  C :/3A 1" 6mÆ|„p `rŸÖ+CYT+Wx^OB]/J,6B4D"3XK\XJ:*Aokƒ£x‡þú"!JþraÃLYk2#"&547#".54732>54&#"!5654&#"&546323&5462654&#"2654'#"&'yc…ƒ#/T=@P e†’òŽ[NÇe¡bAZCAY@1þPG7-2B4DcIJd&áDs¡%(:3&1 /ãx§n 8%BYY="mÆ|„p `rŸÖ+CYT+Wx^OB]/J,6B4D"3XK\XJ:*AokƒýG"X7+" &4"! CKþÁÒ¿2Zc2'654&#"!5>54&#"&546323&546#"&=4&#"#"&5463232654'2654'õa|"6,aZHF\L8þ@(!7,0=5D\KIa&æM„Ó*C4.?,#N5&+6^G:D=?V-54&#"&546323&546#"&547&=4&#"#"&5463232654'2654&'#'2654'õa|"6,aZHF\L8þ@(!7,0=5D\KIa&æM„Ó*/>B./A':,#N5&+6^G:D=?V-54&#"&546323&546#".547&=4&#"#"&5463232654'2654'#"'2>54'#"&547'2654'õa|"6,aZHF\L8þ@(!7,0=5D\KIa&æM„Ó*9F 4" %=7,#N5&+6^G:D=?V-54춮&#"632#"&54632#'2654&"2654'#·!:wE01E«1<=0± . =$)7QBRl$:/@B78LtAQ7II$4+Ñ"$4 !ø2"-.)I(3CB4(6V@#5/$*4L98G98J\Cg} ?+=+B$3 1#$/-H2þi#. .JþI6ÁJT_t"3!##".547#"&46;2>54춮&#"632#"&54632#'2654&"2654'#2654&'#3#"&=·!:w,4S@+> 4Ž1<=0± . =$)7QBRl$:/@B78LtAQ7II$4+Ñ"$4 !Ï.""V7,73%/))I+F32+"3!&54>;254+53254#"632#"&54>2654&#"2654&#"2654&#"A`{=WŸÔ6jvB31Cý¬, <,¢T:Ž$6.=A0;F/>< ay=WÕ6«.*¢€R:Žž#7/32+"3!&54>;254+53254#"632#"&54>2654&#"2654&"2654'#"&'2654&#"A`{=WŸÔ6jw+T=?R.ýÅ, <,¢T:Ž$6.=A0;F/>< ay=WÕ6«.*¢€R:Žž#7/AZV@A'# *9US%MPo8InMZG0J- ?4I!\r$&1 US%MPo8I78LZG;V+þÂ1$!/,#%1þxu/2# '""*7à1$!/-"%1MÿNÃ2=I2#".547&'73254'"&5473&546>54&#"2654&#"o$9 PK ':D1#3 V"F>]xK%#G9+O"==/%#*"!!+!Á$, 7\<02D*" @6<mMT6#+=@W?PMDþâL-)75+Kþ¶##$MÿÃ7BNg2;2#"&547&'73254'"&5473&546>54&#"2654.'2>54&'#".=o$9 PK *= 7#=U!`%F>]xK%#G9+O"==/%#*):"*-83%$&#Á$, 7\$5+ ,#V=6(E6<mMT6#+=@W?PMDþâL-)75+KþÆ/[$ %35!- ' *MþÊÃ&LW]fo2#"'73254'"&5473&5462#"/32654&+#"'#"&5463>32>54&#"4&"325#32=#"o$9 PK ?4c%F>]xK%#G9+O†1),! !*8.5)%2782*Z :==/%#*1%6 "A}j(?Á$, 7\+3F6<mMT6#+=@W?PMDý¸6$%0 # !CS226)0!:E*L-)75+Kþš%30(1'5t%=7FþÉÃ&U`hqz2#"'73254'"&5473&5462#"/3254+53254+#"'#"&54634632>54&#"4.#"325#32=#"o$9 PK ?4c%F>]xK%#G9+O— #G"*8.5)(/6O4*%30==/%#*' ! A}j(?Á$, 7\+3F6<mMT6#+=@W?PMDý¸ 6!CR226)1 7G55*L-)75+Kþš#&2%9 #%s%=69þ6 Ã&hs{„2#"'73254'"&5473&5462#".54732654&+532654+#"'#"&54634632>54&#".#"327#32=#"o$9 PK ?4c%F>]xK%#G9+O‘+-Y>*PO181(CF(bT !$*"!(/?,#$@==/%#*= 0 3eY 3Á$, 7\+3F6<mMT6#+=@W?PMDý±"30;uPUI>MC`1B, .1007)1!6H-%1L-)75+Kþ“ !U2 !q1-<5þëÃ#]hu{‚‹2#"'73254'"&5473&5462'654&#"32#".547##"'#"&546;46323>'>54&#"2654+'."327#32=#"«BVOL ?4c% H>_vK%#G9+O–-B S$=?.8 E7*$) 8.5*%3994** # $+e==/%#*V 1'  %6!!A~k(?ÁY<7[*4F6<oKT6#+=@W=RNCþ5&7,UE4K5H/(&5&/11CS227(0!9E.")8­L-)75+Kþ<#‰'00'1)3s3$=6(þÇÓÃ#p{‡Ž•ž2#"'73254'"&5473&5462#"/3254+572654&#"32#"&5465##"'#"&546;>3267>54&#"2654&+'4&#"325#32=#"ÉBVPK >5c% H>]xK%#G9+O¥*? ,05' .% - ' 3*$, %28.5*%28:3** #==0$#*E(%&!B~k'?ÁY<7\*4F6<mMT6#+=@W=RMDþ5$ ('$/ (1*%# 4 (1?4CS226).#9E/!€­K.+55+Kþ" $,‰$3+,1)3s3%=6&þ`ÆÃ#ny„‹’›2#"'73254'"&5473&5462#!"3!!"&5463!254&+532654#"32#"&547##"'#"&54;>323>'>54&#"2654&+'4&#"325#32=#"¡BVOL >5c% H>]xK%#G9+OÎ:N10fþ !!Xý¨&'ÈY N7F)&-,!3/75*&1o2+Z  \g==0$#*`!^$ !B~k'?ÁY<7[*4F6<mMT6#+=@W=RMDþ31)&0S1#%8$!53&#,.4 0O++.#D0;k/>¯K.+55+Kþ5 Cs+.)#+a* 4-MÿÃ&BM2#"'73254'"&5473&546233!532654#"#&5467>54&#"o$9 PK ?4c%F>]xK%#G9+OV-6"•9þ[%1 3ž==/%#*Á$, 7\+3F6<mMT6#+=@W?PMDþ 6*/ þÝ(9$ %0ÖL-)75+KMþMÃ&P[hl2#"'73254'"&5473&546233##"&547#532654#"#&5467>54&#"2>54&#"7#62o$9 PK ?4c%F>]xK%#G9+OV-6"•9&! /A%ù%1 3ž==/%#*] .$%! Á$, 7\+3F6<mMT6#+=@W?PMDþ 6*/ þÝ0*A/0(9$ %0ÖL-)75+Kýª "&$Mþ.Ã&Q\g{2#"'73254'"&5473&546233##".547#532654#"#&5467>54&#"2654'#2654'#"&547o$9 PK ?4c%F>]xK%#G9+OV-6"•9"2-# $5 2ð%1 3ž==/%#*E##1))'"1Á$, 7\+3F6<mMT6#+=@W?PMDþ 6*/ þÝ#<$5 -# <#(9$ %0ÖL-)75+KýÓ ""P9 ,4 &$,Mþ¾%Ã&OZd2#"'73254'"&5473&5462'654&#""&547&#"&5463267>54&#"2654'o$9 PK ?4c%F>]xK%#G9+O54&#"2654'o$9 PK ?4c%F>]xK%#G9+O9ITB0þø((vþŠ"**"í#2C7  G9T6B /:AIO>(!"==/%#*$!7A"Á$, 7\+3F6<mMT6#+=@W?PMDþ,UFAT3$$D39G3C099-F+A,F (O:P¶L-)75+Kþ2&;(-:$KþXÃ&hs}2#"'73254'"&5473&5464632632#!"3!!"&546;254&+532654#"#"&547&#"&>54&#"2654'o$9 PK ?4c%F>]xK%#G9+OñP:+!$@ˆ./*0þá''sþ ,#)êWL.E6-+5C/:@H==/%#*'!7B"Á$, 7\+3F6<mMT6#+=@W?PMDýª;IS$/#73%0;!%: 1C-<:-?/>/F %L-)75+Kþ6&:(-9$CþÛ#Ã#ju~‡2#"'73254'"&5473&5462'654&#"#"&547&#"#54&#"#"&547&#"&546326326326'>54&#"3254'2654'yBVOL >5c% H>]xK%#G9+O{)70#-$ + ")   * ) *% *0%*(@==/%#*#%"(» "'ÁY<7[*4F6<mMT6#+=@W=RMDþ-SBT* (E6L8I2?3;N- )¦Ÿ#.6I2?>0L/C4L% +Y?O87µK.*65+Kþj*MC,3‰+"C,2ADþ Ã&|‡—2#"'73254'"&5473&5462#!"3!!"5463!27654&#"#"&547&#"#54#"#"&547&#"&546326326326'>54&#"4'32'4'32o$9 PK ?4c%F>]xK%#G9+Ou0)5þ¬œþd)B"' &!$  3 %!$  % ),"'$;==/%#*f# !Ì# !Á$, 7\+3F6<mMT6#+=@W?PMDþ1Q2NC,:"$%.+D)C2-2+C$ "‹…C(C3-3+B%6*G#O4B-.±L-)75+Kþ=@;!%;>Kþƒ$Ã&‹–ž¦2#"'73254'"&5473&5462#!"'#"3!!"&5463!254&'#53254&#"#"&547&#"#54&#"#"&547&#"&546326326326'>54&#"4'32'4'32o$9 PK ?4c%F>]xK%#G9+O“2 $þ“¨þX "U5 '!% !  '!% $& *,$(%K==/%#*s$! Ð#! Á$, 7\+3F6<mMT6#+=@W?PMDþ0$(1#0,"5(# )A)6+2@%"‹…$ )B)6./C%8+E#N3D.-²L-)75+Kþ; $;>?54&#"o$9 PK ?4c%F>]xK%#G9+OO6H'$?(.!9"(1KUJ;9$$==/%#*Á$, 7\+3F6<mMT6#+=@W?PMDþ.WB,F *Z+Fѵ,A0[$.hAZ10´L-)75+KFþÅ(Ã&JU_2#"'73254'"&5473&5462#"&547&#"#54#"&5463267>54&#"2654'o$9 PK ?4c%F>]xK%#G9+OMCZ6+*7D!)97'4MYI96%.==/%#*„6B$Á$, 7\+3F6<mMT6#+=@W?PMDþ3gL7ED6R6 ѵHB4Y"-hBY0/¯L-)75+Kþ)"O.4E$+Mþ…Ã&^iv2#"'73254'"&5473&546462632#"'732>54'#"&54>7&#"#54#"&>54&#"2654'o$9 PK ?4c%F>]xK%#G9+OïN+*D G6C\ $4,H#A93*(5(¸¥A47Q)L-)75+Kþ&+#(5 Mþè Ã&S^2#"'73254'"&5473&5462'654&#"#54&#"#54#"&546326326'>54&#"o$9 PK ?4c%F>]xK%#G9+Ot&4F2#)()('&7 @5'(,).==/%#*Á$, 7\+3F6<mMT6#+=@W?PMDþ-L8^$!S,:.´$+´>9-N%]7M,,))µL-)75+KKþðÃ&Wbk2#"'73254'"&5473&5462#"&547&#"#54&#"#54#"&546326326'>54&#"3254'o$9 PK ?4c%F>]xK%#G9+Os !&&&0 4'!)&&%5 ?4&%*)(==/%#*n(&/Á$, 7\+3F6<mMT6#+=@W?PMDþ)<(.;8,E+ -¬•"(¬•<7*I$W7H**((¹L-)75+Kþu#?@(,Bþ‡Ã&kv~2#"'73254'"&5473&5464632632632#"'732>54'#"&54>7&#"#54&#"#54#"&>54&#"4'32e$9 NM ?4a' H>`uK%#G9+Oò.!"'#$/! *;-$) !""$"" / 7==/%#*’ 8 #Á$, 4^*4F6<nLT6#)?@W=RNCý˜9J,,)(@ C6>T !1(G 1=0'#.& ´š$)²š>:+M&¤L-)75+Kþb,A=MÿÃ&CN2#"'73254'"&5473&546233!5654&#"&5467>54&#"o$9 PK ?4c%F>]xK%#G9+Os- ´5þÌ+!& *;Ã==/%#*Á$, 7\+3F6<mMT6#+=@W?PMDþ ' # þÚ 2$*"*#;2>ÂL-)75+KMþ[ Ã&NYe2#"'73254'"&5473&546233##"&547#5654&#"&5467>54&#"2654&#"o$9 PK ?4c%F>]xK%#G9+Os- µ4":*,9#“* & ):Ã==/%#*o!(*Á$, 7\+3F6<mMT6#+=@W?PMDþ' ! þÛ31?@02 2$)"+ =2=ÃL-)75+Ký¸%"!.Mþ8Ã&R]i}2#"'73254'"&5473&546233##".547#5654&#"&5467>54&#"2654&#"2654'"&547o$9 PK ?4c%F>]xK%#G9+Os, ´5&0 0 !0 0+!& *;Ã==/%#*\ #.%8&+Á$, 7\+3F6<mMT6#+=@W?PMDþ ( # þÛ&@ $--$ @& 2$*"+#;2>ÂL-)75+Kýß Q-$ *) &"/MþÐÃ&.9EL2#"'73254'"&5473&5464632!>54&#"354&'4#"6o$9 PK ?4c%F>]xK%#G9+Oa9T‘þâƒ==/%#*a$¡-/*2,AmÁ$, 7\+3F6<mMT6#+=@W?PMDýwc]°xÓL-)75+Kþ¯),gM<!"6TNMþ Ã&<GSZe2#"'73254'"&5473&5464632##"&547#>54&#"354&'4#"62654'#o$9 PK ?4c%F>]xK%#G9+Oa9T‘'! /A&rƒ==/%#*a$¡-/*2,Am1"11%Á$, 7\+3F6<mMT6#+=@W?PMDýwc]°x0*A/0ÓL-)75+Kþ¯),gM<!"6TNç.2 2$MýõÃ&=HT[fz|2#"'73254'"&5473&5464632##".547#>54&#"354&'4#"62654&#"2654'#"&5477#o$9 PK ?4c%F>]xK%#G9+Oa9T‘(4-# $5 4gƒ==/%#*a$¡-/*2,Am 0?!'&#0& Á$, 7\+3F6<mMT6#+=@W?PMDýwc]°x">$5 -# >"ÓL-)75+Kþ¯),gM<!"6TNÀe') 44 (#-§Mþ»ÃAL233!5654&#"&5462#"'73254'"&5473&546>54&#"ç=R59þûF8-,7C UOË$9 PK ?4c%F>]xK%#G9+O"==/%#*QBA; þÝ1A2=@/O!0eBYÖ$, 7\+3F6<mMT6#+=@W?PMDþâL-)75+KMþ Ã%1Xc233##"&547#5654&#"&5462654&#"2#"'73254'"&5473&546>54&#"ñ=R59")B./A)UF:+-6C UOî$!$%$9 PK ?4c%F>]xK%#G9+O"==/%#*QBA; þÝ41??141A2=@/O!0eBYþS&.&$ƒ$, 7\+3F6<mMT6#+=@W?PMDþâL-)75+KMýëÃ&OZez2#"'73254'"&5473&546233##"&547#5654&#"&5467>54&#"2654'#2654'#"&547o$9 PK ?4c%F>]xK%#G9+OL=R59'3$ 4H3MF:+,7C UO±==/%#*P$&4330Á$, 7\+3F6<mMT6#+=@W?PMDþ*QBA; þÝ <.G4< 1A2=@/O!0eBY¸L-)75+Ký P." '"#& '!/Mþó Ã&U`2#"'73254'"&5473&5462654'7#"&=4#"#54#"&54632632>54&#"o$9 PK ?4c%F>]xK%#G9+O€9B,% /4(),6=4%((!.H==/%#*Á$, 7\+3F6<mMT6#+=@W?PMDýV4&R$c5?4+)W ®—<+.R%b4C(&6(."*ŒL-)75+KMþeÃ&[fq2#"'73254'"&5473&5462654'7"&547&=4#"#54#"&5462632>54&#"2654&'#o$9 PK ?4c%F>]xK%#G9+O}9B%%8.7!$4 ()$6=3L%8I==/%#*m& &Á$, 7\+3F6<mMT6#+=@W?PMDýZ2%N"_A/0)*/.3'S¦:0&O$]1A'%*0,'"ˆL-)75+Ký¶,MþCÃ&do{2#"'73254'"&5473&5462654'7#".547&=4#"#54#"&54>32632>54&#"#"&#"32542654'#".547o$9 PK ?4c%F>]xK%#G9+O{9B)1%# -)3 ((6=  &' .G==/%#*}52& $ Á$, 7\+3F6<mMT6#+=@W?PMDýX2&Q$aH?'1 +<;(V«•;&P$a"3 '&4).("ŠL-)75+Kþ$##€%   LÿEÀ(5%#".547'654&#".546322654&#"´3E/ "*5bXADY0#*.b]tŒ2#+ ' 7.2B 2!A!2vK\]M(82 5P/iƒ~flç# !LþúÀ'3FI%#"&5467'654&#".546322654&+"2>54'#"&'73¢33U<>R>,bXADY0#*.b]t®.%"C&0 5$1/# I,DWV@8F 2vK\]M(82 5P/iƒ~f|Îv+'  '3"! C½LþÇÀ72'654&#".5462'654&".546/]t"4-bXADY0#*.U>L*(A6X9H $&VÀ~f3V6)2vK\]M(82 5P/iƒþ5QE.G M0;<1VD+DWLþÀAM2'654&#".5462#"&547'654&".546322654&#"/]t"4-bXADY0#*.®.BB./A5 A6X9H $&V?>L8&."$À~f3V6)2vK\]M(82 5P/iƒý!?01?@0?  M0;<1VD+DWQEN0£$"-&LýëÀEPd2'654&#".5462#"&547'654&".546322654&#"2654'#"&547/]t"4-bXADY0#*.­#4 -# 4HC A6X9H $&V?>L9 &4350À~f3V6)2vK\]M(82 5P/iƒý!,$ $5 G4K" M0;<1VD+DWQEN0rP." '"#& '!/ 2.7".5463&'632À/G#£x+¿'504 ;VJ€«2CÃ*@"!5 $3ÿ½ 2&5432#.54?654&#".547373Ô(=e1C i<H11$JBP1ü!ú (5# "6 <>Z@rp? 1$#B8þúWG,%þú!,ÕWÕÏþÏÿzÿµ£'5.''6?2'¶-=G( +`%-H E–¼,M(! ,+ÿöwà.+'675#5!#2#"&546326=4.#/.'å=B%--×{\ïêÈ54'"&547>7Ë!Q=—P5/6%G7(1!% 0H6"+UQ!& "*?¼b*,'&#632'6?>57654&#"#"&5>Ÿ$<&! $A6((()53)1   *!L* <#6)-"\); .1Uÿôsƒ.(27#""&547#5!#/.+"'767Ž(*>H-{3 1HZ-3' ª) =H )22þw():4)ÿòdz. <&#"326326#"&'2654'#"&547#5!2"&'26J (%;  )[P:c| 1T4(2 -8)´g!2)-æa$m.TÅ­LcG7&!A4@F2I 0!,)ÿûp8. ""'"'"&/3>'"&5#5!é:)=z.=<)7/A .8'>#ÇKë.5  _9K(22ÿþ:w. 526=/&'7./32654''.=#5!!72_4" å5>7E,0¬C%"$2rAQ&/fþí! 0";K4 o &5B,:HG C.!B¤22 DÿñÙŽ.4327#"&'367#".52654'#"&54?67#5!Â$*&-: 4+#11:+L' G9 ( '") ˆü%, //&>+D`z3f_&22ÿÿ|Ñw-'#"'6?675#5!;#'.'/.ì!3˜ 4. 4'Eí$4A '"]¡  3%@@!2Ç/R"2þ­2´#>CƒB0h%274&'"&46332674&+37#&''.#"+"&547;25'&#632+"'#"=46;>32ì4   6?H%X">Q  [ 8F!‘L4Q$>  þ* $K): 'W¡   M=8,(_&ý LC.l V-=1$* ÿÜ­Oá?23!;3267+"&=>;+"&/5#536=4&+"".547¦2=:ÿV #Ai:&-ò,13 !›;22þýS">9u,ô2 '! •E87>54'#".547>=4'#53.=473{$0/,!{,$ 0( 0 'S‹s8(.6 ¶'7(== *R 9D0tV@,% `#!2 l!/' &A2¥¥.%&'5#5!#67+.'2654'#Í&˜¥ç13 &M;.F(&@( Q >-.ž22•MH%=U?bd6 *LK/-/6¬J.7"'#5!#>7#"&=>732}&9Jì&> #&X¬=22þü D%5Rw,×.+#"&54636;2,]+ &(%H(E-%Y$42,$9/ }yv53#.+'2674&#+"&54>;2) CA 0(A# = 't" ( :6&7$ OV 3þ‚;P82 &0 @!- @"›Ý:.'5#5!#>7'&54Ð+C+':á .,@)— 7#%¦33p#*@=((;4%fb.*3273753#&/./7#"&54632#"'ûJ@]-Ÿ `gA !c8-a") &  ¨;/J8@2þj6G=H%&  ÿò$/.&+"+.54632%3#*;;!0(.WþÃøø$e$ )2K2ß2ðŽ(%'&'"'7654'""&5>327'&#"ÊrR 2+<  p5M&c#%/(: §!* 3^x%o +uâ.74&#"/.#'6?.'&'#5!!632#".'4?2325Ÿ+$ ,A%-9P âþž43_!P76=4&+5!#2654&'#t+","'<z&#g£,2¦ #,,+ %22 h0 8/qp. .'#5!#'.+#'67s30KAk>( pCb5 4ü<]&C 22þu=VA!þúWG,%þú!,ÕWÕÏÿòÈ~.+/.#"&#"&5462#".5463254632'!5~$-N-809+:>34!'-#þvV !  `%,0'" ><4?#4 22=p&&#"#"&'"&54>74/6;2>;2d67 !!-+*,- o *$S|m,0$2""#">%Sÿì*h. %32?4'72654&#"7#"&547#5!Š   '}_B+<8y|º %"2^G&1422ÿîH¼.!.".5#"&'7326=4+5!#'2654&+3b(=7<  4–Î0 .3% 4X*" &S 1D22 #(/:%  83p.34&'#5!#&/32>754&#"#"&=>76oY´) l"C'‡ª*0C14&  9ß22 "I* :.5“"h$ %$.¤. 6%#"&54>72'"'5#5!#>7+.'32654'  5-š¤ä #'CN>1M* )C*1A7#"&=6732#¹$> :Oì!> "*g/_%Cõ22ûD'2$3xny. .2#"&546'.+"'67.'&'#5!#{' /X3v ¨b644> &yKü*-U)þÞ l=XA5.  22þúWG,%þú!,ÕWÕÏÿþ[c. "7.'"54637'675#5!#'.'N"j[3 ©54/&=467#53ÛT b0!(! &$‹öü`-²,'[+ L8-I/22ÿèÿòæ.U!!"'.'&#"#"&54732632'&'7#"&5>7>32#"&5463232654&þýF.C$(| )9*C0J  ":(2E?<H"e D),*.2•3þ¾; YJN<#9=5!  A, . ...M,,;&o#D%$ $ÿðÿ¶Š.>G%25&/675!5!#2#"&546326=4&+"/&#".547;6=H‹Eœ|þŒšôBy1#% X02e%JCOT" jIj##+J4E‚ Us#'22&vU(4,$3Hþ$&=N)!   4#GL 5$ÿº‰G3#/&+""#".547325&/32>54'#"&54726?67¥VV"J " /B ]{865°S6>+B])30!>F(Z=d%2ý¾&,+))3&Dn!g +O"=- 4B#N +^õÿÿÿÖ N3#/&+###".54732.#"632'7674&#"#"&5>32/&5&=— V[$J /B `zg h9*5(2, :X  *!Q>£: c!2ýÚ&.+)&2';G_*6!2-AZ .2S½=*  ‹ÿïÿ®ô.F267#"'47#5!#/&#""##".547325.+"'>?67#"&µ- 6RfA­"$xL^!3# -> Xt54 l9B% +<Š 5 Njx,B22ý²'.,$,4&D2BD' ?ÿñÿsß.87>7&'"&5#5!!/&#".547;25® +dy+ 9‹îþÎ*,7a/B qFZA  cK&Vþ†Dq22   $:@þÇ%***,V<§Bÿóÿcç. Y326=&'&/./.#"#".547;2725&/32676=4.'.=#5!!3632m CR/EQJV; "8H33 ' =Dš-o¨10%:R4s(#)Hæþ” 9& ,Q2 D-2M"T:' - =*&!  1DHL\(0  2K&Ó22 Sÿñÿ}d.3q%#"'22/&547&+"#"&'&#3>36323.54732654&'#"&'47#5!!327./&#"&54Š :&G6J@!;.  8i6%K (þÛ$ dN&K " .DIÕsþç -";0KP#"#:HZÓ &. 6 $( ::a9HB6+ I!#(QN4Œ4# N•' S+6K22  MVsNYˆ-QC#ÿñÿz÷V23!267#"&54632/&#"#"547325.5#5!754#"".5473$': Lþµ'q-1"25@¢Vr" )>,(.‰‰b6-B % '& » /& 2þ±k+# 454'.5473#/.#"&5473325#".547>54'#53Ð+A=#5/!$+5;Fа&B !„9Mˆ94 90 #-%5j ïÐT,@7gK0R42ç/o"<(3 )[$2,T= þÔ& L?,)X/";% „. '2ÿñÿw.L#"./5#5!!>7'.+"'#".547;25#".'32>54”R% Õ#þã%H*0#x3G" XV*:8/H5U0" #*?$(>RE Í22ÂE!]5@8þø.+-% 5$"ˆGbT$"E6@,+$ "ÿíÿp.:%25"'#5!!>7#"&54632/&#".547;6#D2A+,Ï1þÐ2P ) $) !2=ZZAIi& ;¹- Od22þ° X1$&//95þ²&HD&#  ,+ÿñÿòþ.48'.'&#"#"&54732632.'632"&'>%!!k4 $o%:H+<(8b1 0J *1&$09/þ— ýóç.þX; ZHO;/ O6M2(Wn3$("6-+<$2>-O8ü&8+&#  +,;Y2ÿþÿºê‹M3#/&#&#".547;25.+'232654&##"&54>32‚WT( s0E TR)45%GOC, #+?3+Q*"`#b,2ý¾&.+-%3$%@MhS7   (%7 N8$:( N2 ÿó.0'#5!!767'.#"#".=4737&54{=j Eoþ‘4^NU(,%*|,,!9.yR[dDJ22Ó,R@EmKR= !E1%- (MTDÿÿÿºÌ4A32?53#/&+""#"&547;225./7#"&'4632#"'FeN}6Î! }†Ta  J@NP! 1 5gH;~+3*10 ‘+H@]T&IB2ý¾%Q6(*5$4BCO^1( 0 ÿôÿÎ.3%25&'#"&54632!5!#/&#".547327%D 2r#*.(M:/]þkV6_9OKNe b;†Ž &':$5?bA 22ýÒ&9R&#  ,+ÿê.D%25#"&'#"&54632>54&#!5!#/&#".547327"D "X$!$0(#I  þ†2s!7=ZQJMf °;ÒS-.#,%(226'!þ·&=N$%  ,+ÿÈ#pE.#"272'53#/&#&#".547;2&''764&#""&54>;4Q %!5'   DO+ x3G" ”NV"'«G+ " +NÌ@9 Ï!/,~“ 2ýÌ&.+)) X6ÿVª.*  ,3$ÿ½ž.I".'#5!!72#"'46725674&#"'.#"&5473725.+'6?&¤*'žþ%@E{Vÿìÿû./32'.#".547;25"&546322676%!!n<  ‹;:# £3]2$,/#O*!%T þ‚/ýÑÈ3þ} "$G1:( y7ð"02'3&Lf2ÿñÿ…".AE%25#./32654'#"&54632767/&#".547;6!!"D&*[…- @8C*8NP>,?&1$BnB6^9VEMf% þå1ýÏ;~‹“[ Ot;"\2-!>:./$8#>4.'#5!#./&#"#"547327325.'#"&54>32¦BS9Š);;-G,]"G<­ ' ICAT A 3-'+*ü-vA9+]Æ+722ýÍ-•$! .#%7!64"* ÿñÿ·. <.#""'>7'.'#5!#.'&#"+.547;2ÑO2  ^Y0]:D3C . B4 \)W&yA7C '-2L$bü0C z~þO@FT-3 22ý»NS?! & ÿÎÿʇV3#/&+"""#".547;24&#"#"&'"&547'&+'32>?'5¸"CV$T  /B YU*79 EJ,-F!V  A2gK& !'  K 2ýÎ&-*-% 2';^ 22!-.;('2] =$‹uÿÅ+.E5&'".'#5!#./&##".547;25.#'76?67&#Ý= &+%&hKéY+[")*EH/B ' CD2ƒ? D& %0ü)#ŸÜ0-2_7  22ýÉ -#// #  #!> 'fX   ÿ¬.F>35#.#"/#5!#./&##"547;25.#""/727ì0 Ø$'* f")*@M ' CAŒ7%."0:$! |" ¤< %( 22ý°-#”*  #!=þ.2<3G& @ ÿð!ú.:E%25#"&'"&'732654+5!#/&#".54732?>54&+ D4T"< 3 ½ 9%8=ZQJMf l- x ,µ;ÚO)'7!2 E22.$#þ¶&=N#&  ,+ã!#-ÿ\Þ.I'./&##"547;25&/32674&#""&546765.'#5!#2|EBeq ")*EH ' @ ?Hc«”7?W<_*- 7'!P! Áê-1DB@ 0€D$t -#”""  ((Bˆ‡/<&4!;!%4 22 -ÿ´). 6&'%675!5!#./&##".547;25.'›'906T7{FþÖ˜’þe)]")*HE22 ' ?!?DV ‡EŠ @H)$3p¾k."22ý¸-#=*( (8AWÿE".;4.'"546;#%675!5!#'.##".547325.'l3U/ Hi']dwJþÖ—“þl"]-[(-A!.yA4RƒH" *2* "!b9¬H2q¾k."22ýI-01#! )<¨>Vÿúÿ¬ž.o3275#""&'#4'#5!#632"&=4632654&#"/&+""".547325&'#"&546;2654&#""&546;2$R^ i2Z {/8*0!þÜ'H¤ß4[9%0% .53 0B22PlDG$<7)0) "$ ç@P“NE1*L/E"22PN8? $þ@& :(+'4#^W+''1 &*+ÿÆL. #O%2?254&#3&546.#'6?5!5!#+#&'4632.#/./)(#E 0 Ph w `  þÓ+ @:M”þ×Lñ573##"&54672654&'3267"&54632".56?&+4/&/7675#5!654##"54732632b#/ùjÀ-Q" #7#',#$[ &'".vJ(4,N +]9ÚF1$ ”!-916@l !R/%Ö 2I;2 '8nFH12*(!G\(1#:(   > 2 X& -ÿD ô …>=73##"&5467265654'3267"&54632/&+###"5473225"56?&'#4/&/7675!5!654&+"#"5467;2î%.5¹jÀ.P$ #ZJ)%] ') !*$( ›Zx7#7z,*' +]9þéƒC(Ž !7T2,JQ(% þ2I6!38MŸ7&33$* 'þÛ&ˆ1"7#:œ s&9$   > 2 P+ 'ø.e!!2#"&547232654&#6"'&'4'32654'"&54632>54&##"&54632>øýPV84(12 .$ (RG¤o" 6;V,/>!%!)? 2%‡D4GC.2db N *! (#   "M4A>XDcM73%! ) " -)!?VJ' ÿðÿ½.KQ%2#".'32654&+#"&547'./675!5!#2#"&54626=4&#632'SB <)3^A' *A<,.;# @)5|[þêÉ:p! !#*?C H@?%1)âJ844 Nvb( Jf-> .*&( AY22XE( ;¾¼.Gÿtø. y5""!!/&/767&/&/32654'#"&54632>54&##"&54632>?632#"&5467232654&#6)$ (þñøýà  ;,%&$#0.F3"(˜W/>-)!)?2%‡D4G *70:>--2 .$ ,<$Z2þ¡+¯(-  2TYÇ3%!"# "+-)!?VJ'!=.$F#(#   *ÿöÿ+þ. \b35#"#'67.'32654&+#"&547'./675!5!#2#"&54626=4&#6322'.   &)+O4*bw.;# @)5|[þôÉ:p! !#*?C BA M E:%0*v <"-[nO ï> .*&( AY22XE( !;¾J8b+¨7,FÿFø.Š!!#".'32654'"&54>7>54&#"#"&54632>?632#"&'472232654&#6/&#"###".547322øýŠ,&G54 $ " 6;V,/>! !%@2%‡D6A *70:D#(02.$ )$.02Xz7#.2þ% %4WAd+&DcM73%!   "(-)!?VH!=.,>9(#   *$Nð& 9)1"9#:ÿöÿpà.Z`%'&#"#.5473272>73254&#"632#"&5467./675#5!#2#"&546326=4.#2'+ %5J+; P 0 + !2'0$"?55{\ïêȯ )"=(!D/'AZ22[B:! ) ÇÈ0Hÿóþé.dl25#".'32654&+#"&547'./675!5!#2#"&546326=4&#6322'&/&/##"&547Él(&3^A' *bw.; " @)4z\þô Î=n%&!#@C B +0KL ! (!t:E!oD~Nvb( ï> .)') AY22[B8!<¾J8A,þö - BU" $ 0 #ÿúÿŸF. F74&#&/.'"#"&546325./675!5!#72#"&5463*Kh !#ÈY1 . %6B4!G;?#E„”þÐLë ;v1#)# ‘J.‰6Iþ 46  ')%2)L)8 Ug/'22&|Q(4'" ÿõÿˆ¢.E2#72#"&5463274&#/./675!5!#'.'"#".546*Ij+A!‚"7$Î ;v0!+&Y1 4Y5E„”þË­I(   2‘L.(*9+ï&|Q)3%% 6Iþq,,7/Ug/'22ýŒ+I  .ÿúÿµF.Z74&#'.#""5.#"&54632#"&546326325./675!5!#72#"&'4632*Kh+A!ÈY1 #  -*  2,?# ';?#E„”þÐLë ;v2!$$‘J.(*‰6Iþ#+. $+    A)-,-71)8 Ug/'22&|Q*2)$ÿúž. Q"&'#323275#"&'#5!#632#"&'54632654&#"/&'"&546374&#""&54721^ {&|0!iR] »$H¤ß 2]=" & 8+!F6-&' "$3 iNE1uLE?@P322PK6/)  þ˜6f+!# 0. &*3 ÿðÿ~ž.f3275#"&'#7"/.##"546325&'#"&5463654&#"#"&5473254'#5!#632#"&54632654&$#&] i2Z {/8*0![#0%J3=N2$<#%*) "## 'R®ß:U,!%& 8Ý&P‚NE1*L/EÊþ $+7<%I$7QHW$*1 *&/ 22PU+'3  ÿúÿˆ.6n3275#"&'#2#632#"&=4632654&#"64&'#5!#'.'"#".=/&'#"&546;654&#"#"&54732$#&] i2Z {/8*0!„"BÅ 0_-"#& 8+þ™ HJ&# !F,$$) "$# Ý&P‚NE1*L/EV'ïPI2'7  þ¦@w 22ýŒ0D#6f'.1 *'/ÿñÿÓƒ."C27#"&5463254&'632#3267./7675!5!#'5.#"#"&'œ|Y‡)X & ,,:(ŒÈ+ ,#oF/DuWþ¯’R5;9:"CW&V R= #; þó 8ˆþ˜0!@LP&D22ý×.700?*ÿÜêIc%.#"632'767."#"&54632654&#"#"&54632&=&53#'32654.#"632V1C",;?:8'!N7   c4#;%'"C[9k '5 @*- & ¼ J +"4R"A4* .,W 37M6!!S3z  2ýö<=GV<  ÿü.?'5'&#"632'>54#"#"&54>325!!767'&54j>k C!A9  ,=?2M ' #4,6$! µþ4_MWA#+[iFEº 9  ,!0O#; Z3%8  Z2Ó,QAzrLJtcBÿ¾X>SX"'.+#'7'>54#"#"&54632'5;#7'&'54%2>7.#"6Ö  o= B%P %V= 7'!"'³ËO+,þ,<&< O>+îW?MI þà D^S*W 01T!$$ ˜‰/2´2M&aZ *¼™+"%-Ap º 0SÿC? _3274&#764''./>3'&+'7'764&#"#"&54632'53#7'&'c Z<*RÈ0,.š_@+&c( M0&p*COB%:/ K !Q8 :-0 š²O5.8e!/ Cw5TG7y)­ þH-<,=S*=3 */-Y%L5˜‰ 2´:%\Xk +ÿ¹ô‹K3#'&/.#"#".54632.#"632'6?654&#"#"&54>32'&=‡W[> $ C3&G e9,8%@:+ K &>) = a* 3ý¿ 7 %3/Ea)%' $$&A- *((/ ¾79'Šÿ††‹S%2#3#'.#"#"&547.'&#632'6?654&#"#"&54>32'&=£64téI  #& ,,*)6:+ K &>)Bp QEîþW) 3ýŒ'&  !-+)" *, $$&A- *((0 ML79'ŠÿÎôŒe>32'&=3#/.#"'&/&#"&5463632#"&54632>32.'&#7632'6?654&#"#"&U-¬= C[#  !(   *4+-, :-  0-[:+ K &¤:L¾79%‹ * 1ýÓ0    +   ';/?#&6B 6­!$v3ì^  < - - # Fl: BF#DŠ 5Wix+=22ý¥ !8 .", &>2BDH 5ÿñÿò.V654/3#".'#22#"546327&/#/.+'674'"#"&546?&'#5! ?EF>  -!1*8 ~+$P $l(3" V s0B~f9*",$/E-0S  & ? 97 0h",0 @þß-PLS'3) %) '22ÿöÿšR. u654'#".'##".'463254.+/&+"".5472;5/&+'674&'"#"&54746?.'#5!e  - 7M(J¢'-5 ~QKGS' (# >$3+,4I85 LCB~f&*#5 t\ü  ì4B!!> 0<`8!- * þ‡' <*-$1"*< FLS'$) ( 22ÿì¡.*7‡2654.''#275#"3"&'3265#"&'#%47#5!#632#"&54632654&#"'.'"&5463654&#"#"&'2>54'#"&,  < H ] þÔ2'$3l72654&#"./&#"'#"&'32747>54'#"&ÙR] þŽ&  4Û?R{07*.þó#+>GX4 47.*( %ý%«¡ß=R# "  J "Bus'e}+++  ' '>ü @P’  ,#]61*L/ 7!>:,A%A+!#( 1 %)e2Q22PR-'3  þX-OÏ£`]%)%  *4ÿþ‰ )f"567?>54/#"'"&'3267'2?#/&/#"&'>54'#"&547#5*% '*&(> +8(2 (&80L<*=[< SV <¼ W3b€@-7 ,9%¶ ‰ / (   5Ñ-H4*-<- *_õ2þ!¡6L˧þí 0)8.BS2ÿø.k32654'#"&5?6?37'#5!#+"/#""3376?67/47"&=?376?4/"ð % ¨'f›--? "  +R2  * ) ;%;()6   ü& ’ % )22 $S '#! 63:)&"21E7>HX D27 E"74  ÿþÿþ .1D}&'#5##3>3547767"&'"&'326?267#"#"/3272654'#"&=>54?67#5!#/./O(  $ ;2 ('¨, 6S$(I­!$-[/pE  98'6+9 ¶ ^\1÷  k ! &  5- 5 O Lx+¤7K‡1>BT+ @;  8.#  22þ4,Jÿþÿ¦ .1J]¢&'#5##3>3547767"&'"&'32673335./7267#"!>54?67#5!#'./&/#"&'./4?>54'#"&5O(  $ ;2 ('h,) g$(\4#, 6S$(I­!$þ× ¶ ^"4o3?#=+   70'3+9÷  k ! &  5w$; N"PÁ 5 O Lx+  22þY- E0$1>BT+ :"  2# 8.ÿþÿý.0@~27&5/&/#>724&/"'"&'326?>54?67#5!#/&/".'#"/3272654'#"&5&  "$  + *&2 ('oC   þ ¶X L  G!pE  98'6+9ý   … !  /8   5Ÿ9 5%  &\r  22þ-P,    )‡1>BT+ @;  8.ÿˆ;.'i##"'67&#326=##".'32654'"'5&'7>325!#/&/&#&#"#'"/?>;&"5-  |E# ( >0;a/ )P3'6&6S$J8)I   "$S)>!'# ï ,5 ˜( þ¥ x”A9aI(*QQ14 02ýŒ-,  * 20e.'2_5#2636?>?65"'"'"&'26=/&'7#'.=#'.5#5!!h   ¦    Jê#p"^%ô‡> 5  '6eþ× ^ê   þË  CÇEv1 (Iþå¥V˜>Q%   ;(22   !! ÿ´¶.2{;6?65/&/335>?65"'"'"&'326%2&/&/;272>?654/#'&'#'.5#5!!;7;  . Ø  z J _%,(8-'96bt<)910%?* &u%(4  '3žþš2  " : þÆCÇ ÷>)-8"76'h& \  3OM#   ;(22 ÿ¶. +?–5;6?65/&/335>?65"'"'"&'326%2&//.#'76?&/&/;272>?654/#'&'#'.5#5!!;7=?  þù  . Ø  z J _%,(8-'96 M0+<((#3<)910%?* &u%(4  '3žþš'  –K  " : þÆCÇ ÷>)-8"76'ì &/< - \  3OM#   ;(22 ÿ_¶.2©;6?65/&/335>?65"'"'"&'326%2'&'./&/#&#.'&=46?32225&/&/;272>?654/#'&'#'.5#5!!;7;  . Ø  z J _%,(8-'96 "4o/' gDC@<)910%?* &u%(4  '3žþš2  " : þÆCÇ ÷>)-8"76' z-  #>"  E/ \  3OM#   ;(22 ÿ¶ù0)s“¦732?2'&#"6"&'#"/&'"&=47'#'3#6?6;7>32#"&/'./""#%2654/".5463263654&#"%32?6565'&/&/+3v ";#  8 !#  > f;G &3Ø0€$" % 41#  P%H' #*f #  iô! " %%i[ýè   ù': )K#+$ #  ¼VFá20* *.&   l 65H.4,:!IÌ11 # O  " +f*V   ÿÿÿK .T726?6?6=/&/&'#'.5#5!!./&+"+"&546?632x1  "$-‰62 .H¡þ×^  ,/ $-!#H7 /þ¹3Fn22  !  @ þ¸ !V/!, Iÿé.%˜"&'32?22?65254'#"&54?%47#5!!&#"327?6323'&/&5'&54?"/&'326;2+'&/&'#"/./37>54&##"&^f!$' * N) 8 !)7 þì3Ÿýù *+ %/ *16! 54&##"&547#5!!&#"327?6323O" $éf!$' * N) 8 !)7 xN %%& ! +9! (<$ A7 !(3/$$(   *$1":3Ÿýù *+ %/ *16! X<ÙE"& .+-(C3 6,! 5`T.  -  )#HJ&%# % 6I !4#%B<)_&%4'  4;@,22   5  ÿDi. 8%57467'"&/&'326?5'465%467#5!!";267/&//&/&#'2?'./532654/#'.4< %  a %#N %.' ,)   þÄ-½iþý7%9 L*   (:@(L ! /? - >Y#  ³„ P4 & )*„ U‚£'P33 ' OM1&  © ¯%F ?$ C*Ia(-#* $ /?ÿýY¨.$~$274'#"&54>32654&#"'32?/&'467#5!!32?6?6?2#'./#"/&/2654'4#"#"'"/&×l4"`Õ(% 6.3Ë«þŠ N  15! 1 ,R>%  !(L *' Œ3 X3}?+& *-+[22   1 ' 7 7.&I'8ž8.A6&"ÿú`` Z75%4'"32654'#"5463276#"'/./?.#"2#"/&/463256?632‘) "?0_[(/!0$&8(n;\&9;]Œ+ 5 !  ]A(O /9<*2'+÷ !%åF( R0(p#8, µ.9±þÐ:$: a@N" % %#(G5"œ9š"?D4A$ÿ<D-™765'64/%26=4'#"&57>3267'&#"'#"./463?6?2'.'./&/25&/"&'54?6?654&"˜P }5  &Fòm7>((' @4S ( 2. , _)9.!G€;+.®+*3OV0"*C  Ä ! O b %    V„ 3MC)A#  ?R53(#(  "  H$,,)f_  5E#0   !ÿÎ'*+«2654/&#""#".54632654/"'&/5?"/&'3267#"&/;265'4.'"&54?65654'""&546323?6?32722µ%"  "" #‡Z  (2$($ #GL\ HI  #)  &!Z6(%3 '   $  F>\*4)5 & 28 9(7nKS8W$92-!  1&4+ , -]&% .2}4I 7"&/74/&'"/46?67226?'4/&/2?6?/&/'./?654/&'""672"/&5&546?256?6?22šr*'ÀD $"/A &    "    *  ,""Š3;4vn        R"$/[4 &", é22/è-I"¬      <8  ÚS ) v j,`H>F  "   /=C=– f  ÿãÒi23!32?6?6?'.5467"&/&532654'#"&/&=#5!7654/#"&5463732ò '. _þÃ% ! Y^a  !23(R&$9 g< &> 1-N . ""1)&  !23'S,9 «€ &>¶ šB )_& ÆIj C[-.-)1 !%!"²U9#8A3T q8C1 !%Â7 EP$Í2Vc79&‹ -2þ-!+"+++$4."%]?K0>K9’"#:;!<}.!a#"'4'5!32?326?674%#"/5#5!!2?+'&/#'./&/326?4&a$,þÄ % '%5#$Cþy_'+É}þê"J#&XHG:. Y,":#   B7K RPCć. 6`"&/& "LO@22¤K a#Rn ZT8"7 !-/:6.,1%A (ÿˆx.U26?7322#"/5#5!#/&/&#&#"#'"/?67#"/&/32675&÷B 0_ #  k_& ÆxI    %$9U9#8A3T üÂ7 ?E|/ ïªP$Í22ýŒ-.  * ]?K0>K9’"#:;!J|d&#"7'4632#.=>;25!74+"#".546?723!3267"&57632#"&/ÿ!A&  %&(5 #0$ /)DO -B   ¦?QLþ³&'e%4"2S3 2 »- 0&5,) $4 ,,2' '    G52þ±$f038.%<U8 ÿ~|’72;25#"&/5&#"7'4632#.=>;25!74+"#".546?723!3267"&57632/&+###".=4674?363Û*7# 2 !A&  %&(5 #0$ /)DO -B   ¦?QLþ³&'e%4"2 "n  024/:‚ 8 ú- 0&5,) $4 ,,2' '    G52þ±$f038.%<û& :)8  'W|&'2>?653#+"&5&54>?6?6?/74/&'"7'4632#'.546?2765'4&'4/&/&5467–- 6 5#£$)ͧ " 2@+,a+/ 4 )   %&#*@%%)5  C !5#&K92&" "%2% Ç1L02/2z+(6J T$    0&5C9N Y/$‚")5Eª4b46;37#".'&543573265"'#"&=463263654&''54&#"3274;#".W;*$,1  ?07[<2 /^_%++  45( %&C! ²,V$P3+7C$01Jn`; ª‹! '  4 O!,# !6$A .^46;25!!;26?#"&/&/./&';2?6?>="5&'#".#&/&5'*.  XþØ  6%.0\6r   91LZA&   ,!0%  % ¬5™2®&4$m$U2F ( F/ e37L5  1 # % @L@  ÿsª4~%25#".'&543573265"'#"&=463263654&''54&#"3274;#".546;37/&#".547327>7[<2 /^_%++  45( %&C! ;*$,1  3i%LDG` <~1Jn`; ª‹! '  4 O!,# !6$A,V$P3+7Cö'?O,.+ÿF /Š2;25#"&/&/./&';2?6?>="5&'#".#&/&=46;25!!;26?/&+"###".5474?327*6$(6r   91LZA&   ,!0%  % '*.  XþØ  6%. $T  /A 4/%:„F ( F/ e37L5  1 # % @L@   5š2¯&4$m$U ð&-* 8 ÿ[I­.B.#"7'4632#.=>;25!!26?"&57>32"'J98  %&(5 #0$ 5'cþÍ] $ $H;*+-µ/ 0&5,) $4 002þ° Q##  6Bl$Pÿ´Íe7"&546?2'&547'3#'54/./"'432+".54>?2354&/"/4632#”5HE2%    D[7 8!/,/'&" $-4&%  C,'5%0&ùZD>L   2= †2ý¸8K .5 #" 8' *"Ù9V 9* '-ÿˆO X32"&546?2'&=7'3#/&/&#&#"#'"/?674&/"/4632#r#  þ¾5HE2%    ÆI    % C,'5%0&üþU ïþýZD>L   2KH 22ýŒ-0 *9V 9* '- .TX4632#"/&/&/&/326?4/"&54>7>54&#"#"&!!–zQ4G+:"# 4" ""!<8+: !! %  +– ýöQ3bJ'I:2 5$B4 'lC+0&!4+   "  $2ÿf . n25#2!!/&/&/>7&/&/&/&/326?4/"&54>7>54&#"#"&54632E  ! þÑ ýöà  "%&-= 4" ""!<8+: !! %  +zQ4G@<h2þ¡"1½-( 5$B4 'lC+0&!4+   "  $&3bJ'Iÿå}P#"/7>?27;#/&/&/./2?6?654/'74&'"’&0  ( $ =0$ 63  >:FS36,!% R"% + 8"†6!")B.".36# #5"4ýë3%$ p  ( A.  ÿýÿe=.e!!.#'.+"+"&546325#"/&/&/&/&'2>=4/.#""/4?63@ýÀK4 $.D2&F &$$ ' 0.' F9"  + 2=!3x+' j A "(  % 8 O!qÿýÿˆ¬.Hq$2>=4/.#""/4?63#"/&/&/&/&'5!#/&/&#&#"#'"/?6;22F9"  + 2=!3x+' j A Y22ýŒ-.  *) ïÿïÿˆ‘.E2!5!#'.'#"&546324'#".'32654.#"#"&54>C3F0) <ýæ¢XY 3.#H(,P6/ 0YwN !*'ÛTDJ+?D  , 22ýŒ (?5"+) ,3F]@Ï13 32+ÿýÿT=.|!!/&#"/&+"2&5463632#"&5463246;25#"/&/&/&/&'2>=4/.#""/4?63@ýÀ=# (   2,2&4! &$$ ' 0.' F9"  + 2=!3x+' j A "(  % 8 O!qÿó4’ b>?6?!'#5!'&=3#'./&/&#?'>54&"/&/54iEB%& þùÖAmC3ôI3" C[-   *2 .:RB # ) =/ ¡kBE23"S7:%‹ ,2ý÷-)*) **"."AX&F*#5  3'%<*&ÿü. 'R767#"'>754?#267#"'#5!#/.//&/54}% þâQR2 ìf- 6H$(F­!$}AmC3^\0=# 0'! H5 r 5 B$ H"x+/kBE22þ4/G>#5  3'%<*&ÿñ<.?76?6?67'.54754747'&/47'#5!!YC(G ,,$L%&' D , "/( <'<þ?6vC1& ” >> #  "    $J$.(Eo*N*TXþ.  'ª1  ² N $#!-@|D"&" > þ (0$ .2G +,@®44Œ  ÿãÿ”ô.5/&#+"&546326='47'#5!!>? @-S#-08*AmCPþuCC%&~f °$6v&!($7 œ93kBE22Ó ;0ÿòÿÝQ*`2;?/&54?'5#5!!?6?+"'"&/&/;26?5'+'.546?2# #   "*,Ä_þ›B&L /*+)."/`!!  k›#R  "&60      + 0 44|09(2 B:>=PD"306=´,-þÚ(1#!- $+"!ÿòÿ¤×*X2/&/#'.=656?6?325"/&5474?63227&547'5#5!!7676Z % 'W +  - I%)#+'   %!" ):,våþÇ= #L0 )þ¿ "- %2 ´!# +   ,"9*'*0 44|, 9?C ÿòÿQ*ˆ2;25+"'"&/&/;26?5'+'.546?22;?/&54?'5#5!!?6?/&+""#".5474?363â+ 7#@ /`!!  k›#R  "&60  #   "*,Ä_þ›B&L /*?"n /A 4/ X:ˆD"306=´,-þÚ(1#!- $+"!    + 0 44|09(2 B:>e6ü&,* : ÿˆf.F%6;22!>?''#5!#/&/&#&#"#'"/?67&/54b +þ|CC%&W AmC3fI      l  +ïÓ ;0A5F*#5ákBE22ýŒ-0   /<*&'ÿ¡Ì4M'32?53#/.+"+"&546325'./7"/474632#"'"/1(&WAµ! }†T 3 -D2L,<:;~C+/ y!+d N&IB2ý¥ !"4 0 &1E;!-O^. / 'ÿˆX4Q73232?5!#/&/&#&#"#'"/?67.'&/7"/474632#"'"/1(&WAK2þ™! }I    !`"<;~C+/ y!+d uþU ï'&IB2ýŒ-.  * UO^. / J¦Z23!3267"&57632#"&/5.+"#"&546325!5!74+"#".546?Ê?QLþ³&'e%4"2S3 2 %1&0(3- þ×)DO -B   »G52þ±$f038.%<U8 y% 0+*1- Š22' &   ÿ…¦†%2;25#"&/5.+"#"&546325!5!74+"#".546?723!3267"&57632/&+""##".5474?327*6$ 2 %1&0(3- þ×)DO -B   ¦?QLþ³&'e%4"2 $$T /A 4/:‡8 y% 0+*1- Š22' &    G52þ±$f038.1'!þý&-* 8 ÿý'ÕWp.'2?6?653#+"&5&54>57>=&/&/#"&54632>5'4'!53/&5467r)6  /& f; ´’    F4+\&%   "&7); " þýô!&M'C)* "!&' -( 20 /&*6!")L2#6"*!&03  G&2',#)()ÿþ8;.W"&576325!5!!32?#"./&/.'2?4'#"/&/&/   2  þþ=þö +  kW?T'  '  )A*L+X * B 9 ’22º C/!&Yo=.K>9#8G 21.I:    ÿþÿu;.„72;25#"./&/.'2?4'#"/&/&/"&576325!5!!32?/&+"""#".5474?3327Ñ*6$'7?T'  '  )A*L+X *   2  þþ=þö +  7$T  /A 4/ :~=.K>9#8G 21.I:     9 ’22º C/!&V=ø&,* 7 Iƒ.746325!5!!26?"&57>32"'5'&+"#"&F0(3- þàƒþÍ`$  $ G<*+--+1&q*1- ~22þ° T # ' @n$P­ : 0+D.Z#"'"&/3264/##"&/46?&=&/&'#"&54632>5654.#!5!#±(*'  *: 0(  -**D@3)(  )&*2&*g þ”D”!V@9$=&ce +722L>% "+ '#(#,@ 226')ÿqD.m25#27/././>7"'"&/3264/##"&/46?&=&/&'#"&54632>5654.#!5!#N% !½3 %%&'" *{< 0(  -**D@3)(  )&*2&*g þ”D”! (*0<ú8L Ê -`h +722L>% "+ '#(#,@ 226') @ÿÕ'.k#/&#""&/&=74?72?254&+'#72"&/4?'&'#"&54632>54.#!5!!@3N  A*6 )#    &  /!)0(*kþÅ'ü6' þš =%"   E  !Ò '  ".  ")#,A 22ÿ]D.j25+".'26=4.+#"&=46?.+#.=654632654'!5!#/.#".547327KE/'5cC< (21M*8L #3#+ J# 2&FT4.þ”D” R# =ZPKPb ;€AWtF 3!J,'E&  %-#7 2.#,T2-22&72$g@+þý& =N(!*-ÿVó. \6;7&/&'7&/&/&/326=4'7'&#"#"&547567#"&54632>54.#!5!#²$'/à=O $"O/BB; , W28v&T  @!$ )0(*kþÅòs!O 33 <7K(B.-B("  w&<% ': ")#,A 226' ÿüØ.>46325!5!!>?/&/547'5'&+"#"&F0(3- þéØþu FI"&W# BmC "*1&q*1- u22Ó<5A5F*#5 3'%<*&EkAEu * 0+ÿéx.@%'%46325!5!!7>32/&/&#'?'&'"'5'&+"#"&Æ! þ90(3- þéxþÓ[; #7[7'$-70 "*1&· „’*1- u22¢$7T þ$  ?'"/&#"#"/&/57?3'&/47'5.+"#"&F0(3- oºÎþ‘ FI"&U8 )z@ !  K 4- A! .E1&r*1- ‰23Ó<5@¢)8, ,9  $=MG!15JR  0+ÿè2.D7/46325!5!#?6372/&'5/.#'?.#"#"&°Cø6*&Qþá2â  & $  U:0@`< +Ñ7¡f,52"Š22‹ ~wI ú þÂ0@@,33  ÿt2. Z25#22'/46325!5!#?6372/&'5'/./67'.#'?.#"#"&  ! ACø6*&Qþá2â  & $  %%&QK U:0@`< +2<þ7¡f,52"Š22‹ ~wI ú þÂu-H @@,33  ÿ¡[.q7'2;25.#'?.#"#"&546325!5!#?6372/&'5/&+"""#".5474?3327ÙC˜%  A50@`< +6*'Pþ¸[â  & $ G  (7 ,(Ñ7¡á  ;&0 @,33  !,51#Š22‹ ~w/9 ú þ{%,* 7 ÿôÿÞ.C746;25&/.##"&/46;35!5!#/&/.##"'E4  &aP'"))G2  %'þ«êb P(& F€2A~¨ 4E" "&4? %= »22ý”*'2E+>ÿôÿˆX.C3246;3!5!#/&/&#&#"#'"/?6;.##'&'{2þ

3253#/&/./&/&5372654/".57463'&/'6?'&,  <Y-  Y$J[-E4:$*# /" $1)9&7(ŒA Ù'?^Ù 2ÀB!:D%2{6)7  2() ) 3#„  ÿÖ#p S'&#"27&&#'&+"+"&546325&5./'764&#"#"&54?>32'53#/O"> vœ*1 $.D2$F! «G+   ,A)*I,  DOØ @M uþ!V/!&1)ÖEª.* ,$4. ~“  2ÿîy<GU`3#'54/'7654&#"54?>?654&#"#"&54?>32'&=254&//""27&/&#"27&¹ DQ2±6+  D-%    ,A)A} µ);" 7  8H vO"> v`2ýò)c ·.' /  ,E6d{þÏ/.Š'1w  M uð @M uÿˆ¹p d'&#"27&7332"&54?>32'53#/&/&#&#"#'"/?6727675&5./'764&#"/O"> vœ#  þ  ,A)*I,  ÚI     ! «G+ Ø @M u*þV ïŒ,$4. ~“  2ýŒ-0   ÞEª.* ÿÅ#p m'&#"27&"&54?>32'53#/.#"'.+"&546732#"./&54632>;25&5./'764&#"/O"> vò  ,A)*I,  DO# # ' %!, +-&! «G+ Ø @M ub,$4. ~“  2ýÉ0 + $#  A$7çEª.*  ÿû/. ;h27'&/"%76?2'4632'&/#"'7654'""&%.#"/#5!#'5/&#""/&/72?&‚!&c#"/6-ýˆnH'O 2+ < à '* f0  !(.  !  Aƒ,o-d 6  4¤’ r.#:  §!* '  22ýÿ9Ø #:A&%  Wÿâ„j"&'5.#'6?.'&'#5!74+"#".'473723!563#".'4?23257.#">7#"&546;2c: Z0-9P úD@2 *2$% 5¦@PYýü43_i @J' +#0Q!+)rS,‹)2G. 22 /2   H42"FO*:ýG6$   þ– J*!B=tÿ r.s232?4&/"/.#"&/&+"2&546732#"&5463246;25&/&#'?'&/&/#5!!6;2#".'47æ  ?$  '  $2,1'& #"4H:._" rþ5H={,5" 0;(/%$H ,þ0   +  $C';   .2%S1M 22 & ™C `&+#FQ'.jaÜ=þÏ) 6 S    œžMkC1/OD,22×- ,=$()*V& "9*66ÿ=. _'/.#'?5#5!!76?673./&/#"&/&54?3337/&5'4º"Ë%Y>Q'.jaÜ=þÏ) 6 S  "4o5' 1g   œžMkC1/OD,22×- ,=$()*V5ˆ- #= " *  6"9*66ÿ¾L. J%577%>75!5!#72/54&/"/&/&'#'7/#%(6, &?)-þÙK‚ZþºLÕO  , A  ;B!BSã% ¾75<)22´!‘ S ¼ þà %ES2 ÿîÿ®Î./4725./675!5!##/./.+"+"&546ÁI6!uT@—“þ®à\ %  &.C²]dwJjI-:Y[k."22ý²     .#%1 H2qÿöÿ’(.9767#"./32654'#"&'5467&/7675!5!#"2!2%23b[I;mL>! Si,A;+8.:`14UPþÔ2Ô‘.%s.3SOa8QcK˜u09!;7%"RF$822þÈ ÿýÿ Î.N>;25'&/.#'?675!5!#/.#"/&+"&546732#"&54632ÑRK*" >  !+0#@;25##"&'&/2?4&"ýÞªB#+GH " B:6F #  ( %2,-+&'Dd< 9.0"[+.2†&225;#>2F,j< þ÷0  +   $C'B#C  *: 0(2J%**D@3(*0*#0­:t.Lˆ$0 0cY1 ce heL>%+!. 4  ,22ÿýÿû ‹l672654&'#%3#'./7>54&#""'+"/+#"&54727256=4&+5!637632Q Z£ %ÄWT>n+0O&HC- /   *(&*'0<z 16+Q-  R ü ˆ0Lî,2ýÿX4;h!>"  #%4 -2%K;4$  P ÿýÿü. P2654&'#'4&+5!!>?/&/547'5+"/+#"&547272565 £ %’<þu BD&'W# AmC(&*'0t0LI-22Ó ;2A5F*#5   43'%<*&EkBE_#%4 ÿý&£. T2654&'#.#'.+"+"&546325#"/+#"&54727256=4&+5!# £ %`5 .D2&F&(&*'0<¦R" t0Lþ²!,* /!&1,—#%4 -22$0 *ÿñÿ§ù.<F74>325.'#"&54>324.'&/#5!##&/&/&+"+"&w+" G8;'0-%$ -6A  #]   " $- ?U9 %JH&6,4#$ ,:22ý«   %/+wA9+\ÿýÿúDp `'&#"27&2654&'#7632'53#''&/'764&#"+"/+#"&54727256=4&+5!#PO"> vþ´£ %r3f*I,  DO0 «G+  @(&*'0<z& Ø @M u^0LkG$4. ~“  2ýþ-ÿ21ª.* C#%4 -22ÿÈDp Ž'&#"27&2754754&'#4&#"+"/+#"&54727256=4&+5!#632'53#/&+"""#".5474?332732;2'&/'7PO"> vþ·$ £ %ÑA)&*#0<z& 6b*I,  DO$T  /A 4/, 0 «G+Ø @M u` .L6*F#% 4 -22F$4. ~“  1ýÌ&,* 7 ÿ21ª.ÿÅJp š'&#"27&2654&'#+"/+#"&54727256=4.+5!#632'53#/.#"./&+"&546732#"./&54632>;25&5./'764&#"VO"# vþ²£ %v.&)&*#0<z&8cv@  DO# *  *3%&! «G+ Ø @" u_.L-#% 3  22Iƒ ~“  2ýÊ0  #+" $  :%7çEª.* ÿýq. r254/#'4&+5!!6;2#"&'4?232?4&/"/.#'?'&/"&'"'+"/+#"&547272565 3¤ %’<tþ5 &={,6!0;(/%$ ? ":T0:._" 0!(&*'0t<&LI-22 Kg &9X"F/(0(#  ,þx,:#S1M  **#%4 ÿ½‚/ 2654'#7+"/+#"&547263656=4.+5!!72#"&'4?232?4&/'./#".54??2325'&#'?'&/"&'"'¶ %}20)&*'0 <‚þ%H={$-,)k[0$$! %#?O(9  !F  Sy:._"u0 '%G#%3  2354'#"/&/4747467#"/"&54?636=&/&+5!#+"'»<µ *&72.4cQ_U& 164SZE!'+ 5!6" f€Ø$> 1.   " µ1;Q;RdI9-6#_>&"1*1  5 "!  22 ,   *  ÿ¨Í.[m/&/#'.=46?325"&=6?632267&/+".54?654&+5!#'2654&+L&  V + - I%)$() &.  $K :0&1 JÍc" 4 « 2)!þ¿ !.5%2 ´!"/$  =!(%*/'22$6 * @%#: #ÿ7€.…%2672/&#".547327325#"/&/&/2>54'#"/&/4747467#"/"&54?636=&/&+5!#+"'74&+32?6„2.495=ZOLNd "D )_U& 164SZE!'+ 5!6" f€Ø$> R<µ *&Ò1;Q;X3ð&:Q(! ,+;y I9-6#_>&"1*1  5 "!  22 ,   *  Ë1.   " ÿýÿ¥F. #]2654&'#7#4'#"/+#"&54727256=4&+5!#/./"/4?672 £ %}  m">&(&*'0<IX -,, 9t0L4  % &´$0²0#%4 -22ý©-+4 ÿý3³.cp%25+"/+#"&54727256=4&+5!#/.#"./&+"&5463632#"&5463246372654&'#ÿ  (&*'0<¶b"# *  2,1'4!£ %ä|#%4 -22$0þØ0  +    B(;? 0Lÿñÿšù.Xb%25.'#"&54>324.'&/#5!#/&/&#"./&+"3&546732#"&546324639 ;'0-%$ -6A  #]%     (+2,,%²?U9KR&6,4#$ ,:22ýž0    %<.A%±+wA9+\ÿû6.k76?2'2654&'#7+"/+#"&54727256=4.+5!#'5/&#""/&/72?/.+"'Ç-þq£ %}20)&*(0<6f0 F   !  A 'ü 6  4¤ˆ.LH#%4  22ýÿ9Ø #b&%  W ÿš6.“76?2'2654&'#2;2/&#""/&/72?/.+"'+"/+#"&54727256=4.+5!#/&+""##".5474?327Ç-þq£ %ì*0 F   !  A '20)&*(0<6f$T /B 4/ü 6  4¤ˆ.Lþ» #b&%  W H#%4  22ýž&-) 8 ÿùÿëY. m%5'246725!5!#32#"/46?274&#/&#'?4&'#"'4&#"&5432#&/&574>748 Àþœ`Ê  E* G¥1fj #%N  /4 $(  û+  $¬Æ  ˆ33±Q<6 %2þÞ'^HI7 ) .!  *.   ÿòÿí2Œj26?!5!>32/&=3#'.'.#?'>54&#"+.'&+.#"&5462#"&546326.þŠ$W8" W[- ! / *1 +!:S K   7()#80:)N?2/%!  2) 8"S77‹ * 2ýñ-) %*($4."AY*+ 7)1 0'#P?4? #;Jn25!5!74+"#".546?723!3267"&57632#"&/5.+."&5462#"&546326<+þvŠDO-B   ¦@PLþ³&%h%4"2Q5 3  ! 7R#80#! )N@15!  k22( '    H42þ±$f039-&<U8 ™ + 5+1 0&  Q>4?#;ÿwœ%2;25#"&/5.+."&5462#"&546326325!5!74+"#".546?723!3267"&57632/&+"""#".5474?363]+ 6$  3  ! 7R#80#! )N@15! -+þvŠDO-B   ¦@PLþ³&%h%4"2 $T  /A 4/ :…8 ™ + 5+1 0&  Q>4?#; k22( '    H42þ±$f039-&<û&,* 9 ÿþ8~.x#&/&574>?246?25!5!#32?#"&/54?2?4'#"&57'654&'#"'&/&+"&5432Ä $0    !þ¦€ø +  kW7p D*L+V# !   3 /45    " .{22º C/#$YoG7)  %1.F /  & $*ÿþÿf~.¡2;25#"&/54?2?4'#"&57'654&'#"'&/&+"&5432#&/&574>?246?25!5!#32?/&+"#".5474?363*7# /7p D*L+V# !   3 /4 $0    !þ¦€ø +  '"n /A 4/:† G7)  %1.F /  & $*.    " .{22º C/#$1Vú&,* 9 ÿßG/y632767325!5!##"'"&/././.'3264/##"&/467>3735&#"'&/"&'4632#"/.5t Y4   þBGY 5B -j$   (  ;7**D@3&( &# +:/ ,$p`&  t33þû%8O!T#5 #  (d)L>%"+   A<**%$1ÿüD.Q6325!5!!>?6?/&/547'5&+."&5462#"&54632 - þ}DþuJ$'W#AmC 7R#80#! )N@15‡;`22ÓB A5F*#5 !?3($<*&EkBE„+ 5+1 0&  Q>4?ÿÝ/ s%46725!5!#7632/754#"./6?6754&#'./"&54632#"/.57>32€ &,“, þ`    +79" )! 1  % )&(9?"$ Å!  l)'‡33þö +J0$  ^ë  /&(F,3"$ &" + C7!1;ÿòÿúJp Z'&#"27&'!5.+.#"&5462#"&5463263262'53#'&5./'764&#VO"# vâþvŒ*  7()#80:)N?2/%! ->ì@  DO0! «G+ /Ø @" u\22Ø+ 7)1 0'#P?4? #; mƒ ~“  2ýþ-ÿEª.*ÿòO.i6327'&/&/!5!!6;2#"&'4?232?4&/"/.#'?&+.#"&5462#"&54632ø -  5" þø]þ5H={,6!0;(/%$ ? ":U0:. 7()#80:)N?2/%‡;  + 2232Ó#  `È, þa²I    $ )  0 %!)&)8>#$ R ïn)'‡32ýŒ-,  *ö, !"$?+ B7!0<ÿÒ/u25!5!#/.#"'&/"&'4632#"/.=632767325'&/&+/&'"/"&54632+/&57>3246*8þzY % +:/  %" Y5  0 !&"AMF($ ,É4€33ýú #**% : `& BÎ  > 5 0' 7 -P3;)ÿÎÿª‡~4&#"#"/"/4?67/&+'32>?2'5#+"/./&'32>54./##"&/4636732‘D % /# &'  A2g#  1  MS*%J3  -I 4 >>**$8 4!$8  gZ  # !"  .* 1 E'#‹u   2þ¿*>75 H: 2 ‡2&H%! ! %"%6 0¸0 R%26=/&'76325!!#'.5&#""#"/#"&54?4/¤#p".-þ¬+&)0 Yþ×^‡> 517 !!&0,- sv1 /þåµ'0 J2   !! V˜>c'5"+"ÿ´ 0t;6?65/&/2&/&/;2726?654/#'.='&+""#"/#"&54?4/376325!!;7‘  . ³%,(8-'46bt<)910%+J1 &u%' // !!&0,- :+&?”þš >2  "   >)-8"46'h& \+, 3O"qP'5"+"'%+N2 ÿÎÿ½‡c.#'.+"#"&546324&#"#"/#"&/46?67/&+'32>?2'53#Ç5 '$D2#BD % +#  1  A2g#  1 CVC!,* 8&1''Z  #"   * 2 E'#‹u  2ÿÎÿˆ¬‡ m3324&#"#"/#"&/46?67/&+'32>?2'53#/&/&#&#"#'"/?67Ç  ¢D % +#  1  A2g#  1 ÒI    !üþV ï•Z  #"   * 2 E'#‹u  2ýŒ-.  * ÿÎÿ؇…4&#"#"/#"&/46?67/&+'32>?2'53#/.#"./&+"&5463632#"./&5463246;2‘D % +#  1  A2g#  1 CV#  *  "!1'4! gZ  #"   * 2 E'#‹u  2ýÜ0   +"    ;?ÿê . ",\2654/&'"#"32?654/&7#"&/46?274&#/.#'?'&547#5!#   '    Be8! B É*G cO016,8Š   N$  2‹+=W6  $3þ¼/-GG%$ !81422 &,ÿãÿÕ¬.!±2>54/&'""32?654/&#7>;2+"/&'4>72326=4&'#/&#""&/&=74?72?254&+'#72"&/4>7#"'".547#5!!3  '" B´ (      2 (%$@3N  A*6 )#  ' ()8¤Éþ›      2F         ( !þ­ =%#   E  !Ò$  "4'4122 ÿæM½ …2654/7>54/"3723#3?>5.5467#'"&547474?'#"/.=76?#5!656574&/#".547¶$H z( %#ê f=?Sk   š+ !H 4-'+5)   8  T(%9 K [  #;&+,s (2|" ' !!   .$ / & &2% *ÿp °>54/"2654/2;25#'"&5474?'#"/&=76?67#5!67574&/#".54673723#3?>5.5467/&+###"&'&5474?327R( %# B%H *6#-'+5>   Ä| T)%9   f=@Sk  ¯  !H  #l  G%4.†&+,R [  #þ¹:­ .$!8) % 2% '  (2 Œ & #!  þÜ%%? 8 $ôN -c7265'4''2?65&7#6?'43##'.'&=?&/&'465'&+53/&567Ü1f.8=6   ‰ 0!" #2Ĩ D8.$J 69ú(#(TwMDBWc&!%6     œ ("'&J##22<2'F4!.#$6#  -:  X 22<>D+%w/:o5'&'?46327654&+"";2654/&'#.72#"&'/.#&+'?/#".'4.'#5!#>—8)(# /'/‹!  (0SU!&#  1*5  7#'W{3 D|&µ+ Yü'$%Ÿ± 1!ž( !o!c,  Ø?/ $  5)V%þú4(^Xk  33ZPÿìÿú p$/j672654/&'""32?654/&#%'&#"27&47#5!632'53#'&5./'764&#"#"'#"'".% _   '" BO"= vþ8y|&8v@  DO0! «G+ 6()ü _   2 @M u;142ƒ ~“  2ýþ-ÿEª.* &4ÿÈp#.“72654/&'""32?654/&#%'&#"27&"#"'#"'".547#5!632'53#/&+"""#".5474?332732;2'&/'764&9 [   '"  BŒO"= v²6()8y|)2*I,  DO$T  /A 4/*0 «G+ û_ # 2 @M uO &4'142$4. ~“  2ýÍ&,* 8 ÿ21ª.*ÿìJ. n2654/&'""32?654/&#47#5!!6;2#"&'4?232?4&/"/.#'?'&/&'#"'".é   '" B[8y^þ5H={,6! 0;(0$$? %9U/:._"  #()   2$1422?2732/&5472326?'4&//.#"#'".5474?32?24'672"54>7"/.5#"/&5732654'#5!o% 5(N  " :,  #-    1#5..B! -%#$K9 !(  3`$/  0 µmš#"Ac-  6R:)   )$  $ þÝ+"  58 &5#4D   3 , f," < !#D22ÿ¶Ž‰ e3?654#'&/./37>54&'#"&5432?.5#"/&5732654+5!ö)+ !< %(:@ SV  `;PL$%< (   $!0/&6K  $ 0 –ãü;  $-% (/& +$_2ýº 7+Q ' ! "3$Y !#D22M ‡3?654&'3723#3?>5.5467#'"&5474746?67&/&5#"/&5732654'#5!2574&/#".5467ö)+ !þù f=@Sj  ¯  !H 2-'+5)6  D  $ 0 ™  T)%9 ü;   & (2    Œ & #!   .$ ;#4/!#D2 % 'ÿ~. ­2654&'#"&5474?36;2;25#'"&54746?67&/&5#"/&5732654'#5!2574&/#".54673723#3?>5.5467#/&+##x *{**¨SH4/*7# -'+5)6  D  '0 ³©  T)%9   f=?Sj  ¯  !H "n  ˜ &; þ6Q7 8 :” .$;#4.!#D2 % *  +2    Œ & #!  þû&@. f2654&+7#"'"&/./3264/##"&/4672637'.5#"/&5732654+5!ž )x)+`DC  -i$  0(  <6*+D@3&1 ;  $ 0 Ö@˜$; d-%  "bW3S$5   (e(L>%%. F !#D22ÿx@.t25#22654&+/./>?"&/./3264/##"&/4672637'.5#"/&5732654+5!#}  ! 7 )x)+‚D  ; %&40i$  0(  <6*+D@3&1 9  $ 0 Ö@VD.<À$; ÎY2Ç -(P(5   (e(L>%%. D!#D22-%  "ÿÕ. r3?654/&#""&/&=74?72?254&+'#72"&/4?>7.5#"/&5732654+5!ö)+ !< @3O  A*6 )#   )     $ 0 –ü;  $-% þš =%"   E  !Ò '  ".*!#D22ÿJ@.v25#"'"&/./3264/##"&/4672637'.5#"/&5732654+5!#/&#".5473272654&+:F -i$  0(  <6*+D@3&1 ;  $ 0 Ö@VD=7i.QJMf † )x)+";ƒS$5   (e(L>%%. F !#D22-%  "bT1û&=N$% ,+º$; ÿ`. f3?654&#>7327327.5#"/&5732654+5!#+&/&/326=4'7'&#"#"&547ö)+ !ÿ 00'   $ 0 –V$&!?M$ b/BB;:=W26x&T! A $ü;  $ä& & !#D22-% = 8K'  Q.-B(""w&<% ': /. O3?654./&/&+"+"&546?6325#"&5#"/&5732654+5!ö(, ! <   $-!#&F6M  $ 0 –þ=  &-'  þÐ ! %/!, ,³X!#D00ÿúpc67#3?654&#'&#"27&%4+5!632'53#'./'764&#"#&#&##"&5#"/&57326ª×)+ !. !O"# výü –ã)?v@  DO0$ «G+ .6M  $ 0ü ;  $$ @! u2#ƒ ~“  2ýþ-ÿ Wª.* Y !#DÿÈ‹p>7#'3?654&#'&#"27&2;2&5./'7654&#"##"&'#"/&5732654+5!632'53#/&+"""#".5474?3327´ º)+ !) O"# vO*1 ! «G+    !]  $ 0 –ã):v@  DO$T  /A 4/è  ;  $$ @" uþ‹ÿEª.  ?5!#D2 ƒ ~“  2ýÌ&,* 8 ÿņp7264&+%'&#"27&%4+5!632'53#/.#"'.+"&546732#"./&54632>;25&5./'764&#"##"&5#"/&57326ªe *x)+HO"> vþ –ã%9*I,  DO# $ * %!, +-&! «G+   6M  $ 0üd"$; @ @M u2$4. ~“  2ýÉ0 +" $#  A$7çEª.*  X!#DÆ. d3?654/4+5!!6;2#"&'4?232?4&/"/.#'?'&/&'#"&5#"/&57326ö)+ !Ï –Æþ5H={,6! 0;(0$$? #:T/:._" $&6M  $ 0ü;  221F  HD" Ö6v&!(1*7Q 4‡ &$&1  22Sÿ¬¢.{272?6;2+"/&'4>72326=4&'#'&/&/;726?654&#"#"&=46?654&'#5!!ò[ ,2.   2 (%$?D2, D6I6Xh7!V = @)"& ¢þ5Ó=9!#5   (  +:  HD80 4‡ &$&1  22ÿþÿý†.#0r5"/&'"''3275#"&546?674/#5!#754747/.'+&#&5463654&+  !B/ <  3%ƒ  MˆÖX48W"3$ &"' ( C   Æ2   #Ÿ*F®"0 22F5< |Lý  þ€!D!E  *1 "+  ÿ¬T.g25!66;2467>7.#""&5>?654'#5!#'.+.'"&54632+"''&/3lþ/ !4 9%þ]$2#)- 7''1&*Ta3,!4)D!$,R&!Seq³Â7!["É'‡   @" -Ù '1!; #) 22ýÿ1&. 0'F  @?* 0€D­$‡ÿPÞ.w//&#"'.#"'6=>32#"&=>3226325/&/;726?654&#"#"&=46?654&'#5!#2|AK2, D( '!+;3*- ".Xh7!V = @)"& Áê!i>1F  HD‘(3  @ #:!344‡ &$&1  22SÿŽ_Œ +†4&#"76#"&54>7254?>7#76?%3#'.'.#?'+"'#"&/&/326?654'#"/5#5!'&=/ !;Ó#%§ &˜W[- ! / *1 !%!`5>P2  $D#)M",5È"I0" p %-@þb    ² "$ £#ó,2þ- %*+$4." IGNb%&$JK)3B2) %"K »20"S79&‹ÿúÿaF. P%4&#/.#&#'>7./76?6?675!5!#72#"/4?2*!) ! 6@?P$ÈP:  J+#"7L8E,2 *'þÐLë :w0!   T   )  Æ-G?}-RýÏ &1<$ " U  '22&wV)3 ÿ·ôH%4>32/&=7#'&#'76375./&#?'>54&#"#"&l4*<"þ¢>)W8% C[!2Z$5Y.-*1 !%  :R K &ž-*‡(/ 8%P77‹ -2ý» h?(Gi4+*+ ."AY*)ÿýÿ`é.7%7267#""&54?#5!#'&#'>7&/7673> ª, 61J$(E­!$#B 3ì^!0\$45Òþš   $–@  "  >)-8"76'à &0<(  \0' 3O"Ó22 ÿöÿ3d.…25#2/./6?>?67'&5467'"&/&#"376?6363232#"./&/5732>54&'#"&546?#5!!3732?©" $ž7& %%&    "^ 3 % :  :&'D,   _/01  *2@Ðnþç/2  /n<âe*&7UÒ -   {2Y &C& # G &. 4++3a 93R " T,&22)ÿÏÿ‹´M777'&#'767./#5!74+"#".546?723!3267"&57632ê ?^-!0\$ #;;DO -B   ¦@PLþ³%h%4"2Z(ÄQ1þÚ h? 2;22' %    H42þ±f038ÿ’#.B25""#"/5#5!!26?/./>7#"/&/32675&ö< #w_& Æ#þÔB 0N  >%&H U9#8A3T <<P$Í22Â7 ?Et.À -0]?K0>K9’"#:;!ÿÊÐH%5'"&546?2'&=7'3#'&#'>?6754&/"/4632# <"‹5HE2%    G^!0\$/(C,'5%0&*€VZD>L   2KH 22ýÎ h?%  c9V 9* '-ÿýÿ—=. a25""!!#/./&/>?67#"/&/&/&/&'2>=4/.#""/4?632< #þ¤@ýÀ  ,%&3 $$ ' 0.' F9"  + 2=!3&Ì-&>x+' j A "(  % 8 O!q ÿHê‹J%73#'&#'6?./7>54&#""&5?>32@ <"!WT!2Z$k \60O&ID, /  $ .5)+Q- R *1,2ýL h?Q ': h?# ))K;!8+   P ÿé.+7/7>32/&/&#'?'&'"'5#5!!Þ! Â[; #7[7'$-70/þÓ· „{&5T þ$  ?675#%32?5!#/.#'/.'&/7"/474632#"'"/x 4V(1øf1(&WAÔRK*" >þF! }¸] "ˆL  n"<;~C+/ c *"ƒ!+d ,5 * -a&IB2ýû&Jfþô3!dO^. / ÿòø.<'&#'76?&=&/&'#"&54632>5654&#!5!#AL!0 R &32'53#'&#'6;5&5./'764&#"~ <"pO"> vò  ,A)*I,  DO!2Z$Ž! «G+ ˜*+ @M ub,$4. ~“  2ýÆ h?oBEª.* ÿüÿòü0!-8/./&#'/&/&#'?5!5!?5#25 B6" /+ "7X©þ¼þvi‘úÃ8R U+ þ½ K!2"þýô&.: × 9#P6R022¤8@,Ž55*1 !9Úÿñÿ²'. =A%"25"./6?&'32654'#"&54632767'!!k   >%& ©P @8C*8NP>,?&1$Bn/) þ\6ýÊ6 :./$8#>%"œ ,&1 Lϱ  ­  )",# &ü$6  þ±!"[e"%*/ 22™%#*%   ©&2§ÿ….r%5'254&'#"&5474?;2325/&#'7#&/+".54?'4/&+5!#7/&+"##,# &: ­ (¥I>.)# 3  1F"œ ,&1 }e"J º&2§}H*%   þqP7 9    #:[e"%*0  22"8  þU%ÿÇ1/J%46725!5!#'&#'?6754&#'./"&54632#"/.57>32% <"”, þc1`!2Z$[*)! 0  %!)&)8>#$ ´ *Z)'‡33ýË h?E Y-2!"$ ?+ A8!0<ÿÎÿ²‡V%574&#"#"/#"&/46?67/&+'32>?2'53#'.#'7671>""AD % +#  1  A2g#  1 CV M,,Y7d+áZ  #"   * 2 E'#‹u  2ý¶,5LA$ ÿþÿÿ'./:@2654'#5!#'&/&#'73.5#"/&57%2654&'#35q0 «)c$! 1F#º>A   % 5(C,!"&ŽD22*)þ§:]x D% !# #"AÁ'2§ÿ¬.M%?675!4&'#5!#/&/&#''&/;>754&#""&5>?6 RK*" >þ¡3+PV(1þ_ ] %2!"/-feq³Â7![" "1#*- 7''  &[5 * -~ "./*"$ 22ýû&P!'=' 0€D­$‡ &3!; ' ÿ.Þ. Y%5'.'/.#'>?'&/;726?654&#"#"&=46?654&'#5!#2+? % LAK2, D? K3+*/# Xh7!V = @)"& Áê!i' –)1F  HD 0é &0<" 4‡ &$&1  22Sÿõÿº¼‰„4>72"/&//&+"#".547474?36;2;25&/&/&/?>54/#"&=632?3!2?4'#"&Ê"%!"n /A 4/*6  MvS*%&)= +C'!+0L< = - SÈþâ +4, €:8þ{&,* 8 5D   Lg / ( *0-H4 3<- #(õ2‘7 /$ÿõÿº‰y2?3##7/&=4'4'/&+"#".547474?36;2;25&/&/&/?>54/#"&=6C0L< = -ãV:   : 8"n /A 4/*6  MvS*%&)= +C'! -H4 3<- #(õ 0 *_T 5%$0 ‰ þ¦&,* 8 5D   Lg / ( *03Ý.b46327#"&'./3265'#".'4632>54&'.#"?32'7674#"'XL+ ,\ 5/"=3%Ia$ <1&('/ '  ( 3=   %>M*­'L &n©0*$/1*ÌQZ ,503( YQ1H >5?   ÿÖÌ…4>72"/&//&+###".5474?32732;2.'.#?'>54&#"#"&54>32'&=753!2?4'#"&Ú"%!$n  /A 4/ *7# %)4 )1 !%!:R J &>)¡< 3ØþÝ5, €:8þ’&-* 7 :%-!++$4."AX*)(/ ½79&‹ -2Š)/$ ÿÖ‰v4>32'&=353#7/&=4'4'/&+###".5474?32732;2.'.#?'>54&#"#"&>)¡< Àà7   :3$n  /A 4/ *7# %)4 )1 !%!:R J &¤(/ ½79&‹ -2œ *_T 5%$‰ þÂ&-* 7 :%-!++$4."AX*)ÿμ“4>32/&=753!2?4'#"&54>72"/&//&"'&/&+"&5463632#"&54632>;2535./&#?'>54&#"#"&>)W8% 3ØþÝ+4, "%!# (   +33%4!.-*1 !%  :R K &¤(/ 8%P77‹ -2Š7 /$:8þŠ0)   +    :0:?<3Î4+*+ ."AY*)ÿÎ{…3#7/&=4'4'/&"'&/&+"&5463632#"&54632>;2535./&#?'>54&#"#"&54>32/&=‡Þâ9   :6# (   +33%4!.-*1 !%  :R K &>)W8% c* 2 *_&@ 5%$0 ‰þº0)   +    :0:?<3Î4+*+ ."AY*)(/ 8%P77‹ÿöÿ}J.>»%#"'333/&5467'"&/&#"376?636323274>72"/&/./&/#"&/&54?&/&/5732>54&'#"&546?#5!!3732?"2?4'#"&‹ :&G61g    "^ 3 % : Í"%! !&"4o5   _/01  *2@ÐTþ/2  /K 5, Ó &.6 )  :{2Y &C& # G˜:8 L &7Uˆ- )8 " "+3a 93R " T,&22)M  )/$ ÿöÿ}ä.>¨%#"'333/&5467'"&/&#"376?6363232/&=4'4'./&/#"&/&54?&/&/5732>54&'#"&546?#5!!3732?7‹ :&G61g    "^ 3 % : í :6&"4o5   _/01  *2@Ðîþg/2  /F  Ó &.6 )  :{2Y &C& # G:&@ 5%$0 ‰ $&7Uˆ- )8 " "+3a 93R " T,&22)I *ÿòá.x!!4>72"/&/'.'&++".546?3237632'&'7#"&54746?6?22?4'#"&áýï"%! $o 6D C  '<%4   021( @5, .2|:8þ®;  6D*: Y&!  $% (4>*/()/$ ÿò›.i!!'.'&++".546?3237632'&'7#"&54746?6?27/&=4'4›ýeý/ $o 6D C  '<%4   021( @4   :.2Ê þÝ;  6D*: Y&!  $% (4>*/9 *_T 5%$0 ‰ÿÿÿº¼‹…4>72"/&//&+""#"&5474?36;2;25'./7>54&#""&5?>32!!2?4'#"&Ê"%!#i PD2-(2 e;0O&ID, /  $ .5)+Q- R )þÚ+4, €:8þs&Q7 : 2%(D h?# ))K;!8+   P ,2†7 /$ÿÿÿºj‹z%/&=4'4'/&+""#"&5474?36;2;25'./7>54&#""&5?>323#7þ : +#i PD2-(2 e;0O&ID, /  $ .5)+Q- R ×Ô+  ®&@ 5%$0 ‰ þ¢&Q7 : 2%(D h?# ))K;!8+   P ,2– *ÿš. T7654'5.#"&/./#"&/46?23257>54'#"&547#5!!>76ú3 c8 48 >!#6' 2)19ES722W(:7ÿóò/k7?3'&/47'#5!!>?2?4'#"&54>72"/&/'"/&#"#"/&/57)  K 4- A! .Eoòý³ FI"&U 6, #%!& ({@ Æ  $=GM!15J33Ó<5@*/$ :6n)8, ,9ÿó”/]7?3'&/47'#5!!>?7/&=4'4''"/&#"#"/&/57)  K 4- A! .Eo”þ FI"&U   : 5 ({@ Æ  $=GM!15J22Ô<5@  *_S 5%$0 ‰9)8, ,9ÿºœ4ƒ74672"/&//&+""#".547474?23;25'./7"/474632#"'"/32?5!!2?4'#"&541(&WA~*"%!a  *-.* I <:;~C+/ ! }VþÜ0/, y!+d !:6þu% 9)  9 4!-O^. / &IB2‰:/$ÿºP4w/&=4'4'/&+""#".547474?23;25'./7"/474632#"'"/32?5!#71(&WA· : .a  *-.* I <:;~C+/ ! } Ø/  y!+d Ù&@ 5%$‰þ¤% 9)  9 4!-O^. / &IB2˜ *ÿß1.##"/&/./&'3;2?674&'"&5463273265./##"&467'&'#"&54632>5654.#!5!›! )  /. <.,-"%. '( !!  #)D>)&*2&*g þ©1ü6'5#,&  - aƒ\)(" )"  $#JI'#(#,@ 22ÿó¥/„4>72"/./'"/&#"#"/&/57?3'&/47'5.+"#"&546325!5!!>?2?4'#"&³#% !0$ )z@ !  K 4- A! .E1&0(3- þ×¥ýº FI"&U 6,  :8-i)8, ,9  $=MG!15JR  0+*1- Š22Ô<5@ */$ÿóU/v46325!5!!>?7/&=4'4''"/&#"#"/&/57?3'&/47'5.+"#"&F0(3- þ×Uþ FI"&U   : ; )z@ !  K 4- A! .E1&r*1- Š22Ô<5@ *_S 5%$0 ‰7)8, ,9  $=MG!15JR  0+ÿÈôp Š'&#"27&4>72"/&'/&+"""#".5474?332732;2&5./'764&#"#"&54?>32'5!!2?4'#"&/O"> vÊ#%!&$T  /A 4/*1 ! «G+   ,A)*I,  þà9, Ø @M uZ:6þ&-* 8 ÿEª.* ,$4. ~“  2–-/$ ÿÈ´p ~'&#"27&"&54?>32'53#7/&=4'4'/&+"""#".5474?332732;2&5./'764&#"/O"> vò  ,A)*I,  Õà7   :3$T  /A 4/*1 ! «G+ Ø @M ub,$4. ~“  2œ *_T 5%$‰ þ´&-* 8 ÿEª.* ÿÅïp ‘'&#"27&"&54?>32'5!!2?4'#"&54>72"/&//.#"'.+"&546732#"./&54632>;25&5./'764&#"/O"> vò  ,A)*I,  þå /0, "%!# # ' %!, +-&! «G+ Ø @M ub,$4. ~“  2œ :/$ :6þ‘0 + $#  A$7çEª.* ÿÅ´p …'&#"27&"&54?>32'53#7/&=4'4'/.#"'.+"&546732#"./&54632>;25&5./'764&#"/O"> vò  ,A)*I,  Õà7   :3# # ' %!, +-&! «G+ Ø @M ub,$4. ~“  2œ *_T 5%$‰ þ±0 + $#  A$7çEª.* ÿýÿº”.s74>72"/&//&+"#".547474?36;2;2335'&/.#'?675!5!!2?4'#"&ÑRK*" > #%!`  )9 -)&    !+0#@   !+0#@;25'&/.#'?675!5!!2?4'#"&54>72"/&//.#"/&+"&546732#"&54632ÑRK*" >  !+0#@;25'&/.#'?675!5!#7/&=4'4'/.#"/&+"&546732#"&54632ÑRK*" >  !+0#@72"/&//./#".=46?725#"/&54?6322?6322?4'#"&áýï"%! €3L' )g'; 0 =C"  89  5 5, .2|:8þµ!56& 0 &ð 1+  :?  +  )/$ ÿûž.a!!/./#".=46?725#"/&54?6322?6327/&=4'4žýb6 €3L' )g'; 0 =C"  89  5 9   :.2Êþç!56& 0 &ð 1+  :?  +  *_T 5%$‰ÿÈp ±'&#"27&2754754&'#%472"/&'/&+"""#".5474?332732;2'&/'764&#"+"/+#"&54727256=4&+5!#632'5!!2?4'#"&PO"> vþ·$ £ %.M%!1$T  /A 4/, 0 «G+ A)&*#0<z& 6b*I,  þÞ6, Ø @M u` .L 2:6'þ†&,* 7 ÿ21ª.*F#% 4 -22F$4. ~“  2Œ*/$ ÿÈÓp ¦'&#"27&2754754&'#7632'53#7/&=4'4'/&+"""#".5474?332732;2'&/'764&#"+"/+#"&54727256=4&+5!#PO"> vþ·$ £ %p6b*I,  ÓÞ5   :1$T  /A 4/, 0 «G+ A)&*#0<z&Ø @M u` .LnF$4. ~“  2› *_S 5%$0 ‰ þ´&,* 7 ÿ21ª.*F#% 4 -22ÿÿÿÉâ.Š4>72"/&/./&/#&#.'&=46?32225'./"/4?6724&/&/&/#5!!2?4'#"&¦D   a"%!"4o/' gH 3 , 9+ *-  8ãþÝ5, ü: %  &]|:8þ…-  #>"  7 ,   /8 22Š)/$ ÿÿÿÉ›.{./&/#&#.'&=46?32225'./"/4?6724&/&/&/#5!#7/&=4'4¦D   n."4o/' gH 3 , 9+ *-  8œÜ3   :ü: %  &]Ê þ´-  #>"  7 ,   /8 22š *_T 5%$0 ‰{. S72#"&54674>72"/&//./&#'76?675!5!!2?4'#"&¡'‰5,'D4*V"%! -4.%-AZ U(1þÍ{þê40, ‘$#õ4- :8 þÊS6Y; (!22š> /$ ?. H72#"&5467/&=4'4'/./&#'76?675!5!#7¡'‰5,'D4*  : /-4.%-AZ U(1þÍ?Ú1  ‘$#õ4- ã&@ 5%$0 ‰ þëS6Y; (!22™ *ÿ˜/'•463275.#"'&/"&725!5!##".'&/3265'#"'46;3>54&'.#"73'7674#".54>7.=632767‰   (%* +:/ ­/þzY 1*-7P<#$!# 3-$$#-5  & /7 !   $7:G A() Y4  2%    R8‡%** ©Bt33þ˜ + </+)7EC 69$%  0  A=&4 1(/    9 `& ÿùYØU…2?674&'&/&/+"/+&54?67//724?6;37#"&/&/&/&/32>?'#"&'4>n%.    1+ ?    + #  ^  ; $#RK", )f HR    &  '   0h& ; 2E&(,.#NEF+b0*K "ÿÎÿÊæ‡–4>72"/&//&+"""#".5474?36;2;24&#"#"/#"&/46?67/&+'32>?2'5!!2?4'#"&ô"%!$T  /A 4/ *3D % +#  1  A2g#  1  þá4, €:8þŠ&,* 8 1;Z  #"   * 2 E'#‹u  2)/$ ÿÎÿÊ¡‡‰%/&=4'4'/&+"""#".5474?36;2;24&#"#"/#"&/46?67/&+'32>?2'53#75 :-$T  /A 4/ *3D % +#  1  A2g#  1 ÇÚ1  ®&@ 5%$‰ þ´&,* 8 1;Z  #"   * 2 E'#‹u  2™ *ÿÎÿØá‡¬4&#"#"/#"&/46?67/&+'32>?2'5!!2?4'#"&54>72"/&//.#"./&+"&5463632#"./&5463246;2‘D % +#  1  A2g#  1 þæ 5, "%!#  *  "!1'4! gZ  #"   * 2 E'#‹u  2• )/$ :8þ0   +"    ;?ÿÎÿؤ‡ž4&#"#"/#"&/46?67/&+'32>?2'53#7/&=4'4'/.#"./&+"&5463632#"./&5463246;2‘D % +#  1  A2g#  1 ÊÝ4   :.#  *  "!1'4! gZ  #"   * 2 E'#‹u  2› *_&@ 5%$‰ þÃ0   +"    ;?ÿÈèp#.¹72654/&'""32?654/&#%'&#"27&4>72"/&//&+"""#".5474?332732;2'&/'764&#"#"'#"'".547#5!632'5!!2?4'#"&549 [   '"  BŒO"= vÆ %%!$T  /A 4/*0 «G+ 6()8y|)2*I,  þå .1, û_ # 2 @M uH:6þ&,* 8 ÿ21ª.* &4'142$4. ~“  2” :/$ÿÈ«p#.«72654/&'""32?654/&#%'&#"27&'632'53#7/&=4'4'/&+"""#".5474?332732;2'&/'764&#"#"'#"'".547#5!9 [   '"  BŒO"= vµ)2*I,  ÓÞ5   :1$T  /A 4/*0 «G+ 6()8y|û_ # 2 @M uA$4. ~“  2› *_S 5%$0 ‰ þ´&,* 8 ÿ21ª.* &4'142ÿã:. ~2654&+7###"&'3;2>74&'"&5463273265./#"#"&5467&5#"/&5732654+5!Ž *x**`$  ‰/Y‚C,- 1-, '!! 4"'QC4  '0 Æ:˜$; d-%  1# i Ÿ¶\ /( " -""*(N -(!#D22ÿÿÿ¬Ö.ƒ76?2'4>72"/&'./&/#"&/.54?3225/&#""/&/72?&5.#"/#5!!2?4'#"&®-^#%!(""4o5' KgA&  (.  !  A '* Öþá6,  ü7  4¤|:8þl- < " 0!þ #:A&%  W  22*/$ÿÿÿ¬“.x76?2'/&=4'4'./&/#"&/.54?3225/&#""/&/72?&5.#"/#5!#7®-¡ : 3""4o5' KgA&  (.  !  A '* “Ü3  ü7  4¤þ²&@ 5%$0 ‰þ—- < " 0!þ #:A&%  W  22š *ÿÁÝ.—76?2'.#"/#5!!2?4'#"&54>72"/&//.#"/&+"&5463632#".5&5463246;25/&#""/&/72?&®-µ '* ÝþÚ6, #%!#  '  )-+4!  (.  !  Aü7  4¤{  22†*/$ :6þz0   +   !  B?*Ô #:A&%  WÿÁŒ.ˆ76?2'.#"/#5!#7/&=4'4'/.#"/&+"&5463632#".5&5463246;25/&#""/&/72?&®-µ '* ŒÕ,   : +#  '  )-+4!  (.  !  Aü7  4¤{  22— *_T 5%$‰ þª0   +   !  B?*Ô #:A&%  WÿÈ\p²>7#'3?654&#'&#"27&4>72"/&//&+"""#".5474?332732;2&5./'7654&#"##".'#"/&5732654+5!632'5!!2?4'#"&´ º)+ !) O"# vÌ"%!$T  /A 4/*1 ! «G+    67  $ 0 –ã):v@  þà+4, è  ;  $$ @" uR:8þ‡&,* 8 ÿEª.  8% !#D2 ƒ ~“  2Ž7 /$ÿÈp¡>7#'3?654&#'&#"27&&#".'#"/&5732654+5!632'53#72/&=4'4'/&+"""#".5474?332732;2&5./'7654&#"´ º)+ !) O"# vî#67 < $ 0 –ã):v@  Õà76 :3$T  /A 4/*1 ! «G+  è  ;  $$ @" ub 8%*VD2 ƒ ~“  2œ-‰&@ 5%$0 ‰ þ´&,* 8 ÿEª. ÿÅ\p´7264&+%'&#"27&%4+5!632'5!!2?4'#"&54>72"/&//.#"'.+"&546732#"./&54632>;25&5./'764&#"##"&5#"/&57326ªe *x)+HO"> vþ –ã%9*I,  þÛ+4, "%!# $ * %!, +-&! «G+   6M  $ 0üd"$; @ @M u2$4. ~“  2ˆ7 /$:8þ0 +" $#  A$7çEª.*  W!#DÿÅp¨7264&+%'&#"27&%4+5!632'53#7/&=4'4'/.#"'.+"&546732#"./&54632>;25&5./'764&#"##"&5#"/&57326ªe *x)+HO"> vþ –ã%9*I,  ÓÞ5   :1# $ * %!, +-&! «G+   6M  $ 0üd"$; @ @M u2$4. ~“  2› *_T 5%$‰ þ°0 +" $#  A$7çEª.*  W!#Dÿwñ.GK'&/&/&/32?6?654&//674&/"2+&#.5?6?27%!!›HW$>…"EH&M31FF&%  I  -  KINþeÍþ3;K! +u= 10 }   0 _    > XI¶2ÿ¬X.W27/&=4'4''&/&/;726?654&#"#"&=46?654&'#5!!òV8   :7 ?82, D6I6Xh7!V = @)"& XþÓ:9 *_T 5%$0 ‰%.  HD80 4‡ &$&1  22ÿýÿ÷—.M&/.'574>72"/&'/&/.#'?675!5!!2?4'#"&@(81' &7K*" e#%! + %2!+0#@72"/&//&/.#'?675!5!!2?4'#"&= >!B%'”RK*" >ž"%! %2!+0#@!B%'”RK*" >â :2 %2!+0#@72"/&/./&/#&#&5?35'&/.#'?675!5!!2?4'#"&‘ >!!S:”RK*" > #%! (ƒy. %8g82  !+0#@!!S:”RK*" >þä%8g82  !+0#@54'#"&547#5!K$.?4Mi /þH '7(/ }[*FJ)<,$9S2 %,9E?!5!#"+&+"#"'#"&#"'546?65'&/.+"#"&54: *  /P!,óPS/þƒtE*3') -*!'$3n3$? B&!g P;§>+: B222& h !"'@& $3n   -)ÿê‚.'…#326?65'&546?#76325!#"+&+"#"'#"&#"'546?65'&5467.'#5"'#""#"/#"&54?4/‹A  / *  /P!,þÇ,% ‚B*(") -*    !!&0,- ü þA$3n1&? B&!g P8'22& h !"8@$3n3$8  '5"+"ÿìÿê3.$G€72654/&'""32?654/&#326?65'&546?#47#5!#"+&+"#"'#"&#"'546?65'&5#"'".% S   '" B / *  /P" ì8yGB*(") -* 8()ü_   2þU$3n3$> B& h P|14213&!g # 8@$3n()4ÿê¾.-g7#3?654&#4>7#32>5'&/&7"#"'"'54>5/&=#"&5#"/&5732654+5!ªÑ)+ !›0P!$) &.   Z (AB"0 !(!  6M  $ 0 –¾ü ;  $©*8?& –+@> 2! 25×[+>Q%2J% ."n1&Y !#D22ÿ¬ª.U3274&=4>7!2%"#"'./;726?654&#"#"&546?654'#5!|7-A*$þ¬!i *#[EJE KBÍ}7W) 9+/!%&&*ª>B' 7S %U~ V7C[^DH‹‡ 4!2 22ÿúÿ^F. <3#4&#/./76?6?675!5!#72#"/4?2[N›3þø 6@?P$ÈP: 4W4E,2 *'þÐLë :w0!   !&-G?}-Rþq,-6-U  '22&wV)3 ÿ^‡‰>3#2?#/&/&/?>54/#"&=6žN›3ýï0L< = - SV   MvS*%&)= +C'!!«-H4 3<- #(õ2þ Lg / ( *0ÿE‚?3#3#'./&#?'>54&#"#"&54>32/&=™N›3ÈW[-.-*1 !%  :R K &>)W8% :-2ýñ-)4+*+ ."AY*)(/ 8%P77‹ÿýÿLt..3#267#""&54?#5!#/./767‹N›3þi, 61J$(E­!$#B 3ì^]0B03> 5W G#x+"4) 22þ4.HD2ÿGZ3#4#"37>#"'#'./32654'#"&'5./7632#"'2?,N›3‘ 0 '- "2'%'_# Lt7D #, ;CJ) (U3K;"8†0 g 19,+? GK-50vD;›7- 9y :M b %2 Z"ÿÿÿ^±.63#26?6?6=/&/&'#'.5#5!!ÈN›3þú1  "$-ó“? .H¡þ×^!1 /ŒC«Fn22  !  ÿýÿ3.P3#;6?65/&/2&/&/;272?654/#'.=#5!!;7,N›3þŠ  . ³%,(8-'96btÒþšLÿ  "  >)-8"76'h& \0' 3O"Ó22 ÿöÿ^Ý.p3#"&546?#5!!3732?"/&5467'"&/&#"376?6363232#"./&/5732>54&'ôN›3þG2@Ðpþå/2  /K7&(   "^ 3 % :  :&'D,   _/01  *!ŸT,&22)Me*&7U z2Y &C& # G &. 4++3a 93R " ÿÿÿ^Ÿ‹73#/&/&'/.'&/76?5!5!;#¶N›3þÇ U#5!· l6Ce.,[þÌd 9S!7 4074/"&46327654&+"7#"&//./#+"&/&=?32'&#"72+"5463>32¶N›3 #  #&  !u L®' #*e!?(LeMB+9 !+ TŽD9c0$I8V  .!##f. &Qæ4,: HÒ, -#+- &&4""H 0( \> &p!jHÿÏÿ^·I3#23!3267"&57632#"&/#5!74+"#".546?ÈN›3¦@POþ°%h%4"2 /( 4 ;;DO -B   !]H42þ±f038.6#  +/);22' %   ÿ^ß_O3#4'32>3##'.547>54'#535./.547öN›3|=…  '2#y '$а  @7$617& µ–5!ÀRM*ŒA #)UF )413 D'A%*; #- .E%'3  #Z:*ÿ^#.53##"/5#5!!26?#"/&/32675&,N›3N_& Æ#þÔB 0'TK9’"#:;!ÿ^±.$3#26?"&57>32"'#5!!ÈN›3þü] $ $H;*+-J­þÍ!N Q##  6Bl$Pc22ÿ^$;3#"&546?2'&=7'3#'4&/"/4632#;N›3þ£5HE2%    G^6C,'5%0&!›ZD>L   2KH 22þ89V 9* '-ÿýÿ^y.P3#!!2>=4/.#""/4?63#"/&/&/&/&'N›3ý·@ýÀF9"  + 2=!3x+' j A  ÿXN‹?3#3#'./7>54&#""&5?>32eN›3™WT>e;0O&ID, /  $ .5)+Q- R ' ,2ýÿX(D h?# ))K;!8+   P ÿ[I.-3#'#5!!>?/&/54`N›3×AmC3ôþuCC%&W# $kBE22Ó ;0A5F*#5  3'%<*&'ÿ=/4 73#'32?53#/.'&/7"/474632#"'"/FN›3ê1(&WAµ! }†T  n"<;~C+/ B<!+d N&IB2ýò3!dO^. / ÿôÿD3.)3#46;3!5!#'74.##'&'JN›3þH1  %'þ«ÞW1^4 "8 ;Ü3@ %=  22ýö8p % #@ÿDp@3#'&#"27&"&54?>32'53#'&5./'764&#"¤N›3þÕO"> vò  ,A)*I,  DO0! «G+ ;” @M ub,$4. ~“  2ýþ-ÿEª.* ÿNr.C3#232?4&/"/&/&#'?'&/&/#5!!6;2#".'47_N›3/  ?#24H:._" rþ5H={,5" 0;(/%$1ú ,þx?)%S1M 22N›3þÝRK*" >o %2!+0#@2F,j<  MÍC %=X(]'!ÿNU.93#/&/"/4?6724&/&/&/#5!#lN›3þbC   0 L , 9+ *.  ôX1®9 5%  &\þ-P,   /8 22ÿDA.+3#'.'&#'?'&/#5!#XN›3þ‡ " ! & 5)2X99D+k.&"ÞW;¸ &! * !3~ýÿ/n T-U  22ÿN.33#2#"&546/./&#'76?675!5!#3N›3Ø5,'D4*’'Ý-4.%-AZ U(1þͽX184- ÿ$#S6Y; (!22ÿHj/B3#46725!5!#'4&#'./"&54632#"/.57>32N›3þ¶, þ`4)! 1  % )&(9?"$ 7F)'‡33ýÿ1,3"$ &" + C7!1;ÿÎÿN{‡M3#4&#"#"/#"&/46?67/&+'32>?2'53#'’N›3·D % +#  1  A2g#  1 CV61Z  #"   * 2 E'#‹u  2þ.ÿLC/73#'&'7'54.'#5!#/.#&+'?/#".ZN›3ß# /'/Ä8)þÇå[{3 D|&3ÿ 1!žÜ'$%Ÿ 33þ4(^Xk ÿHq.?3#76?2'.#"/#5!#'5/&#""/&/72?&ˆN›3þp-µ '* f0  (.  !  A7´7  4¤{  22ýÿ9Ø #:A&%  Wÿ[ã.D3#'&/&/;726?654&#"#"&=46?654&'#5!#2úN›34AK2, D6I6Xh7!V = @)"& Áê!i$ã1F  HD80 4‡ &$&1  22Sÿ^y.P3#'#"&54>72+"'#"&/&/326?654'#"/5#5!!76?63N›3ê#%‰eH>P2  $D#)M",5È"þ× &# A!n    YqNb%&$JK)3B2) %"K »22£#- qÿ^.13#'#"&54632'326?"&5763"/#5!!/N›3õ! * o W$ 1! eA,$K³þÎ!†)!$!¸ M'!4H6sX>22ÿK?.23##"&54632'&#'76?.'&'#5!#VN›3þ” J $, b'b #'”OªC.7$?êb4±M 2;HþT'$sÁU,+*22ÿýÿK). -3#&/.'5/&/.#'?675!5!#@N›3¶(81' &7K*" 1 %2!+0#@!B%'”RK*" >o %2!+0#@3>32. ö  %  &  &9  %. §,+ L   2 !H `'¿??þM  n  -$ ( ,Y &. ?$   $<  ý£ÿ|;¡2`753##"/&/&'46?27654/./57672"&54?>3632#"&/2654.'4öX"*   $2 G" ! $G  4,1] L*+6 ä??™R$/  ": ý¬1  PB!2E,0@…D#'/ +ÿo!§  Lh7"7654&#"4&#"#32753'27654/./57672#"/&'467"&5467&54>372š&1"/O=6 .ºö. $[+, L $V(- /;'%B8)&5$®#î. &"1??Ê 'H  '->% þ€.'': 1>+,0" 'ÿt@º,or7"&54?>;2#"&/2654.'2'#53'&/&/&/3272?654'4&/&54>?6;'±! $E ;(/] @.+7  "P % !.$ öæ#"# &  "9 k)0 OB -}G,0Nt E"(hQ3  )', ,? m   *  ‡ÿøÿn!  Tp7"7654&#"4&#"#32753&54?>;2#"&/2654.'".'"&5467&54>372š&1"/O=6 .ºöÄ $E  7+._ K,2/  w(- %E'%B8)&5$®#î. &"1??=  MD!5~F,0'† J( þ .''4'1>+,0" 'þhÿ'ÿ¹L732?654/"723275'7&/"&/4?67þ• ++* 4  3=*!,7  +' 12*1 " ÿ¦éÔ.'+4>72"/&/52?4'#"&73##%!# 6, ØØ€:6#5*/$ Ã2þŽÿÿÈW'%27&#"2?67'"/"&5746þñ 7 Œ‹  ';!;! ' vy+ 2ÿµœ.7/&=4'4'573#0 :;>  \ÀÀ®&@ 5%$0 ‰J *!2þ{þõÿ|=&/?Ÿ@8n’)q*#ð0!?k2QP! $ÿ¹Äí.594&'#'72?6;2+"/&'4>723265!!€(%$  ,2.   2 Ç4þÌ(  !!#5   (2þ6/C3#26373#"'"&/./&/.'32>54/##"&/4666² &*M* .j$   (  <6*+ '/!3&1/2¨  !:'FRT#5 ;#  (e( -%%.ýðÿå60T3##"/&'3;2>74'"&54636;65./#"#"&54>72#66:‰/FB3K,- 1,- '!  4")"J45N 02þYi ;<Æ\/( " - ##%"-!:.$ þ1ÿÖ6/;3#2/&#".5473263254&#"632+"&5467266’.@ U .3 793$ >  +TD/2‡!þš =  ;*/142!Ò *+)-8gÿEÿ05«&/47'5376?   $& <80).8!  4&+,>B#!R&Ф4)?6þwÿEÿ¶«-8'4#"./6?6=37632/7'p + @9" * % ^&,0ë / /( EQ -+J0$  U !  ÿò4ø.,"=&/&'#"&54632>5654.#!5!#":+ )&*2&*g þŇ!I'#(#,@ 226' %þÿjÿ*|%257/&/.#+"&546þp6F0 '$-0_7Xþî6( &!(#8þ˜ÿÔÿ¸ª.#'&+"#"&5463257H*1 $(#B4G8+,!V 9%2IPþáÿÿ§Q 25""&/&/6?637'Ú<   X 4%& 6" !<d -Òþfÿxÿ7µ%7&#'763767þå <"2Z$[9 G* Ñh?E* þÃÿ–ÿ÷N. /./&#'?675#5!#‰8RK*" L 6,"/-@3þÊ.# (  *43%4!n<3Ä0)  #+    :0:?þfÿÃÿ³0'25/&#".#"'6=>32#"&=>;6°.(  9 %!,:3*) Œ)"‡(30 7@ #:%3ð/;25!5!#/.#"'&/"&'4632#"&'.=6327679/þzY * +:/  : Y4  ÊBt33è  ** %  `& .167';267'&'"6?4467#53##"/&¢F   #2 HÀ6mÌ)  T7 +V D  x  H >$J33 2"UHã. .3?654#"&5#"/&5732654+5!ö)+ !<$&6M  $ 0 –ãü;  $-% Z !#D22þeÿa6/:3#2&/&/326=4'7'&#"#"&5475>?363666«%P>N$ b/BB;:=W26x&T! @!$ 1'/2‘J75P%  Q.-B(""w&<% &; +-&( C%2674#""&54632;#"=4#"#"=4#6232>7>32¸0,+"&;;.$:8µ $& ""%F  %í"'3.$*1)9"'1CI8Sõd+0 Oî&6Hü-0 :! K-ß' )932?>74#""&54632;#"54#632;#"54#632E ) +4&;;.*48´ &(&%‹ &(&% 3.l*1)9(!4@K9TG&7Nþ²9TG&7N/T',32?>74#""&54632;#"54#632º ) 4':;.*48´ &(&% 3 m*1)9(!1CH9TG&7N ÷&.(7"&546?2&/&/"/4632#‰5H;<% '5%*,÷ZD2V  =9* '1.ÿêâr +2#"/46?274&#/.#'6?F07'* G cO0-`i 8!!! r#E+6 %2þ¼/-GG#@!>+ÿæM½_7"&54747467>7!5!656574&/#".5473723#3?>5.5467#¡+5)\hþ¶8  T(%9  f=?Sk   š+ !H 4-'N.$ ;8nG2% * (2|" ' !!   ÿýÿê‚.D232>5'&/&'546?3#"'"'54>5&/&54?#5!ÇB  N &.   /VY +84/!!(! /‹‚üN<.;9e( 2! % 35- 8 BC)X@#)@& ."4B'82B22L.0%"#"'>54'#"&547#5!!>767  7@,2)19ES722W(:7 "8 ?rÿòÿ´Š.FX"=&/&'#"&54632>5654.#!5!#/&/&/"/4?>724'"7#:+ )&*2&*g þŘX > )  #6  ‘!I'#(#,@ 22ý¸-*%     8" . %  &¦6'%ÿÄÿ‹; ,4&#".546323?632#"5špZlb% TBš|&DK6#" &GøfxJ2   O6J\ $8dAýñ&# $YÿÄt•« 7254&#"&54632#"&54õ&"!A-jAYxW6Nš¶4;6D*(*;*3V([!Z@1l*8;1(ÿÿ4Š'åþÄÿÿCŠ'åDÅÿÿÚŠ'åÂÆÿÿÿÿþÍ,Š'åLÈÿÿÊ'å@ÉÿÿÿýùŠ'å¡Êÿÿþ»CŠ'å|ËÿÿþÈŸŠ'åÌÿÿ)Š'åÑÎÿÿòŠ'å"Ïÿÿ#Š'åTÐÿÿ'åŽÚÿÿÿÿÿþŠ'åeÓÿÿzŠ'å¢Öÿÿþ” Š'å¨ÕÿÿØŠ'åPæÿÿþÁŠ'å»Òÿÿÿý_Š'å¾ÍþÀÜ\/:%+#"'>?67!"&54>73!.54632"7654&Ü Å F:# 9A þÄ=))GRq\68"@)Q9Fb8'.=2/(¬!% FVP&/5¶ þ #hUNd D0 „NcMrLV=2BÜ\)7%#!"&54>7;.54>2#"&746732>76&#"Ü ýÀ=))Ú7>L~ÔTP:=d%Kq2+h/*)2//5¶ þ 2?6bHUMLIKJG aL>„)!2+/ 41GÿÿþÍX P%3276=!"%547#2>54&+#".54;547!"#32#"'&5&76.hMP;þó)TÏrb™\<PM`ðOp4|8 › ‡$A=#þßàÓ”°r F(8J5{¿=K2Do-_•++•ý£.G_Y.p`‚¬(CA$•W 0 '•2aBÄã˜ÐësdÄE}UJ%Dÿ •[V7#"547!"#>3232654>732?2#"=!"54;>54&#"547#32?2¡.,G8÷ › D-+3#M+Ü!.,Gþ#$¨5G7) #-%*²!fMYœW 0 '­>4#I0Um° ý&MYšeA6H ,0&%&+*þr&øX+3?+327#"=47##".54;547!"+#547#3276=!"ø )Dsð@b8# |8 ‡ OφhMP;þó)`0µ##1/Rº ‚¬):4•W 2 '••++•¡=K2Do-þ¶Xx327!32>54#"".543!654.#"3267#"&5463#"632#".54>3!+"6323254>7+bªyødýÎ[7)% VH&ZŠN1‚v33!+!1 Þ1O, 'd &bJ,E$-BqEŸ V ;FUV%^$)>…+——‘L:†N58(.r.ýÇ&4,49BCa2w1!-<3<.=S3S#;%bn/@O5LcR9â.ˆwbR7= ý‚>,EVÿ@ÛlX2#"'&54>76323276#"54&#"32>54&#"3267#"&54>76OAQ/G{N½ƒR)P_AX‘'p‹$G "4!DÆ¢.JQ*<9i´?D3!8/F&' *!1)/‚u`-ZfM3¨g×uµ}R!,I4ioþs&(2RšŽ­5*<ØyT"²'326326323254>7+! '&543!6=4#"#".54>7&#"#".5467&#">32%"32654'&32>7!""32654'&»E 0)# )!¥fEOj1J‰WknVk[mTrº6µ$*=ä¢ýÛþËTq‚TpV4kP7P#9+M[&(kP7P#?:IUAi=*[5 &g!I 6$.:oüž²âo¦«†1üBMÊ!I 6$/9o.3 &- G(/'Nel•lJgS<..//þürQº47= ý‚?+·&3\4n¿oî Y¼pŠ@^INo'& Y¼o‹@^IK‡0$*=L::#;à™C7+#"'&543!6!"32Úψ#9; R9þóJ^&"BðKm7|8 › i¤N•$ ))>ÅGÎs…Fq‚Fmþ3M>WN¨]•++•‡.C"2Do›4B ‚¬)BC"•U2 '• £z7= ý‚>,Va&=R4g™&( þ¸ÈYKT23254>7+#".543!654&#"#"547#3262#"547!"+>!"326;:^›$ ))>À7ÈqHr@)‚öC+*.%*²!.,G8÷ › ZIþEM¡5f¢creB7= ý‚>,Wb-6'4;K_K )!X($Ó+*þr&(MYœW 2 'þÎ/-þR&)8Cÿ^\#"=#!"&54>73!2654>7327D þÂ=))D)òR£/5¶ þ ° ý##1/ÿÿþZ\D%265#"#432+#"'&<>7632765!"&54>73Ž7M RN C^2€dU,JzT±‘Œ 1 Z-Ò_„\*þù=)2žRvþ‚r´'IV8—ÃDfb>&€{K)J2< eÊŒŽb•j/ 04¶ þ!ÿ\5"=!"&'#"54>73274>7;2654>767326?ÒDþÒ4,;Xh)AB))þ( -òR "%Gd¶ þKeI þ ° ý#  ,&þÍÃXL%262#"547!"+632#"'&547632654&#"#"547#±.,G8÷ › )rBVCgƒv6ºŒ¤i .Z;ui˜Ë6" #-%*²A(LYœW 2 'þ×krN^˜]?˜Ð»£ #:‡V>aV^$EÈG7-X($Ó+*þr&þ·X Zc%4#"3267#".54763232=4./632!254>7#!!"'&543!65&=4#">32!"326Z& :6)#Of=/J(HXÍR/tX%$*ACŒ$)>þØBþÿ…Fq‚¸†vqƒ [51TÎþyM®9gp¨q!_GKhi,>N9ji5"„Ç­¤BI ^t{ëF7= ý‚?+·&>Q4+8؇£‰z:KþM&,7Fÿ¯[HT"=!"54>54.#">32#".54>32!2654>73274#"326pEþ@080*V91F:/G01U#99-F$/J\Z(;]7# -(7 ))ýŽY'0 :7)"òR  )3pIKU: %:jD7,KV;V,/@P3BsM8#5HC#8dG-° ý##1/žr)'$\FþŸ ]Q%265#"2>54&#""=!"&54>7;432+632#".54>>7M R£#]lH-&%4þø=)ø D^1€dV6Bu×µN“˜qG"/2" W!7NSaU3žRvþ‚þ£=)))(3r05¶ þ!r´(JU7–ÅV32#".54>32>3!+"632#".5476! 7654&#"ùZ+ /)#C.,G ˜_!.,Gq]¤ [5*,#998N! 2L^W$u#22sV/U@WN‚®¹cn»‡jC,i S;ƒv*09­r" '- GD(LYvþ¸&(LZZrŽu:!C.;V,BaGFvL6K&$, û=pPc¡iG#:RZf]0øf  ,<}Nßþï†y1O[5þ½È]BK623254326323254>7+#"'&543!>54#"#"54#"#".53267!"OŸ`%'N¦ •$ ))>¾‚å‡Dq‚ü \*2&(QLF - ¡5[©/þDMh(0h…44¦þÀL[*7= ý‚>,·&>Q4!Qk:;þ…43yxwþ¦[/* þé)8DCþºœY ]lv%4&#"32>6=4#"#".5467&#">32#".54>326323254>7+# 543"32654'&!"3 +/E7&% TpV4qP5L#=8JZBi<*[5 &iS8P 1J‰WpoUnºY¼$ ))>îLâ‹þt‚À"G 6$/9o ¶ý©MFkR#¬2>.377(/ðˆ¥oî Z»o‹@^IJ…0'+,X_µ40—D>H1iU¢Býž&*êZ[547#"3276="+32>32!"#!"&54>7654&#""=&+#".54;547”»>)$. .>E2 ‡ KgT.9T44‚þ”""-6*-DVQ$.=7<`9%|8b•++•25_2Co*2 '•U83VD1L-  ("$$A>HoDPwi‚*@%+:5•W þ”‚[€"=!"54;>54&#"#"547#32?2#"547!"+>3232654>7632#".546;2+"3 7654.#"327mDþ#$¨5G7) #-%*²!.,G8÷ › D-+3#M+Ü>U$4 OzÊ‚·ï{.DP¥3-¥I Jºæ[V," &,)˜RFeA6H ,0($&+*þr&MYœW 2 '­>4#I0Um° ýä@41/WZA*3=-(>!I3(‡F6* B##1/þžXdlx‚%# '&54>32#"'32>54&#"32>75#"=47##".54;547!"+!+632%547#3276=!"%2654#"#^ò™þù´º%>C%)*JBQ,cB%š\œkU1! 2$7 &Ds,LK,Op4|8 ‡  -R>RýóφhMP;þô)þþ%7M*;51eqW9 ¦ÕbI! 8(HK<+&Œ—cŽ0??A.&G 2.Rº ‚4H"(CA$•W 2 '•0~Jbá•++•¡=K2Eo-)(4^V"Bþ´»X„‘˜2632#"5467#"+#".5463!654.#"3267#"&5463#"632#".54>3!+"632325463!+"32>54#"!"32>--H ¬-)>…!dvu?ZŠN1AAv 9',(+!1 Þ1O, 'd &bJ,E$-BqEŸ V 9S%:#%^$#³Pû97)% VHýÎMªyøS)MY06ýè>,4K(&3*9B$IK.&]1! -<3<.=S3S#;%bn/@O5LcR9ò= 2FC%aR7,!4, ýÏ'58(.r.þL:ÿ6/^GW46&#"32>54&#"32673#"&54>7632#"'&5%632#"&74&#"#"326 ];L€±Õµ“+PO/9.<' /!10^EM,D]T-»…RMVªÉ ?.DNÜ% 0('$+T;TIþëáÉÿ:rNI`v0E>3=ª þÔK~^U„L0¨g׈’(–g)8%RDA<%& &þºÚX›¥³%4&#"326262#"5&63#"+! '&543!6=4#"#".5467&#"#".5467&#">32#"&54>32632632325463!+"4&#"32632$7!""32654&(-.& 7'#)5--H ¬-)>ä¢ýÛþ¦Wq‚8QXU!(?=-E$?:HV†[8 W8;KhDOj 7LxIipWj^mVmº6µ$$³Pý"[%"GH9,<ûÿKǪè1^üMñ"F 6$+<\ª4>68?Ë)MY-6ýë>,·&3\4mÀoî Y¼q‰@^IJ†1&Z»Gh4-=N5Jˆ1#d>c9XHfl•l;QMC)..00þürV¶37&9, ýÒ'A\†™CF…rþ­!(6Qb˜CÆFÌu…Fq‚F0FBðKm7|8 › i¤N•$$³Pýþ3M=WN§a•++•‡.C"2Doþ‚)+-Y-6ýë>,Va&=R4gˆOM‚­)CC"•W 2 '• ¢{7&9, ýÒ'?&( þ»nYir%4&#"#"547#3262#"547!"+>3232547!+"3262#"5463#"+#"'&543!6!"326ˆ;2*.%*²!--G8÷ › Z!10›$B³ P#,H¬-)>À2V‚K…Fq‚ø%þEM¡5d¡jU )!X'#Ó+*þr&(NZœW 2 'þÎ/--Z>d@7W ýÒ')+-Y-6ýë>,5@(&=R40b&)8Cþœk\X3 7654.#"326?#"=!"&54>73!2654>7>32!"'.6'6;2+"[7[^4X#" .: -Dþ‹=)D)+()< O‹þüÉR$0  †¥3-¥!à . œ?/)4.#  ,&R<04¶ þ!° ýâ#  59\S’&# ^!þ¸…\CM%265#"%32767!"&54>7;432+#".54632#"'72654#"¹7M RüôùÈuU1þú=)ø D^1€dU.^¼1[jYU;$_VHJR:G-f$9M)92žRvþ‚u»þþL,ž04¶ þ!r´(JU7•Å 7q 2Tmœ_´D@PD= +2^O.>þœ \[3 7654.#"32>7#"=!"&'#"54>73274>7;2654>7>32#".54;2+"\?Ê»V#" ), )DþÒ4,;XhAB)þ (6þñάàv,•¥3-¥?Á(.œ?/)#I# 10RF"%Gd¶ þKeI þ!° ýõ¤Œ¾,7(s!þÊX W2654#""'32654&#"#"547#3262#"547!"+632#"$&54>32¬$9M)7MI* .Ur­h’Ò5$ $-%*²!.,G8÷ › *u4WüÑ¥þõ%>C%ƒU)+2^N/>-=f*Zg[J,Ë¡C9-X($Ó+*þr&(LYœW 2 'þ×lZcÁðyä’bI!@IþººXv„Ž2632#"5463#"#!.'&543!65&=4&#">32#".54>3232=4./632!25463!+"%4&#"32>!"326=--H ¬-)>þØr‡bq‚¸…;P7W/! [5 &$99:V%=ds=2F&tW $*G=Œ$$³Pü+/E7&% þzMagepP)MY-6ýë?+GW =R4*7؇XQ-=Q3:#;%;V,Ws:VˆP("?9-Ç­¤$3& aq{ë>#7$;, ýÒ'ü2>.377(/þÞ&0Fþ”…[ …%4#"3264>54.#">32#".547632!2654>7>32#"$&546;2+"3 7654.#"326?3#"=!"Y'0 :7)"a -, *V91F:/G01U#99-F$?m«;\8# Y-7(4+; OzË‚æþõ_FO¥3-¥? ·ì\V#" &, -DþA¬r)'$\Fs):`:KU: %:jD7,KV;V,/@P3eV™"6KG&Už#° ýí53-UZB*+F8)I!7"(œ=0( B# 10RFþ”“\P\%265#"4&#""=!"&54>7;432+632# 54>32#"'3262654#"Ç7M R—.#%4þø=))ø €h€dV6NiwÀ‚þæþ%>B&)*ICJ* e(†‹v)¤Íü¼$9M( 2Svþ‚Þ6&(3}.6¶ þ r´†vœÀaþ—ÔXŠ”%32>54&#"%"3262#"5467#"3262#"54#"632#"&547632>3!+"632#".54>32#"'! $54&%2654#"í7'% &0, 45!"/+G ˜_!.,Es5L?3;^;K$K5SdCd³s%14sV /N>-!/GrÈv—ø¥xB*92)*N>Q,¡rÊP5ûb%7M*;¾68'-.E#1&^7*LXžxþ¸(*MY\r $8gAYXH!AE*’mha‘J%%,øCF3K/]eYR:"1Vk~u54#"#"54#"#".542325432632325463!+"3267!"ñ,H¬-)>¾GÈiqIq‚ú\*2&(QLF ,!a$&O¦”$#³ Pû¡5\¤0þGMQ)+-Y-6ýë>,aX(=R4"Ir“>;þ43vuþ¦[0+ (0h…42ªþÆŽC7)7 ýÒ'e)8AFþ¼BZ |Š”%4#"3267#"&54>32632325463!+"32632#"5463#"+# 543!6=4&#"#".5467&#">324.#"326!"3 ZE 0)#OmONZ1J‰WpoUnºY¼$#³ P%,H ¬-)>îLâ‹þt‚¡UEC@2(?=-E$=8JZBi<*[5 &a)+"GH8-=:ý«MFkR#­q.3 &- GKR~¤\JgS<11þür·ˆ7'7ýÔ')+-Y56ýí>,X_µ4‡¦o…j!Z»Gh4-=N5I…1'+7;254326;.54>32#"&5473+">32#".546;2.+"!2>54&#"3254&ÿ, H Yc &(QL*Eþú=))î3n!CL=$$BrC¶[16D*AWI³ u'>+,@!8[}‚‘u8/8nGa?<DQ¥`B"x&¥"Ý`ʹwP*,4(BA-E( +.Y—@Uþ¬43yvuþ¦4(/6¶ þ ?h…E?R1;:'”F?D8.9b/L+ þÈ)'@C$MYE)  $5 .?<<&+ !s-U•]:Q,$'2%/]D0;þ¼X (4¤±%4&#"326">54&547#3276=!"%+#"'676?#"54>54.#"632#"&547##".54;547!"+36323767.54>323254.9+/+ 0)#&8 O7 - Aü3φjKP;þó(   $5Q< ." ƒd 0!.D*6,ð>'=;H4( 4H" bML^Gð@b8# |8 › [Eœ$?F2 Fí(1='/E8-G'œ" b; ©3@# &- F¦#3)Bc ,&)=MÊ—++—¡=K2Do.¬(H'2 16'ò"&€l#)P/:U*Q1.\pya$0‚¬):4—V 2 '—Š #8b@M`*70 6Q.5M$*3%þû468  ÿÿþFŠ'åhÇÿÿþ¿$Š'åä×ÿÿ(Š'åÐØÿÿþ³$Š'å,Ùÿÿþ¼Š'å¼ÏþbªY%7262#"54'&#"#"&54632y.,G:q‘&% IQ|vA]D!A(LYØq#]n =  MGN[BoQþ-&þbªD$7262#"54'&#"#"&54632y.,G:^TQ!"Objuc€A(LYØ]#^;(0 E=J^……þ-&&3h °È' ]ž Í Fe$ö,u f œ  º NÏ G 4h ¹ Œ× H¬ X$¢$ †²$H:$T„Copyleft 2002, 2003, 2005 Free Software Foundation.Copyleft 2002, 2003, 2005 Free Software Foundation.FreeSerifFreeSerifMediumMediumFontForge 1.0 : Free Serif : 28-11-2006FontForge 1.0 : Free Serif : 28-11-2006Free SerifFree SerifVersion $Revision: 1.56 $ Version $Revision: 1.56 $ FreeSerifFreeSerifThe use of this font is granted subject to GNU General Public License.The use of this font is granted subject to GNU General Public License.http://www.gnu.org/copyleft/gpl.htmlhttp://www.gnu.org/copyleft/gpl.htmlThe quick brown fox jumps over the lazy dog.The quick brown fox jumps over the lazy dog.navadnoDovoljena je uporaba v skladu z licenco GNU General Public License.http://www.gnu.org/copyleft/gpl.html`erif bo za vajo spet kuhal doma e ~gance.ÿœ2×  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a¬£„…½–膎‹©¤ŠÚƒ“òó—ˆÃÞñžªõôö¢­ÉÇ®bcdËeÈÊÏÌÍÎéfÓÐѯgð‘ÖÔÕhëí‰jikmln oqprsutvwêxzy{}|¸¡~€ìîºýþ    ÿ øù !"#$%&'()*+ú×,-./0123456789:âã;<=>?@ABCDEFGHI°±JKLMNOPQRSûüäåTUVWXYZ[\]^_`abcdefghi»jklmæçnopqrstuvwxyz{|}~€¦‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒØá„…†‡ˆ‰Š‹ŒÛÜÝàÙߎ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ     › !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ                           ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  € ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ Ž ‘ ’ “ ” • – — ˜ ™ š › œ ž Ÿ   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ                           ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  € ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ Ž ‘ ’ “ ” • – — ˜ ™ š › œ ž Ÿ   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ®²³ ¯ °¶·Ä ±´µÅ ²‚‡ ³«Æ ´ µ ¶ · ¸ ¹ º »¾¿ ¼ ½ ¾ ¿ À Á  à ļ Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç÷ è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ         Œ                   ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  € ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ Ž ‘ ’ “ ” • – — ˜˜ ™ 𠛍 œ ž Ÿ   ¡ ¢š £™ï ¤ ¥ ¦ § ¨ © ª¥ « ¬ ­’ ® ¯ ° ± ² ³ ´ µ ¶ ·œ ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í§ Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à ᔕ â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ                           ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  € ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ Ž ‘ ’ “ ” • – — ˜ ™ š › œ ž Ÿ   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ        ¹                   ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  € ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ Ž ‘ ’ “ ” • – — ˜ ™ š › œ ž Ÿ   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿÀÁ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖר softhyphenAmacronamacronAbreveabreveAogonekaogonek Ccircumflex ccircumflex Cdotaccent cdotaccentDcarondcaronDcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflex Gdotaccent gdotaccent Gcommaaccent gcommaaccent Hcircumflex hcircumflexHbarhbarItildeitildeImacronimacronIbreveibreveIogonekiogonekIJij Jcircumflex jcircumflex Kcommaaccent kcommaaccent kgreenlandicLacutelacute Lcommaaccent lcommaaccentLcaronlcaronLdotldotNacutenacute Ncommaaccent ncommaaccentNcaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautRacuteracute Rcommaaccent rcommaaccentRcaronrcaronSacutesacute Scircumflex scircumflexuni0162uni0163TcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflexZacutezacute Zdotaccent zdotaccentlongsuni0180uni0181uni0182uni0183uni0184uni0185uni0186uni0187uni0188uni0189uni018Auni018Buni018Cuni018Duni018Euni018Funi0190uni0191uni0193uni0194uni0195uni0196uni0197uni0198uni0199uni019Auni019Buni019Cuni019Duni019Euni019FOhornohornuni01A2uni01A3uni01A4uni01A5uni01A6uni01A7uni01A8uni01A9uni01AAuni01ABuni01ACuni01ADuni01AEUhornuhornuni01B1uni01B2uni01B3uni01B4uni01B5uni01B6uni01B7uni01B8uni01B9uni01BAuni01BBuni01BCuni01BDuni01BEuni01BFuni01C0uni01C1uni01C2uni01C3uni01C4uni01C5uni01C6uni01C7uni01C8uni01C9uni01CAuni01CBuni01CCuni01CDuni01CEuni01CFuni01D0uni01D1uni01D2uni01D3uni01D4uni01D5uni01D6uni01D7uni01D8uni01D9uni01DAuni01DBuni01DCuni01DDuni01DEuni01DFuni01E0uni01E1uni01E2uni01E3uni01E4uni01E5Gcarongcaronuni01E8uni01E9uni01EAuni01EBuni01ECuni01EDuni01EEuni01EFuni01F0uni01F1uni01F2uni01F3uni01F4uni01F5uni01F6uni01F8uni01F9 Aringacute aringacuteAEacuteaeacute Oslashacute oslashacuteuni0200uni0201uni0202uni0203uni0204uni0205uni0206uni0207uni0208uni0209uni020Auni020Buni020Cuni020Duni020Euni020Funi0210uni0211uni0212uni0213uni0214uni0215uni0216uni0217 Scommaaccent scommaaccent Tcommaaccent tcommaaccentuni021Euni021Funi0226uni0227uni0228uni0229uni022Auni022Buni022Cuni022Duni022Euni022Funi0230uni0231uni0232uni0233uni0235uni0237uni0250uni0251uni0252uni0253uni0254uni0255uni0256uni0257uni0258uni0259uni025Auni025Buni025Cuni025Duni025Euni025Funi0260uni0261uni0262uni0263uni0264uni0265uni0266uni0267uni0268uni0269uni026Auni026Buni026Cuni026Duni026Euni026Funi0270uni0271uni0272uni0273uni0274uni0275uni0276uni0277uni0278uni0279uni027Auni027Buni027Cuni027Duni027Euni027Funi0280uni0281uni0282uni0283uni0284uni0285uni0286uni0287uni0288uni0289uni028Auni028Buni028Cuni028Duni028Euni028Funi0290uni0291uni0292uni0293uni0294uni0295uni0296uni0297uni0298uni0299uni029Auni029Buni029Cuni029Duni029Euni029Funi02A0uni02A1uni02A2uni02A3uni02A4uni02A5uni02A6uni02A7uni02A8uni02A9uni02AAuni02ABuni02ACuni02ADuni02AEuni02AFuni02B0uni02B1uni02B2uni02BAuni02BB afii57929 afii64937uni02BEuni02BFuni02C9uni02CAuni02CBuni02CDuni02CEuni02CFuni02D4uni02D5uni02D6uni02D7uni02EE gravecomb acutecombuni0302 tildecombuni0304uni0305uni0306uni0307uni0308 hookabovecombuni030Auni030Buni030Cuni030Duni030Euni030Funi0310uni0311uni0312uni0313uni0314uni0315uni0316uni0317uni0318uni0319uni031Auni031Buni031Cuni031Duni031Euni031Funi0320uni0321uni0322 dotbelowcombuni0324uni0325uni0326uni0327uni0328uni0329uni032Auni032Buni032Cuni032Duni032Euni032Funi0330uni0331uni0332uni0333uni0334uni0335uni0336uni0337uni0338uni0339uni033Auni033Buni033Cuni033Duni033Euni033Funi0340uni0341uni0342uni0343uni0344uni0345uni0360uni0361uni0374uni0375uni037Auni037Etonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammauni0394EpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsiuni03A9 IotadieresisUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronrhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonosuni03D0theta1Upsilon1uni03D3uni03D4phi1omega1uni03D7uni03DAuni03DBuni03DCuni03DDuni03DEuni03DFuni03E0uni03E1uni03F0uni03F1uni03F2uni0400 afii10023 afii10051 afii10052 afii10053 afii10054 afii10055 afii10056 afii10057 afii10058 afii10059 afii10060 afii10061uni040D afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097uni0450 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109uni045D afii10110 afii10193FL96FL0461hFL0462hFL0463hFL0464hFL0465hFL0466hFL0467hFL0468hFL106FL046ChFL105FL046DhFL046FhFL046EhFL109FL046BhFL0471hFL0472hFL0473hFL0474hFL0475hFL0476hFL0477hFL0478hFL0479hFL047AhFL047BhFL124FL047DhFL126FL047FhFL0480hFL0481hFL0482hFL0483hFL0484hFL0485hFL0486hFL137FL0488hFL0489hFL048Ahuni048Cuni048Duni048Euni048F afii10050 afii10098uni0492uni0493uni0494uni0495uni0496uni0497uni0498uni0499uni049Auni049Buni049Cuni049Duni049Euni049Funi04A0uni04A1uni04A2uni04A3uni04A4uni04A5uni04A6uni04A7uni04A8uni04A9uni04AAuni04ABuni04ACuni04ADuni04AEuni04AFuni04B0uni04B1uni04B2uni04B3uni04B4uni04B5uni04B6uni04B7uni04B8uni04B9uni04BAuni04BBuni04BCuni04BDuni04BEuni04BFuni04C0uni04C1uni04C2uni04C3uni04C4FL04C5hFL198uni04C7uni04C8FL201FL202uni04CBuni04CCFL04CDhFL04CEhFL207uni04D0uni04D1uni04D2uni04D3uni04D4uni04D5uni04D6uni04D7uni04D8 afii10846uni04DAuni04DBuni04DCuni04DDuni04DEuni04DFuni04E0uni04E1uni04E2uni04E3uni04E4uni04E5uni04E6uni04E7uni04E8uni04E9uni04EAuni04EBuni04ECuni04EDuni04EEuni04EFuni04F0uni04F1uni04F2uni04F3uni04F4uni04F5uni04F8uni04F9FL0500hFL0501hFL0502hFL0503hFL0506hFL0507hFL0504hFL0505hFL0508hFL0509hFL050AhFL050BhFL050ChFL050DhFL050FhFL050Eh afii57801 afii57800 afii57793 afii57794 afii57795 afii57798 afii57797 afii57806 afii57796 afii57807 afii57842 afii57658 afii57664 afii57665 afii57666 afii57667 afii57668 afii57669 afii57670 afii57671 afii57672 afii57673 afii57674 afii57675 afii57676 afii57677 afii57678 afii57679 afii57680 afii57681 afii57682 afii57683 afii57684 afii57685 afii57686 afii57687 afii57688 afii57689 afii57690 afii57716 afii57717 afii57718uni05F3uni05F4 afii57388 afii57403 afii57407 afii57409 afii57410 afii57411 afii57412 afii57413 afii57414 afii57415 afii57416 afii57417 afii57418 afii57419 afii57420 afii57421 afii57422 afii57423 afii57424 afii57425 afii57426 afii57427 afii57428 afii57429 afii57430 afii57431 afii57432 afii57433 afii57434 afii57441 afii57442 afii57443 afii57444 afii57445 afii57446 afii57470 afii57448 afii57449 afii57450 afii57451 afii57453 afii57454 afii57455 afii57456 afii57457 afii57392 afii57393 afii57394 afii57395 afii57396 afii57397 afii57398 afii57399 afii57400 afii57401uni066Buni0674 afii57506 afii57507 afii57508 afii57509uni06CCuni06D4uni0780uni0781uni0782uni0783uni0784uni0785uni0786uni0787uni0788uni0789uni078Auni078Buni078Cuni078Duni078Euni078Funi0790uni0791uni0792uni0793uni0794uni0795uni0796uni0797uni0798uni0799uni079Auni079Buni079Cuni079Duni079Euni079Funi07A0uni07A1uni07A2uni07A3uni07A4uni07A5uni07A6uni07A7uni07A8uni07A9uni07AAuni07ABuni07ACuni07ADuni07AEuni07AFuni07B0uni0901uni0902uni0903uni0905uni0906uni0907uni0908uni0909uni090Auni090Buni090Cuni090Duni090Funi0911uni0913uni0914uni0915uni0916uni0917uni0918uni0919uni091Auni091Buni091Cuni091Duni091Euni091Funi0920uni0921uni0922uni0923uni0924uni0925uni0926uni0927uni0928uni0929uni092Auni092Buni092Cuni092Duni092Euni092Funi0930uni0931uni0932uni0933uni0934uni0935uni0937uni0938uni0939uni093Cuni093Duni093Euni093Funi0940uni0941uni0942uni0943uni0944uni0945uni0947uni0948uni0949uni094Buni094Cuni094Duni0950uni0958uni0959uni095Auni095Buni095Cuni095Duni095Euni0960uni0961uni0962uni0963uni0964uni0965uni0966uni0967uni0968uni0969uni096Auni096Buni096Cuni096Duni096Euni096Funi0970bn_candrabindu bn_anusvara bn_visargabn_abn_aabn_ibn_iibn_ubn_uubn_ribn_libn_ebn_aibn_obn_aubn_kabn_khabn_gabn_ghabn_ngabn_cabn_chabn_jabn_jhabn_nyabn_ttabn_tthabn_ddabn_ddhabn_nnabn_tabn_thabn_dabn_dhabn_nabn_pabn_phabn_babn_bhabn_mabn_yabn_rabn_labn_shabn_ssabn_sabn_habn_nukta bn_avagraha bn_aakaarbn_ikaar bn_iikaarbn_ukaar bn_uukaar bn_rikaar bn_rrikaarbn_ekaar bn_aikaarbn_okaar bn_aukaar bn_hasanta Khanda_Ta bn_aumarkbn_rrabn_rhabn_yyabn_rribn_lli bn_likaar bn_llikaarbn_zerobn_onebn_twobn_threebn_fourbn_fivebn_sixbn_sevenbn_eightbn_nine bn_asamira bn_asamiba bn_rupeemark bn_rupeesign bn_currency1 bn_currency2 bn_currency3 bn_currency4bn_currencyless bn_currency16 bn_issharuni0A05uni0A06uni0A07uni0A08uni0A09uni0A0Auni0A0Funi0A10uni0A13uni0A14uni0A15uni0A16uni0A17uni0A18uni0A19uni0A1Auni0A1Buni0A1Cuni0A1Duni0A1Euni0A1Funi0A20uni0A21uni0A22uni0A23uni0A24uni0A25uni0A26uni0A27uni0A28uni0A2Auni0A2Buni0A2Cuni0A2Duni0A2Euni0A2Funi0A30uni0A32uni0A33uni0A35uni0A36uni0A38uni0A39uni0A3Cuni0A3Euni0A3Funi0A40uni0A41uni0A42uni0A47uni0A48uni0A4Buni0A4Cuni0A4Duni0A59uni0A5Auni0A5Buni0A5Cuni0A5Euni0A66uni0A67uni0A68uni0A69uni0A6Auni0A6Buni0A6Cuni0A6Duni0A6Euni0A6Funi0A70uni0A72uni0A73uni0A74PulliAyuthamTamlATamlAATaml_ITaml_IITamlUTamlUUTamlETamlEETamlAITamlOTamlOOTamlAUTamlKATamlNGATamlCATamlJATamlNYATamlTTATamlNNATamlTATamlNATamlNNNATamlPATamlMATamlYATamlRATamlRRATamlLATamlLLATamlLLLATamlVATamlSSATamlSATamlHATaml_v_ATaml_v_I Taml_v_IITaml_v_U Taml_v_UUTaml_v_E Taml_v_EE Taml_v_AI Taml_vow_O Taml_vow_OOTaml_AUsTaml_pulTaml_AUuni0C02uni0C03uni0C05uni0C06uni0C07uni0C08uni0C09uni0C0Auni0C0Buni0C0Cuni0C0Euni0C0Funi0C10uni0C12uni0C13uni0C14uni0C15uni0C16uni0C17uni0C18uni0C19uni0C1Auni0C1Buni0C1Cuni0C1Duni0C1Euni0C1Funi0C20uni0C21uni0C22uni0C23uni0C24uni0C25uni0C26uni0C27uni0C28uni0C2Auni0C2Buni0C2Cuni0C2Duni0C30uni0C32uni0D02uni0D03uni0D05uni0D06uni0D07uni0D08uni0D09uni0D0Auni0D0Bl1uni0D0Euni0D0Funi0D10uni0D12uni0D13uni0D14k1k2k3k4ngch1ch2ch3ch4njt1t2t3t4nhth1th2th3th4n1p1p2p3p4m1y1r3rhl3lhzhv1z1shs1h1uni0D3Euni0D3Funi0D40u1u2r1uni0D46uni0D47uni0D48uni0D4Auni0D4Buni0D4Cxxuni0D57r2l2uni0D66uni0D67uni0D68uni0D69uni0D6Auni0D6Buni0D6Cuni0D6Duni0D6Euni0D6Funi0D70uni0D82uni0D83uni0D85uni0D89uni0D8Auni0D8Buni0D91uni0D94uni0D99uni0D9Auni0D9Buni0D9Cuni0D9Euni0DA0uni0DA1uni0DA2uni0DA4uni0DA5uni0DA7uni0DA8uni0DA9uni0DAAuni0DABuni0DADuni0DAEuni0DAFuni0DB0uni0DB1uni0DB3uni0DB4uni0DB5uni0DB6uni0DB7uni0DB8uni0DB9uni0DBAuni0DBBuni0DBDuni0DC0uni0DC1uni0DC2uni0DC3uni0DC4uni0DC5uni0DC6uni0DCAuni0DCFuni0DD0uni0DD1uni0DD2uni0DD3uni0DD4uni0DD6uni0DD8uni0DD9uni0DDFuni0E01uni0E02uni0E03uni0E04uni0E05uni0E06uni0E07uni0E08uni0E09uni0E0Auni0E0Buni0E0Cuni0E0Duni0E0Euni0E0Funi0E10uni0E11uni0E12uni0E13uni0E14uni0E15uni0E16uni0E17uni0E18uni0E19uni0E1Auni0E1Buni0E1Cuni0E1Duni0E1Euni0E1Funi0E20uni0E21uni0E22uni0E23uni0E24uni0E25uni0E26uni0E27uni0E28uni0E29uni0E2Auni0E2Buni0E2Cuni0E2Duni0E2Euni0E2Funi0E30uni0E31uni0E32uni0E33uni0E34uni0E35uni0E36uni0E37uni0E38uni0E39uni0E3Auni0E3Funi0E40uni0E41uni0E42uni0E43uni0E44uni0E45uni0E46uni0E47uni0E48uni0E49uni0E4Auni0E4Buni0E4Cuni0E4Duni0E4Euni0E4Funi0E50uni0E51uni0E52uni0E53uni0E54uni0E55uni0E56uni0E57uni0E58uni0E59uni0E5Auni0E5Buni10A0uni10A1uni10A2uni10A3uni10A4uni10A5uni10A6uni10A7uni10A8uni10A9uni10AAuni10ABuni10ACuni10ADuni10AEuni10AFuni10B0uni10B1uni10B2uni10B3uni10B4uni10B5uni10B6uni10B7uni10B8uni10B9uni10BAuni10BBuni10BCuni10BDuni10BEuni10BFuni10C0uni10C1uni10C2uni10C3uni10C4uni10C5uni10D0uni10D1uni10D2uni10D3uni10D4uni10D5uni10D6uni10D7uni10D8uni10D9uni10DAuni10DBuni10DCuni10DDuni10DEuni10DFuni10E0uni10E1uni10E2uni10E3uni10E4uni10E5uni10E6uni10E7uni10E8uni10E9uni10EAuni10EBuni10ECuni10EDuni10EEuni10EFuni10F0uni10F1uni10F2uni10F3uni10F4uni10F5uni1200uni1201uni1202uni1203uni1204uni1205uni1206uni1208uni1209uni120Auni120Buni120Cuni120Duni120Euni120Funi1210uni1211uni1212uni1213uni1214uni1215uni1216uni1217uni1218uni1219uni121Auni121Buni121Cuni121Duni121Euni121Funi1220uni1221uni1222uni1223uni1224uni1225uni1226uni1227uni1228uni1229uni122Auni122Buni122Cuni122Duni122Euni122Funi1230uni1231uni1232uni1233uni1234uni1235uni1236uni1237uni1238uni1239uni123Auni123Buni123Cuni123Duni123Euni123Funi1240uni1241uni1242uni1243uni1244uni1245uni1246uni1248uni124Auni124Buni124Cuni124Duni1250uni1251uni1252uni1253uni1254uni1255uni1256uni1258uni125Auni125Buni125Cuni125Duni1260uni1261uni1262uni1263uni1264uni1265uni1266uni1267uni1268uni1269uni126Auni126Buni126Cuni126Duni126Euni126Funi1270uni1271uni1272uni1273uni1274uni1275uni1276uni1277uni1278uni1279uni127Auni127Buni127Cuni127Duni127Euni127Funi1280uni1281uni1282uni1283uni1284uni1285uni1286uni1288uni128Auni128Buni128Cuni128Duni1290uni1291uni1292uni1293uni1294uni1295uni1296uni1297uni1298uni1299uni129Auni129Buni129Cuni129Duni129Euni129Funi12A0uni12A1uni12A2uni12A3uni12A4uni12A5uni12A6uni12A7uni12A8uni12A9uni12AAuni12ABuni12ACuni12ADuni12AEuni12B0uni12B2uni12B3uni12B4uni12B5uni12B8uni12B9uni12BAuni12BBuni12BCuni12BDuni12BEuni12C0uni12C1uni12C2uni12C3uni12C4uni12C5uni12C8uni12C9uni12CAuni12CBuni12CCuni12CDuni12CEuni12D0uni12D1uni12D2uni12D3uni12D4uni12D5uni12D6uni12D8uni12D9uni12DAuni12DBuni12DCuni12DDuni12DEuni12DFuni12E0uni12E1uni12E2uni12E3uni12E4uni12E5uni12E6uni12E7uni12E8uni12E9uni12EAuni12EBuni12ECuni12EDuni12EEuni12F0uni12F1uni12F2uni12F3uni12F4uni12F5uni12F6uni12F7uni12F8uni12F9uni12FAuni12FBuni12FCuni12FDuni12FEuni12FFuni1300uni1301uni1302uni1303uni1304uni1305uni1306uni1307uni1308uni1309uni130Auni130Buni130Cuni130Duni130Euni1310uni1312uni1313uni1314uni1315uni1318uni1319uni131Auni131Buni131Cuni131Duni131Euni1320uni1321uni1322uni1323uni1324uni1325uni1326uni1327uni1328uni1329uni132Auni132Buni132Cuni132Duni132Euni132Funi1330uni1331uni1332uni1333uni1334uni1335uni1336uni1337uni1338uni1339uni133Auni133Buni133Cuni133Duni133Euni133Funi1340uni1341uni1342uni1343uni1344uni1345uni1346uni1348uni1349uni134Auni134Buni134Cuni134Duni134Euni134Funi1350uni1351uni1352uni1353uni1354uni1355uni1356uni1357uni1358uni1359uni135Auni1361uni1362uni1363uni1364uni1365uni1366uni1367uni1368uni1369uni136Auni136Buni136Cuni136Duni136Euni136Funi1370uni1371uni1372uni1373uni1374uni1375uni1376uni1377uni1378uni1379uni137Auni137Buni137Cuni1D00uni1D03uni1D05uni1D07uni1D0Buni1D0Cuni1D0Duni1D0Euni1D1Buni1D1Cuni1D20uni1D21uni1D22uni1D29uni1D81uni1D84uni1D85uni1D87uni1D8Duni1E00uni1E01uni1E02uni1E03uni1E04uni1E05uni1E06uni1E07uni1E08uni1E09uni1E0Auni1E0Buni1E0Cuni1E0Duni1E0Euni1E0Funi1E10uni1E11uni1E12uni1E13uni1E14uni1E15uni1E16uni1E17uni1E18uni1E19uni1E1Auni1E1Buni1E1Cuni1E1Duni1E1Euni1E1Funi1E20uni1E21uni1E22uni1E23uni1E24uni1E25uni1E26uni1E27uni1E28uni1E29uni1E2Auni1E2Buni1E2Cuni1E2Duni1E2Euni1E2Funi1E30uni1E31uni1E32uni1E33uni1E34uni1E35uni1E36uni1E37uni1E38uni1E39uni1E3Auni1E3Buni1E3Cuni1E3Duni1E3Euni1E3Funi1E40uni1E41uni1E42uni1E43uni1E44uni1E45uni1E46uni1E47uni1E48uni1E49uni1E4Auni1E4Buni1E4Cuni1E4Duni1E4Euni1E4Funi1E50uni1E51uni1E52uni1E53uni1E54uni1E55uni1E56uni1E57uni1E58uni1E59uni1E5Auni1E5Buni1E5Cuni1E5Duni1E5Euni1E5Funi1E60uni1E61uni1E62uni1E63uni1E64uni1E65uni1E66uni1E67uni1E68uni1E69uni1E6Auni1E6Buni1E6Cuni1E6Duni1E6Euni1E6Funi1E70uni1E71uni1E72uni1E73uni1E74uni1E75uni1E76uni1E77uni1E78uni1E79uni1E7Auni1E7Buni1E7Cuni1E7Duni1E7Euni1E7FWgravewgraveWacutewacute Wdieresis wdieresisuni1E86uni1E87uni1E88uni1E89uni1E8Auni1E8Buni1E8Cuni1E8Duni1E8Euni1E8Funi1E90uni1E91uni1E92uni1E93uni1E94uni1E95uni1E96uni1E97uni1E98uni1E99uni1E9Auni1E9Buni1EA0uni1EA1uni1EA2uni1EA3uni1EA4uni1EA5uni1EA6uni1EA7uni1EA8uni1EA9uni1EAAuni1EABuni1EACuni1EADuni1EAEuni1EAFuni1EB0uni1EB1uni1EB2uni1EB3uni1EB4uni1EB5uni1EB6uni1EB7uni1EB8uni1EB9uni1EBAuni1EBBuni1EBCuni1EBDuni1EBEuni1EBFuni1EC0uni1EC1uni1EC2uni1EC3uni1EC4uni1EC5uni1EC6uni1EC7uni1EC8uni1EC9uni1ECAuni1ECBuni1ECCuni1ECDuni1ECEuni1ECFuni1ED0uni1ED1uni1ED2uni1ED3uni1ED4uni1ED5uni1ED6uni1ED7uni1ED8uni1ED9uni1EDAuni1EDBuni1EDCuni1EDDuni1EDEuni1EDFuni1EE0uni1EE1uni1EE2uni1EE3uni1EE4uni1EE5uni1EE6uni1EE7uni1EE8uni1EE9uni1EEAuni1EEBuni1EECuni1EEDuni1EEEuni1EEFuni1EF0uni1EF1Ygraveygraveuni1EF4uni1EF5uni1EF6uni1EF7uni1EF8uni1EF9uni1F00uni1F01uni1F02uni1F03uni1F04uni1F05uni1F06uni1F07uni1F08uni1F09uni1F0Auni1F0Buni1F0Cuni1F0Duni1F0Euni1F0Funi1F10uni1F11uni1F12uni1F13uni1F14uni1F15uni1F18uni1F19uni1F1Auni1F1Buni1F1Cuni1F1Duni1F20uni1F21uni1F22uni1F23uni1F24uni1F25uni1F26uni1F27uni1F28uni1F29uni1F2Auni1F2Buni1F2Cuni1F2Duni1F2Euni1F2Funi1F30uni1F31uni1F32uni1F33uni1F34uni1F35uni1F36uni1F37uni1F38uni1F39uni1F3Auni1F3Buni1F3Cuni1F3Duni1F3Euni1F3Funi1F40uni1F41uni1F42uni1F43uni1F44uni1F45uni1F48uni1F49uni1F4Auni1F4Buni1F4Cuni1F4Duni1F50uni1F51uni1F52uni1F53uni1F54uni1F55uni1F56uni1F57uni1F59uni1F5Buni1F5Duni1F5Funi1F60uni1F61uni1F62uni1F63uni1F64uni1F65uni1F66uni1F67uni1F68uni1F69uni1F6Auni1F6Buni1F6Cuni1F6Duni1F6Euni1F6Funi1F70uni1F71uni1F72uni1F73uni1F74uni1F75uni1F76uni1F77uni1F78uni1F79uni1F7Auni1F7Buni1F7Cuni1F7Duni1F80uni1F81uni1F82uni1F83uni1F84uni1F85uni1F86uni1F87uni1F88uni1F89uni1F8Auni1F8Buni1F8Cuni1F8Duni1F8Euni1F8Funi1F90uni1F91uni1F92uni1F93uni1F94uni1F95uni1F96uni1F97uni1F98uni1F99uni1F9Auni1F9Buni1F9Cuni1F9Duni1F9Euni1F9Funi1FA0uni1FA1uni1FA2uni1FA3uni1FA4uni1FA5uni1FA6uni1FA7uni1FA8uni1FA9uni1FAAuni1FABuni1FACuni1FADuni1FAEuni1FAFuni1FB0uni1FB1uni1FB2uni1FB3uni1FB4uni1FB6uni1FB7uni1FB8uni1FB9uni1FBAuni1FBBuni1FBCuni1FBDuni1FBEuni1FBFuni1FC0uni1FC1uni1FC2uni1FC3uni1FC4uni1FC6uni1FC7uni1FC8uni1FC9uni1FCAuni1FCBuni1FCCuni1FCDuni1FCEuni1FCFuni1FD0uni1FD1uni1FD2uni1FD3uni1FD6uni1FD7uni1FD8uni1FD9uni1FDAuni1FDBuni1FDDuni1FDEuni1FDFuni1FE0uni1FE1uni1FE2uni1FE3uni1FE4uni1FE5uni1FE6uni1FE7uni1FE8uni1FE9uni1FEAuni1FEBuni1FECuni1FEDuni1FEEuni1FEFuni1FF2uni1FF3uni1FF4uni1FF6uni1FF7uni1FF8uni1FF9uni1FFAuni1FFBuni1FFCuni1FFDuni1FFE afii61664afii301uni2010uni2011 figuredash afii00208 underscoredbl quotereverseduni201Funi2023uni2031minuteseconduni2034uni2035uni2036uni2037uni2038uni203B exclamdbluni203Duni203Euni203Funi2040uni2041uni2042uni2043uni2045uni2046uni2047uni2048uni2049uni204Auni204B zerosuperioruni2071 foursuperior fivesuperior sixsuperior sevensuperior eightsuperior ninesuperioruni207Auni207Buni207Cuni207F zeroinferior oneinferior twoinferior threeinferior fourinferior fiveinferior sixinferior seveninferior eightinferior nineinferioruni208Auni208Buni208Cuni20A0 colonmonetaryuni20A2lirauni20A5uni20A6pesetauni20A8uni20A9Eurouni20AFuni20B2uni20DDuni2102uni2103 afii61248uni2109uni210Auni210Buni210Cuni210Duni210Euni210Funi2110Ifrakturuni2112 afii61289uni2115 afii61352uni2117 weierstrassuni2119uni211Auni211BRfrakturuni211D prescriptionuni211Funi2120uni2123uni2124uni2126uni2127uni2128uni212Auni212Buni212Cuni212D estimateduni2130uni2131uni2132uni2133alephuni2136uni2137uni2138uni2139onethird twothirdsuni2155uni2156uni2157uni2158uni2159uni215A oneeighth threeeighths fiveeighths seveneighthsuni215Funi2160uni2161uni2162uni2163uni2164uni2165uni2166uni2167uni2168uni2169uni216Auni216Buni216Cuni216Duni216Euni216Funi2170uni2171uni2172uni2173uni2174uni2175uni2176uni2177uni2178uni2179uni217Auni217Buni217Cuni217Duni217Euni217F arrowleftarrowup arrowright arrowdown arrowboth arrowupdnuni2196uni2197uni2198uni2199uni219Auni219Buni219Cuni219Duni219Euni219Funi21A0uni21A1uni21A2uni21A3uni21A4uni21A5uni21A6uni21A7 arrowupdnbseuni21ABuni21ACuni21ADuni21AEuni21B0uni21B1uni21B2uni21B3uni21B4carriagereturnuni21B6uni21B7uni21BAuni21BBuni21BCuni21BDuni21BEuni21BFuni21C0uni21C1uni21C2uni21C3uni21C4uni21C5uni21C6uni21C7uni21C8uni21C9uni21CAuni21CBuni21CCuni21CDuni21CEuni21CF arrowdblleft arrowdblup arrowdblright arrowdbldown arrowdblbothuni21D5uni21D6uni21D7uni21D8uni21D9uni21DAuni21DBuni21DCuni21DDuni21E0uni21E2 universaluni2201 existentialuni2204emptysetgradientelement notelementuni220Asuchthatuni220Cuni220Duni2210uni2213uni2214uni2215uni2216 asteriskmathuni2218uni2219uni221Buni221C proportional orthogonalangleuni2221uni2222uni2225uni2226 logicaland logicalor intersectionunionuni222Cuni222Duni222Euni222F thereforeuni2235uni2236uni2237uni2238uni2239uni223Auni223Bsimilaruni223Duni2240uni2241uni2242uni2243uni2244 congruentuni2246uni2247uni2249uni224Auni224Buni224Duni224Euni224Funi2250uni2251uni2252uni2253uni2254uni2255uni2256uni2257uni2259uni225Auni225C equivalenceuni2262uni2263uni2266uni2267uni2268uni2269uni226Auni226Buni226Cuni226Duni226Euni226Funi2270uni2271uni2272uni2273uni2274uni2275uni2276uni2277uni2278uni2279uni227Auni227Buni227Cuni227Duni227Euni227Funi2280uni2281 propersubsetpropersuperset notsubsetuni2285 reflexsubsetreflexsupersetuni2288uni2289uni228Auni228Buni228Cuni228Duni228Euni228Funi2290uni2291uni2292uni2293uni2294 circleplusuni2296circlemultiplyuni2298uni2299uni229Auni229Buni229Cuni229Duni229Euni229Funi22A0uni22A1uni22A2uni22A3uni22A4 perpendicularuni22A6uni22A7uni22A9uni22AAuni22ABuni22ACuni22ADuni22AEuni22AFuni22B2uni22B3uni22B4uni22B5uni22B6uni22B7uni22B8uni22BAuni22BBuni22BCuni22BDuni22C0uni22C1uni22C2uni22C3uni22C4dotmathuni22C6uni22C7uni22C8uni22CBuni22CCuni22CDuni22CEuni22CFuni22D0uni22D1uni22D2uni22D3uni22D4uni22D5uni22D6uni22D7uni22D8uni22D9uni22DAuni22DBuni22DCuni22DDuni22DEuni22DFuni22E0uni22E1uni22E2uni22E3uni22E4uni22E5uni22E6uni22E7uni22E8uni22E9uni22EAuni22EBuni22ECuni22EDuni22EEuni22EFuni22F0uni22F1uni2300uni2301uni2308uni2309uni230Auni230B revlogicalnotuni231A integraltp integralbtuni2322uni2323 angleleft anglerightuni2347uni2348uni2350uni2357uni235Euni23AEuni2423uni2460uni2461uni2462uni2463uni2464uni2465uni2466uni2467uni2468uni2469SF100000uni2501SF110000uni2503uni2504uni2505uni2506uni2507uni2508uni2509uni250Auni250BSF010000uni250Duni250Euni250FSF030000uni2511uni2512uni2513SF020000uni2515uni2516uni2517SF040000uni2519uni251Auni251BSF080000uni251Duni251Euni251Funi2520uni2521uni2522uni2523SF090000uni2525uni2526uni2527uni2528uni2529uni252Auni252BSF060000uni252Duni252Euni252Funi2530uni2531uni2532uni2533SF070000uni2535uni2536uni2537uni2538uni2539uni253Auni253BSF050000uni253Duni253Euni253Funi2540uni2541uni2542uni2543uni2544uni2545uni2546uni2547uni2548uni2549uni254Auni254BSF430000SF240000SF510000SF520000SF390000SF220000SF210000SF250000SF500000SF490000SF380000SF280000SF270000SF260000SF360000SF370000SF420000SF190000SF200000SF230000SF470000SF480000SF410000SF450000SF460000SF400000SF540000SF530000SF440000uni256Dupblockuni2581uni2582uni2583dnblockuni2585uni2586uni2587blockuni2589uni258Auni258Blfblockuni258Duni258Euni258Frtblockuni2594uni2595 filledboxH22073triagupuni25B6triagdnuni25C0uni25C6circleuni25CCH18533uni25D0uni25D1uni25D2uni25D3uni25D4uni25D5uni25D6uni25D7uni25E2uni25E3uni25E4uni25E5uni25E7uni25E8uni25E9uni25EAuni2605uni2606uni260Cuni260Duni260Euni2610uni2611uni2612uni2619uni261Auni261Buni261Cuni261Duni261Euni261Funi2620uni2622uni2623uni2626uni2628uni262Auni262Cuni262Euni262Funi2630uni2631uni2632uni2633uni2634uni2635uni2636uni2637uni2638uni2639 smileface invsmilefacesununi263Duni263Euni263Ffemaleuni2641maleuni2643uni2644uni2645uni2646uni2647uni2648uni2649uni264Auni264Buni264Cuni264Duni264Euni264Funi2650uni2651uni2652uni2653uni2654uni2655uni2656uni2657uni2658uni2659uni265Auni265Buni265Cuni265Duni265Euni265Fspadeuni2661uni2662clubheartdiamonduni2669 musicalnotemusicalnotedbluni266Cuni266Duni266Euni266Funi2670uni2671uni2701uni2702uni2703uni2704uni2706uni2707uni2708uni2709uni270Cuni270Duni270Euni270Funi2710uni2711uni2712uni2713uni2714uni2715uni2716uni2717uni2718uni2719uni271Auni271Buni271Cuni271Duni271Euni271Funi2720uni2721uni2722uni2723uni2724uni2725uni2726uni2727uni2729uni272Auni272Buni272Cuni272Duni272Euni272Funi2730uni2731uni2732uni2733uni2734uni2735uni2736uni2737uni2738uni2739uni273Auni273Buni273Cuni273Duni273Euni273Funi2740uni2741uni2742uni2743uni2744uni2745uni2746uni2747uni2748uni2749uni274Auni274Buni274Duni274Funi2750uni2751uni2752uni2756uni2758uni2759uni275Auni275Buni275Cuni275Duni275Euni2761uni2762uni2763uni2764uni2765uni2766uni2767uni2776uni2777uni2778uni2779uni277Auni277Buni277Cuni277Duni277Euni277Funi2780uni2781uni2782uni2783uni2784uni2785uni2786uni2787uni2788uni2789uni278Auni278Buni278Cuni278Duni278Euni278Funi2790uni2791uni2792uni2793uni2794uni2798uni2799uni279Auni279Buni279Cuni279Duni279Euni279Funi27A0uni27A1uni27A2uni27A3uni27A4uni27A5uni27A6uni27A7uni27A8uni27A9uni27AAuni27ABuni27ACuni27ADuni27AEuni27AFuni27B1uni27B2uni27B3uni27B4uni27B5uni27B6uni27B7uni27B8uni27B9uni27BAuni27BBuni27BCuni27BDuni27BEuni3001uni3002uni3003uni3005uni3007uni3008uni3009uni300Auni300Buni300Cuni300Duni300Euni300Funi3010uni3011uni3012uni3014uni3015uni3041uni3042uni3043uni3044uni3045uni3046uni3047uni3048uni3049uni304Auni304Buni304Cuni304Duni304Euni304Funi3050uni3051uni3052uni3053uni3054uni3055uni3056uni3057uni3058uni3059uni305Auni305Buni305Cuni305Duni305Euni305Funi3060uni3061uni3062uni3063uni3064uni3065uni3066uni3067uni3068uni3069uni306Auni306Buni306Cuni306Duni306Euni306Funi3070uni3071uni3072uni3073uni3074uni3075uni3076uni3077uni3078uni3079uni307Auni307Buni307Cuni307Duni307Euni307Funi3080uni3081uni3082uni3083uni3084uni3085uni3086uni3087uni3088uni3089uni308Auni308Buni308Cuni308Duni308Euni308Funi3090uni3091uni3092uni3093uni3094uni3099uni309Buni30A1uni30A2uni30A3uni30A4uni30A5uni30A6uni30A7uni30A8uni30A9uni30AAuni30ABuni30ACuni30ADuni30AEuni30AFuni30B0uni30B1uni30B2uni30B3uni30B4uni30B5uni30B6uni30B7uni30B8uni30B9uni30BAuni30BBuni30BCuni30BDuni30BEuni30BFuni30C0uni30C1uni30C2uni30C3uni30C4uni30C5uni30C6uni30C7uni30C8uni30C9uni30CAuni30CBuni30CCuni30CDuni30CEuni30CFuni30D0uni30D1uni30D2uni30D3uni30D4uni30D5uni30D6uni30D7uni30D8uni30D9uni30DAuni30DBuni30DCuni30DDuni30DEuni30DFuni30E0uni30E1uni30E2uni30E3uni30E4uni30E5uni30E6uni30E7uni30E8uni30E9uni30EAuni30EBuni30ECuni30EDuni30EEuni30EFuni30F0uni30F1uni30F2uni30F3uni30F4uni30F5uni30F6uni30F7uni30F8uni30F9uni30FAuni30FBuni30FCuniF639uniF63AuniF63BuniF63CuniF63DuniF63EuniF63FuniF640uniF641uniF6BE commaaccentcopyrightserif registerseriftrademarkserif onefitted arrowvertex arrowhorizex registersans copyrightsans trademarksans parenlefttp parenleftex parenleftbt bracketlefttp bracketleftex bracketleftbt bracelefttp braceleftmid braceleftbtbraceex integralex parenrighttp parenrightex parenrightbtbracketrighttpbracketrightexbracketrightbt bracerighttp bracerightmid bracerightbtffffiffluniFB06 afii57694 afii57695uniFB2CuniFB2DuniFB2EuniFB2FuniFB30uniFB31uniFB32uniFB33uniFB34 afii57723uniFB36uniFB38uniFB39uniFB3AuniFB3BuniFB3CuniFB3EuniFB40uniFB41uniFB43uniFB44uniFB46uniFB47uniFB48uniFB49uniFB4A afii57700uniFB4CuniFB4DuniFB4EuniFB56uniFB57uniFB58uniFB59uniFB7AuniFB7BuniFB7CuniFB7DuniFB8AuniFB8BuniFB92uniFB93uniFB94uniFB95uniFBFCuniFBFDuniFBFEuniFBFFuniFDF2uniFDFCuniFE70uniFE74uniFE76uniFE78uniFE7AuniFE7CuniFE81uniFE8CuniFE8DuniFE8EuniFE8FuniFE90uniFE91uniFE92uniFE95uniFE96uniFE97uniFE98uniFE99uniFE9AuniFE9BuniFE9CuniFE9DuniFE9EuniFE9FuniFEA0uniFEA1uniFEA2uniFEA3uniFEA4uniFEA5uniFEA6uniFEA7uniFEA8uniFEA9uniFEAAuniFEABuniFEACuniFEADuniFEAEuniFEAFuniFEB0uniFEB1uniFEB2uniFEB3uniFEB4uniFEB5uniFEB6uniFEB7uniFEB8uniFEB9uniFEBAuniFEBBuniFEBCuniFEBDuniFEBEuniFEBFuniFEC0uniFEC1uniFEC5uniFEC9uniFECAuniFECBuniFECCuniFECDuniFECEuniFECFuniFED0uniFED1uniFED2uniFED3uniFED4uniFED5uniFED6uniFED7uniFED8uniFED9uniFEDAuniFEDBuniFEDCuniFEDDuniFEDEuniFEDFuniFEE0uniFEE1uniFEE2uniFEE3uniFEE4uniFEE5uniFEE6uniFEE7uniFEE8uniFEE9uniFEEAuniFEEBuniFEECuniFEEDuniFEEEuniFEFBuniFEFCuniFFFD uni0937091Fr4xxx1y2y2u1y2u2v2 NameMe-195550 NameMe-195551k1xxnhxxn1xxl3xxlhxxr3xxk1u1k1u2k1r1k1r2k1l1k1k1k1k1u1k1k1u2k1k1r1k1k1r3k1k1r3u1k1k1r3u2k1t1k1t1u1k1t1u2k1t1r3k1t1r3u1k1t1r3u2k1t1nhk1nhu1k1nhu2k1th1k1th1u1k1th1u2k1th1r1k1th1r2k1th1r3 k1th1r3u1 k1th1r3u2k1n1k1n1u1k1n1u2k1m1k1m1u1k1m1u2k1r3k1r3u1k1r3u2k1l3k1l3u1k1l3u2k1shk1shu1k1shu2k1shr1k1shnhk1shnhu1k1shnhu2k1shm1k1shm1u1k1shm1u2k1shm1r1k1s1k1s1u1k1s1u2k1s1r1k1rhrhk1rhrhu1k1rhrhu2k2u1k2u2k2r1k3u1k3u2k3r1k3r2k3k3k3k3u1k3k3u2k3k3r1k3k4k3k4u1k3k4u2k3k4r1k3th3k3th3u1k3th3u2k3th3r1k3th3th4 k3th3th4u1 k3th3th4u2 k3th3th4r1 k3th3th4r3 k3th3th4r3u1 k3th3th4r3u2k3n1k3n1u1k3n1u2k3m1k3m1u1k3m1u2k3r3k3r3u1k3r3u2k3l3k3l3u1k3l3u2k4u1k4u2k4r1k4r2k4n1k4n1u1k4n1u2k4r3k4r3u1k4r3u2ngu1ngu2ngk1ngk1u1ngk1u2ngk1r1ngngngngu1ngngu2ch1u1ch1u2ch1ch1ch1ch1u1ch1ch1u2ch1ch2ch1ch2u1ch1ch2u2ch1ch2r1ch1ch2r3 ch1ch2r3u1 ch1ch2r3u2ch2u1ch2u2ch2r1ch2r3ch2r3u1ch2r3u2ch3u1ch3u2ch3r1ch3r2ch3ch3ch3ch3u1ch3ch3u2ch3ch3r1ch3njch3nju1ch3nju2ch3r3ch3r3u1ch3r3u2ch4u1ch4u2ch4r1ch4r2ch4r3ch4r3u1ch4r3u2nju1nju2njch1njch1u1njch1u2njch1r1njch2njch2u1njch2u2njch2r1njch3njch3u1njch3u2njnjnjnju1njnju2t1u1t1u2t1r1t1r2t1t1t1t1u1t1t1u2t1r3t1r3u1t1r3u2t2u1t2u2t3u1t3u2t3r1t3t3t3t3u1t3t3u2t3t4t3t4u1t3t4u2t3m1t3m1u1t3m1u2t3m1r1t3r3t3r3u1t3r3u2t4u1t4u2t4r1t4r3t4r3u1t4r3u2nhu1nhu2nht1nht1u1nht1u2nht1r3nht1r3u1nht1r3u2nht2nht3nht3u1nht3u2nht3r1nht3r3nht3r3u1nht3r3u2nht4nht4u1nht4u2nht4r1nhnhnhnhu1nhnhu2nhm1nhm1u1nhm1u2th1u1th1u2th1r1th1r2th1th1th1th1u1th1th1u2th1th1r1th1th1r2th1th1r3 th1th1r3u1 th1th1r3u2th1th2th1th2u1th1th2u2th1th2r1th1n1th1p4th1p4u1th1p4u2th1p4r1th1m1th1m1u1th1m1u2th1m1r1th1r3th1r3u1th1r3u2th1l3th1l3u1th1l3u2th1s1th1s1u1th1s1u2th1s1r1th1s1r2th1s1th2 th1s1th2u1 th1s1th2u2 th1s1th2r1th1s1n1 th1s1n1u1 th1s1n1u2th1s1m1 th1s1m1u1 th1s1m1u2 th1s1m1r1th1s1r3 th1s1r3u1 th1s1r3u2th2u1th2u2th2n1th2n1u1th2n1u2th2m1th2m1u1th2m1u2th2m1r1th3u1th3u2th3r1th3r2th3th3th3th3u1th3th3u2th3th3r1th3th3r2th3th4th3th4u1th3th4u2th3th4r1th3th4r2th3th4n1 th3th4n1u1 th3th4n1u2th3th4m1 th3th4m1u1 th3th4m1u2 th3th4m1r1th3th4r3 th3th4r3u1 th3th4r3u2th3r3th3r3u1th3r3u2th4u1th4u2th4r1th4r2th4n1th4n1u1th4n1u2th4m1th4m1u1th4m1u2th4m1r1th4r3th4r3u1th4r3u2n1u1n1u2n1r1n1r2n1th1n1th1u1n1th1u2n1th1r1n1th1r2n1th1r3 n1th1r3u1 n1th1r3u2n1th2n1th2u1n1th2u2n1th2r1n1th2r2n1th3n1th3u1n1th3u2n1th3r1n1th3r3 n1th3r3u1 n1th3r3u2n1th4n1th4u1n1th4u2n1th4r1n1th4r3 n1th4r3u1 n1th4r3u2n1n1n1n1u1n1n1u2n1n1r1n1n1r3n1n1r3u1n1n1r3u2n1m1n1m1u1n1m1u2n1m1r1n1m1r3n1m1r3u1n1m1r3u2n1r3n1r3u1n1r3u2n1rhn1rhu1n1rhu2p1u1p1u2p1r1p1r2p1t1p1t1u1p1t1u2p1th1p1th1u1p1th1u2p1th1r1p1th1r2p1n1p1n1u1p1n1u2p1p1p1p1u1p1p1u2p1p1r1p1p2p1p2u1p1p2u2p1r3p1r3u1p1r3u2p1l3p1l3u1p1l3u2p1s1p1s1u1p1s1u2p1s1r1p1s1r3p1s1r3u1p1s1r3u2p2u1p2u2p2k1p2k1u1p2k1u2p2t1p2t1u1p2t1u2p2th1p2th1u1p2th1u2p2th1r1p2n1p2n1u1p2n1u2p2p1p2p1u1p2p1u2p2m1p2m1u1p2m1u2p2r3p2r3u1p2r3u2p2l3p2l3u1p2l3u2p2s1p2s1u1p2s1u2p2s1r1p2rhrhp2rhrhu1p2rhrhu2p3u1p3u2p3r1p3k3p3k3u1p3k3u2p3k3r1p3ch3p3ch3u1p3ch3u2p3ch3r1p3th3p3th3u1p3th3u2p3th3r1p3th4p3th4u1p3th4u2p3th4r1p3th4r2p3n1p3n1u1p3n1u2p3p3p3p3u1p3p3u2p3p4p3r3p3r3u1p3r3u2p3l3p3l3u1p3l3u2p4u1p4u2p4r1p4r2p4r3p4r3u1p4r3u2m1u1m1u2m1r1m1r2m1n1m1n1u1m1n1u2m1p1m1p1u1m1p1u2m1p1r1m1p1r3m1p1r3u1m1p1r3u2m1m1m1m1u1m1m1u2m1m1r1m1r3m1r3u1m1r3u2m1l3m1l3u1m1l3u2y1u1y1u2y1r1y1k1y1k1u1y1k1u2y1k1r1y1k1k1y1k1k1u1y1k1k1u2y1ch1y1ch1u1y1ch1u2y1th1y1th1u1y1th1u2y1th1r1y1th1th1 y1th1th1u1 y1th1th1u2 y1th1th1r1y1n1y1n1u1y1n1u2y1p1y1p1u1y1p1u2y1p1r1y1m1y1m1u1y1m1u2y1m1r1y1y1y1y1u1y1y1u2r3u1r3u2r3r1l3u1l3u2l3r1l3k1l3k1u1l3k1u2l3k1r1l3k1k1l3k1k1u1l3k1k1u2l3k3l3k3u1l3k3u2l3k3r1l3ch1l3ch1u1l3ch1u2l3th1l3th1u1l3th1u2l3th1r1l3th1th1 l3th1th1u1 l3th1th1u2l3p1l3p1u1l3p1u2l3p1r3l3p1r3u1l3p1r3u2l3p2l3p2u1l3p2u2l3p3l3p3u1l3p3u2l3m1l3m1u1l3m1u2l3l3l3l3u1l3l3u2v1u1v1u2v1r1v1r3v1r3u1v1r3u2v1l3v1l3u1v1l3u2v1v1v1v1u1v1v1u2z1u1z1u2z1r1z1ch1z1ch1u1z1ch1u2z1ch1r1z1ch2z1ch2u1z1ch2u2z1ch2r1z1n1z1n1u1z1n1u2z1m1z1m1u1z1m1u2z1m1r1z1r3z1r3u1z1r3u2z1l3z1l3u1z1l3u2z1z1z1z1u1z1z1u2z1z1r1z1z1r3z1z1r3u1z1z1r3u2shu1shu2shr1shk1shk1u1shk1u2shk1r1shk1k1shk1k1u1shk1k1u2shk1k1r1shk1r3shk1r3u1shk1r3u2sht1sht1u1sht1u2sht1r1sht1r2sht1r3sht1r3u1sht1r3u2sht2sht2u1sht2u2shnhshnhu1shnhu2shp1shp1u1shp1u2shp1r1shp1r3shp1r3u1shp1r3u2shp2shp2u1shp2u2shm1shm1u1shm1u2shm1r3shm1r3u1shm1r3u2s1u1s1u2s1r1s1r2s1k1s1k1u1s1k1u2s1k1r1s1k1k1s1k1k1u1s1k1k1u2s1k1k1r1s1k1r3s1k1r3u1s1k1r3u2s1k2s1k2u1s1k2u2s1t1s1t1u1s1t1u2s1t1r3s1t1r3u1s1t1r3u2s1th1s1th1u1s1th1u2s1th1r1s1th1r2s1th1r3 s1th1r3u1 s1th1r3u2s1th2s1th2u1s1th2u2s1th2r1s1n1s1n1u1s1n1u2s1p1s1p1u1s1p1u2s1p1r1s1p1r3s1p1r3u1s1p1r3u2s1p2s1p2u1s1p2u2s1m1s1m1u1s1m1u2s1m1r1s1r3s1r3u1s1r3u2s1l3s1l3u1s1l3u2s1s1s1s1u1s1s1u2s1s1r1s1s1r3s1s1r3u1s1s1r3u2s1rhrhs1rhrhu1s1rhrhu2s1rhrhr3 s1rhrhr3u1 s1rhrhr3u3h1u1h1u2h1r1h1n1h1n1u1h1n1u2h1m1h1m1u1h1m1u2h1m1r1h1r3h1r3u1h1r3u2h1l3h1l3u1h1l3u2lhu1lhu2lhlhlhlhu1lhlhu2zhu1zhu2zhk1zhk1u1zhk1u2zhk1k1zhk1k1u1zhk1k1u2zhch1zhch1u1zhch1u2zhth1zhth1u1zhth1u2zhth1th1 zhth1th1u1 zhth1th1u2zhn1zhn1u1zhn1u2zhn1n1zhn1n1u1zhn1n1u2zhp1zhp1u1zhp1u2zhm1zhm1u1zhm1u2zhv1zhv1u1zhv1u2zhs1zhs1u1zhs1u2rhu1rhu2rhrhrhrhu1rhrhu2 bn_initekaar bn_initaikaarbn_reph bn_baphala bn_raphala bn_half_ka bn_half_kha bn_half_ga bn_half_gha bn_half_nga bn_half_ca bn_half_cha bn_half_ja bn_half_jha bn_half_nya bn_half_tta bn_half_ttha bn_half_dda bn_half_ddha bn_half_nna bn_half_tha bn_half_da bn_half_dha bn_half_na bn_half_pa bn_half_pha bn_half_ba bn_half_bha bn_half_ma bn_half_ya bn_half_ra bn_half_la bn_half_sha bn_half_ssa bn_half_sa bn_half_ha bn_half_rra bn_half_rha bn_half_yyabn_half_asamirabn_half_asamiba bn_yaphalabn_k_rabn_k_ra1bn_kh_rabn_g_rabn_gh_rabn_c_rabn_ch_rabn_j_rabn_tt_ra bn_tth_rabn_dd_ra bn_ddh_rabn_t_rabn_t_ra1bn_th_rabn_d_rabn_dh_rabn_n_rabn_n_ra1bn_p_rabn_ph_rabn_b_rabn_bh_ra bn_bh_ra1bn_m_rabn_y_rabn_sh_rabn_ss_rabn_s_rabn_s_ra1bn_h_ra bn_asamir_ra bn_asamib_ra bn_k_ss_rabn_k_kabn_k_tta bn_k_tt_rabn_k_tabn_k_ta1 bn_k_t_ba bn_k_t_ba1 bn_k_t_ra bn_k_t_ra1 bn_k_t_ra2bn_k_nabn_k_mabn_k_labn_k_ssa bn_k_ss_nna bn_k_ss_mabn_k_sabn_g_gabn_g_dabn_g_dha bn_g_dh_babn_g_nabn_g_mabn_g_labn_gh_nabn_ng_ka bn_ng_k_ra bn_ng_k_ssa bn_ng_k_ss_ra bn_ng_khabn_ng_ga bn_ng_gha bn_ng_gh_rabn_ng_ma bn_ng_ma1bn_c_cabn_c_cha bn_c_ch_ba bn_c_ch_rabn_c_nyabn_c_nabn_j_ja bn_j_j_babn_j_jhabn_j_nyabn_ny_ca bn_ny_chabn_ny_ja bn_ny_jha bn_tt_tta bn_tt_tt_rabn_tt_mabn_dd_ga bn_dd_ddabn_dd_ma bn_nn_tta bn_nn_tt_ra bn_nn_ttha bn_nn_dda bn_nn_dda1 bn_nn_dd_ra bn_nn_dd_ra1 bn_nn_ddha bn_nn_nnabn_nn_mabn_t_ta bn_t_t_babn_t_thabn_t_nabn_t_mabn_t_ma1bn_t_labn_d_gabn_d_ghabn_d_da bn_d_d_ba bn_d_d_rabn_d_dha bn_d_dh_babn_d_nabn_d_bha bn_d_bh_ra bn_d_bh_ra1bn_d_mabn_dh_nabn_dh_mabn_n_tta bn_n_tt_ra bn_n_tthabn_n_dda bn_n_dd_ra bn_n_ddhabn_n_ta bn_n_t_ba bn_n_t_ra bn_n_t_ra1bn_n_thabn_n_da bn_n_d_ba bn_n_d_rabn_n_dha bn_n_dh_ba bn_n_dh_rabn_n_nabn_n_mabn_n_sabn_p_ttabn_p_tabn_p_nabn_p_pabn_p_mabn_p_labn_p_sa bn_ph_ttabn_ph_labn_b_jabn_b_da bn_b_d_rabn_b_dhabn_b_nabn_b_bhabn_b_labn_bh_labn_m_tabn_m_thabn_m_dabn_m_nabn_m_na1bn_m_pa bn_m_p_ra bn_m_p_labn_m_pha bn_m_ph_rabn_m_bha bn_m_bh_ra bn_m_bh_ra1bn_m_mabn_m_labn_m_la1bn_m_sa bn_m_s_rabn_l_kabn_l_gabn_l_tta bn_l_tt_rabn_l_dda bn_l_dd_rabn_l_tabn_l_dabn_l_dhabn_l_pabn_l_pha bn_l_ph_rabn_l_mabn_l_labn_sh_tabn_sh_ca bn_sh_chabn_sh_nabn_sh_mabn_sh_labn_ss_ka bn_ss_k_ra bn_ss_tta bn_ss_tt_ra bn_ss_ttha bn_ss_nnabn_ss_pa bn_ss_p_ra bn_ss_pha bn_ss_ph_rabn_ss_mabn_s_ka bn_s_k_rabn_s_khabn_s_tta bn_s_tt_rabn_s_ta bn_s_t_ba bn_s_t_ra bn_s_t_ra1bn_s_thabn_s_nabn_s_pa bn_s_p_ra bn_s_p_labn_s_pha bn_s_ph_rabn_s_mabn_s_labn_s_la1bn_h_nnabn_h_nabn_h_mabn_h_labn_h_la1bn_rr_gabn_k_babn_g_babn_gh_babn_c_babn_ch_babn_j_babn_tt_babn_dd_babn_nn_babn_t_babn_th_babn_d_babn_dh_babn_n_babn_p_babn_b_babn_bh_babn_m_ba bn_m_b_rabn_l_babn_sh_babn_s_babn_h_babn_h_ba1 bn_kh_r_ukaarbn_kh_r_uukaar bn_g_ukaar bn_g_r_ukaar bn_g_r_uukaar bn_g_l_ukaar bn_g_l_uukaar bn_j_r_ukaar bn_j_r_uukaar bn_t_r_ukaar bn_t_r_uukaar bn_th_r_ukaarbn_th_r_uukaar bn_d_ukaar bn_d_r_ukaar bn_d_r_uukaar bn_dh_r_ukaarbn_dh_r_uukaar bn_n_t_ukaarbn_n_d_r_ukaarbn_n_d_r_uukaar bn_p_r_ukaar bn_p_r_uukaar bn_p_l_ukaar bn_p_l_uukaar bn_b_r_ukaar bn_b_r_uukaar bn_b_l_ukaar bn_b_l_uukaar bn_bh_r_ukaarbn_bh_r_uukaarbn_m_p_r_ukaarbn_m_p_r_uukaar bn_m_r_ukaar bn_m_r_uukaar bn_r_ukaar bn_r_uukaar bn_l_g_ukaar bn_sh_ukaar bn_sh_r_ukaarbn_sh_r_uukaar bn_sh_l_ukaarbn_sh_l_uukaarbn_ss_p_r_ukaarbn_ss_p_r_uukaar bn_s_t_ukaar bn_s_r_ukaar bn_s_r_uukaar bn_s_l_ukaar bn_s_l_uukaarbn_s_p_r_ukaarbn_s_p_r_uukaarbn_s_p_l_ukaarbn_s_p_l_uukaar bn_h_ukaar bn_h_rikaarbn_asamir_ukaarbn_asamir_uukaarbn_asamib_ukaarbn_asamib_uukaarbn_asamib_r_ukaarbn_asamib_r_uukaarbn_d_yabn_n_yabn_sh_yabn_ss_yabn_s_yabn_h_ya bn_k_hasanta bn_kh_hasanta bn_g_hasanta bn_gh_hasanta bn_ng_hasanta bn_c_hasanta bn_ch_hasanta bn_j_hasanta bn_jh_hasanta bn_ny_hasanta bn_tt_hasantabn_tth_hasanta bn_dd_hasantabn_ddh_hasanta bn_nn_hasanta bn_t_hasanta bn_th_hasanta bn_d_hasanta bn_dh_hasanta bn_n_hasanta bn_p_hasanta bn_ph_hasanta bn_b_hasanta bn_bh_hasanta bn_m_hasanta bn_y_hasanta bn_r_hasanta bn_l_hasanta bn_sh_hasanta bn_ss_hasanta bn_s_hasanta bn_h_hasanta bn_rr_hasanta bn_rh_hasanta bn_yy_hasantabn_asamir_hasantabn_asamib_hasanta bn_one_two bn_one_three bn_one_four bn_two_three bn_three_four bn_ukaar1 bn_ukaar2 bn_uukaar1 bn_uukaar2 bn_rikaar1 bn_post_ka bn_below_tabn_below_t_ukaar bn_below_t_ra bn_below_da bn_below_dha bn_above_na bn_below_na1 bn_below_na bn_below_ba1 bn_below_ba bn_post_ba bn_maphala bn_maphala1 bn_raphala1 bn_raphala2 bn_raphala3 bn_below_la bn_below_la1 bn_above_la bn_pre_ssa1 bn_pre_sa1 bn_below_tha bn_glyph571 bn_glyph572 bn_glyph573 bn_glyph574 bn_glyph575 bn_glyph576 bn_yaphala1 bn_glyph578bn_above_na.001 taml_v_i_2 taml_v_ii_2TamlKA_Taml_pul.halfTamlNGA_Taml_pul.halfTamlCA_Taml_pul.halfTamlNYA_Taml_pul.halfTamlTTA_Taml_pul.halfTamlNNA_Taml_pul.halfTamlTA_Taml_pul.halfTamlNA_Taml_pul.halfTamlPA_Taml_pul.halfTamlMA_Taml_pul.halfTamlYA_Taml_pul.halfTamlRA_Taml_pul.halfTamlLA_Taml_pul.halfTamlVA_Taml_pul.halfTamlLLLA_Taml_pul.halfTamlLLA_Taml_pul.halfTamlRRA_Taml_pul.halfTamlNNNA_Taml_pul.halfTamlTTA_Taml_v_I.abvsTamlTTA_Taml_v_II.abvsTamlKA_Taml_v_U.pstsTamlNGA_Taml_v_U.pstsTamlCA_Taml_v_U.pstsTamlNYA_Taml_v_U.pstsTamlTTA_Taml_v_U.pstsTamlNNA_Taml_v_U.pstsTamlTA_Taml_v_U.pstsTamlNA_Taml_v_U.pstsTamlPA_Taml_v_U.pstsTamlMA_Taml_v_U.pstsTamlYA_Taml_v_U.pstsTamlRA_Taml_v_U.pstsTamlLA_Taml_v_U.pstsTamlVA_Taml_v_U.pstsTamlLLLA_Taml_v_U.pstsTamlLLA_Taml_v_U.pstsTamlRRA_Taml_v_U.pstsTamlNNNA_Taml_v_U.pstsTamlKA_Taml_v_UU.pstsTamlNGA_Taml_v_UU.pstsTamlCA_Taml_v_UU.pstsTamlNYA_Taml_v_UU.pstsTamlTTA_Taml_v_UU.pstsTamlNNA_Taml_v_UU.pstsTamlTA_Taml_v_UU.pstsTamlNA_Taml_v_UU.pstsTamlPA_Taml_v_UU.pstsTamlMA_Taml_v_UU.pstsTamlYA_Taml_v_UU.pstsTamlRA_Taml_v_UU.pstsTamlLA_Taml_v_UU.pstsTamlVA_Taml_v_UU.pstsTamlLLLA_Taml_v_UU.pstsTamlLLA_Taml_v_UU.pstsTamlRRA_Taml_v_UU.pstsTamlNNNA_Taml_v_UU.psts*TamlSA_Taml_pul.half_TamlRA_Taml_v_II.pstsTamlCA_TamlSSATamlJA_Taml_pul.halfTamlSSA_Taml_pul.halfTamlSA_Taml_pul.halfTamlHA_Taml_pul.halfTamlCA_TamlSSA.half taml_v_i_3 taml_v_i_4ÿÿ &Yóôõöjk€¬­­®NOOP A B B C    úû2334–—˜™™š ¡¢£×ØÙÚ  !!"'(())**++,-.7889CDDEEFFGJKKL^__``aabijjkrsstuvvw‚ƒƒ„ˆ‰‰Šš››œ¢££¤ª««¬­®®¯×ØØÙáââãæççèòóóôúûûüÿno•–ÎÏÏÐÔÕÖÿü· žÐDFLT&arab4bengBlatnbmlymrtaml‚ÿÿÿÿÿÿ  ÿÿÿÿ ÿÿ aalt˜abvsžakhn¤akhn¬blwf²blws¸dlig¾fracÄfracÊhalfÐhalfÖhalnÜhalnâhalnèinitîligaôligaúligaprespstf pstspstsrlig rphf&vatu,     8@HPX`hpx€ˆ˜ ¨°¸ÀÈÐØàèðøØÞ’6Ü:'4'¨'Æ)Ê'ê+ +0*Â,-’3\7š9x7ª7Ö˜>‡ˆšÏæ1N>! BVD3ˆˆ’N0 $ÅQ0Q;I¬SÕQ<!<%º%P\0ÜB¦6rJübt " ^ ˜ nÀTÌ\æVš¬Pjˆ‚¶bâH!v% œ[Y8r€Žœª¸ÆÔâðþ &2>JVblv€Š”ž¨²¼ÆÐÚäîø  *4>HRZbjrz‚В𢍮´ãQ<Q<IâQ<Q<HÜQBQ9JÛQBQ9IÚQBQ9HØQBQ/I×QBQ/HÄQ0Q;HºQ+Q;I¹Q+Q;H´Q!Q;I³Q!Q;HÖQBQ/áQ<Q<¸Q+Q;ÙQBQ9ÃQ0Q;²Q!Q;ÍQ;HËQ9IÊQ9HÈQ4IÇQ4HßQCIÞQCHàQCJÂQ0SÁQ0JÀQ0I¿Q0H½Q/IÕQBJÔQBIÓQBH·Q+I¶Q+HÑQ=IÐQ=HÎQ;I±Q!J°Q!I¯Q!HÆQ4ÏQ=µQ+¾Q0ÝQC»Q/ÉQ9ÒQBÌQ;®Q!­«JªI©HæJåIäH#HZl|Š˜¦²¼ÆÐÚäîø  *4>HR\dlt|„Œ”š ¦ýQ2Q3Q;IüQ2Q3Q;HûQ2Q3Q;úQ2Q3JùQ2Q3IøQ2Q3H÷Q2Q3ÿQ4H Q=IQ=HQ;IQ;HQ9IQ9HQ4IöQ2JõQ2IôQ2HòQ$JñQ$IðQ$HîQ#JíQ#IìQ#HþQ4Q9ïQ$Q=óQ2Q;ëQ#êSéJèIçH  *4>FNTZ`Q;IQ;HQ4IQ4HQ;Q4 S J I H  *4>HPX^Q!QJQ%HQ%IQ!IQ!HQ%Q!IH (6BLV`jt|„Š(Q'Q;I'Q'Q;H&Q'Q;%Q'J$Q'I#Q'H!Q&I Q&H"Q'Q&IH"*06.Q;I-Q;H,Q;+J*I)H(2<FPZdlt|‚ˆŽ<Q;I;Q;H9Q*I8Q*H6Q(J5Q(I4Q(H7Q*:Q;3Q(2S1J0I/H$,28>CQ;IBQ;HAQ;@S?J>I=H",6@JT^hr|†Ž–ž¦¬SQ*IRQ*HPQ(IOQ(HMQ'JLQ'IKQ'HIQ&JHQ&IGQ&HNQ(QQ*JQ'FQ&EIDH  *4>FNTZ`]Q;I\Q;HZQ+IYQ+H[Q;XQ+WSVJUITH _I^H",6@JT^hr|„Œ”œ¢¨oQ;InQ;HlQ9JkQ9IjQ9HhQ.IgQ.HeQ-IdQ-HfQ.mQ;iQ9cQ-bJaI`H"*06uQ;ItQ;HsQ;rJqIpH6DR`nz†š¤®¸ÂÌÖàêôþ&.4…Q-Q;I„Q-Q;H}Q+Q;I|Q+Q;HƒQ-Q;{Q+Q;‡Q.HQ9IŽQ9HŒQ/I‚Q-JQ-I€Q-H‹Q/H‰Q.JˆQ.IzQ+IyQ+HŠQ/Q9†Q.Q-~Q,xQ+wIvH2ft‚ž¬ºÈÖäò&2>JT^hr|†š¤®¸ÂÌÖàêôþ$,4<DLT\bhnÁQCQ;IÀQCQ;H¾QCQ9J½QCQ9I¼QCQ9HºQCQ4I¹QCQ4H·QCQ1J¶QCQ1IµQCQ1H›Q0Q;IšQ0Q;H¸QCQ4´QCQ1¿QCQ;»QCQ9™Q0Q;°QCH®Q=I­Q=H«Q;IªQ;H¨Q9J§Q9I¦Q9H¤Q8J£Q8I¢Q8HŸQ1JžQ1IQ1H³QCS²QCJ±QCI˜Q0S—Q0J–Q0I•Q0H©Q;¡Q8 Q4¥Q9¯QC¬Q=œQ1”Q0“S’J‘IH (2<FNV\ÊQ9JÉQ9IÈQ9HÆQ4IÅQ4HÇQ9ÄQ4ÃIÂH8FTbp~Œš¦²¾ÈÒÜæðú"*2:@FLâQ3Q;IáQ3Q;HßQ3Q9JÞQ3Q9IÝQ3Q9HÛQ3Q4IÚQ3Q4HàQ3Q;ÜQ3Q9ÙQ3Q4åQ;IäQ;HØQ3S×Q3JÖQ3IÕQ3HÓQ2SÒQ2JÑQ2IÐQ2HãQ;ÔQ3ÏQ2ÎSÍJÌIËH(2<FPZdlt|‚ˆŽóQ;IòQ;HðQ9JïQ9IîQ9HìQ4IëQ4HñQ;íQ9êQ4éSèJçIæH3hv„’ ®¼ÊØæô $0:DNXblv€Š”ž¨²¼ÆÐÚäîø  (08@HPX`flr Q9Q;IQ9Q;HQ4Q;IQ4Q;HQ3Q;IQ3Q;H Q2Q;I Q2Q;HÿQ0Q;IþQ0Q;HQ4Q; Q2Q;Q3Q;Q9Q;ýQ0Q;Q4H#Q;IQ9JQ9IQ3JQ3I Q3HQ9H"Q;H&Q<IQ2JQ2IQ2HQ1SQ1JQ1IQ1H%Q<HQ4JQ4IüQ0SûQ0JúQ0IùQ0HQ9Q2Q4$Q<!Q; Q3Q1øQ0÷SöJõIôH#HVdpz„Ž˜¢¬¶ÀÊÔÞèòü$.8@HPX`hpx~„ŠIQCQ;IHQCQ;HGQCQ;FQCJEQCIDQCHBQ=IAQ=H?Q;I>Q;H<Q6I;Q6H9Q5J8Q5I7Q5H5Q4I4Q4H2Q0S1Q0J0Q0I/Q0H-Q+I,Q+HCQC@Q=6Q5:Q6.Q0=Q;3Q4+Q+*S)J(I'H"FTbnx‚Œ– ª´¾ÈÒÜæðú",6>FNV^fnv~„kQ<Q<IjQ<Q<HiQ<Q<hQCJgQCIfQCHdQ-IcQ-HaQ;I`Q;H^Q9I]Q9H[Q5IZQ5HXQ4IWQ4HUQ0JTQ0ISQ0HQQ+IPQ+HNQ!IMQ!HeQCYQ5RQ0bQ-\Q9OQ+VQ4_Q;LQ!KIJH!DNXblv€Š”ž¨²¼ÆÐÚäîø &.6>FNV^djŒQ=I‹Q=H‰Q;IˆQ;H…Q7I„Q7H‚Q4IQ4HQ3S~Q3J}Q3I|Q3HzQ2JyQ2IxQ2HvQ(JuQ(ItQ(HrQ#JqQ#IpQ#HwQ2†Q8ŠQ={Q3sQ(€Q4‡Q;ƒQ7oQ#nJmIlH$,28>“Q;I’Q;H‘Q;SJŽIH2@NZdnx‚Œ– ª´¾ÈÒÚâêòú ¡Q5Q;I Q5Q;HŸQ5Q;§Q;H¥Q9J¤Q9I£Q9H«Q=IªQ=H¨Q;IžQ5JQ5IœQ5HšQ4I™Q4H¢Q9›Q5¦Q;©Q=˜Q4—S–J•I”H#HVdr€Žš¦°ºÄÎØâìö (2<FPZbjrz‚Š’˜žÀQ0Q0J¿Q0Q0I¾Q0Q0HµQ!Q!I´Q!Q!H½Q0Q0³Q!Q!ÅQ5HÃQ4IÂQ4HÎQ:IÍQ:HËQ9JÊQ9I¼Q0J»Q0IºQ0H¸Q&I·Q&HÉQ9HÇQ5JÆQ5I²Q!J±Q!I°Q!HÈQ9ÌQ:¹Q0ÁQ4ÄQ5¶Q&¯Q!®J­I¬HÑJÐIÏHÖQ<HÔIÓH*Vdr€Žœª¶ÂÎØâìö (2<FPZdnx‚Œ– ¨°¸ÀÈÐØàèîôïQ5Q;IîQ5Q;HéQ0Q0IèQ0Q0HÛQ!Q!IÚQ!Q!HíQ5Q;çQ0Q0ÙQ!Q!úQ=HøQ9IìQ5IëQ5H÷Q9HõQ7IôQ7HæQ0JåQ0IäQ0HâQ&IáQ&HßQ#JÞQ#IÝQ#HòQ6IñQ6HûQ=IØQ!J×Q!IÖQ!HùQ=ÜQ#ãQ0öQ9ðQ6àQ&óQ7êQ5ÕQ!ÔJÓIÒH  (.¯Q>I®Q>H­Q>¬I«H#HVdr€Žœ¨´ÀÊÔÞèòü$.8BLV`hpx€ˆ˜ ¦ÆQ4Q4IÅQ4Q4HÀQ0Q0I¿Q0Q0H·Q!Q!I¶Q!Q!HÄQ4Q4¾Q0Q0µQ!Q!ÑQCHÏQ@IÃQ4IÂQ4HÎQ@HÌQ9IËQ9H½Q0I¼Q0HºQ&I¹Q&HÉQ5IÈQ5HÒQCI´Q!I³Q!HÍQ@¸Q&ÇQ5ÊQ9ÁQ4»Q0ÐQC²Q!±I°H $.8BLV^fntzQ@IQ@HQ=IQ=HQ;IQ;HQ@Q=ÿQ;þJýIüH@N\hr|†š¤®¸ÂÌÖàêôþ$,4<DLTZ`&QAQ;I%QAQ;H$QAQ;#QAJ"QAI!QAHQ=IQ=HQ;IQ;HQ9JQ9IQ9HQ4IQ4HQ'JQ'IQ'HQ&J Q&I Q&HQ9 QAQ'Q=Q4Q; Q& J IH,Zhv„’ ®¼ÊØæô $0:DNXblv€Š”ž¨²¼ÆÐÚäìôü "(RQ9Q;IQQ9Q;HIQ5Q;IHQ5Q;H<Q+Q;I;Q+Q;H4Q!Q;I3Q!Q;H1Q!Q!J0Q!Q!I/Q!Q!H2Q!Q;:Q+Q;PQ9Q;GQ5Q;.Q!Q!>Q,HKQ6HOQ9INQ9H9Q+S8Q+J7Q+I6Q+HLQ6IFQ5IEQ5IDQ5HBQ/IAQ/H?Q,I-Q!J,Q!I+Q!H@Q/5Q+CQ5MQ9=Q,JQ6*Q!)J(I'HH’¤¶ÆÔâðþ (6DR`n|ˆ” ¬¸ÄÐÜèòü$.8BLV`jt~ˆ’œ¦°ºÄÎØâìö &.6>FNV^fnv~„ŠšQ<Q<Q;I™Q<Q<Q;H˜Q<Q<Q;”QCQ;I“QCQ;H€Q5Q;IQ5Q;HrQ0Q;IqQ0Q;HjQ+Q;IiQ+Q;HaQ!Q;I`Q!Q;H^Q!Q!J]Q!Q!I\Q!Q!H—Q<QIhQ+Q;~Q5Q;–Q<QH_Q!Q;’QCQ;pQ0Q;•Q<Q<[Q!Q!|Q5I{Q5HyQ4IxQ4HvQ1JuQ1ItQ1HQ=IŒQ=HŠQ;IoQ0SnQ0JmQ0IlQ0H‰Q;H‡Q9J†Q9IgQ+IfQ+HdQ"IcQ"H…Q9HƒQ6I‚Q6H‘QCJQCIQCH}Q5JZQ!JYQ!IXQ!HbQ"ˆQ;kQ0sQ1zQ5„Q9ŽQCwQ4eQ+‹Q=Q6WQ!VSUJTISH",6@JT^hr|„Œ”œ¢¨ªQ=I©Q=H§Q;I¦Q;H¤Q9J£Q9I¢Q9H Q4IŸQ4H¡Q9¥Q;¨Q=žQ4JœI›HYY!DnHR\ô- "(ÿIOþILýOüLûIõMW ÿOþL,ILVû ÚNÚN;b*  ÛNÜNÜN7;bÂ%PZdnx‚Œ– ª´¾ÈÒÜæðú",6@JT^hr|†š¤®¸ÝNÞNßNàNáNâNãNäNåNæNçNèNéNêNëNONìNíNîNïNðNñNòNóNôNõNöN÷NøNùNúNûNüNýNþNÿNN!@QS bc#2<FPZdnx‚Œ– ª´¾ÈÒÜæðú–å—å˜åÐå™åšå›åœåå§åžåŸå å¡å¦å¢å¥å¤å£åÑåÒåÓåÄÙD ,8l\k[jZm[n\YZ[N:ædz¦Ð"*2:BJ  ±   ±   ±   ±   ±   ±   ±  "  ±   ±   ± V>HR\fpz„Ž˜¢¬¶ÀÊÔÞèòü$.8BLÜÜÜÜÜÜ Ü Ü Ü Ü ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ Ü"Ü#Ü!$&(+.0: =@cc11š:d®àê,NhФ¾BTÖ"T^ØJ|ÖXz„ $k<i9h4g1e0  &,28>D4?0</9.4+'0& %+$! &,;<:99473625#<4$*06<E9C$B#A"@#?1>=! L4JH'G&P*O)M( T)S(R'Q&W9V U+Z9Y-X#$*06<d9c/b.` ^-],\ [+$*06<w9ut8q3pn2m$l# y9x4"(.4:@FLRX^djpv|?Œ9‹4Šˆ3‡…2„1‚€0.~ }-|,{ z+"(.4”?“<’9‘540Ž+ –<•+ &,<œ8š3™˜2—(ž< &,28>DJPV\bhnt°¯?­<¬9ª©8¨§6¦“¥¤5¢4¡2 1Ÿ0$*06<BHNTZ`fl¾<½9¼»6º5¹3¸2·0¶ µ-´ ³+²#±! &,Ä<Ã9Â4Á'À&¿0 $*06<BHNTÏ9ÎÍ6ÌË5Ê/É,È Ç+ÆÅ!"(.4:@FLRX^djpv|á<à9ßÞ6Ý“ÜÛ5Ú4Ù1×Õ0Ô Ó+Ò"ÑÐ! æ<å9ä4ã/è#3N92N/OÝßàáâäæçéëíîïðñòóô÷øùúûü1Î:z„– ª´¾ÈÒÜæø  *4FPbl†˜ª¼Îàò(:L^p‚”¦°ÂÌÖàêô"4FXbt†˜ª¼éÛ FêÛëÛìÛíÛîÛïÛðÛñÛòÛ FôÛõÛöÛ÷ÛøÛùÛúÛ %G$FüÛ 'FýÛþÛ8H7FÿÛ :G9F <G;F GF GF  GF  G F  G F GF GF GF GF GF #G"F )G(F 0G/F >G=F)Û GFIÛNÛfÛoÛrÛ FÛ†Û GF GF GF !G F&F +G*F -G,F .FÖÛ 4G3F 6G5F 2G1F:!#$&'(+-/02345789;<=?@bc "';HMenq€…‡“¥²ÄÌÕÜÝá ©Ü¨ÛÉ.  Ÿ:Iž:H @:Q|,>Pbt†˜ª¼Îàò(:L^p ¼ÞªÝ ½Þ«Ý ¾Þ¬Ý ¿Þ­Ý ÀÞ®Ý ÁÞ¯Ý ÂÞ°Ý ÃÞ±Ý ÍÞ»Ý ÄÞ²Ý ÅÞ³Ý ÆÞ´Ý ÇÞµÝ ÌÞºÝ ÈÞ¶Ý ËÞ¹Ý ÊÞ¸Ý ÉÞ·ÝÎÑÜÄÆÈÖÒÒ›[\\Â%PZdnx‚Œ– ª´¾ÈÒÜæðú",6@JT^hr|†š¤®¸ENFNGNHNINJNKNLNMNNNONPNQNRNSNTNUNVNWNXNYNZN[N\N]N^N_N`NaNbNcNdNeNfNgNhNiN!@QS bc#2<FPZdnx‚Œ– ª´¾ÈÒÜæðú–å—å˜åÐå™åšå›åœåå§åžåŸå å¡å¦å¢å¥å¤å£åÑåÒåÓåÄÙ^(2<JT£Q¤Q¥Q¨Q×Q<I¦Q§Q!/4;<=> ŽJK r˜DFLT&arab2bengÐúŒ–¬ºÄÞ,V`j°ºÌæ    Ò Ü   ‚ ì  p ž  > l Þ T Z h ~ Œ š ´ º À Þ ä"0>LZhv„Š ª´ÆÌ$ÿýÿéÿö&ÿÍ*ÿÇ2ÿÄ4ÿÄ7ÿÊ8ÿÂ9ÿ}:ÿ<ÿ¯DÿúEÿìFÿãGÿäHÿåJÿìRÿØTÿëWÿìXÿäYÿ¯Zÿ·\ÿ­mÿÀ‰ÿǘÿÄ›ÿœÿÂÿžÿ©ÿã ‘ÿŒ •ÿ¥ ¦ÿ¶$ÿÍ2ÿè9ÿ¿:ÿÅ<ÿ¼ƒÿÍ„ÿÍ…ÿ͆ÿ͇ÿ͈ÿÔ”ÿè•ÿè–ÿè˜ÿèšÿéÿî $ÿé+ÿþ.ÿö2ÿôƒÿé†ÿé‡ÿéˆÿñ•ÿô˜ÿô $ÿ½-ÿ×7ÿö9ÿ¹:ÿÇ;ÿÀ<ÿ¶‚ÿ½ƒÿ½„ÿ½…ÿ½†ÿ½‡ÿ½ÿÍÿÆ$ÿ¹-ÿó2ÿöDÿÞHÿíLÿóMÿìRÿëUÿöXÿõ‚ÿ¹ƒÿ¹„ÿ¹…ÿ¹†ÿ¹‡ÿ¹˜ÿö£ÿÞ¦ÿö§ÿÞ¨ÿÜ«ÿíµÿë¸ÿëºÿëÿë $ÿæ7ÿë9ÿé:ÿî<ÿæ‚ÿæƒÿæ„ÿæ…ÿæ†ÿæ‡ÿæˆÿí$ÿˆÿˇÿˈÿÒÿÁ&ÿÕ*ÿÏ2ÿÍ6DHÿíRÿáXÿí\ÿª•ÿ͘ÿͦ§µÿá¸ÿá¾ÿíÿÔ&2ÿý67ÿ·8ÿæ9ÿ:ÿ§<ÿœXÿö\ÿȈ”ÿý•ÿý–ÿý—ÿý˜ÿýžÿæ¾ÿö ‘ÿƒ •ÿœÿòÿë$ÿä&ÿð*ÿí2ÿìDÿåHÿïRÿëXÿçƒÿä†ÿä‡ÿäˆÿë‰ÿð•ÿì˜ÿì£ÿå¦ÿå§ÿå¨ÿå«ÿïµÿë¸ÿëºÿì¾ÿç $ÿÆ7ÿ÷9ÿ»:ÿÊ;ÿÉ<ÿ¸ƒÿƆÿƇÿƈÿÎÿ¢ÿÛÿ›$ÿ¦-ÿÌDÿïHÿéRÿçƒÿ¦†ÿ¦‡ÿ¦ˆÿ¥£ÿï¦ÿï§ÿï¨ÿî«ÿéµÿç¸ÿçºÿçÿçÿÌ&ÿ×*ÿÔ2ÿÓ7ÿÞ8ÿÈ9ÿ·:ÿ½<ÿ´DÿþHÿéRÿÜXÿè\ÿÛ‰ÿוÿÓ˜ÿÓžÿÉ£ÿþ¦ÿþ§ÿþ¨ÿû«ÿéµÿܸÿܼÿè¾ÿèÿÙÿá $ÿÛ7ÿí9ÿå:ÿë<ÿâWÿìƒÿÛ†ÿÛ‡ÿÛˆÿâ-ÿ¶ÿ·ÿ®ÿ©ÿ©$ÿË&ÿø*ÿõ-ÿî2ÿö6ÿö9:< Dÿ³Fÿ©HÿªJÿ¥LÿîMÿçRÿ¦UÿÎVÿ·Xÿ£Yÿ—Zÿ–\ÿšmÿŽ‚ÿ˃ÿË„ÿË…ÿˆÿˇÿˈÿÓ”ÿö•ÿö–ÿö—ÿö˜ÿöšÿö¨ÿ°ºÿ§ÿü ¦ÿƒ ÿáÿÛ$ÿ¿PÿßQÿáSÿäUÿåƒÿ¿„ÿ¿…ÿ¿†ÿ¿‡ÿ¿ˆÿÆ$ÿ—ÿ»ÿÿ¦ÿ§$ÿ„&ÿÁ*ÿ¾2ÿ½6ÿÑ7 Dÿ¨Hÿ«Jÿ›LÿìRÿ§UÿÈXÿÍ\ÿÊmÿ“‚ÿ„ƒÿ„„ÿ„…ÿ„†ÿ„‡ÿ„ˆÿ˜”ÿ½•ÿ½–ÿ½—ÿ½˜ÿ½šÿ¿¨ÿ§ºÿ¨ ¦ÿ‰$ÿ§ÿÈÿ ÿ¯ÿ¯$ÿ&ÿË*ÿÈ2ÿÈ6ÿ×7Dÿ°Hÿ¸Jÿ¥LÿóRÿ´UÿÑXÿÕ\ÿÓmÿŸ‚ÿƒÿ„ÿ…ÿ†ÿ‡ÿˆÿž”ÿÈ•ÿÈ–ÿÈ—ÿȘÿÈšÿɨÿ¯ºÿµ ¦ÿ• ÿÊ&ÿÌ2ÿÃ4ÿÃDÿùHÿäRÿ×Xÿã\ÿ ˜ÿÃ$ÿ ÿžÿ™ÿ“ÿ”$ÿ¶&ÿ¼*ÿ¹2ÿ»6ÿÔ7 DÿHÿ™JÿLÿïRÿ•Sÿ¨Xÿ²Yÿªmÿy‚ÿ¶ƒÿ¶„ÿ¶…ÿ¶†ÿ¶‡ÿ¶ˆÿ½”ÿ»•ÿ»–ÿ»—ÿ»˜ÿ»šÿ»¨ÿšºÿ– ¦ÿoYÿÐ\ÿÎMÿæYÿâZÿá\ÿà ‘ÿØYÿãZÿâ\ÿàKÿñNÿíWÿöYÿåZÿä[ÿÝ\ÿâ ‘ÿâDÿçHÿÞILMO,RÿÚVÿëW £ÿç¦ §ÿú¨ÿç«ÿÞµÿÚ¸ÿÿºÿÛÿÜ ‘ DÿïHÿçOÿùU ¦ÿï§ÿï¨ÿî«ÿçµÿæ¸ÿæ\ÿâ ‘ÿÚ7ÿäMÿÜÿ¿ÿþDHÿíJÿôRÿàVX£¦§¨ÿÿ«ÿíµÿà¸ÿà¾Yÿä\ÿçSÿ÷YÿâZÿá\ÿá7ÿÉSÿóYÿâZÿá\ÿá ‘ÿÙ7ÿ¥Wÿ÷YÿÜZÿÜ[ÿÜ\ÿ× ‘ÿÞWÿú\ÿäFÿùXÿô.ÿ×ÿÒÿÐÿùÿùDÿÿFÿøGÿöHÿúIJÿñKÿúLMNÿöOÿîPQRÿøSTÿöUWXYZ[\]¢ÿÿ£ÿÿ¤ÿÿ¦ÿÿ§ÿÿ¨ÿý©ÿøªÿú«ÿú¬ÿú´ÿøµÿø¶ÿø¸ÿøºÿùÿù ‘ÿíWÿñ ‘ÿÚ ÿøÿø6D K Rÿø£ ¦ § ¨ µÿø¸ÿø ‘ÿã ‘ÿÜÿ»ÿäÿ´ÿìÿìDÿèFÿÛHÿÜJÿ×OÿáRÿÚVÿë¢ÿè£ÿè¤ÿè¥ÿè¦ÿè§ÿè¨ÿèªÿÜ«ÿܬÿÜ´ÿÚµÿÚ¸ÿÚºÿÚÿÀÿèÿ¹ÿéÿéDÿåFÿßHÿáJÿÕOÿßRÿÝVÿé¢ÿå£ÿå¤ÿå¥ÿå¦ÿå§ÿå¨ÿåªÿá«ÿá¬ÿá´ÿݵÿݸÿݺÿÞDÿõFÿÞHÿàRÿÓTÿæ«ÿàÿ¾ÿåÿ·ÿéÿéDÿàFÿÛHÿÝJÿÐOÿàRÿÙVÿæ¢ÿà£ÿà¤ÿà¥ÿà¦ÿà§ÿà¨ÿáªÿÝ«ÿݬÿÝ´ÿÙµÿÙ¸ÿÙºÿÚ ÿýÿö&ÿÍ*ÿÇ2ÿÄ4ÿÄ7ÿÊ8ÿÂ9ÿ}:ÿ<ÿ¯ÿýÿéÿö&ÿÍ*ÿÇ2ÿÄ4ÿÄ7ÿÊ8ÿÂ9ÿ}:ÿ<ÿ¯DÿúEÿìFÿãGÿäHÿåJÿìRÿØTÿëWÿìXÿäYÿ¯Zÿ·\ÿ­mÿÀ ‘ÿŒ ¦ÿ¶ ÿýÿö&ÿÍ*ÿÇ2ÿÄ4ÿÄ7ÿÊ8ÿÂ9ÿ}:ÿ<ÿ¯ ÿýÿö&ÿÍ*ÿÇ2ÿÄ4ÿÄ7ÿÊ8ÿÂ9ÿ}:ÿ<ÿ¯ÿýÿéÿö&ÿÍ*ÿÇ2ÿÄ4ÿÄ7ÿÊ8ÿÂ9ÿ}:ÿ<ÿ¯DÿúEÿìFÿãGÿäJÿìRÿØTÿëWÿìXÿäYÿ¯Zÿ·\ÿ­mÿÀ ‘ÿŒ •ÿ¥ ¦ÿ¶ÿýÿéÿö&ÿÍ*ÿÇ2ÿÄ4ÿÄ7ÿÊ8ÿÂ9ÿ}:ÿ<ÿ¯DÿúEÿìFÿãGÿäHÿåJÿìRÿØTÿëWÿìXÿäYÿ¯Zÿ·\ÿ­mÿÀ ‘ÿŒ •ÿ¥ ¦ÿ¶$ÿå7ÿ÷9ÿ»<ÿ¸$ÿÆ7ÿ÷9ÿ»:ÿÊ<ÿ¸7ÿ÷9ÿ»<ÿ¸7ÿ÷9ÿ»<ÿ¸$ÿÆ7ÿ÷9ÿ»:ÿÊ;ÿÉ<ÿ¸$ÿÆ$ÿ¿ÿáÿÛ$ÿ¿PÿßQÿáSÿäUÿå$ÿ¿ÿáÿÛ$ÿ¿EPÿßQÿáSÿäUÿåYÿâZÿá\ÿàYÿâZÿá\ÿàYÿâZÿá\ÿàYÿâZÿá\ÿàYÿåZÿä\ÿâYÿåZÿä\ÿâYÿåZÿä\ÿâYÿÜZÿÜ\ÿ×YÿÜZÿÜ\ÿ×Wÿ÷Wÿ÷YÿÜZÿÜ[ÿÜ\ÿ×$ÿé2ÿôKÿñNÿí$ÿÛ7ÿí9ÿåWÿìWÿñYÿÐ\ÿÎ$')*-/13 5= DFHLN\‚‡,‰‰2”˜3šž8¢£=¦¨?«¬B´¶D¸¸GÎÏH"#J??LòŽ 0bhntz€†Œ’˜ž¤ª°¶¼ÂÈÎÔÚàæìòøþ "(.4:@FLRX^djpv|cžcž6ž§žj¢|žcžâÊôÌìÊ„¦ùÈìÊúÊQÊùÈ}È-¢cžôÌ+ž¢§žj¢j¢ùÈõž|žìÊæÍÜÈÿÈÿÈÞÌæÍæÍÚÍÝÍŽÍùÈìÊÁ¤¤ô›Á¤¤š¬¿0$&(,28<DFHLRX\¨ºHIJPRYabchqrŸïðñó÷øúû (346@A*Jk­­Z`flrx~„Š–œ¢¨®´ºÀÆÌÒØÿZÈÿXÈÿ\Ìÿ\Ìÿ\ÌÿÌÿ\Ìÿ\Ìÿ\Ìÿ\Ìÿ\Ìÿ\Ìÿ\Ìÿ\Ìÿ\Ìÿ\Ìÿ\Ìÿ\Ìÿ\Ìÿ\Ìÿ\Ìÿ¹ÌÁ]-IÁ‘ÄÁ‘Ärgl/inst/fonts/FreeSans.ttf0000644000176200001440000077527014100762640015413 0ustar liggesusers€pGDEFU•]ŽåôrGPOSäCú‘èˆ0GSUB¹G«ŒæhOS/2N˜Ò¸xVcmapëñæ#Ì ‚cvt !y-Pgaspÿÿåìglyf×þ¢_OT@Äheadßznü6hheaÀ œ4$hmtx>ëÐ!üloca ss¤-T"maxpÞX nameÁ0-qWpost‡ák–pO{Egç*r_<õè½Wøà½Wøàüãþ5`u ÿ8Zªüãý:`Üm@.¹Š»ŒŠ»ß1 À_ŽÿP`û PfEd@ ÿý ÿ8ZuË€¿ß÷°!M|c4,, y›4¿0MIM&…(H2WM.Wÿø,+,f,", ,,#,+,.,%,&nnH-H2H2,M÷"››OÒ0ÒY›ZcZ ,ÒSdô›O,PAKÒL &›[ &Ò]›0cÒU›°›› c@ÿøÕ,,ÿêM,*,6ô,,(,,FÞBÞÿîô:ÞDAF,F,$,6,MEô",Aô ÒôôôN+dNHKMy,4,,C, d,+Máÿór%,bH(M.áÿóM^—H2__M\,A0WM'_=m(,be=e=ec_››››››è Ò0›Z›Z›Z›ZGÿÿ ÒÒL & & & & &H_ ÒUÒUÒUÒUš š[cC,*,*,*,*,*,*y"ô,(,(,(,(ÿûAÿù,$,F,$,$,$,$,$H2c,A,A,A,Aô+6ô›,*›,*›,+Ò0ôÒ0ôÒ0ôÒ0ôÒY{Ò,›Z,(›Z,(›Z,(›Z,(›Z,( ,, ,, ,, ,,ÒS,ÿàÒ',ÿöÿëÞÿðÿýÿñBÞ`^¼dvBôÞÿà›Oô:ô:,FÞ?,PÞ?,P$D,PôD,ÞÒL,FÒL,FÒL,F,FÒL,F &,$ &,$ &,$è+°(Ò]MEÒ]MAÒ]M0›0ô"›0ô"›/ô"›0ô"cc4cÒU,AÒU,AÒU,AÒU,AÒU,AÒU,A°Ò› ô› côcôcô,›O,6›,ÿ÷Ò0Ò0ôÒ›N,6›Z &›0c,  ,ô:Òÿô,F &,6›0ô"ccY¸Y  P P¼D†L°L F›,*ÿù &,$ÒU,AÒU,AÒU,AÒU,AÒU,A,(›,*›,*è y" ,,›OôÿÔ &,$ &,$Þÿß5YÆY  ,,ÒL,F›,*è y" c›þú,þ¼›ÿn,ÿ0›ÿ,þÁ›ÿs,ÿ4þ<þ1þ°þ¤ ÿ.,þ¹ ÿ¢,ÿ,Òþ®MþlÒÿ"MþàÒÿ,þºÒÿŠ,ÿ.›0ô"cÒS,F›,*›Z,( &,$ &,$ &,$ &,$› ô,*,,D,6ô,,,(,(ô"ô",,,F,F,FÞÿøÞB^ÞDAFAFAF,ÿî,F,$MEMEMEMEMETTôÿÊ,Aô Òôôô$ô:,MMM\MMMsMOM9MMÿÝþÉÿþÇþ¸þÏþÂÿ&þÑÿþþÆþþÂÆÿ6ÆÿþÚþìÇ'ÇLnž®ëKÚY˜ÿÔ©ÿ¹æÿÂÿðÆÿžöÿúÿ߬tJFR¬ ŠPt#«Aî-ìE¬J¬ @Ž8vAî2ÑP~Nt(t'¬ÍÓ$é4Ð*ìÿï¬`0'#38(T020%þ'Î&-8B0>NøÖ&"•569h"*(å.<–*ä$ÿß()"(ä$›Z›OþcZÒ0›0dô8SöSþ›OÒLŠÒS››O›OcO,"›Oÿ?›0ØOØO›O¡!LOÏO &ÏO›OÒ0cЍ@›åOˆO<OROQhO›OÒ0S¾ ,*,$ F®FZ,(E,ô"7F7FþF-FjF.F,$-F@Fôð<ô=ôBFF´FÈFÞ9²F(FôöF,(,(8®Fôô"ÞBÞÿîHFRF8ô:,Fô,F›O(F›[,6cZ®FcZ®FcZ®Fÿ?E›0ô"›Oô:›Oô:›Oô:›Oô:ÒS,F$SüFÒS,FÒ0ôÒ0ôcð<› ô › ô ›ôS`F‚SüE‚SüE‚SüE &,(°',(dÿ?E,›Oô:ÒS,F‚SüE›,*›,*è y"›O,( &,( &,(ÿ?E,›0ô"›0ô"ØO7FØO7F &,$ &,$ &,$Ò0ôŠôŠôŠôˆOFhO²FÒOÁOSòRÒOïåTÒJ?C»?¡]UB"ÇJL—3™O™/ô-o1 [(ÒJˆBÒJï*îJÒOìJ›-»Jo<¡L*~$ 0Ì'Þ5…EM+XAA,J<#EI&<L*À^,?8DF0!B-<B,+*GB$(('(+ IÞÿÒ IÈ5,E†#AAý&#P@bGwI,E! `LU+LC2²*!FZo FOIIFÈȼ¼FIFFè&ÈÔ>FnF€:O:ÒV&n?Ô>_'o?`=È:&&9X%o?m0Ô>z3_=K$?98? N3^>#%;¯#X8É4É2É3É,ôjôjôjrTrW>>…ˆ>Ä#Ä9>ÿ¸…ÿ¸…ÿ¸ýkýkªmId”±sÿ¸Îÿ¸Îÿ¸äÿ¸ªÿpXa”ÿ¸ªkkÎÿ¸ΧÎÿ¸>ÿ¸>ÿ¸~Iÿ¸ýkªÿ¸ªc§ÿÿp„)0)ˆˆË•§§0)0)0)‰n¨ØüG%÷¼àßø·+«+ŸŸ‘‘º+ÏÃ??%ºMŽú®þî¶-¬ÿû¬ÿú¬ÿ?þ}ÿ)ÿÿþµþ̬ÿɬÿ`¬ÿpÿh‚(ÿ”H”H­HH…H/HqHcHNHfH™‚(,,€ÿì ÿìÿìÿìÿì&ÿìl¤àllÐŒÿìôêÒÿìêÿìÿìvÿìNÿì¨þÿìêÿìÿìÿìÖÿìêÖÿìêÄÿì0ŠÿìàÿìLÿìàÿíÖÿìàÿìØÿìÖÿìÖÿìÿì ´ÿì´ÿì´þ @IÃ#ÿÎTÿìTÿìäÿìäÿìx´ÿˆÿìÿìÖÿìd¤êdhd̤0†à¤àÿöÖÿóÖÿìx¸¤¤è’²žTTòèTè&j²"Pì>, >äøú2"žÖÖÿþ""T¬¾¾ÿ„þaþbþ~þxþdþ8ÿ4jÿþìäúhà0ÿúàÿþÔìÿøÿü<0þòT„!þÁ!ÿHÿ'Á'ô(ï((¾(uõ'd'k'9&(f'l(^(Z'w(ï(((ÿ'f'&'X'©(Y$c''B(¬&§(ç(Fÿ¯X'.'ž('P'8'X' &(èFèEèÿN!þP!þO!þ½!þ!þuèÿfèÿK‡ß' (Ñ&Õ'òÏ'Ã'þ'Ç(è'ƒÿœ.ÿØ0„xÿývÿý)ÿý\ÿíÿÿ<ÿþ:ÿþDÿþ5Dÿþ4ÿÿ?ÿý5ÿý5 ÿþ<¼ÿýÿølŒ0ÿû5ÿý5ÿý!ÿþ €þ&¾ÿÝþßÿ,þLŒÿú3ü¨¸XÿôXXÿùXX0ÿ8ã/ßS}ú ’”ÿ±¤D ÉèèP - - - °è¤P Ø :˜ÿä1ÿé_¹¹² iÿþe [ ¹ey ( $¨ }þTþ´T Š Í  ª Mv[  qlˆèVlOXr¸>:DMÿûUÿûqÿû5F\‹ÿü˜ÿûc Kb= H #=H ` ` = øm l l ‰@&O=@7O2 -@2@7`-@-PÔ<>” $'>F%\ èÍ#\å?äF#v v &F+\\\{Í!F%”\ Í”v F%\ ÍF\v,'>F*Ív5v/Í>Í(ý°|¤üíýüíüãõ Œ!ˆ*TÿŸT0TÿT0TÿT0Tÿ¤T0¬ÿ¬¬þ!¬ÿÙ¬þ?¬¬þÓ¬ÿ¦þÿŒþ'þÿ þ'þÿ þ'ŠþvŠPŠýsŠÿCŠýsŠÿCÿ©ÿÿÿœ«þg«A«ýd«ÿ4«ýd«ÿ4«ýø«þËþï8þm8þm8þôÿÇìþkìEìýhìÿ8ìýhìÿ8ìýüìþÏ&ÿŸ&"&ÿ&"&ÿ&"îþî2îý¯îÿsîýëîÿ¦ÿŽ(ÿ (ÿ (ÿ“(¬¬ÿ¬ÿ¬þ˜äÿýä$äÿ{ä$äÿ{ä$ää$ÐþžÐ*Ðý¡ÐÿqÐýøÐÿªÐþDÐÿT0T0þ'þ'ÿüÿü&"&"((ä$ä$TÿŸT0TÿT0TÿT0Tÿ¤T0rÿrrþ!rÿÙrþ?rrþÓrÿ¦ÿ©ÿÿÿœYþgYAYýdYÿ4YýdYÿ4YýøYþËäÿýä$äÿ{ä$äÿ{ä$ää$±þž±*±ý¡±ÿq±ýø±ÿª±þD±ÿT0T0T0T0T0T0T0¬¬¬¬rÿÌÉMÿ6ÿcMŠÿCŠÿC«ÿ4«ÿ4YAFÿ6Fÿ6Mÿ6ÿÎÿÛÿßÿÖÿÇ8ÿÕìÿÞìÿëìÿ8ìÿ8FFM ((((6ÿ´69((¬¬¬ÿ¬ÿ~NM‰Mä$ä$ä$ä$ä$îÿyîÿ¸ÐÿwÐÿž«*M\MÆM.,ÿûèÿ÷ÞAÝ@Þ@Ý@M0M1M/M1,&,&^2^Fèsè P 1Õ1¨11Õ1¨1M[MUnb,|,M§ÿRXMBMB|0__ ________=___a____¥[Æ]e<,É!g):j ðLRÿþ„è?Ð*Ð*›O›Œ"o2-cÿ»cZ8e=ee=eeee=ee=eeee=d,dBd±d›±Çݱd›±Ç,PÒ0ÒYAKÞB¼BšBÒBô Ò ° Ž ÒBôÒ°ÞDô,AFÛ [-Û1[-’Û['Û-[,›,$›Z,+Ç Ç É-É,7i7i$)H(H2ô@ÉÉ[[((,dd¼d,d_£%HKHH_H2|5$ H-H-+++’7'é+7èfèPè˜èècèÏèMèXèè·è¾è¼è2è¼è2èªèÅè±è„èÎè¥èóèÍè†èPèˆèUèwèYè–èzèóèáèuèYèœèƒèŒèrèè÷è€èbè_è?èRè1è(èè~è`è¸è‡èjèèaè¹è¢è:è‡èaèMèUè{è_è_èrèUèUè@èèèLè+è+è{è_è_èXèmèNè`è‰èeè)è’è`èŠèVèzè è£èMè£è‚èMè8èkè”èLèÿèÿèÏè¢è¨èvè©èzèŒèSè„èMèˆèmè¤è‰èkèMèièKè»è¢è™è}èŠèmèRè1è_è?è‰ènèsèVèqèRèžèlèNèZè9èyèrèvècèlè2è¸èNè.è.è‡èmèmèèaèaèjèLèLèIè(è(è‹èÛè‡è®èZè™èdè¨ètèèè¾è·èèQè²è¾è·è‹è]èoèÐè¹è_è¶è›è‹è]èoèÐWèÿ÷è¸è¸,+,", ,,#,+,.,%,&ÞÿîMt,f,ô ô  , "È:1:K%z:P&h? 9R%i?%©#H2;;;;€:€:€:O:ÒV&n?_`= &&9X%m0z3_=?98?N3^>#%;¯#Ô>O:&98?€H#|` ~€‰Œ“™Ÿ¥©«®ãíõ3TY\ajmsu…‰Žœž ÇËÝ (uz~ŠŒ¡Î_ÄÈÌõùV^‡Š¹Äê ,J   3 9 C E I M Q p ƒ Œ ¨ ° ² ¹ ¼ Ä È Í × Ý ã ú  ( 0 3 6 9 < B H M \ ^ p t ‚ ‹ ¨ ° ³ ¹ Ã È Ì Ð ï        ! + 0 3 9 C G ` o ƒ Š • š œ Ÿ ¤ ª µ ¹ Á È Í × Ý á ƒ Š š œ ¨ ³ ï ƒ … ‹ ‘ ” œ ž ¢ ¥ « ± » ½ Æ Ê Ô Ö Ù ßEMWY[]}´ÄÓÛïôþ   # & 7 = D I K q y ‰ ¨ ª ¬! !!!!"!(!-!3!!•!µ!Ô""" """"" "."4"<">"C"I"`"e"—"¥#%Ê&j00000“0™0›0þöAö¾öÃöÜûû6û<û>ûAûDûOÿýÿÿ  ‚‹Ž™¥§«­Äæðø&PV[`emouy‚‡Œœž ÆÊØ &tz~„ŒŽ£ŒÇËÐø1Za‰°»Ð0     5 < E G K P f … “ ª ² ¶ ¼ ¾ Ç Ë × Ü ß æ    * 2 5 8 < > G K Y ^ f r … • ª ² µ ½ Ç Ë Ð æ         * / 2 6 > G ` f ‚ … Ž ’ ™ œ ž £ ¨ ® · ¾ Æ Ê × Ú á ƒ … Ž ’ œ ž ° æ ‚ … ‰ ‘ ” ™ ž   ¤ § ­ ³ ½ À Ê Ï Ö Ø ß HPY[]_€¶ÆÖÝòö    & 0 9 D G K p t € § ª ¬! !!!!"!&!*!0!S!!µ!Ð"""""""" "'"4"<">"A"I"`"d"•"¥#%Ê&j00000A0™0›0¡ö9ö¾öÃöÜûûû8û>û@ûCûFÿýÿÿÿõÿãÿÂÿÁÿÀÿ¿ÿºÿ·ÿ²ÿ±ÿ°ÿ¯ÿšÿ˜ÿ–ÿ”ÿ’ÿŒÿpÿoÿnÿkÿhÿfÿeÿdÿaÿ_ÿ^ÿ\ÿ[ÿPÿOÿNÿ)ÿ'ÿþùþøþ÷þõþôþãþ˜þ”þ‘þŒþ‹þŠþ‰þXþ,þ*þ(þ%þ#ýìýéýçýæýÁýÀýµü üžü›úåúãúâúàúßúÞúÜúÛúÚúÙú×úÃú³ú²ú°ú®ú­ú¬ú©ú§ú¦ú¤ú¢ú™ú•ú”ú’úˆú„ú‚úú€úú~ú|ú{úwúuújúiúbúaúUúSúJúIúHúGúDúAú?ú<ú'úúúúúú ú ú ú úúùýùüùúùöùóùÛùÖùÄùÃùÀù¿ù¼ù»ùºù·ù´ù±ù°ù¬ù¨ù§ùžùœù™øøø÷øôøóøòøñøêø¸ø&ø%ø"øøøøøøøøøøøø øøøøæàæÞæÜæÚæØæ×æÖæÕæÔæÒæÑæÐæÎæÍæËæÊæ¹æ·æ´æ²æ©æ¨æ¢æ æŸæ{æyæsæVæUæTåöåóåðåìåçåäåãåáåÂå²å“åyåNåMåLåGåDåBå@å?å9å4å-å,å*å%åå äÝäÐävá­á×x×w×v×t×I×D×C×>ˆ„l I 3 2 1 0 / .’²Ÿ À~{€utho  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a†‡‰‹“˜ž£¢¤¦¥§©«ª¬­¯®°±³µ´¶¸·¼»½¾rdeix¡pkvjˆšsgwl|¨ºcnm}b‚…—¹Áy„ŒƒŠ‘Ž•–”œ›qz!yVVVV‚²Ø¬v”ÔNx¢¼ÔîJz(´êœ 0 T Œ ° Ø þ z v ¬ & Œ Ö  . ¬ Ü ö<r’Æöd¶*¨NrºÞP|ªÌè .Hb€æZθ,n º8„èT¸ö†Î>vªò ˜² |Œ¸2èrºÞ Æ ê!À"d"˜"¸"Ò#¬#Æ$*$`$Ì%P%j%Æ& &"&€&¬' 'V'¸(V))ˆ)Ì**X*È++¤+î,²,ð-,-p-¶-Þ..2.b.Â/,/¨0"0¤1L1Ð22„2Ú303Ž3î4(4x55Ì67\8N9:.;(;â$>J>x>¨?@?È@:@¬A&AÆB@BrBòCJC¢DDdDºE&E†EÊFŽFèGÆH&HúIlIàIøJJ(J>J¸K2KL"L‚LøM4M¶MÎMäNNžNöO¢OæPnPŠP QDRR(R>RØSžS¶SÎTTxTT¦TÌTòU U UjUÆUìVVV6VNVšVîW<WlW˜W¾WüX4XrXªXÂXÚYY>YzYÔZ"ZŠZÎ[0[|[Ö\B\¼],]D]Z]â^`^Ú_ `*`vaajaübPccžc¶cÌdÄe fZfþgg,gdgÌgðh8hPhfh¼ii,iBiäjˆjêkNkÆlDl\ltlŒl¢læm"m\m–mÐnnVnŽn¤n´o"o€oøp p˜qq q6qLqbqàr‚rÐs<sât*tpt¼u8uÐuæuüv.vŽvîw8wPwhw€w˜w°wÈwàwøxx(x>xVxlx„xšx²xÈxàxöyy&y>yVyny†yšy²yÈyàyözz&z>zTzlz„zœz²zÊzàzö{{&{>{V{n{†{œ{´{Ì{ä{ü||,|D|Z|r|ˆ| |¶|Î|ä|ü}}*}@}X}n}†}œ}´}Ê}â}ø~~&~>~TÄ€€l€„€œ€´€Ê€â€ø&>Tl‚š°ÈÞò‚`‚t‚úƒƒš„$„:„N„d„t…B…R…f…Ô†V†Š†Â†Ò‡ ‡‡šˆDˆº‰4‰¤‰¸‰öŠVŠ”Šð‹&‹<‹èŒTŒÀ hxŒ ´ŽŽ0ŽDŽÈŽê ,^vÜdŠœ®ÀÒäö‘‘‘,‘>‘P‘v‘Š‘ž‘Ƒܒ’’(’D’^’š’ª’Æ’Ü’ò“*“B“Z“r“Š“¢“º“Д”œ”¾••0•d•’––,–`–Ž–Ì–ø—0— —Ę˜T˜x˜®™2™€™ìšhš€š˜š®šÄšÚšð››œœ2œxœú€òžPž¾žøŸ&Ÿ¨  6 Þ¡@¡”¢¢˜££R£°¤<¤¨¤þ¥¢¥¸¥Î¥ä¥ú¦¦*¦p¦Ò¦ü§p§€§§¨§¸¨.¨’¨Ô©©P©œ©È©Øª4ªDªbª°ªÞ«,«Ö¬¬X¬Š¬Ì­­0­@­f­¸­È­Ø­þ®‚®’®À®ú¯(¯^¯°°°^°Ð±X±´±Ä²X²Þ²ü³F³V³˜´$´P´¢´Ðµµ:µdµtµ˜¶¶¶8¶H· ··D·~·¬·â¸2¸¸Þ¹P¹Æº"º8ºNºÐºü»j»z»Š» »°¼>¼¸½½Z½”½ª½Ö¾&¾|¾Œ¾œ¾¾¾à¾þ¿¿:¿X¿¦¿ìÀ–Á"ÁTÁ„Á¶ÁæÂÂHÂzªÂÚÃÃ8ÃfÌðÃÀÃÐÃàÃðÄÄ$Ä4ÄXÄhČĜĬÄÚÅÅ:ÅjÅ ÅÐÆÆ2ÆFÆVÆjÆzƊƢƺÆìÇÇLÇvǬÇÜÇôÈ È"È8ÈHÈXÈpȈȘȬÈÄÈÚÈòÉ É"É8ÉâÊnʆʜʴÊÊÊâÊøËËË0ËFË^Ëtˌˢ˺ËÐËèËþÌÌ,ÌDÌ\̺Í&ͼÎÎvÏTÏzÏÞЖÑрўÒÒÈÓ&ÓtÔdÔÀÕ6ÕšÖVÖº×P׬Ø2ؤÙÙøÚTÚ¶Û`ۼܮÜÐÝzÞÞtß4ß`ßzßÈßâàLàÄá"á áüâ`âèãã~ä&ä¦äøå冿Hæ˜æêçÆèè˜é(é`éìê~êÔënëèìæíhíÆîîºïïªïÈðjðôñ`òòZò~ò°òÐóó>óróˆóªóÖóìô ô$ôRôjô‚ôžô¶ôÐôêõõõ*õžõüöXö~öê÷÷&÷|øNøhøÄùRù®ùþúPújú²û‚ûàüfýýhýÌþ"þ~ÿ0ÿÂÎ>HR^jv€ Œ ¦ @ fÔ6žÂ2¨è–ø@t®ÞDˆ®àÆžöPª0r´ìP¤ø&ZŒú8t Ò6xÖ0t–ÚŠöŽ $ J n ê""ä##À$Œ%(%ö&†'N((f(ä)ê*Î+ì,–-H-Š.".¸//à0T11ˆ1æ2‚33š3ò4@4Ò5J5ü6>6Ž6Ú7d7â8f8²9"9n9Æ:R;;t<<‚<ò==ª>>B>˜>î?@?¢?ê@0@X@¼AATAÊAøCJCdCÈDHD¸E6EžFFœGGdGàI2IŽJ J¦K(KºLjM0MÆN„O O’P PÌQvR`RäSnSæTJTúUdUúV¤VüWäX€Y&YšZ Z|Zò[v[Ê\<\š]]²]ú^š_2_ž``’a$a†aþb€b°bÚc*cšcúdPdpd¤døeveèf„f®gg–h&h®iHj*jkRk¼llvlÞmzmònfnÈo@oºp pˆp¸q>qnqÒrNrjrÂs&s‚tt4tLtdt|t”t¬tÄufu~vvzvÞwdwöx^y yZzznzÖ{L{Þ|Z|à}j}Ì~,~€Pà€P fÄ‚,‚ðƒÞ„P„Ô….…†…ž…À††n†–†Ò‡‡^‡‡æˆˆ ‰0‰¬ŠF‹‹`‹ÜŒRŒðšêŽ–Žü<´þ~‘4’j’Â’ú“~””œ•*•Ú–†—@—Ș,˜¤™*™ÞšX››¶œxœêhž ž’ŸŸ¸  À¡>¡Ú¢H¢¸£f£Ð¤V¤¤¥J¥ê¦^¦Þ§<§ì¨P¨Æ©Šª ª$ªjª²« «h«®«È«ì¬¬D­ž®®˜¯¯ž°&°š±D±è²2²’²ö³¤´lµB¶J· ·â¸@¹¹Úº¦»T¼¼È½š¾†¿$¿ŠÀ,ÀÌÁ¾Â~Ã*ÃäÄšÅhÆÆ„Ç<ÇVǘǶÈ6ȦÉÉ’ÊŠÊîË€Ì̪ÍLÎ ÎÈÏ„ϦÏôÐZÑrÒBÓTÔÂÕBÕè× צØ0ÙvÚ¨ÛìݰÞJÞ´ß à~áZázâ´ãvãîäÎäôåXå¨åÖæxçPèèÄélêœë–ìÄììí<í²íÜîzïTð<ðøñîó:ófôô’õHõÐöVö®÷4÷ÌøˆùZúRû&ü`üæý˜þBþæÿ¶ª8úJ("Ô¤öòj  Ø ¢ , ð r þ „ ìôt|äD˜,Ò¸<ž$¬ÐüÈ”Ž¢žž!."Ê$%¸'0(Î*J,Ä.¼/Þ12„3ú6f7Ò8¨9Ö; <¨> ?*@:AîBøDÚG,HlI|J–KþM^NÐP&QzRÔS²T@TòUbVV–WDW²X8Y YúZÜZò[[[4[J[`[v[Œ[¢[¸[Ð[è\\\0\H\^\t\Š\ \¶\Ì\ä\ü]],]D]\]r]ˆ]ž]´]Ê]à]ö^ ^$^<^T^l^„^œ^´^Ì^â^ø__(_@_X_n_„_œ_´_Ì_ä_ü``,`D`Z`p`†`œ`²`È`à`øaa(a@aXana„aša°aÆaÜaòbb b8bPbhb€b˜b®bÄbÚbðcc c8cPchc€c˜c°cÈcàcødd&d<dTdjd€d–d®dÄdÜdòe e"e8eNedezee¦e¼eÒeêfff2fJfbfzf’f¨f¾fÔfêggg,gBgZgrgŠg¢gºgÒgêhhh2hJhbhzh’hªhÂhÚhòi i"i:iRiji‚i˜i®iÄiÚiðjjj4jLjbjxjj¢j´jÄjÖjîkkk0kFk^kvkŽk¦k¾kÖkîlll4lJl`lvlŒl¤l¼lÔlìmmm4mLmbmxmŽm¤mºmÒmènnn0nHn`nxnn¨n¸nÐnèooo0oHo`oxoo¨o¸oÈoâoüpp@pppžpÐqqjqºrr:rvr®rÊrøtu˜uºuðv<v^v”vàww"xxTxÒxîyy¤z>z~zÊzì{{ˆ||<|æ}n}€}’}¤}¶}È}Ú}ì}þ~~"2€2€²@‚Æ„Z…Z†Úˆ ˆžŠRŒHŒ–Œ¦ ŽžŽ®޾~’@“¢”.”X•¾•Þ•þ––6–V–v–Ž–®–Æ–æ——&—>—N—f—†—ž—®—Ɨ昘&˜6˜N˜n˜~˜Ž˜ž˜®˜¾˜Ö˜ö™™™6™V™~™–™¦™¾™Þ™î™þšššTšˆš¼šò›n›ìœœ^œ¨œò<®Äžbž’žþŸ(Ÿ>ŸŠ  6 L „ ž Ô¢¢>££Ö£ú¤¤B¤’¤ä¥<¥â¦Ô§,§¼¨¨p¨Ø© ©>©Ìª ª<ªn««”¬8¬\¬ð­&­~­¬®®Ê¯L¯ä°P°¸°ò±,±„±Ú²²6²n²¨³(³®´Æµä¶b¶æ·Š¸0¸ô¹¨ºî¼@½4¾„¿lÀ¬Á*ÁìÂŒÃjÃàÄœÅXÆ\ÆÎÇ€ÈZɆÊ^Ë„Ì"ÍÍØÎòϸÐÂÑ@ÑÄÒŽÒöÓ¤ÔÔÞÖÖ”×èÙÙÒÚÚÜ>ݦÞFß&ààòâ ã>ã¤ähå:æLç®éê&ëìJí>î&îîï°ðœñžò^ó:óâô‚õxön÷ ÷Ìø„ù¶ûFüPýýRýbýÌþHþ”þàÿ:ÿÿ¾ÿîžHಠ"ê`D®¸@  ” Z ò Ô 8 à pZÒŽþl(„&jòV|ên´°lÖŽX¦<Ü6ؒШú€Ü:¶  Z „ ® Þ!!h!¾","n" "ì#<#Š#Ì$$€%%ª&&4&J&`&v&†&˜&Þ&ô'''$'4'D'T'd't'„'º'â'ò(j(Ä))¦*,*¤+n+”+æ,,j,æ- -z. .j.¼//¬/Î0Ž1L22à3`3è4h4Ò5:5l5ä66877<7¤8>8¤99V:2:Ä;z;ê>4>ž?8?î@:@À!nš.±/<²í2±Ü<²í2±/<²í2²ü<²í23!%!!!MþÔ þõšýf!X|ÐÙ #'#5Ð'STÙþ®ßßRýhh4Ð1Å 3#'73#'4]' ]'Åo††oo††ÿì¹3#3##7##7#537#537337#3å$]jiu'L&|'L&erly$L$}#0| }¹ÄD®DÓÓÓÓD®DÄÄÄþø® ÿ‚18A3#&'&'&##5&'&73&'&54767567654'&ó;~/O9dUD 1K;š+O#G]!GŒ`¯=*/6 ]&/M" ù0jh= gg u.:J0 3_’*þÉð LZþù(<=ÿì[Å!%5F2#"'&5476"327654'&%3#2#"'&5476"327654/&ÇT3?/18Lt8!4$JF A.?2EljÙp&;Y$]]$Y;&2ÿöÚ ##5#5353ÏFÏÏF FÏÏFÏÏWÿmÀh 73#5676=#Wii+ ,R>TU(=$/L(GZ¹dT](4X6GOS;SwD4‚B$/V.?(3f%.Å #6767!5ÊB ^2]7]þÅJþôþñ/1Ú«e„W%ÿéÅ,<#"'&547&'&547632'"327654'&"327654'&‡zV?Y|C/yHQ7Mt;&- P =#P A!Y'B".['C#u:wp=.R:Pv:-0c5%L0AD)ü:F 9K þ×@!*R&A!*R&&ÿéýÅ02#"'&'332765"'&5476"327654'&îA5as7XI o" F\p>,R>WL(G&S)=%Åþ¦¹dQ](4X6GMS;SwD4M@# f%A$0W.nÖ 7#5#5Öhhhhhh¤hhnÿm× #53#5676=#×hii+ < hhþ\xƒ&'-ÿ÷Ú75% -éþvŠÆEÏO¡¤O2oa!5!5þäþaFF¬FF2ÿ÷Ú5-5þŠþv EÏO¡¤OMýå%)%#5476767674/&#"#47632#5JZ#J=RU´~83? ZÇ72%!BBF :"@ÓS$+F;:Žhh"ÿr·åFX3327654'&'"#"327#"'&'&5476767632#"'#"'&547672'"32767676'&™SZ  @53ac“q"cil¢Orpr´ƒz_#l—%%¦{tVLn`BLR/"OMeT&€B2-/:,!,õþè# HGWxY\f"qŽad C*kd“š‚'be^‡yfYMHE1AmTSWG?PC"A0T6Ù %!#3# ÚþçMcxhepxÛÛÙý')Lþ´OoÙ'3!2#32764'&+4'&+3276O(g7:ei89fì´H"(("H´fG"ããA "Ù34Rp/)PX;=ŸvþHW û#$0ÿé¥å#&'&'"32767673!"'&547632–_&6Z€=(_;Sm3 `!þõRjfR•î÷K#,sKpªO1M *GþßUm¹·o[Y›Ù 3!2#'327654'&+Y£O!tIl¼¬®% ¨¬Ù„+QlÑ_=Rµ-8ö ZeÙ !!!!!·®ýõùþdLúRÙRéRZCÙ #!!!·]éþt\Lþ´ÙRéR,ÿéÅå)#'#"'&54767632#&'&#"276=#5Å;h‘™^WfU…³Q! __*5„G5=HprB1Þþ{atrh¢°n Fv1Bb$hNs~T HP]§Ù(#!2#&574'&#'327654'&+º]Pª) H> qPðáy& Iá:þÆÙx!*b3 (%V` 0GAmRVB 0ÿémå7#&'&#"#"'&'332767654/&547632TXm (h) 6)·x: I„©L*X 3uY-,nµh@[°?o>8 1!aT? 8h9^-"=8L#0%…|8"o1QÙ##5!b]ð<‡ýy‡RRUÿé…Ù3#"'&5332765(]hHi¥I)]n"*|-Ùþ‚A-e:Qþu P",…Ù!#33ˆdþúdÖÊcÙý—i¡Ù !# #333èf¨£f»h‰¢d¦†hWý©Ùý°Pý°P‰Ù # #33‡sÇÈqòq»¼ovþŠ0þÐvcþâ •Ù#33ƒ]þçsÖÐoþâ»þcGÙ !!5!5EþL¶ýÕ¶þfÙTýÍRR5R@ÿ,úÙ#3#úggºÙHüãH­ÿøÿìÙ#/í7íÙýíÿ,ÑÙ53#53ggºÔHHüS,I©Å3# #ÅI›EzyEÅþ„,þÔÿêÿPBÿ‚!5Bý¨~22Pçä#'‡`<•ä””*ÿé->%#"'&'"'&5476767676=4'&#"#6763232'53276#G W[n+\$^I QgT!7w°- ‰ R jCH4 1? ?LK#-f&   @ K H%=t þÌ)v^ 6 A/6ÿé Ù 3632#"'#"327654'&6S9i€;%[9Pk;KåS'E!,T*H%ÙþìVlDc¡M1ZCÍT2E}4O3F5ÿéÝ #&/"3273#"'&547632×T T^#O'kT h+8>)\;Rj:\ad.?‰-~‰.iFe M1D+ÿéïÙ$#5#"'&547632"327654'&ïJ:V ‚<&Y9Ol5“U)F$/S'H!Ùý'ESpGgšK/QþôR&3z6R2Eƒ3(ÿé$%!3273#"'&547632!654'&#"þ~+Sf#Th,6ˆ?'^—X%N'Y#R þJš@ <X''1)fR @M™O6[Z0B‹/\.?–+FæÙ367632#4'&#"#FS6Bn'S" *T%SÙþëF J'þtk7M*:þßB–Ù#7#5–SST ýô Íiiÿîÿ&™Ù3"#"'532765#5FS€ 4 SS ý‡gG %ii:öÙ 73##Þk¶Ög±QSÙþUÞµþ©PÌÙD˜Ù#˜TÙý'ÙFú*36763267632#4'&#"#4'&#"#FM6JY+6?zT?=%TG >%T JL AA bþwiQ6%.þ·iW8$-þ·Fç367632#4'&#"#FM6Li*S;T%T XUF )þtkF M*:þß$ÿéþ2#"'&5476"327654'&˜9f8O X„Y$ x7+7E%'B8 %BX?&(7L! c?4J .Wš?$&*'C…é',%'#"''7&547'76327'"327654'&å:5(<5)380 687,5:(;979 /!7 0¾65391+;9-7575:7)42/É/7-: !Å#3##5#535#5333着ªX¬¬¬—ÍU¹³UÉb3M3¯¯3M3cþ¾Bþdÿ, Ù3#3#d<<<<Ùþo‹þo+ÿ+úÙBP#54'&#"#"'&'&53327654/&'&54767&547632654/ÐT76 +’Rm0G2Bd4 U7@ 7ªTO ,D2Cc0þì¦II¡>  G+ $^58!s)70U1"E!56,/2&u:Q T333O1%J+<þ½{'?=3m(* ) d(Ë#5!#5†h hËggggÿóÿêïæ 8H327673#"'&547632#&'&#"2#"'&'&547676"27654'&ú6(RG1We6'P1Dx'G2 K w—nl jg™ ‘mkgf“\\[_|‡\[\[f_0rO%FU=Uƒ@(M L)Ige“›nl fe—nl >]]†‚^^_]…ƒ^]%/Mæ+7!5%#"'4'#"'&54767676=4'"#6723232'5276@þë", 18J9 D+C/ ;szT>? 04 b33_,%+8>  + g^³G3  +#bjǶ 757757b˜jj5˜jjãYzSSSSyYzSSSS(V w!#5!(øFþNwþßÛ.ð8#5î8HHÿóÿêïæ!9I#32#&574/3674/#72#"'&'&547676"27654'&FÎ ! O.†G4a—nl jg™ ‘mkgf“\\[_|‡\[\[E¹½~3+=#*(;? ::Üge“›nl fe—nl >]]†‚^^_]…ƒ^]w.½!5.þî½FF—Æ®2#"'&5476"327654'&/J- <)4H. <(44,7,®;)3L-;)4J.9,3.42ÿõo ##5#5353!5ÏFÏÏFÏþ FÏÏFÏÏþ›FFFÅ!!676?654'&#"#67232CþÐ&;:;+3 >†W' `?1V:U* /- '+‘;R/ "BÅ-527654/"#632#"'&53327654'&'&‡U25 ?` 9GG$0q >? H( Ü3 4 #%ŽB;LR"VN 8 .\P-ä3#¼q•<ä”Aÿ$  %#"'&5#"'#332765332 !O;h6$SS:U&S-1? ISßèþF N*9)þL)0ÿO Ù####&'&'&54763 9@R@M0IM>UÙ@ü¶Jü¶´(=i pG9W.Ó«#5Ó|«}}'ÿ*;632#"'&'72765&'"'¥& FB ,?  9 & ' 87?( "=ÞÅ #5767673# c= +>D.)þW(/Dæ$!52#"'&5476"327654'&:þùƒlO#e T ;7;: b33„j%w% _"+~" 4C&]Cabjö 57'557'5üšllašll=YzSSSSyYzSSSS=ÿìQÅ #5767673#3#%#533##= c= +>ã:þ<:¼Ì.CC>D.)þW©ý'x; þð5d™ªª=ÿìLÅ 1#5767673#3#%!676?654'&#"#67232 c= +>Ë:þ<:¢þÐ&;:;+3 >†W' `?1D.)þW©ý'N:U* /- '+‘;R/ " ÿìQÅ-1<?527654/"#632#"'&53327654'&'&%3#%#533##=‡U25 ?` 9GG$0q >? H( Ó:þ<:¼Ì.CC>Ü3 4 #%ŽB;LR"VN 8 .éý'x; þð5d™ªª_ÿ' #'3327653#"'&54767676=3Z) J=&RU´71? ZE72%$ BBF:"@ÓU->F:9Žhh« %!#3# #'ÚþçMcxhepxX`<•ÛÛÙý')Lþ´‚””« %!#3# 3#ÚþçMcxhepxšq•<ÛÛÙý')Lþ´‚”¬ %!#3# 3#'#ÚþçMcxhepxH_`?QO@ÛÛÙý')Lþ´ƒ–``” %!#3# 3#"'&#"#6763232ÚþçMcxhepxÚ:J@# :;*'ÛÛÙý')Lþ´kh %] ’ %!#3# #5!#5ÚþçMcxhepxZh hÛÛÙý')Lþ´igggg¹ +%!#3# 2#"'&5476"327654'&ÚþçMcxhepxw2 +0 *   ÛÛÙý')Lþ´+ 1 */ ,   ¶Ù%!#!!!!!!#ÔþóUg+nþ`þ …þdŠÖÖÙRéRúR(_þ¡0ÿ*¥åB632#"'&'732765&'"'7&'&'&'&54767632#&'&'"32767673{ FB .D 9 & ' U- maR•î+_&7X=(`;Rm3 `!!7?( "E NŸ+/²o[îK#+sKp¬O0M +GþßZe« !!!!!#'·®ýõùþdþü`<•LúRÙRéR_””Ze« !!!!!3#·®ýõùþdÖq•<LúRÙRéR_”Ze¬ !!!!!3#'#·®ýõùþdþå_`?QO@LúRÙRéR`–``Ze’ !!!!!#5!#5·®ýõùþdþ÷h hLúRÙRéRFggggÒ«#7#'Á]`<•Ùý'ÙÒ””G«#73#Á]Cq•<Ùý'ÙÒ”ÿÿ¬ #'3#'#Á]_`?QO@Ùý'ÙÓ–`` ‹ #7#5!#5Á] h hÙý'Ù²gggg›Ù#53!2#!327654'&+3YEE£N!uIjþæ]­²"¡­«SCC„+QlÓ_;Sþÿ¿*2ï%ñCL†” ##3'3#"'&#"#6763232†iþ‡Xe}[:J@# :;*'Ùý'Oý±Ùý¬T»h %] &ÿéæ«"&2#"'&5476"327654'&#'…®a8R[‡§bWo_‘‚H8_CaH:bB~`<•å{&`ƒ”iMuh¡¸k[RfPvžS;dOu¥S8””&ÿéæ«"&2#"'&5476"327654'&3#…®a8R[‡§bWo_‘‚H8_CaH:bBCq•<å{&`ƒ”iMuh¡¸k[RfPvžS;dOu¥S8”&ÿ鿬")2#"'&5476"327654'&3#'#…®a8R[‡§bWo_‘‚H8_CaH:bBŽ_`?QO@å{&`ƒ”iMuh¡¸k[RfPvžS;dOu¥S8–``&ÿéæ”"82#"'&5476"327654'&3#"'&#"#6763232…®a8R[‡§bWo_‘‚H8_CaH:bB:J@# :;*'å{&`ƒ”iMuh¡¸k[RfPvžS;dOu¥S8h %] &ÿéæ’"&*2#"'&5476"327654'&#5!#5…®a8R[‡§bWo_‘‚H8_CaH:bB|h hå{&`ƒ”iMuh¡¸k[RfPvžS;dOu¥S8ÿgggg_"è« ''7'7¶1’“2“’2“’1’«2’“2“’1“’1‘ÿéèó'?&5476327#"'7&#" 327654QLp_‘‰]W(YTp_‘aMi€Ib„H7Ñþ}Jk„H7Yj’¸j[Q_$ajž¸j[ZTÁ£@gOuh*þ[JgOurUÿé…«3#"'&5332765#'(]hHi¥I)]n"*|-Ú`<•Ùþ‚A-e:Qþu P",Ò””Uÿé…«3#"'&53327653#(]hHi¥I)]n"*|-¥q•<Ùþ‚A-e:Qþu P",Ò”Uÿé…¬3#"'&53327653#'#(]hHi¥I)]n"*|-ê_`?QO@Ùþ‚A-e:Qþu P",Ó–``Uÿé…’3#"'&5332765#5!#5(]hHi¥I)]n"*|-Øh hÙþ‚A-e:Qþu P",¹gggg •« #33%3#ƒ]þçsÖÐoþØq•<þâ»þcÒ”[hÙ7#332#'327654'&+¸]]Ћ8N5HåÂd N"½½Ùx_1Dn:(RK[ Cÿñ;Ø1674/&#"#47632"#"'5327454'"+&”K&sX]8R“=O@"Ž1=!¤˜ « hJ V(þq4S)8_3J'$´4KŒ…*ÿéä->B%#"'&'"'&5476767676=4'&#"#6763232'53276#'#G W[n+\$^I QgT!7w°- ‰ R jCH4 Š`<•1? ?LK#-f&   @ K H%=t þÌ)v^ 6 A/f””*ÿéä->B%#"'&'"'&5476767676=4'&#"#6763232'532763##G W[n+\$^I QgT!7w°- ‰ R jCH4 Uq•<1? ?LK#-f&   @ K H%=t þÌ)v^ 6 A/f”*ÿéå->E%#"'&'"'&5476767676=4'&#"#6763232'532763#'##G W[n+\$^I QgT!7w°- ‰ R jCH4  _`?QO@1? ?LK#-f&   @ K H%=t þÌ)v^ 6 A/g–``*ÿéÍ->T%#"'&'"'&5476767676=4'&#"#6763232'532763#"'&#"#6763232#G W[n+\$^I QgT!7w°- ‰ R jCH4 :J@# :;*'1? ?LK#-f&   @ K H%=t þÌ)v^ 6 A/Oh %] *ÿéË->BF%#"'&'"'&5476767676=4'&#"#6763232'53276#5!#5#G W[n+\$^I QgT!7w°- ‰ R jCH4 h h1? ?LK#-f&   @ K H%=t þÌ)v^ 6 A/Mgggg*ÿéò->O_%#"'&'"'&5476767676=4'&#"#6763232'532762#"'&5476"327654'&#G W[n+\$^I QgT!7w°- ‰ R jCH4 q2 +0 *   1? ?LK#-f&   @ K H%=t þÌ)v^ 6 A/t+ 1 */ ,  "ÿéM;LU%3"'&'&'#"'&54767676=4#"#6763267632!32%5"32767!4'&#"ïTd32k; ][g+d6jF vgT!7u€/1^oB þ~+Seþ³![g<=21P&A"-U)Ÿv,Ca H$/i%  NM H%=RE P 7pH(Dge0=&&°],K$ÿ*Ý?632#"'&'732765&'"'7&'&'&547632#&/"3273 C B ,<  7"& ' 9$Z \;Rj:T T^#O'kT[2!2 ?) "G @Ž M1D+Fad.@‰-z5(ÿéä$(%!3273#"'&547632!654'&#"#'þ~+Sf#Th,6ˆ?'^'']&M )Z'Re-'(,/-%)DAfq Á?„>W²B# (f\0@‡1X/B‘.FçÍ-367632#4'&#"#3#"'&#"#6763232FM6Li*S;T%T4:J@# :;*' XUF )þtkF M*:þßÍh %] $ÿéþä#2#"'&5476"327654'&#'˜9f8OEJGs¯F$AA¨þó0\0@B· 4\0@DAÿéâä!#5#"'&53327653'#'âK8Jk)S;U&Sï`<•IO F )”þF N*9)Ø””Aÿéâä!#5#"'&53327653'3#âK8Jk)S;U&Sºq•B%#"'&'"'&5476767676=4'&#"#6763232'53276!5#G W[n+\$^I QgT!7w°- ‰ R jCH4 þî1? ?LK#-f&   @ K H%=t þÌ)v^ 6 A/?FF£ %!#3# 3327653#"'&ÚþçMcxhepx;TM ; V*ÛÛÙý')Lþ´zB9‡9*ÿéÜ->L%#"'&'"'&5476767676=4'&#"#6763232'532763327653#"'&#G W[n+\$^I QgT!7w°- ‰ R jCH4 þù;TM ; V*1? ?LK#-f&   @ K H%=t þÌ)v^ 6 A/^B9‡9ÿ3´Ù%!#3327#"'&54767# ÚþçMcx`H%0!$?F$epxÛÛÙý'.;7 - 9:&)Lþ´+ÿ3T8I%327#"'&'4767&'#"'&5476767676=4'"#6763232'53276HH&*+=/ 9Qan+]#]F uhT 8v°- Š R jCH4 1?#87 - <. CMK#-e'   MM G&=t þÌ)v^ 6 A/0ÿ饫##&'&'"32767673!"'&547632'3#–_&6Z€=(_;Sm3 `!þõRjfR•îÕq•<÷K#,sKpªO1M *GþßUm¹·o[Æ”ÿéÝä $#&/"3273#"'&5476323#×T T^#O'kT h+8>)\;Rj:§q•<\ad.?‰-~‰.iFe M1D+B”ÿÿ0ÿ饗'ï²&ÿÿÿéÝÊ'ïƒÿåFÿÿ0ÿé¥i'ôÚ&ÿÿÿéÝœ&ô\ÐF0ÿ饬&#&'&'"32767673!"'&547632'#'373–_&6Z€=(_;Sm3 `!þõRjfR•î¿_`?QO@÷K#,sKpªO1M *GþßUm¹·o[1–``ÿéÝå '#&/"3273#"'&547632'#'373×T T^#O'kT h+8>)\;Rj:˜_`?QO@\ad.?‰-~‰.iFe M1D+­–``Y›¬ 3!2#'327654'&+7#'373Y£O!tIl¼¬®% ¨¬Ì_`?QO@Ù„+QlÑ_=Rµ-8ö –``ÿéˆÙ$0#5#"'&547632"327654'&3+52'#ïJ:V ‚<&Y9Ol5“U)F$/S'H!ñd097Ùý'ESpGgšK/QþôR&3z6R2Eƒ3 gL &V›Ù#53!2#!327654'&+3YEE£N!uIjþæ]­²"¡­«SCC„+QlÓ_;Sþÿ¿*2ï%ñCÿé-Ù(3##5#"'&5476325#5353"327654'&î??JFbv>.Y8Oa@––SåU)D$0T'H 5ý¨;ReKo™K/N‹5LþðQ1Ev5R1B€2Ze„ !!!!!!5·®ýõùþdbþîLúRÙRéR8FF(ÿé½$(%!3273#"'&547632!654'&#"!5þ~+Sf#Th,6ˆ?'^—X%N'Y#R£;UM ; V* þJš@ <X''1)fR @M™O6[Z0B‹/\.?–+B9‡9ÿÿ,ÿéÅi'ôå*ÿÿÿ&éœ&ôXÐJ,þãÅå)4#'#"'&54767632#&'&#"276=#53#52'#Å;h‘™^WfU…³Q! __*5„G5=HprB1ÞDd;97þ{atrh¢°n Fv1Bb$hNs~T HP—X%N'Y#R%d;77 þJš@ <X''1)fR @M™O6[Z0B‹/\.?–+‚gX&TÿÿS„—'ïȲ+ÿÿÿàæ—'ïÿ̲K'°Ù!5%53!533##!##5°wþ,]w],,]þŠ^,øZZH™™™™FþLþ´úFæÙ3#67632#4'&#"##5353™––6Bn'S" *T%S??S5”F J'þtk7M*:þßX5Lÿÿÿö0i'÷ÿñœ,ÿÿÿë%œ&÷æÏó„#7#5Â^®þÙý'Ù«FFÿðç½#7#5•S¥÷ ýô ±FFÿÿÿý*ˆ'óÿî¬,ÿÿÿñ»&óâßóBÿ4êÙ327#"'&54767#Â8"  I 3 +Ùý'38(  - 14, Ùÿ4¾Ù327#"'&54767#7#5–* " F -  ST ýô&1 *  - /0+  Íii`È“#7#5Ã^chÙý'Ùºhh^² #²T ýô ÿÿdÿérÙ'-È,ÿÿBÿ&1Ù'M˜Lÿÿÿé —'ïØ²-ÿàÿ&ÿ3"#"'5327653#'#FS€ 4 _`?QO@ ý‡gG ]–``Oþã’Ù #33 #3#52'#¬]]kxþ×,nþÿd;97ÿÿÙþqþ×þPvþNgX&V:þãöÙ 73##3#52'#Þk¶Ög±QSŸd;97ÙþUÞµþ©PÌÙüëgX&V:ö 73 #%#Þkþð0gþþS ÞÞþüþøØØ F« !!73#­hþ;Vq•<ÙýyRÙÒ”?«#73#˜T[q•<Ùý'ÙÒ”PþãÙ!!3#52'#­hþ;±d;97ÙýyRÙüëgX&V?þã£Ù#3#52'#˜Td;97Ùý'ÙüëgX&VPÙ!!;+52'#­hþ;Ád097ÙýyRÙgL &VD1Ù#;+52'#˜T‰d097Ùý'ÙgL &VÿÿPÙ'y/ÿÿD±Ù'yÞO(Ù 7!!573­««{þ(PP]–yLz÷R9M8uÔÙ 7#573’BBS??S¥3@3þ›92@2`L†« ##3'3#†iþ‡Xe}©q•<Ùý'Oý±Ùý¬TÒ”Fçä367632#4'&#"#3#FM6Li*S;T%Tðq•< XUF )þtkF M*:þßä”Lþã†Ù ##33#52'#†iþ‡Xe}þüd;97Ùý'Oý±Ùý¬TüëgX&VFþãç"367632#4'&#"#3#52'#FM6Li*S;T%TŸd;97 XUF )þtkF M*:þß­þ°Hþ[;|e6336d}GõRJ\\d¸ÎeEXLRîR‘exNMLN(ÿéƒ%9B%3#"'&'#"'&54763267632!32"327654'&'&!4'&#"$Tf,7|@?ƒ›8z1B‡=6gsA þ~+Sfþ]&O(['QÝ&A"-U)Ÿx+]g…>WÀ?jXR7pH(D˜]'5 ‹/Y0A.  ],K$]§«(,#!2#&574'&#'327654'&+3#º]Pª) H> qPðáy& IáÅq•<:þÆÙx!*b3 (%V` 0GAmRVB $”EKä367632#3#EM::  H;T•q•< _]U+nþðä”]þã§Ù(3#!2#&574'&#'327654'&+3#52'#º]Pª) H> qPðáy& Iá…d;97:þÆÙx!*b3 (%V` 0GAmRVB ý=gX&VAþãA367632#3#52'#EM::  H;Td;97 _]U+nþð qPðáy& IáÚ_`?QO@:þÆÙx!*b3 (%V` 0GAmRVB –``0Oå367632##'373EM::  H;Tª_`?QO@ _]U+nþðO–``0ÿém«7;#&'&#"#"'&'332767654/&5476323#TXm (h) 6)·x: I„©L*X 3uY-,nµh@[°?êq•<o>8 1!aT? 8h9^-"=8L#0%…|8"o1f”"ÿéËä04#&#"#"'&53327654/&'&5476323#¶XfRBPvZ4JÂX!GT 6NwT1D‘# £q•<zT1-F`,¢ /#/.3+]*eI”ÿÿ0ÿém­'ï¬È6ÿÿ"ÿéËÊ&ïVåV/ÿ*måV632#"/732765&'"'7&#'&'&7332767654/&547632#&'&#"OFB -B 9 & '  ,u1X 3uY-,nµh@[°?Xm (h) 6)·xG#8 7?( "Eb7C-"=8L#0%…|8"o1Bo>8 1!a^@"ÿ*ËM632#"'&'732765&'"'7&'3327654/&'&547632#&#"ôFB -B 9 & ' ¨X!GT 6NwT1D‘# XfRBPvA& 7?( "G /#/.3+]*e!T1-FO/ 0ÿém¬7>#&'&#"#"'&'332767654/&547632'#'373TXm (h) 6)·x: I„©L*X 3uY-,nµh@[°?Ø_`?QO@o>8 1!aT? 8h9^-"=8L#0%…|8"o1Ñ–``"ÿéËå07#&#"#"'&53327654/&'&547632'#'373¶XfRBPvZ4JÂX!GT 6NwT1D‘# _`?QO@zT1-F`,¢ /#/.3+]*e´–``ÿÿÿ*QÙ'z€7ÿÿÿ%œ&zéWQ¬##5!'#'373b]ð<î_`?QO@‡ýy‡RR–``ÿéA ##327#"'&5#53533+52'#þV 'Y GGS5d097 Dþ™&FC ŒDgL &VQÙ##5!b]ð<‡ýy‡RRÿéþœ#327#"'&5#5353þV 'Y GGS Dþ™&FC ŒDÿÿUÿé…i'÷Ëœ8ÿÿAÿéâœ&÷pÏXUÿé…„3#"'&5332765!5(]hHi¥I)]n"*|-2þîÙþ‚A-e:Qþu P",«FFAÿéâ½!#5#"'&53327653'!5âK8Jk)S;U&SGþîIO F )”þF N*9)±FFÿÿUÿé…ˆ'óȬ8ÿÿAÿéâ»&ólßXUÿé…¹&63#"'&53327652#"'&5476"327654'&(]hHi¥I)]n"*|-»2 +0 *   Ùþ‚A-e:Qþu P",à+ 1 */ ,  Aÿéâò(8!#5#"'&53327653'2#"'&5476"327654'&âK8Jk)S;U&SÑ2 +0 *   IO F )”þF N*9)æ+ 1 */ ,  Uÿé…«3#"'&53327653#%3#(]hHi¥I)]n"*|-ßq•<q•<Ùþ‚A-e:Qþu P",Ò–––Aÿéä!#5#"'&53327653'3#%3#âK8Jk)S;U&Sïq•<q•,6Aÿ4  *327#"'&547#5#"'&5332765â;- 3` `8Jk)S;U& ýô"4 (  - 6=2IO F )”þF N*9)ÿÿ¡—'ï8²:ÿÿÄÊ'ïÂÿåZÿÿ •—'﮲<ÿÿÿ&ÞÊ&ïVå\ •’ #33%#5!#5ƒ]þçsÖÐoþ£h hþâ»þc¹ggggG« !!5!5%3#EþL¶ýÕ¶þf#q•<ÙTýÍRR5RÒ”Éä !!5!573#»þÉEþV9þÜâq•< Jþ‡IKxIØ”G“ !!5!5%#5EþL¶ýÕ¶þf;hÙTýÍRR5RºhhÉÌ !!5!57#5»þÉEþV9þÜûh Jþ‡IKxIÀhhG¬ !!5!5%#'373EþL¶ýÕ¶þf6_`?QO@ÙTýÍRR5R=–``Éå !!5!57#'373»þÉEþV9þÜö_`?QO@ Jþ‡IKxIC–``Ü3##53547632&#"«SFFJ :ÈDYXE5ÿÿÿé-ÙGÓGÀ@ÿÿOpÙi6ÿé Ù""327654'&!!632#"'S'E!,T*H%þï‡þÌ9i€;%[9Pk;ÍT2E}4O3F5þ4ÙIËVlDc¡M1ZCpÙ 7327654'&+532#!57537¬ÔQ)A#.Ô¥ú T=UþÆOO]¬R>#.T'ªX­rA/Ý4M4¯qqLÿ÷ÿé Ù("327654'&'632#"'#57537S'E!,T*H%¾9i€;%[9Pk;K??SBÍT2E}4O3F5†VlDc¡M1ZC2@2zN3@ÿÿ0ÿé¥å&ÕÎÀ0ÿéíå/547632&#"1#&'&'"32767673!"'&547632?I 3_&6Z€=(_;Sm3 `!þõRjfR•î÷Y\ O(RK#,sKpªO1M *GþßUm¹·o[ÿé.,(632&#"#&/"3273#"'&547632”R 3T T^#O'kT h+8>)\;RTî>E(Rad.?‰-~‰.iFe M1ÿÿ›Ù’ÿÿNpÙGC¾À@ÿÿ6ÿé ÙGDAÀ@ÿÿZeÙG(¿À@&ÿéæå'67632#"'&547!&'&#"!3276/{Rl®a8R[‡§bWa e?V‚H ùþe;MH,Ä M4{&`ƒ”iMuh¡ œI-f-<•A&d<0ÿémå7#"3276'3#"'&'&54767&547632#&'&#";œlQ3+-Yu3'X*L©„I@ m ih@[°?Xm (h) 01=XA;#$8&=.B^9h83Tr3-l|8"o1Bo>/--ÿ&CÙ 73#"'5325#!!!Z]X$ D]]éþt\àþ³OQ;˜þ´ÙRéR ÿ,â!#"'732767#53767632&#"Ó~K.:M$ENq}-3@#, G ÎFþsg/7 TaFhP,0O~F,ÿéå9547632&#"#'#"'&54767632#&'&#"276=#5dI 3 ;h‘™^WfU…³Q! __*5„G5=HprB1ÞüY\ O(R{þ{atrh¢°n Fv1Bb$hNs~T HPQI.å{&`ƒ”iMuh¡¸k[þœœI-eGfF‘E*dA6ÿ&HP"2547632&#"3632#"'"327654'&¤V 3þEM;l<&Y'4a@’S'E!,T*G#€YdE(Rý¦æO^oGhšK! Nþï§T2E}4Q2E5ÿÿ0ÿémåG6À@ÿÿ"ÿéËGVíÀ@GÙ 5!!!!5÷Ù þfÛÛ¶ýÕmTRþæþåRRÿ&þœ!&'#53533#327#"'532765ªPGGSVV r 4 CŒDDþ™&£` G ÿéÿÜ!3#327#"'&5#53547632&#"¨VV 'Y GGJ :^RDþ™&FC ŒDYXEÿ&QÙ %327#"'&5##5!bD v]]ð<àþÔ;QFM§ýy‡RRÿÿY¬'?¼'ÿÿYå'@Ä'ÿÿÿéõå'@,GÿÿPÿéÖÙ'-,/ÿÿPÿ&ÅÙ'M,/ÿÿDÿ&wÙ'MÞOÿÿLÿénÙ'-Ä1ÿÿLÿ&kÙ'MÒ1ÿÿFÿ&ÅÙ'M,Qÿÿ£'ð®¾$ÿÿ*ÿéÙ&ðpôDÿÿ"£'ðÿð¾,ÿÿÿùÙ&ðæôóÿÿ&ÿ鿣'ðâ¾2ÿÿ$ÿéþÙ&ðnôRÿÿUÿé…£'ðʾ8ÿÿAÿéâÙ&ðoôXÿÿUÿé…'qÈCžÿÿAÿéâ9&qm|¾ÿÿUÿé…N'vójžÿÿAÿéâ‡'v˜£¾ÿÿUÿé…P'ðÊkžÿÿAÿéâ‰'ðp¤¾ÿÿUÿé…N'C¤jžÿÿAÿéâ‡'CI£¾ÿÿ(ÿéH)Àÿÿ'qªC†ÿÿ*ÿé9&ql|¦ÿÿã'q¬&²ÿÿ*ÿé&qn\³ÿÿ ¶S'qÈ–ˆÿÿ"ÿéM‰'qÿ̨ÿÿ,ÿéÅ£'ðè¾*ÿÿÿ&éÙ&ðZôJÿÿO’£'ð̾.ÿÿÿÔö—'ðÿÁ²Nÿÿ&ÿ#æå'öÉÿð2ÿÿ$ÿ#þ&öTðRÿÿ&ÿ#æS'qà–‚ÿÿ$ÿ#þ‰&qk̃ÿÿÿßÿ&þÊ&ðÌåFÿÿYÙ'=Ò'ÿÿY›Ù']Ò'ÿÿÿéõÙ'],Gÿÿ,ÿéÅ¡'v½*ÿÿÿ&é×'v‚ÿóJÿÿL†¡'C ½1ÿÿFç×&CNóQÿÿu'vÕ‘‡ÿÿ*ÿé®'v™Ê§ÿÿ ¶¡'vó½ˆÿÿ"ÿéM×'v=ÿó¨ÿÿÿéè¯'v Ëšÿÿÿâ×'v—ÿóºÿÿþú£'j¿$ÿÿþ¼ÿéÙ&,õDÿÿÿn”'¬¸$ÿÿÿ0ÿéÊ&nîDÿÿÿe£'p¿(ÿÿþÁÿéÙ&1õHÿÿÿse”'±¸(ÿÿÿ4ÿéÊ&rîHÿÿþ<£'ÿ¬¿,ÿÿþ1²Ù&¡õóÿÿþ°Â”'ÿî¸,ÿÿþ¤²Ê&âîóÿÿÿ.ÿ鿣'ž¿2ÿÿþ¹ÿéþÙ&)õRÿÿÿ¢ÿéæ”'à¸2ÿÿÿ,ÿéþÊ&jîRÿÿþ®§£'¿5ÿÿþlAÙ&ÜõUÿÿÿ"§”'`¸5ÿÿþàAÊ&îUÿÿÿÿé…£'†¿8ÿÿþºÿéâÙ&*õXÿÿÿŠÿé…”'ȸ8ÿÿÿ.ÿéâÊ&lîX0þãmå7B#&'&#"#"'&'332767654/&5476323#52'#TXm (h) 6)·x: I„©L*X 3uY-,nµh@[°?þÏd;97o>8 1!aT? 8h9^-"=8L#0%…|8"o1ýgX&V"þãË0;#&#"#"'&53327654/&'&5476323#52'#¶XfRBPvZ4JÂX!GT 6NwT1D‘# ñd;97zT1-F`,¢ /#/.3+]*eþ)gX&VþãQÙ##5!3#52'#b]ð<þ³d;97‡ýy‡RRý=gX&Vþãþœ"#327#"'&5#53533#52'#þV 'Y GGS9d;97 Dþ™&FC ŒDý¸gX&VÿÿS„£'ðɾ+ÿÿFæ—'ðt²Kÿÿu'ôª©$ÿÿ*ÿé«&ôlßDÿÿZÿ1eÙ'z¨(ÿÿ(ÿ&z^ðHÿÿ&ÿéæ'qáC˜ÿÿ$ÿéþ9&ql|¸ÿÿ&ÿéæ'qçE—ÿÿ$ÿéþ;&qr~·ÿÿ&ÿéæu'ôÞ©2ÿÿ$ÿéþ«&ôißRÿÿ&ÿéæã'qà&ºÿÿ$ÿéþ&qk\»ÿÿ •S'q¬–<ÿÿÿ&Þ‰&qTÌ\ÿÿ*ÿéDAÀÿòå#4763253#5"#"'&%4'&#"3276V6PZBSS9=1U><s:&5J&7)8Q"ŸJ/PBýô96 VTko;&Y7B`<-`0ÿÿDÿòÁ) À6ÿé Ü .547632&#"#3632#"'#"327654'&6J :SS9i€;%[9Pk;KåS'E!,T*H% YXE5RGVlDc¡M1ZCÍT2E}4O3F5ÿÿÿéÝFüÀÿ&LÙ."327654'&#"'&5476323327#"5 U)F$/S'H!r:V ‚<&Y9Ol5S*  ‹ÍR&3z6R2Eƒ3þxSpGgšK/QüÛ8 GmÿéFÜ."327654'&7#5#"'&547632547632&#" U)F$/S'H!¼J:V ‚<&Y9Ol5J :ÍR&3z6R2Eƒ3‘ý¢ESpGgšK/Q›XEÿÿ(ÿéGH)À@ÿÿ(ÿéH)Àÿÿ"ÿéËGÊíÀ@ÿÿ"ÿéËÿ&@Š7G547632&#"'3#"'&'33276="'&'&547632'"327654'&œV 3MM)0m Š2U$;Q#;IS=BU9Qb>—X%N'Y#RºYdE(RRþJš@ <X''1)fR @M™O6[Z0B‹/\.?–+ÿÿÿ&éJÿÿFÿ3æ K, ÀFæÜ %547632&#"#367632#4'&#"#FJ :SS6Bn'S" *T%S YXE5RHF J'þtk7M*:þßFÿ&æÜ-4'&#"#47632&#"67632"#"'53276“" *T%SJ :6Bn'€ 4 L·7M*:þßeXE5šF J'þgG ÿøæÙ#5533##5#5–TSPPSKÙiiþ_ÔÔHððHBÿéë 327#"'&5• 'Y  þU&FC Ðÿÿ^² óDÿ&ðÙ3327#"'&DT  † mFüÛ5 G`ÿÿFÿñú P@ ÀFÿ8ú (#"'&'"'&53327653327653úM6J!Y+6?,zT?>%TG >%TÈL AA b‰þ—Q8$-Iþ—W8$-IFÿ&ú:%3#"'53276536763267632#4'&#"#4'&#"#¦Tr 4 ý M6JY+6?zT?=%TG >%Tàþ³` G XJL AA bþwiQ6%.þ·iW8$-þ·ÿîÿ&ç'73#"'532765367632#4'&#"#FTr 4 M6Li*S;T%Tàþ³` G XXUF )þtkF M*:þßFÿ&@'%327#"'&5367632#4'&#"#è  † þ²M6Li*S;T%TàþÔ5 G`M,XUF )þtkF M*:þß$ÿéþ!2#"'&5476&'&#"!3276˜9f8O‹7j B‚ˆ@ˆÿÿµ"#"=336? JLÀ/ Ocj ÿÿnÿm× ®IÿÐ#'ÿ)Ї‡ÿÿKCUK&ý{j-ßÿÿ¦Ð&ÄYȼ02#"'&5476Š    / " " ÿÿÿÔfÐ'ÿ&ÿÿÿ¹qÐ'ÿ !ÿÿÿ£Ð'ÿ#ÿÿÿðÿøÞÐ'ÿB)ÿÿÿžÿþ—Ð'þð.ÿÿÿúÿÿÀÐ'ÿL2ÿÿÿßÿø_&”B¦Ì!#'!#3&'¦jTþÔNffHh = ÚÚÌþZ%VœD&JgÌ#,%#!!2'4'&'&+32764'&+32g> <†þð ”; U%M3 #Fœ?Hm*¦²ªÔ^; 0ÌP$`0 5ÛE ØìböR6Ì!#!6þ|`äxýˆÌ ÿÿ«Ì!&"#3&'&'«Zþ8E7fš©  ˜Ìýˆ¼ &AIþ\PfÌ )!!!!!fýêþXŒþt¸ÌTÜTô#YÌ )567!5!!YýÊp+þpþDÈXÊ7TTýÜAqÌ !#!#3!3q^þŒ^^t^Rþ®ÌþÚ&-ÿóÙÉ$(#"'&'&547632327654/&#"!5!Ùj]ZKP01lZ‹`hý´V@^•BY6H¢9œþ°P]ªfY$%OM}¸fUV\¯L7‚>Y˜N!AkRE£Ì3#3£^^ÌJšÌ !##33š~þþr^^bxþÞjrøÌþžbþÞÿÿ¦¼ !#0#3¦jðš %ffsþMWh¼@ìÌ!###373ì\ÐVÎ\¨&¬€Xý¨býžÌþE%rò8lÌ !##33l`þˆ\bxZ2ýÎÌýÎ2Aÿÿd» !5!!5!!5!Sýî9þg™IýÞ"iRþƒRþpR2ÿøÞ¾#47632#"'&7327654'&'&#"2oZXNM21j^޵^C`V@^•Bf7R¡:R¶cR%&PNz§cW|ZŠI6=W K&Š@Pÿÿ€¼!#!#!€^þŒ^0iý—¼Nÿÿp¼"+#!24'&+3276pü¸^4CbR>¸ºòÎþã¼ :d[ûV(ÿþ^½!5'5!!!^ýÊìÊþp%t òÈV#óRR&Ž&þÙ'ÿþ_»###5!_î^ì8iý–jRÿþ—» #367—þè\þòpŸ>—ºþnþÖ*’ó.'gáÿþ°¿)##5"'&547635324'&'676°RR|S|RR]QsQ‡SG[\.;p5 þèo6[.XzKMGGMJ{QEPP[Mjp8þc T2‘ P#+u;$¨°!##36767673¨tϰpîm™  x fö$ðgHÓ šþ¼4ÿý¶º#+#5#"'&'&5;3327657¶((@ J^i0 FZC#<VqZdX25  9qVþ¸gÛþ%; 8H*ÿÿÀµ)476323!567654'&#"!53&'&/W[nMo ްþî\./SAa{A.sþø®_‹cg0H…)+«[ IM$JMZƒLÿÿÿJòÐ&[@ÿÿ8ÿøÐ&Bÿÿ(ÿòÞ_&3N0ÿóG"2"'&=&5#"'&5476763533274'&#"3276÷3 )'2Õ!a#*o3H +t)"Iz t ) ñ5Ch FNþ[ ECB7œ±~!2ÿ:øÜ2%#"'&'#476763227654'&+5327654'&#"øQ4IV1 V# 5V‰-`žài'/L2*^ "!0;)Èw:%( ú°p4/b'3z"þÖ\G#JL 8)jþªSÿ: #5&#"'472 ¼V§  */vþææ˜F4þÐ~%ÿðÎ*%#"'&547632'5!!'";2767654'&x5QiDA”& ÓŽþó¯8LøZ*_/6 R!ú¾5DC{¿7 —HH)M5T+7Ž"(\z)'ÿöÜ-%#"547&5476732#&'&#";#"32767Üj*<Öffw'8 ”-Lc =#..\h e$ ˆm ’_`oN(< UB;0J -&ÿ>¸Î$'654'&#"'&54767#5!¸&L" W\M‡/:àdOH.+4K*7aE!. =2qÀ’3%HXXÐrÆ <ÎÒÒÀÿö,Ü(%#"/5'&'#&'&'&#"7632327,0!2 X [ `Æ   !5  ˜ 0ì@6Wù0$E R  'Yþf Nÿ8ò"'&'#3327676=3#5 A' XX = #!!VP': * üÎÚx#= 7jÜýú>= è #367èÄRÄ\s rýúþÂ4,Y <ÿ>¹Î;'67654'&+"'&7456767&'&54767#5!#";#"32¹'J 9;"25=K 4 dt¦2"[1Rn`5M&/JE'=^Q  N+>U// ?$F. FF8%'L@D+M" P"ÿô"'&54762'27654'&#"“="DCÖCD]=Xe$I!.e$*( uAZ‡DCCD‡—I0Jd*8/g*5b135ÿüi%#"'&5##'!#32767i07ì^F(@  <Pþ>ÄFFþ²' 9ÿ8$#"'#476324'&#"3276"+Gc5XGGbŒA'Z,,BC),++BA-,b.: GþûÖŠ>>jAa`222/ed1105ÿJõ.#4'&#"'67654'&#&'&/&'&547672õ[S W+Q"ZW0ZHZ0N"L’x>)DbN(Bh.  0,n 48 5hS:uQ6"ÿôN""'&547632!#'27654'&#"“="DCkˆ@]=Xe$I!.e$*( uAZ‡DCRRf—I0Jd*8/g*5b13*ÿüî#327#"'&'&5#5!îÈ   #!P ¤ÄÂþÖ/ O .>2D(ÿòÞ%#"'&'&5332767453Þ /#Y_#/ X $=<# XÆa31c@þâb [ .ÿ8¹ $/7;32+#5#"'&'&547674'&+3276‚E0BX‰N=l7M XŽI b!*^ãE+<_.þ[6&Ã]IkM$¾¾d"4.†XD<[e2þ—L,ÿ,= +"/#&'&##5723327=B1a¸hê•  8:!ƒ™`ÃÈ YÅþîhN1 ôþšû *ÿ8l%##5"'&533327653l(1VÇ& ZD!7Vq ZÖ©% ÆÆ‘ '0þìy!¬þTN#9$ÿ÷À7%27654'7#"'#"'&5476767367676=3þZlP3$c "0`0.bu03PE H) T ?z”u)jJ@¦<ZZr;Mce0E^(0‰  $ßß$ÿÿÿßÿø¾&jÁóBÿÿ(ÿòÞ¾&j`óNÿÿ"ÿôÐ&@Hÿÿ(ÿòÞÐ&5Nÿÿ$ÿ÷ÀÐ'žRÿÿZe•'Cر(OZ’ !!!!!#5!#5¬®ýõùþdþöh hLúRÙRéRFggggÿlÎØ !+536754'###5!#32Ì& #?Qc4Bî]ÇêÅèc,G" B 8 A5þŒˆPPÂK%,ZC• 3#!!3#·]éþtq•<ÙR”0ÿé¥å$32767673!"'&547632#&'&'"!Žb8Jm3 `!þõRjfR•î+_&6Z~= lL£G'M *GþßUm¹·o[îK#,p'2Rÿÿ0ÿémå6ÿÿdÂÙ,ÿÿŒ'jÿêÁ,ÿÿÿéªÙ-SþÙ%!##527645!36#74'&+3276á‹R ²=89fzG"¿¿A "‡Ü6þº)^Í_'þÆj*?&#ÿÿOoÙ%O8Ù3#!!¬]éþtÙR"ÿy Ù%!!67645!3#5!#5KþúÇUÂ[Pý¸PR5äîk'ÔXýqч‡ÑOZÙ !!!!!¬®ýõùþdLúRÙRéR?´Ù # 333 ##ËþânEþåtî]îtþåEvþê]Dþ¼wbþÌ4þÌ4þžþ‰Dþ¼0ÿémå:5327654'&#"#67632#"'&'332767654'&#XI4!H'4Xz#.T'OÙ %#!332327654'&+#oT=UþÆ]¥ú þ=ÔQ)A#.Ôm^ârA/Ùþê­«>#.T'hý'ÙOpÙ %#!332327654'&+oT=UþÆ]¥ú þ=ÔQ)A#.ÔârA/Ùþê­«>#.T'0ÿé¥å#!5!&'&#"#632# 33276Hþ‘lf/<[2&_+î•RfjRþõ!` )f @'LRŸ;+#Kî[o·¹mU!G*R oBSÿé¾å+##3367632#"'&"327654/&'v^]yLh»W;ROX±Z=D=$f8Q‹>&m ,Lþ´ÙþÅÁT2b’”iC…ZË|IgµM*xHhÁJ oÙ #"'&'4763!##";£þën3 89fI]ãA "" Aã:þÆ:†!(X;=ý':M#$76$#ÿÿ*ÿéD$ÿéþ 0632#"'&576?67653"327654'&u,o˜9f8OE<fXo",z59SZ4JÂX!GU'#ÝL75Tw I%2G$,P`,¢ /#2%Fñ 33##FTëlSëm þcýôþcFñ» 33##3327653#"'&FTëlSëm?;TM ; V* þcýôþc»B9‡9Fä 73#'#™Ô`ûjáS ÔÔúþîââ Fÿöç !###5276”ST¬%d<  ýôÀ×a’PºIF$ 33###Fh‡‡hT‚2‚T þºFýôkþ½Cþ•Fè 3353#5##FTúTTúT ××ýôééÿÿ$ÿéþRFç !###F¡TùT ýôÀþ@Fÿ&"3632#"'"327654'&FM;l<&Y'4a@’S'E!,T*G#ÚæO^oGhšK! Nþï§T2E}4Q2E5ÿÿÿéÝF<° !###<tT Lþ@Àÿÿÿ&Þ \=ÿ&R¢"2B632#"'&'##"'&54763253"327654/%"327654'&ï-d0`%.E.S*1 ˜' h,<^1Sƒ_ T^ Wþ‘fa^ ^½^=T®D+þï> 3@ÂA^åÕt&1ž$ h*6Ÿ%~"+ªp'1«ÿÿÙ [Fÿˆ$ 33333#5FTùT=F þ@Àþ4¸xF 3;53#5#"'&5FT+šTT—N* Å)÷ýôÉ2*Fn %33!333„–TýØT–TLÀýô þ@ÀFÿˆª )333333#dýâT–T–TnA[§G'‡:?é ×™\0@‰0X/B‘. Ù 7&'&5476;#5###";Ûn )(JøTEËgw‰. &‰Ý V!>,+ýôÚÚÁ" ÿÿ(ÿéä&CtHÿÿ(ÿéÌ&j{Hÿ\Ù+"##53533#67632'5676754'&FX$STTS««5Co'kD; /4I" ÃR)5þîT@EE@ŸEJ'þíƒS6(0Ecü7FmÈ !##3#F'ÓT‹q•< Lþ@È”ÿéÝ#%#3273#"'&547632#&/"3XâR kT h+8>)\;Rj:T T^# ßè% ~‰.iFe M1D+Facÿÿ"ÿéËVÿÿB–ÙLÿÿ Ä&jåùóÿÿÿîÿ&™ÙMF0 .32+##5276=3276?4/&+çqŽ-6+7ö¬ %f< S|U)" | Ö7  H+À‹Z*“P¬P¿þ@" 7F1 )32+5##33533276?4/&+èqŽ-6+7öúTTúT|U)" |67  H+éé ××þ@" 7Ù!"##53533#67632#4'&FX$STTS««5Co'R" ÃR)5þîT@EE@ŸEJ'þƒ\7:öÈ 73 #%#73#Þkþð0gþþSÅq•< ÞÞþüþøØØ ¼”FçÈ 33###'FTëbSëcÙ`<• þcýôþcÈ””ÿÿÿ&Þ»&óSß\Fÿˆè !#5#333:F®TúTxx þ@ÀýôOoÙ %#!3364'&+3276o89fþ·]´²=VG"ããA "ÐX;=ÙþÆj*=W û#$Fè 2#!327654/&+šx ))IþùT˜. &˜ Ù L%>,, þ@*ÿÿ[iÙ3ÿÿ6ÿ& SZC93#!53!·]Œ]þtÙ`²Fmu353##FÓTÓT iµþ@ZCÙ3#!!·]éþtÙRFm !##F'ÓT Lþ@ZCÙ3#!!·]éþtÙRFm !##F'ÓT Lþ@?´Ù # 333 ##ËþânEþáxî]îxþáEnþâ]Dþ¼wbþÌ4þÌ4þžþ‰Dþ¼3 %# 35373 #%#wþþg0þðkÞSÞkþð0gþþSØØÞÞÞÞþüþøØØ0ÿémå:5327654'&#"#67632#"'&'332767654'&#XI4!H'4XzE<fXo",z59SZ4JÂX!GU'#ÝL75Tw I%2G$,P`,¢ /#2%O’Ù 3#33 #¬]]kxþdŸnþˆÙþÅ;þžþ‰D:ö 73 #%#Þkþð0gþþS ÞÞþüþøØØ O’Ù 3#33 #¬]]kxþdŸnþˆÙþÅ;þžþ‰D:ö 73 #%#Þkþð0gþþS ÞÞþüþøØØ O’Ù 3#33 #¬]]kxþdŸnþˆÙþÅ;þžþ‰D:ö 73 #%#Þkþð0gþþS ÞÞþüþøØØ O’Ù 3#33 #¬]]kxþdŸnþˆÙþÅ;þžþ‰D:ö 73 #%#Þkþð0gþþS ÞÞþüþøØØ S„Ù !#3!3#&þ‹^]v^^Lþ´ÙþÅ;ý'Fè 3353#5##FTúTTúT ××ýôééSÙ !#!#3!!!„^þ‹^]vÞþ€Lþ´ÙþÅ;RF» !#5##335!#èTúTTú'Óéé ××LS„Ù!#!#&þ‹^1^‡ýyÙý'Fç !###F¡TùT ýôÀþ@ÿÿ0ÿé¥å&ÿÿÿéÝFÿÿ0ÿé¥å&ÿÿÿéÝFÿÿQÙ7<° !###<tT Lþ@Àÿÿ •Ù< æ !#33[¸^Œ”^ þW©ÿÿ •Ù< æ !#33[¸^Œ”^ þW©ÿÿ‰Ù;ÿÿÙ [SÿyàÙ %33#5!3&^\PýÃ^R‡ýqчÙýyFÿˆ8 33333#5FTùTQF þ@Àþ4¸xS*Ù !"'&53!3#ÍþãN ]]].= Zþ§Yý'E° 3353#5#"'&5ETÃTTÃ@ ááýôß!S*Ù !"'&53!3#ÍþãN ]]].= Zþ§Yý'E° 3353#5#"'&5ETÃTTÃ@ ááýôß!S*Ù !2#!#3°N ]þã]]«= þ¦Yþ§ÙE° !#5##332°TÃTTÃ@áá ß!ÿÿ&ÿéæåý ÎÀÿÿ(ÿéHÿÿ'ÿéšFHóT³Mÿÿ(ÿéHÿÿdÂÙ,ÿÿ?´ˆ'óT¬nÿÿ,»'óûÿߎO’Ù 3#33 #¬]]kxþdŸnþˆÙþÅ;þžþ‰D:ö 73 #%#Þkþð0gþþS ÞÞþüþøØØ S„Ù !#3!3#&þ‹^]v^^Lþ´ÙþÅ;ý'Fè 3353#5##FTúTTúT ××ýôééS*Ù !"'&53!3#ÍþãN ]]].= Zþ§Yý'E° 3353#5#"'&5ETÃTTÃ@ ááýôß!ÿÿˆ'óª¬hÿÿ*ÿé»&óg߈ÿÿh'j¬hÿÿ*ÿé›&jjЈÿÿ ¶Ùˆÿÿ"ÿéM¨ÿÿOZˆ'ó±¬mÿÿ(ÿé»'óœÿßÿÿ&ÿéæåNÿÿ(ÿéH)Àÿÿ&ÿéæ™'jáÎýÿÿ(ÿé›&jvÐþÿÿ?´h'jVnÿÿ,›'jþÿÐŽÿÿ0ÿémh'j¨oÿÿ"ÿéË›&jPÐ0ÿémå:5327654'&#"#67632#"'&'332767654'&#XI4!H'4XzE<fXo",z59SZ4JÂX!GU'#ÝL75Tw I%2G$,P`,¢ /#2%ÿÿO‰G'qÄŠpÿÿFñz&qr½ÿÿO‰h'jÆpÿÿFñ›&jtÐÿÿ&ÿéæh'jãvÿÿ$ÿéþ›&jnЖÿÿ&ÿéæå2ÿÿ$ÿéþRÿÿ&ÿéæh'jã ÿÿ$ÿéþ›&jnÐÿÿ0ÿé¥h'jþ…ÿÿÿéÝ›&j1Ð¥ÿÿkG'qžŠ{ÿÿÿ&Þz&qT½›ÿÿkh'j {ÿÿÿ&Þ›&jVЛÿÿk—'ø¦³{ÿÿÿ&ÞÊ&ø\æ›ÿÿO9h'jœÿÿF›&jXПÿÿOh'jƒÿÿFl›'jÊÿУOÿ×ÙÌ%#"'&'&5327653CE<<¹= ^!+MŒ†0/D)aþºWž E#(0X)*7?ÿþØA%275#"476;54'&'#"'#"#47676;23#+"'"'"'&'&T!,—³F]4/l´,*>³ z_ 0¿B,66h5Q   YÚN ‰›1"‹1,BT‰ýþ ('p P4IKN¤x9 L)Cÿö~Î)"'&=47672;533##/"2767670…@(5“\c`h2; +'%.IH  R3H~3.dÀÀKÿr<ËWk<. =?qÜ!"#367632#54'&'&'&_‚+ ^b b&eC> ^ +æDBþâÜÖ& D9*k4 _× %4‰(3ÿt,4-)KLÿ¶7Õ2'&'"#&'&'%6ø, &&þñ€ 7þ†t,Õg.þ¸°£-"ª¸83ÿÖPØAO2&'"'&/47672676=4'&'&#"'5476762767&'&#"LG.))+(/I/I-A "R +B0"g  7&_^0†>'Ø`>X?]LJ(%: "(&&e 1*bAV,z* 8 2=BiF ý  " OŠØ!#4'&'"#547676323ŠÀ+(;D! _*l!Œ=aS ;ÌÒ2/QY /4þ@/qÔ")476767&'7672/&'"qý¾i- /<; =ˆBz@0o# X=u&/%/Ûµ("=G7?C7-B•ÈHEÒy5CKcj-ÊÙ#"'&'&53327653Êj9 @eh?@_--g|'Ç|þ¿¡E "'(@Ibžþb†0/[,^Ÿ1ÿô*ØA%#"'"'&'&'&5327654'&+5327674'&#"#4767632*eAZIC];<('<<450èç2)(u F`22Ow<5  Ëv;&4), HMF\((('95MO!!  +( ÖÙ33276=3#"'&'&'' ù"+M†0/D)aþcž E#(0X)*7BÿòGØ*%56767676=4'&'&'"547632èþnƒ 660)&)AN2_@Ks­G#&7)0—iU%87ZUC%/ 9"C@HSDK“*%tN9<# (J}Ù$%#"#54767632#4'&'‹_^9%@ei>M_,Fߥ2)a*+ E#(0X)*7þb…1þp*ÿøÇàP32674'&'&'&#'4'!#533276='&'&#'"'"'547676;2232IX0 ³dL)#,=5pSEþYZZZ4! \FgP I  0'#8 T"'{s” 2"8"1%CVGJ; ýd76º7*& 4YD#:h 560..|V#lJÉÙ%34'&'"#4767632}KO]--gl+ ^9%@ei>MúP§†0/D)aþcž E#(0X)*7Oÿô‚Ì3#"'&'&532765#_2'>i¹= ^!+k4 _Z× %4‰(3edt,4-)Küý†^-ÿôgØ7"#"'&5727654/&'&'&'47632&Hx" rt+= /j&*ï8 Y § c1TÒX%e@W¤C [ …@'--64J ¯$Ž3)G:2!9l6#`#& ‡J}Ù#54'&'"#4767632}_--gl+ ^9%@ei>M&x†0/D)aþcž E#(0X)*7<ÿô9Ø;P2#"'&'32767654'&/"'6767&'&'4767627654'&'&8ç2 1$/p #xE=]#!&"%% !$" h#j"46`a #- -!!$!ظL(  D %;;4S?7a8 !A="" 5,G$*) !þØ<. 0# L_Ó33##L_´´_ÓøPþu*äÕ#*54767675332#5&'&'&'&76767674'&'*CAF<)^"ADCBBDA$^KB 2C_Ðz9,‰2 †")j|FC77 FF~GE// !%DÁ)Ñ d1þÑg#7ž6 $VØ-"'&'!!#5#534767632'3254'&'"sA'& }þ‚]WWE5P¦5 t.ÖA)0€0-.?.ˆNyyND/@'„(#ª6Å>$ŸR+70ÿôÝÙ""'&'4767232654'&#"‡£aQ`^™a),4o?þÃEGhkŠs:FdJH wc°fdp$SnkVh.gJK–Š´I%EE'ÿ÷¡Õ A#3276=4'&%375#'"&'&547676;32#"'&'&'&533'"'&´..F+)þm"f & )`_.¦9 O3R….:7%  ] (%G-"±þ’4"A7E#8‘H’¿&%@ /Ù†)#VeC( #) p5é›Ó 53'65=^.5mfPA$"NL™Î73X)hL‚‚I.Ú"'67676;27+t,  "),0$(N$/  0-&+GãÐ#'3ãGqvG‰S,"4'&'"#56767632#"53276ÿ!$D/ $&?J?Z, %¬+'&5I 0DZ& Aÿö("'332765332767453#5#"'âžX6$%XH "!8XO!Gt= ®dþ¹E $$Q-þ¯i %k  ýùI9[[Jÿ-ï%#54'&'&#"!!#3632ïX 7G' Jþ¶XOÑ,[rþòùP <ÿõæÑ!#5#"'&'&'&'7!3276=3áO:k\. YQþ¯ "6+)WJU4*8É\ßM #$da*ÿ/B,747632533##"'&'&'&27674'&#"*M7S>"" Rc¸)U l9 äH#>(a 7õŽL76ýp:A l ##¢Y/7€2t&.i6^ÿ‡eÑ %/#33#>K”V±±JÃwÑóMþ¹?ÿ0ä #4'&'&#"!%3632äX 5B'Hþ_O-0ÿòFÓ*476;533#+'"'"'&'&'&%#"27676'&0B8UŒYbbi0C& V^z…I<# xI=ÓÔDé„>  8†Õ¾Z753&4™*Bÿ3èÌ3632#4'&#"BX>]—XX D(Í™þÿG€!"þ·Ip 4 $<þ<ÿ0÷#3÷ºW}S×ý|Bÿ.ÖÉ"##3327653#5"'&'&'&760™UUò $8))XO8mW0·ýw›ÁþÂL $"eýùJT1%<·2+ÿò æ+@"'&5476?67637&'&'473#'2767674'&'&#" B 0.AU3;)’f H9PT#x s ~AQ:(' (=64( @T!tE6FeV@ ^*$µGÿ-îÑ'"'&'&'332767653îX=_s*XnG&XÓEN)L ýô~7 %;BèÌ33632#4'&#"BX>]—XX D(ÌþÿG€!"þ·Ip 4 $<þä(ÿòØà2I#5#"'&'&547676767674'&'&'47322765474'&'&+"‘La*M" >>23  #DS*$)H8þðC*Z"%/  '&&l= e6Cþì?!">EL $ 02;*1  þ‹€1x8 \.,  67'ÿ/#4'"#3676323¹Q[%VR))DK#$dÑ,[S þÒùS3 )'2ýí+ûÛ&!&'476767'767&'&'&'&#û œ–þ='&E@1>fh$1 6(#«¦¦ä8\u\\1@2zUýkX %NfZKIÿöÕÕ0476;2'"#5"#"'&53276754'&'&'&ôd@ T( 1, T8#CT/V Gz$%€J D 1.þb8$B"†þ Tp Ë!ÿÒÿ.™27653#"'7 ,X60*…3(!ýÝ€# KIÿöÒÖ-!#5"/&/47676;"2727673ÒP (&(0 -HAf! . %(WS"  .!©A> *='  þ•9Z35ÿ/‰þ/4'&#"'672;67#"/"'&'&'&'47676?6=) 3.+;VO3'("f\ ƒF<   #m"% B4#8:I@0<@;*0&&? ;š/!8Eÿÿê#4'&'&#"#3632êX 3E( XO,) VG)=&EC W cÑ '$4à )D:*U56  ^\ Aÿ+("'332765332767453##"'âžX6$%XH "!8XO!Gt= ®dþ¹E $$Q-þ¯i %k  ý#9[[&ÿ/Ï7V6763237373#"'&'476767654/&'&574747"6?6767654'4'&'&'&-T.+!X !u7#p \“HG (%*'$ À\ N !.&‰N(.m)wg,!#?>-'(&#L HS$#:Z !49; 7Pÿþ÷)654'&'"#36323'5276Ÿ.(H'XO"7 "CþêMX, *!+%rQM a@ÿôä!5#"'&'&'&5332767653–=hF6  X 8H&XLX* )-%BþàM66 "CýùGÿ-DÌ"'&'&'3327676533–=_s*XnG&XXÒEN)LDþ¼~7 %;Úü¬KIÿó@5#4'&'&#"#5#"'&'&'&5332767653632@X 7H' T=hG6  X 8F'U<))*+;:*(ŠK7J?þ?w3QJ - OM UDo@^g.///c_010+Lù3#¡~ÓùþE>ù+ÿ2"Ó52#4'&/#"##"'&'&53327676736qM5  X 5E' U=gG6 "X :I& T<.)(*þ¿ L55 "CþX+ ,hBþàJ97 FãþæXÿ/7/%"'!!#5#5336763274/"#"27276UP25þËVddQ#">…>8-Hf\$? !8)U "A¥:UU:;At;Pc;5 í‘0/Q`1`#2ÿô!47632"'&7327654'&'"2š(1jDEP7FmCCZ,*CA+,,*BA,*Ç9GE{šC FD…e0112f_2120*ÿ/oÖ'0847672732##5#'"/&'&533"'&327654#'35"Y}r=Ž*d2=-W( -'(N ;87%_ ãHbDnß—§@ ÐÐ !;Jn#$Fþ’i&0¯–E >Fÿø!Ó7275335"'&'&53ìŒVP£%'-(4VC’þãDR/%9`ýÈUZ¾5353Zddd¢eeþ^dd ¦& %"'727&AU*Z.&!'0Ë"L ÿGÿÄ3#53#GGGG¸FÂGÿOÿÄ 3#73#3#73#53#GGGG@FFÈFFFFÿœ•¼3>Wd üà€ÆÇ3#GGÇGF€Ç3#FGGÇGÿÿnÖ ”GÛ3#GGÛG:FX##5&76767'367676753#ü0 W9 &”fä/ W: &”fE > %TPÒþ» =$––QM Ò:6X%&'&'&'&'#533!5• "j‹‘^1 () JþL'6 'L  4= þÒLL±X%#73'&'&'&'&'&'4#B¯uÏQ > RWF"2X¬¬Ë§. L*R "þ…&X#!5!ÌWþ±ù ýô LL?:X#&'&'&/&'"'#5!3:W  &9 ùS2#! þWzþ†t7 L 2Bþwþ‰>•X33>WXý¨'(X##5!ÕWW ýô LL?;X#&'&'&/&'"'##!2;W  &9 £W@? Qzþ†t7 ýôX!)=:XD"5632#"'&'&'&'336767674767475&'&'&/&'&: -*&HL$"  #MHIM!$ W  2 +#    3  R+1AœG,!++!4@zþŒ8 "18:‘X3:WWXþé#&ÿ8ÚX#&'&'&/&'"'#53ÚW  &9 ²ºS2#! zý¾<7 L 2B9X-3#536767676767075&'&'&'&'#53㪤N    "j¤ª_7 ()  "5¬L   .Ž6 'L  4= œE/E%!í%#47676767675!53!”W.þ[W¥.Ð*aEx1+$%)V 5á•™<9 $$?<X )32&'&'&'#;þÙUT'3W) 9G‚X*?5 þÕ+3' þ@0:X##532!534'&/&#Ö:X:NçM5U-þÖÓ#$8 ýô L!A-;þ‰L+&%>ÿ8•X3>WÈ üà3FX)53&'&'&/&'4Fþí¼  4 IMUL(7L+.…=9XB!"'&'&'4'!2'6767674767475&'&'&/&'"'#;IM!(@B $"  #MH+#    &9 £  2 +!:9z"1AœG,!+L "18 þØ8$ÿÉX73767676?367ÍxYs?  W %AOnþÖCþ .#Xþ¢J)*LO9ÿ8 X)32#&'&'&/&'"'#3/&'&'&'9×@? #! W  &9 yB"(G$+X!2Bý¾<7 4 L$7 ?X93#53276767675&'&'&'"+3/&'&'4'532ôµ¯87 , ,;5 XB"(G%+µLB / $ #aL<Ž9* 4 L$: Ò5?œ&= !* ÿ8åX676767670753#3.  W !"&,WÄcT *“š70"þ/ê63X67676767670753!5!3<.   W !"«þ&Fþ²dU *“š70" þóL >ÿ8&X%#5367677!5!#,>7h þoè 0þÏW!L*!2Lþ§G( IuýŽr%ïX#&'&'&/&'"'#53ïW  &9 ÈÏT2#! zþ†t7 L 2B;ÑX:72;7676767453#&'&'&'&7336767676=3'— =$/R' 6!W^ @GRG?C-$Wc' W 3Rà52  4&(Rþ®fT#?:>RþÔ  ÏÏ+#3#{X.6+532767676=#5!#&'&'&'&'&/  % AT2)<›0! W  &;  þÔ?+L,)LH2@þ†t8  87ø/?O_oŸ¯¿%2#"'&547632#"'&54763"327654'&'2#"'&547632#"'&54763"327654'&%2"'&547632"'&54763"327654'&'2#"'&547632#"'&54763"327654'&@"! "! $! $" Ý" ! " ! $! $" „#  #  " #! Í$! $! $! %! q " " " "" #! %Ä" "" "" #! %" !" !! # $ " " " "" #! %4c£Ò72#"'&5476k" ! Ò " "2ÿ¡ÿÿ2#"'&5476i" !  " "3d¢Ä/?O_72#"'&547632#"'&54763"327654'&'2#"'&547632#"'&54763"327654'&j$ ! $ ! $! %! " ! " ! $! $" Ó " " " "" #! %ñ" "" "" #! %,ÿœp/?O_2#"'&547632#"'&54763"327654'&'2#"'&547632#"'&54763"327654'&d" ! " ! $! $" " " " " # $"  " " " "" #! %ñ " " " " "! %jŠq/?O_%2#"'&547632#"'&54763"327654'&'2#"'&547632#"'&54763"327654'&R"! "! $! $" ½" ! " ! $! $" p " " " "" #! % " " " "" #! %jÿ’Šq/?O_%2#"'&547632#"'&54763"327654'&'2#"'&547632#"'&54763"327654'&R"! "! $! $" ½" ! " ! $! $"  " " " "" #! %p " " " "" #! %jÿ“Šp/?O_%2#"'&547632#"'&54763"327654'&2#"'&547632#"'&54763"327654'&R"! "! $! $" ½" ! " ! $! $" p " " " "" #! %n " " " "" #! %Ta5Â/?O_72#"'&547632#"'&54763"327654'&'2#"'&547632#"'&54763"327654'&þ"" "" # $! $ ! $ ! $ $! Ð # " # " " %ò " " " "" "! %Wÿ9p/?O_2#"'&547632#"'&54763"327654'&'2#"'&547632#"'&54763"327654'&"# "# $ $" $ ! $ ! " %! ‚ " " " "" $! %ò " " " " "! % $È/?O_oŸ¯¿Ã2"'&547632"'&54763"327654'&2#"'&547632#"'&54763"327654'&2#"'&547632#"'&54763"327654'&'2#"'&547632#"'&54763"327654'&7!5y#  #  " #! ¼" ! " ! $! $" K"! "! $! $" "! "! $! $" øýöÈ" !" !! # $" "" "" #! %ý« " " " "" #! %ð" "" "" #! %ª\\õ$ /32#"'&547632#"'&54763"327654'&7!5 $! $! $! $! øýöd " " " "" #! %¨\\ˆ±àm7'77°0Œ2æM~Y-ä$Ò/?O_cgw‡—›Ÿ¯¿ÏÓ×2"'&547632"'&54763"327654'&2#"'&5476%2#"'&54762#"'&5476#3!52#"'&5476%2#"'&54762#"'&5476#3!5"327654'&%"327654'&"327654'&#!!Ç#  #  " #! " " þÁ" ! " ! çeeÏýö¯" " þÁ" ! " ! çeeÏýö¯# $! þ§$! $" $! $" Îe3ýö ±" !" !! # $þÏ" " "." "þ4îÆ\\Œ" " "." "þ4îÆ\\Œ! #" $" #! %." #! %þ4îþ(\#ÿwŸz!##67676=474'&/&'3&3ŸÜ!,S9.U3 «N;O‡A8-*K.Z2%)DC7OÊ9t‚2##6?676'&'&'&'33‚½  S!U ŒÆ#)%#@.&6/"%@# ÿ¸«)5!5!5!ýžþÜ‚ZùXÿ¸ÿa""'&547'!5!73#""'&5'73Ý( tþm¦þûM ¯ d'f #ç! Z–-þ=Z# $} ÿ¸ÿa%"'&547'!537373#""'&5'73Ý( tþmÔb(˜þûM ¯ d'f #ç! Zšš–-þ=Z# $} kÿqÙ­#537!5!754'4ñyyèþ’('(—²;=S5M;Rh>6Ù<(6$+?&5%Õf?1G>Qh=0G=Í3!&<'4&9(±ÿV\s2'6767&'&5476; 0 : $Gs×s1…^*{5-4Dÿ¸O"!#'#'!53547O$JzþÐøÃÖppssZ½Ã\rÁÿ¸ÿ_ª '!5!73#ª¯_þ´þðJô.¦Dš¡Z–,þ>Z_ÿ¸ÿ_ª '!5!73ª¯_þ´þðJôš¡Z–,þ>ÿ¸À%'!5!5Àjþie£O`Z·ÁÿpÿSõ/?AQo2#"'&54762#"'&547632#"'&5476'2#"'&5476727654'&#"%35'###"'&'&54763Þ" ! U" ! Ñ"! U" ! þŸî/& +"/†£j¸[ƒ 'K E6 B.Dd> " "²" "" "Œ" "ýO5 %E+9'$K$·Á?ObD”,EX!V<"$-v@-aÿ(%Û#654#"%632×Z\@Dt€aþþE\I[Ø•WHO]qZU´;Rnÿ¸p˜)5!7pýHfþUJ³ZûCýÍkÿv…« )##5!5#…þ‘=S½ØOŸ^ŠÝXþ¯ùùkþ§“?ksµ'þ¿<žeýÈ$7ÿ¸ÿÿ±¨0A2#'+"'!5!&'476763264'&#";76'54'&#"676/S G$@F ªþÉ'"=8- )5w%'""Ué*(M+oe-5r&UUZ+aY7 :#Æ6'2_  ’"&"*N* 0N §ÿ2±¨%7H2#'+"''7&'&'&'&5476763264'&#";76'54'&#"676/S G$@F  (dHš47% "=8- )5w%'""Ué*(M+oe-5r& ?†2´,(".Y7 :#Æ6'2_  ’"&"*N* 0N ÿ¸¤%#"'&'!5%27732767¤kFP4$þ€&8,ÜA¼*&*:KK>R D1Z)m+þÀB#Bÿ¸@)5!'#"'&'&54?'032ýœ >%C8/ Å-w< FZ‘Jc*3þó¥ $7 ÿ¸@##"'!327654'&'H?Å) 8C%>  þ)FG ‡@3*cN& ‘Z31 $ þ“‚+!5!"'&'&'&547;635'#"'&'iþ)Œ IÓ]  +D< ¢i ¬8"7¸<Iþ“ZT| +_A[ ´Â>O] !7W ' ÿ¸&«)"'&'&'#53!5#&þÍ "ÎàŽFý AdGþ¹ïïkÙ`#53!5!754'4{{¼þ’('(—²;=Rý ZxSZSÿ¸…«!#"'!5!'#5!3…Í/þ\° ÈÁ  Ã;;Z÷ZY÷cÿökë%327676&'"#"'&54767kþ¯n*1?>((46U15[GˆÀJ*K 9& OIhg^þlŒ''7'77''7' &%Y(,$"5'=öd+jA!5ý þϽ77''7'77m &$Y(+#"5(>þjƒ+jA!5þ÷Oé 3#3#,####þÔs–ò–ý®à /'ÂK7Kõ½Íý{þü¸ //šK7KÍqÍ©ø!2#"'&5476'2#"'&5476À$! ˜"" þò¤ " "\# "ýà '7''7'7Œ8!8 8K K7þR®^_`‚]_ýgþü¸ 77'7'!9 8 8K K7ÿª^_`‚]_—ÿ• 3#'3#'r##–##ÜK–––âþöš //|KiK}@Kú[Ê 535#53#3©HH²IIþ¥L"< <"ýµÿDÒ 535#53#3% HH²IIþ.¼"< <"½ÿOv2#"'&5476%>"! þÏB " "C{2#"'&5476/537ù    ‹/ƒ++þ°•    U y!;9ý=ÿÍ2"'&54767#'7%y  s.ƒŒ++þØ-     w";8µvÙ2#"'&5476>"! þÏÙ" "ý(ÿfq#53%qbbþš]>vÙ2#"'&5476>"! þÏÙ" "ý(ÿOv2#"'&5476%>"! þÏB " "Cx!2#"'&547672#"'&5476@$! "! þÍV " "ª" "ýþ±w!2#"'&547672#"'&5476%?"# "" þÎà " "ª # "7Ú/12#"'&547632#"'&5476'2#"'&5476Þ" ! Ñ"! U"! þÍt" "" "Œ" "ýþÉÚ/147632#"'&747632#"'&2#"'&5476%§ $" "Ä $"","! þÎn! &  ! &  N " "ÉØ %ªþæ¾¾N,`ýÿHÚ%'º þâ¨RHfS§7Ô!#7777''7''7''7''7'²$"$$#" ï ; ; ;> ? ? @ @ ( D C C C B @ B A ¥ #.9GQ\jt‹”–533##'#7472"'&5472"'&274&#""'4632'#"'&547632'43#""'4632'#"'&547632'43#"4'"276'4'"27654'&#"36ÕV'SR'U•    r  *› r  *± … þòÌPO%QQQ   z  cz  cd  |,ýÿý0±'7#"'&'&5432327671///:%57  .E%ƒ--.d#6 F#ÿpÿÖ‚'7*333O333)ÿþ‹ÍD23275#53#'5'&'#"'&'&54323254'&#"'676367654#"'6ÉD7+&/01‡ûG-&9>&+R[>0._"<#23,!v/&%Í('.¦((þY.Ÿ 9!d 8* Z  = ")ÿþ5ÍH23275#5!#'#'5'&'#"'&'&54323254'&#"'676367654#"'6ÉD7+&/01‡¥E--&9>&+R[>0._"<#23,!v/&%Í('.¦((þY.yþY.Ÿ 9!d 8* Z  = "ÿ²ˆÍ77"'&5476;5#5!##"7632''&5432327654'&ž0%7cõˆd% <)'Qm"v6 )) .$$¸)/A((g6 ;' al", ÿ²ˆK7"'&5476;5#53&'47632&#"3##"7632''&5432327654'&ž0%7cõõ2--( !* &nd% <)'Qm"v6 )) .$$¸)/A(A78 1$E& 12(g6 ;' al",  ËÍ14'&+5!##"'&'&5432327654'&#"'67636?4#ÊËžA)G=&+Q]=/.B <#12/-H2(()4*&G:$e  8)!4 •ÍF4'&'&+5!!632'654#"#"'&'&5432327654'&#"'67636C6 Ì•þšD*3?;$ 8?9:, >&,R]=0.B =#226.H3 ((,1)-1$': F98):$e  7*!4ÿþ…Í>!65432327#"'&54767&'&''5'75&#"'6325!5!…þåT!5 mT"%)F/7`-ÖóG]? EDL þÃ…¥­'-    /1'& * 0Ì.‰h v5*! ‹(ÿ¸Í"'654/&=#5!##/32=#®0ðF*©D+ 3K"Þ6ó7J&  }$ý((Ù$ '×ü € ÿ¸ ,3##/32=#'654/&=#5!&+'32\MD+ 3K"Þ6ó7 0ðF*6T.8%23+GÍ(Ù$ '×ü € &  }$ý(†M0P)ÿþ5p]#"'&'&54323276723275#5!#'#'5'&'#"'&'&54323254'&#"'676367654#"'6*:%57  .E%ýÂD7+&/01‡¥E--&9>&+R[>0._"<#23,!v/&%M#6 F#›('.¦((þY.yþY.Ÿ 9!d 8* Z  = ")ÿþ5 R23275#5!&+'323#'#'5'&'#"'&'&54323254'&#"'676367654#"'6ÉD7+&/01‡1Q/8%22,B2ME--&9>&+R[>0._"<#23,!v/&%Í('.¦(†M0IZ(þY.yþY.Ÿ 9!d 8* Z  = ")ÿþ5âg23275#5!&'&'&547632&'&/"54323#'#'5'&'#"'&'&54323254'&#"'676367654#"'6ÉD7+&/01‡-29$ Ac! !((LE--&9>&+R[>0._"<#23,!v/&%Í('.¦(5 *fH 542Š(þY.yþY.Ÿ 9!d 8* Z  = "ÿþ[Í-:!67632'67654'&#"'5#"'&5476325!5!5&#"32[þî1/$* # ! !>-0D<(:R-þä[þÁ4@* ) P¥°+ ;)&5+  & '%8¼.q/%: ?“(ýH"- ÿþtÍ!<#'5'&'&'&7632676=#5!5&#"325#"'&'&76325!32t=-k[T_S žtj2Dba9>.=U-?#%G.þÄ! =*)q¥þY.;YMD&  Š(ò#5?E65'5&0!yŠ7!:$ÿþ®Í#'##"/&54;5#5!®F-•63y®¥þY.yå(8 œ(ÿþÞÍ2#'5#"'&547&'&547#5!5!"&#"3276ÞF-AY/0=2, 2ÞsÿA"C:&?FJ ¥þY.ƒ8":%% (ìÄ 6 58Í4'74'&#"'&5476;5!5!##"32#"'&54323276ü-..;5Da$1œþškË&1&G87K(Šu e~D&&$´- >2A((g>$"O “ {(ÿþ Í#'5#"'&547#5!#3275!5! F-AKD1%Xf-9CUþg ¥þY.z22%,((%;8Ò(GÍ<I##"547&'&547632&#"3273#"32767&'&547675!5!"654'G“5_UX %0 :)#.:8 6 KC()aT 401?þ|G·)&*-¥Y;TA:^&%/  >(7' J %'6T(œ 17ÿþ)Í%#'5##"'&'&76323254'&'7!5!5!)D-¶T14AF 9,(9%)>þH)¥þY.öK,1 8+.%&bþû¼‡}G u "(2$25.$–((¾?àÍ&4##"'&'&5476767654'&#!5!4#"3276à–%H*5?H: df  þüàsn]0+0?]¥+.L'9/, J( 2(þÇY 6#'-A Í0%4'&#"'&5476;5!5!##"32#"'&54323276–5Dc$1žþ— sÌ%(.I88J )u f~> p- >1A((g>#!M “ {%ßÍ$2##"&547632#"'&5476;5!5!4'&#"3276ßr¾W= :E#B dGJ%K…þÂßk% Q K¥†Z<6 )J-K DA^%"_(þ£+G%*ÿþþÍ#'##"'&=#5!5#32þE-}0.0%)þþãŠ- C¥þY.yÉ, $À(ñÉÑ ÿþ½Í#'5#"#&'&'&76;5!5!½F-³@}-P@ ¨þ¶½¥þY.õ?R}X2($> ](+ÿþ$Í&0#'5#"'&'67&'&5476323275#534#"76$F->auF E92(+DO$^%#H P\`ÓþÊKI?! ¥þY.ƒ2<E2!:3  AÈ(eE<'ÿΫÍ)7476;5!5!##"723&5476'#"'&*Q!bþæ«cyT 639,# DI TLSö?U((|/-!! , ps26+ÿþÍ/=#'5#"'&547&'&76323&#"3275#534'&#"3276E-,R¥þY.™0 / 5 )$ "„¹(“E ( ÿþÕÍ#'5##"/&54;5#5!5#ÕF-Ä/ (pÕsÄ¥þY.œ// ·(ß··ÿþÉÍ$#'5#"'&5654/#5!5#3276ÉF-.F[8&…! ÉsŸ+(*+'_+¥þY.…(3$00 (ç¿%/ !  ?Í#'&54323276=#5!?pJ‹"‡8 ¡?¥“K¢ C)‰(ÿÿ?Í7'7'4323276=#5!#'&ˆ333& ¡?pJ‹"‡82333Œ)‰((“K¢ Cÿþ+Í/#'5&#"'67&'&#"#"'&5476326325!5!+F-% 9)+: ^+ ¸7C<+; þH+¥þY.ã/0!*9N  reF ?.z(0Í!/:7"'&547632675!5!#'&'%4/#"3276'&#"327¼J,H$,]&QþN ) ?O!) <"[B èTl,B0='2@86r((s1!Q' $Q–5 'c<+6i+ 3ÿþÀÍ%#'5#"'&5476325!5!5&'&#"32ÀF-.B D0$E'*`.þ³Às& -8!<D¥þY.{& 2%,7@Š(ù- !=ÿóQÍ44#"7236%!#'#''&'&5432767&'&547#3e-:.3þÍQE-¯10/Gƒ) 7(4[A"e?f 4ª(þY.y"C:86ƒ (5' 03ÿþ”Í"#'5#"'&=#5!5#54/3276”F-A 1.$)”sÀº ¢(> ¥þY.†*"!®(Ê¢œ5 ˆ¢ÿþÍ%7276=#5!#'5#"''&5432%5#32… £F-6H,0"‰9  »4CÜ) ‰((þY.• +"¢ B)»ž*ÿ×®Í8##"632#"4327654#"&'&547&'&5476;5!5!®Yß!/J-$ bG+1tqMA  :œþÙ®¥h()#& "$ -- 2!% 6.:(& $-A(þîÿsÿTÿÙ'7¬333Z333-0pÍ'#"#"'&'&54323254'&'&5476;p½-T-"$:O2  ( ]-F-+«™%E,$1"'<  P)0;'$ÿûÿþ±Í#'#53±E-D¶¥þY.y(ÿúÿþ¢b47632&'&#"3#'#53& ?!%†w0]**INF-EC 2 zB &(þY.y(ÿ?ÿþ±~#'#53&'&#"#&5476323±E-DE 3$(Q!!$:Y: O¥þY.y(A,4 75@P,5þ}ÿO#"'7327654'&#"'632ar…pm7#  .6/,(a;lY  "$!ÿ)ÿE•47632#'&#"326;'&'&×-,/²0‘#)' $ 5  "P/ '”x"     ÿÿ~ÿó&'&'&54763"327 *Q-C!0V ) 0r (/ %  ÿý0p#"'&'&5432327670:%57  .E%M#6 F#þµÍÿº  #&+'32F&T.8%23+G͆M0PþÌÍÿÂæ#&'&''&547632&'&'&#"5432>*2.$ Ac!!()Í7 *fH 543ÿÉÿþäp#"'&'&543232767#'#53ä:%57  .E%E-D¶M#6 F#ÃþY.y(ÿ`ÿþ± #'#53&+'323±E-DBQ/8%22,B2M¥þY.y(†M0IZÿpÿþ±â&#'#53&'&'&547632&'&'&#"54323±E-D>29$ Ac!!((L¥þY.y(5 *fH 542ŠÿhÿO™ÿÿ #&'&+'3™$-=;+#QKc±4,*&d(DW(iw'7#"'&'&5432327672#"'&'#"'#"'&'&5432327654'&#"'676367654#"'632332?64#"327670--—-.%89  4'p8"$ +>/ CT2@&+R\>1/E">#112!y+"&%ND8 &I)8-H+r4+$ )0%%'W!5 1%Z48< &3 L :!c7*"5  = "'.)1\1yQ2% . ÿ”Íÿõs#7 ;&>d—¦”b¯k%#"'&547632'"327654'&¯1+2W$8(-]#ŽD 7A!õ>-(=&=, <.2< /K ­ÿ²ÁÍ*#"'254/7&'&54763274'&#"67¬+.²`D(;7&iV I4  )™`1 "= 7&(9iß#67ÿ½ÄÍ$2'#"'&=47632327654'&#"'6*M,v{ˆ (  7/ G<GÍ@)5`:¶"Ì201%!!…ÿÇÏÍ*%'&'&5476327654+'3254'&+'32ÏZ N!S:$51H‹¥'-‰ž=, B²H-] f @)B'E,(1#(+*/&»#"'&54?'774/3276¬O&D !5()%5ê ö½T#:7U9‘£8++  "2© ±³þÄ,4+ qÿÆäÃ!'#"'&'&7673254'&547632äX#3^. EK- $ÖH *2<!*BSD 6cÿÅûÍ5'"'&'&547&'&5476;#";#"3254'&5432û!S;‚A 1!2"ŸŽ"'¥ 9s0"$,uD '18(G'.Q & N&øÅ!+%#"'&543232767#"'&547632#4#"32øG(8qND3=lH!?%*R$.R"FCêr4…v##vd|E# +3 H#D! 5fÕÆ7327#"'&547’P"W<""E&$T82ú ?\81*3"þü ™ÿÈúÍ)#"5254/&5476324/#"3276ú#* Ì8D+)O$(!N¯+q‚8.1À5.6$4"(¤(L7 [((DW(iw'7#"'&'&5432327672#"'&'#"'#"'&'&5432327654'&#"'676367654#"'632332?64#"327670--—-.%89  4'p8"$ +>/ CT2@&+R\>1/E">#112!y+"&%ND8 &I)8-H+r4+$ )0%%'W!5 1%Z48< &3 L :!c7*"5  = "'.)1\1yQ2% . 2 476'&'767'&'&Z#" #" F&@9.@/4> Ö'  &  @W&7†5(%phþ(327654'&#"032760'&#"0'&'3&E"3&E"2*4*44vnf("hz¤/,/,$4$4€ ‚€6•%dþ #/"'&7632'"3276'&"'&7632'"3276'&ŒQ!IQ!I2 !3 !Q!IQ!I2 !3 J4+),4+),–'$'$þ„4+),4+),–'$'$ÿì”X%#''&'7676''&'676!'l(PxLa_NQ!CyNE@ .)!-938#0þ (X<ý䥘 ‡õþáL151eRQ=.&! R´L®<ÿì X-!''#''&'7676''&5476!'!53#Ð<')vMb_NQ!AyNG@ %.'"+84V  1þ (€(d(PJ–<ý䨜 ‡öþæN33/bWV?2!1¦(.L®<<<<ÿì64/&'36!!'&'&1'7676'&''&5476Ì|>ÉZj)‚u! þ>((þ ’d+(pã)(]x!%s$2D5/ _hoa*‘hXf0[<<þ˜hG)|c<+0# L 3 #2S3#ÿì=!!'#4/&'36'&7'7676'&''&5&766767®þ>(((|>ÉZj)‚u! $4)5F(b[0F6" 1+% /21C<2MX<R^92|PeW5E* d*"((€@Ë[l+„x"þ4ðF'G…K?ufžþÄ|PWt”I/ð4FÉ(àZ…1'\Ž¢8+X<ð.D ¢…^#(&)z&+DFð<9 $7.* vX#)!3'#'#'&'&7675&'&1&P(d<<(n# *&/003Pþ蟎YE0hë) 3m+%ÿÿ6[36'&'&76'&/6&767'&'&/7676'61M@SX#!%/   ?XL'4;<5;N *!?d^„ ^þ¶(Š(þü½‘=Sr.>O>$(4þHNu6È(<<þX*6763'#&/76'&'�&Œ) \L¾†”kP(dM•ŒB=,9 -&("®S''/n6rS<þ*f; P&?;#2#,5 þX$53#'&6'6'&'&547632rd(P5+! .Y2 ¶Š+Bœ†_&*:RóBLøeDU?RG'FŠ /(? Y# :  ÿìÿX 676'&'&'&''#'!!neXj=~7 5]n/`x%(ê)þoàþkFTJ6=I ŒqM3é<<ÿìÿ°'X.6761&'&'#'!!&'&1'76'&nIR'<%ÅKœ %()þG¾, 7/JhlF(nÖ.ƒZQ Äš@!OE53 <<49:J6 fDyJ<*'IÿìÿØŠX5#767'&&576765'&/5#'!!07&'&70'&@Z(4K,FMGl ^;A@ d"Œ(v(þÞBH2H %*"+ZÜ&3œ…\ $<\ 5:þö\9$$e,0Tð<<>djŠTHP<}¯/ÿìbX!3'#'!!5&'&1P(d<þR(Jþ¢š–T<3©<þ Fš<(È>}G‚;þÅUI xXI'&766'&767'&'&#"'&5?606'&'&767616764/ %'.%6/7 39%RY+,}  *69P<6S/. Ÿ9!3{HCR:1/6:/ ‚<£I`(H GúÜL H0(awa0!^˜u\V33c330b(4<l.&<!20<ÿìÿúX"!6767'&'&576765'5#'ô(þü\# I6'R\Uy  oJVK&(Q F¾(X<ð("™‚[$):QîGSþcAT6A, Fð<ÿìX!67676''&'&7676'#'ê)þ[R[e6/" 1E" [s %(X<þ/R]K 4#+ 9…€Z( 3é<êX"&'&76763153#'&6xD#$J 9qf(P<˜L*!2#  MNOS fn<ýä@s‹@$M$U*0$ ÿìÿþ0X '!6'&765'&/760(ýä(Â-X1?- .'"2*ASNZ3)qU]N<<þžßE&?2zmQVbàþË€a/(þX)203#6'&'&/7676'&#'&5476–]*" ŒA…4d(PU’™¾-=!.!('PXD75P>QÖ<ýäG{?n&-O"-WÿìëX!'!307677&767'n})þ*((þ™Í : .; ‹• <<EX)?6'&#"'4763253#''7&'&60x 2"˜A‡e(P=þòÜ6cB  *7ð* á‹ <ýä<TÒð*4L%C  %ÿìžX-&%&1'7&'&7#'!!032'&767&'šWþá¾o&NW(Š(ý²( z¾g[8<5;N *!?d¸þH^° n%:<<4 n?:1r.>O>$(4ÿìêX0!'!#4'&/%^ú?:þ¶(Ö(P]…¤^½‘=Sš<<ýäJkIÈÿìbX.'!'&'&'7676''&7676767(N(ƒUfmRC"NˆYQE;X?*+-0  3**) 0<<þVz œ€ÌþãL170]IGz43;0 /* /"J hZ ÿíêX-&/'&7676076'&'&'&'&767#'!0!šL†N*''7MP)Õ(þö0J;/þð -Eýä{@ <, 54 +  <<œ%A+&'š!2ÿìêX !04'&'&/7&'&7#'!^þò( z¾FŠ*Q‹22ýäAzGn%:<<ÿìêX#761&'&7#'!#'&765!@'”-ER(Ö(P<.:H,3Ñ,þñYb,,p%%6<<ýä<2A &+#7 )N1$)+ #ÿj­7#sRRKK44ÿÎÿÕ 7?2tRR sRR§K44§K44ÿìhX!#6'&76761#T(ª2M6( 4ï>!jŒX!jŒX<<<ýä<–†)7 4- ý€T(ª2M6( 4ï>!jŒX<+17#N6 '@ÿˆÈ'#3'#4'&#"'&52<((P#tlŠ>#P^Yil! _Yik |X"'&763227654/&'(_ŒiØe!,= h" IohD,FeR=ÉB1.'>,,]"+/.sTZRä P,3? 0x~f#*Yv>þ†˜n4.gX$0&767632#"'&76"3276'&'276'&#"I? ;-3M41 ! < :.7H53¡e%'EK&"^b#'HJ'"+'XO6)KFI/'VO6*IFI7;..06/-5>:-.26/-5ÿþ_X !&'&7&'&77'&'&767ᘠ09$ h%F(­]"D1"¡l=“ôT’I>#,Ds?92$2 6ç;&%­ ZSY!&766767'&'&57676''à9ME9)T_Uy nJUM&AiF*ð"-<œ†_&*:RóBLøeDU?RG'F^V'&7676'&'5&!­B.;QY! /+I6"$,!X=UK!-Q,þ5 2 ‡J5:'9´W!'&764?66767´,0[ Z„&X•_þ´±6[mÇZgfN2à É% þ´E|%#  }X$'6'&'&76'276'&/&(m€5W %7)55 .$"4•: lID`_i/%~N@-/<,3(n95LPd8ÿöôX 0'&'70!'!#4'&/%Æ?>+17Žú?:þ¶(Ö(P]…¤^…N6 '@V‘=Sš<<ýäJkIÈÿóñX0!'!#4'&/%0'&'eú?:þ¶(Ö(P]…¤^æ?>+17½‘=Sš<<ýäJkIÈþ¢N6 '@h[ 6'0'&'&#­i-(5n&,T(¿SV2‰'ÿìë#)6#3676'&'&7!'!54P Œ(d%–8E6$ 2?!\7)þò@4B ²Tâ<þ£35AQ )M&E<èrE ]h¤ 77670#­i-(5n&,d(¿SV2‰']h¤776706'&76'P(¬^* ( "h'2".*%  "  <(¼TX1ˆ'R0"&- **+bh¤%7276'&''&5476327676?'&'P( && 56JD (UEEFË.,4 / 652 (;6Z# dRdPX<Xýä<‘Y07677&767'&)fLØ574'&'#53676733##5##"547674'&'#"54~/ 2U#$ =+4&˜r2@˜ "1;4 .1 V(ú@l&9'h'/ A#L 9þ#ÓQ@B9HJ -N A+%:Aÿÿt&¹Øÿÿÿõ’»&ºÓ®ÿÿÿõ»&Ó»âÿÿÿaDÛ&Ô¼0ÿÿÿ DÛ&Ô½0ÿÿÿõäÑ&Ó¾ôÿÿØ &¿ÆÿðDÚ!*33#"!##"'&'&'&'#53627654'!!!676 ¨¨`6Ú9$Q!hQ$ +û: þè>þ†$ ÚC>&9^T.Bb( `,2LŸ(9ÄýY+*!® 7H0>3ÿÿæþ&Á*"27476326765!5!##&'#"'&732767&'&#"#H+8FQ! þ@*@B&_1$c.E4"9@;4 C ÈM(( {99vf'R€g)%; .2 #,##5#"'&'654'#53!535!322@-CZ^6'' V*rrþòTbPÝþ#\*A&':][+9T]±þ™}53TÿôZ !%5#"32!5!####"'&5476;(†//+$LþØZ2@€zZ=9?!a+ //+°99þ#Ýþ}f=9LU ¢.##5#"'#"'&'654'#533654'33273¢2@7`4(]R'>*>gA(N*.2D.;9rÝþ#D*<!;`O-9Cu[= .p‰frK- 1wÿó'1!!2#&'#"'&547632654'&#!5#5!&'&#"32þN,IL"FIWO/P"(s9@6 þ° ÀFPSVÝtCb7- !=0 )G F.30 ­9þL( 85ÿóö ##"'&5#4763!5!5!!3254öd)7]9,8HþböXþú ):…Ýþõ˜2^I[E8¯9þß-+E¨ÿô@'0;#!"3!2#"'&'&547&54763!5!5!4+3276%;5#"@2þ -@) ,nh<2  7*þ2@h^-1@þª0/-: Ý•  +@E$  :/#0D \9þ]@€& (€!Ü##5##67#&543235!5!Ü2@Ò@8` Òþ–ÜÝþ#×G :\8Í9.6!3276#''&5476323276'&'&#"#"/7&'#5!#Øþ¦%‰e&!F8‚ ^9/+++0+F  "I*3: :z'3>. )CÝ‹5ëG% <& ! + +@99MA"õ %#!"3!#37#"5"'&547&'&5#5!5!õ þ¹) =è¨@GãK$?>ò`þì&Ýš0' 9k9¢3"D > 9ša,5ÿôþ!#&# 327676;#"'&'676;5!5!þ-+þðg;4,%" 86<:LKI!ZJ· þXþÝÏU^/""<.044ZZ–9ÿô&#2#"'&547635#5!327654'&#"è>GMDBllBDMG>ôþLA74<88H/5M6)Ý{9?HL0220LH?9{9þŠ+&%&%C'0%ÿòü 3%&'&#"325!##"547632654'&"##"5432765S4\@qFþåü22D7±¸ceD  4‚LG;9µ99Œ'UF% XX= ' $%#)-.M)/ÿó*%#"'&5#476335!5!#!6324'&#"3276ÝP&”< 8@öþr2þÊ.aT,?7ML8R? {B[K8™99Òh%=,#" /(ÿý.*"'&'676327&'!5!#&/&#"327GŒjE-70)6&"þà.Ö Z2(35S;F  N99zTS4t#N+3Z990<" G)f$1 @'|d3 ÿúÔ.5!##"'&'76767654'&#"5432765Ô/ ON!4vD QqP&0!‚LG;Û;;e> 7KP4K#L# 5-.L). %5!32'!5!'#5!##5#"'&'654”þìTbPêþÑ_ 2@-CZ^6'¯i(,TáŒ2299þ#\*A&':][ÿôè#!3276;#"'&'#5476;35!5!èþÌ„*24 >0:£- 8%$ôþnèÝêÆ10F0$±$*G G±9 7327!'#5!##5#"'&'64jTbP$þÑ$i 2@-CZ^6'âT?IFAÐ99þ#z*A&':šÿþ +##5027654'&'37"'&547675#5! àb)?W,7,&L1-=961c6#A%fê Ýg<)ALQ#;#@?) ;72$;5"/LA%@g973273##5#"'&'64'#53jTbP$r2@-CZ^6'' V.âT?I9þ#z*A&':š+9ReDÿõê"0#!"67632#"'&'&5476;5!5!4#"3276êþêT=N!S'K%,†]&| ÖþlêDV< DBݯF:>? 0 Dl 5@r v9þP0 & ! ""##5#"'67&'&'#5!5!5#"32"2@9=‚nS6&(,"rþÁhÀt^- 'K 9Ýþ#@„V&@ Z9јl,È/; ÿ÷ô ?&#"3276327654'#"'&547632654'!5!##"'&'&76H.D>)@*þÛ(`6#C*We" Q!)^7þ~ô2.U.:zR6  „#,#!") ;J /N 99f>!L?Y(Rÿû3##5##&5476?&'#53 r2@à '75 H€  9þ#Óz#:?EH(ŸB9E’"Ž!&'&'654'#5!##5#%535w j$'46 Ž2@¥þï-%d1åQ+8_cI99þ#ïîSZPF &êµÿõ !##"'&5476;5!5!5#"3276 2='2SUQ6äþh rÎC;76@Ýþ©L*IEVG “9þ}~888+8ÿþÆ8A"'&54767&'#5!##'5327654'&'&'&'327!676îY8+1K#Ɔ#J1?7D671&C"956 3%;*'ÞþÐD#"82';->;12j99j11;N/)9*!$34 0  50!0%9ÝPN)N<ÿþÿúÆHQ72#"'&5476"'&54767&'#5!##'5327654'&'&'&'327!676ÕY8+1K#Ɔ#J1?7D671&C"956 3%;*'ÞþÐD#"82'< >;.=;12j99j11;N/)9*!$34 0  50!0%9ÝPN)N<ò&#!"3!#37#"'&'&'&5476;5!5!ò þ° & Fèi"@2ŠD)T$8"þþnòÝš ( 9W9C(<1>a9ÿú*!32#"'&5476##5##&5476?&'#5 þðà~ö2@à '75 HÝRÐ Ú9þ#Óz#:?EH(ŸB9ÿû!3##5##&5476?&'#5 þðàr2@à '75 HÝR 9þ#Óz#:?EH(ŸB9ÿôõ7325!5!##"'&'&5476;#"a9/<~þ}õ2¬K*1*':#484ÒF4+199þ½¦=:6I!9TÂr7#5Ânrrrœ##53|@<œÝþå99*»#54'&#"3###53547632*@% )<<@225!&>&(-' ,9þ#Ý9.<%3 &ÿ„®»###5354'&#"#5476323®2@<<% )@5!&>&2Ýþ#Ý9,-' =%2 %.þaÿaÿ–ÿ¤ #"'5327j`;:``:;`—;þbÿ ÿ”ÿ®#"'53#"'53l_?=W,hž_?=W,hR88_88þ~$ÿÖÑ &#"'&5476*žs& Gmn$k sþx ÿÐ &#"5432&'&"#'&547630gmP$Fa]9On!  Q_d @%8(*8  FIþd<ÿ¼ #&+"'3;2D4š_0–J<@†F<þ7 ÿ¼þ5"'&7453372#5254'&#"3öd:9 Ž\@   R(&9I)o$ #ÿ4ÿH2ÿè &##"543532SW"H@W¸M -$ÿú.##5#"'&'654'#53!535!322#"'&54762@-CZ^6'' V*rrþòTbPþïÝþ#\*A&':][+9T]±þ™}53T4 ÿþÿôZ !1%5#"32!5!####"'&5476;2#"'&5476(†//+$LþØZ2@€zZ=9?!þ÷a+ //+°99þ#Ýþ}f=9LU û ÿúÜ)##5##67#&543235!5!2#"'&5476Ü2@Ò@8` Òþ–Üç Ýþ#×G :\8Í9þ& Ô67&54327654'&#"#"543276765!5!##'#"'#0(>;B'2*7]m)># þ„Ô 1 OIHH2!LD@Z% $0 /9  ,.99P8 0JI1L: $Tÿõê"0@#!"67632#"'&'&5476;5!5!4#"32762#"'&5476êþêT=N!S'K%,†]&| ÖþlêDV< DBþ¥ݯF:>? 0 Dl 5@r v9þP0 & !  ÿò8" 47632#"'&%4'&#"3276ZNrv¨¨v€RHøJ?SbC7J?SbC7 €QG¢vv¢YOpbC:L@SbC:L@Ú$)!#"'&=#"'&5476324'&#"3276ÚBB 4I]8(L2?]8(/…?"K" ?"K")Sl'>,=W0 >,=þù@#{E 4E 4ÿúú%%%'#"'&543267654'&#"76¬u3[C'‚LvOA>LWos„YA]Yx )R9D$5)+5 FA) _-P8C+6,N2$8PL'3HBM DK ~4!#A9@$0N2)CM,9)4C)2NY'95ý> /5'ÿø 727653#5#"'&'654'3ÓA/@@&Y}I "B3µýê $E`;HMDVFG:ÿü½=2#'"3!!"'&547&'&54767&5476'"2#"&#"3R5OÄ-3þÞO$93 ¡!',56r8@ &f(H,&; (% 298%G 0`$>-Y;F5&"$&#0é !&547632#52767654'&#"r O/=h9% &¢yŸ›rr < )N "!!^-E.?!”K99A>fF$;! ÿü !;#"'&5#4763 þ„@HÆ..æ\LPY¾9¸FP;hVËYXÿüÙ(!3#"'&5#47633&547632&#"ijþŽ!:Q«.ÞSAH"KîWf(3 I=VA 4Š6+"9bM°THIeh"92þ>ÿeÏ#654'&#"#&547632·( " 2 &:B >" 0 & 0& ÿõä!(%#"/4767&'#5!##&32763'5!ä?/:`GgC N â,C-*t,O0$Ý^T.Bb( `,2LŸ(9ÀS0D<(?%C7H0>3þ‹+*!®ÿøÔÀ3JT]m#54#"&#"!##"'&'&'&'#5367632632"'&547632#"'&=%!36764'#3276%4'&#"3276Ô@9uC+2>+—7  I!*D=@ @+3(3 Yi6$ üÃI. ?)/S+`BB &@þ¼ û# +ñ6n7 þ-0 +0 O(c:J #9SG )7W"57[%:>3E39 TS"ÿö0»?#5'74'&'47632?37&5432#"'7327654'&s‹_çA·,04'1=P2 6_p8C $4-VJ)/# 0(5Bݸ†@TBh'R,:m, ½›1 ==" 759M G)*%$$/'ÿù'Å+2&#"3!##"'73274'&#'7&76766I -4T#®Rm(2p\H -1f' éLUÅE)! 8R] FEI)8J@@'G»"53#5#'&'&=6'&+73232=3ê]]X"/Q9$( 1^9 38Z9‚þEí)"0!"3uF8…31¨V''Å%!#3%2#"'&'7327676'&'&#"56']]þŸ€.¼F4 H'H  2.!'» T"-µ0+ $D  I &Ç-%03#5#"'&547&'&767632&"#;#"76«]](Tr<&G/ ',CW$$(m>ji>p9?,± þEZ!6#17#'4$ G -6C43!(ÿôÅ;2#"'&547627656'&'&'&5&7672&#"&#"'&'7ß# $  ÓG $X)3O(<0.'7SVLnf f,8UI/L"2n   #þÎ&!  .PL2=h%.5''#µ»&%#"'&'#7327676'&+732#"'76767µ':2g2 /˜0 ¨H!&4 a+4/`M7G& " F>99"W! (ÿþ'Á3A;#"327#"'47676#"'&767"'&5476;#"27654'&#"† < :/r4 „7'a DKs¾% H+(s=3%  3J# I 2 izU+r*6_FMb7%63!E, /I(ÿüTÇ47"'&5476327'&'&547676'&#"3276'¯E($#;`W‹@¡ 8B¨2*#M˜þEÕ 't  K ~B#(ÿô³Â'72767#"'&54765&'&#"763ö97 0*a1”i+*7%@" %WW086M<L$2P*#$S C0;1(ÿôË 374767&767672&#"#"'&27656'&'&'&(=/b!'5&":HE-[ ]-<¶!Û0  "(1 #C'!S  K8?e(m<%!   2 (ÿôÎÅ+%27656'&'&'&5&7672&#"&#"'&'7ÿI $Y(3O(7> <%J#^þE'»»$%3#5#&'&=6/#7323767276^]] A E- K( +  ¹þEo1!(’F&˜%(ÿ—Å63%2#"'#'&'&'7767676'&''7&767632&Û  ª)3`)3ƒsY/#H9A$*"Ü —D[L6DQD !K&.S in 7   &( .T9D> &XûÅ"7276=33#'&747632&'"æ8 \a` /G‡-F *")/=Ÿ2‰GG6$$W-Ck) ?is(.õ×+23#'&'&76354'&'&&'&5476G0#ZY+*F1  " D*Y5×1#,1I1+M3( ,AA8'%/DA…=$(l6Ä7"'&54354'&#"56323#…@R 0jZY1l5 Q07 I `WH'ÿ¯¼6'&1"7673#'#"'&5476;27654'&#"7676U:$. &5^:^] "54WDK V( ARH1 \PU8=6? C þEU 38R  )V' !'7§Ï5&#76767'&'&547637654'&#"#&547632ZX/%(6%bc_! 3U! ,&Q*; %D&'L_"  R(H !,,$7#!'ð½%7"'&547676&#"3276753#5#5ðZ<3E4D[ T.‚]]¬ K?Sc@/C N't I ÿ²þEÄE(RÀ)&#&'&547632&#36765476;#õ-@0 1_6'=&4, W5 A)©]a ¡~,V>O‡4@YE:”&þE'Ê»%#"'&547676&3276753#mHH'S#-()%* l'*]]r3d$.^&B  4Z öþE'Ê8!#3#&'&'&+'327676'&'&7'&'&547632]]‡)- kD1'€A")%  'F T"i4 »{*._G6"6   6 0KA''â» %'3276753#5#&'&576'&+73~¿, 3( ]]%BD2% &mΘ. 5ÃþE€ /$*”F'»(53#5##0;#"/#73276'&'&+532º]]s{¿& ;Ÿ" & {¢A" -ŽþEë ^ F)…F"*F4 %&ÿÙÛÌA%4'&#"3767#"'&'&767&54&'&#"'&3576KX/,AD5BhrBD9*C#?%5V" A)*!8#Ñ/BB*) L!9:_P.FB  5LD (ÿôϼ)%#"'&'73276/&'&'&'&76232#"΂!'UI.@+73r)$d/++_I'sP+4ˆt1@#/>"75 E,,F£»3#3£]]»E.—"#476'&$R!^X-@V0 PALH )þE»Š6D'$#KÿM£Ÿ3#4'&'&#&7632£^''#  IwOFD›U:* $2nXUWþPþáÿƒÿž27654"#'?6'&'7þ×@ :/!DCDS(/R7%(ä%/B9 21.þOþÎÿëÿ 476324'&'&765'&þO[!)jO-@)7F4;8 MF%ÐM O++-5E*4 #þ½þóÿó476;#"327#"'&þ½5(‡b/ b)4&7RJ12C&CL%C$()þ»ÿÀ™#'3@Pà|»Þþu»ÿ¿¨'7#'7µaVMýC ‚í•;ÿf£™#'3#3–Pà|Á]]»Þýg»ÿK£¨ '7#'7#3!aVMýC]] ‚í•;ýu»ÿöC¢It2#"'&5476'&'&'3767#"'&'77676'&'&#"#"'"7532?6%"'6#"'&'73276/&+73276'&Ç  é 4›f; \([cúB*=H/ $6*# !#,L  % B&CC%'ý´.4 T1¤8g$,^I/ Q 9FR SR1&¢  9 ])"RMþ~}?*H % 5R%-)X0Cw6998 DlZ1_ C+/W>% H<& '!šš7476#"'&276'&'&'B5EY6(54NO67½0+  + ÜX9-E3CM7776 <<6)/A;(ÿï¦Ç,2767'&='&'&7676"7676=4'&ÂW*$ X.*"  1 #(I,% "Ç1$þù  S8z  /L4#*F,+&  M&ÿùŒÅ#2327#"'&5&5632654'&#"'6¸g>/¡,"0:+X$qG;-S6"26EÅ8+<‚##KD"$HDLC1B'ÿöÈ0%#"'7767656'&707676'&#"'6M-;ZY-C:O_)0 C+#/$R.k+  S‚M':?07 9G(  C:"$ ÿù¬Å)"'&767&'&/776'&'&#32áR-g5.,:(#€A†#:$  Y$78$0MK"^!r?o*5,H*Ž R7'ÿÿ¹»'!#'&='&'&576'&+73232753;¹Q%2&K&  B( ' ,\ ^3$pF&ƒ# çþ¤ 'ÿj‘Å72&'&327'&/2765&/&'&76767&'&5476ÚWH8 …\/ /ˆq# L:9L/'I}ÅB  DR   (B]? $-6. ^ 'ÿÿ»Å$277676'"'&767623'&'&'&76776/&36t0b· &EU&r'6%  A ö+ :!š/ A•, "E%1á3^ 8" .j-)/ (ÿù‚À"'&54?327âa6#8ä>é225>7=(8K,³B¶(/DR'ÿù£¸%#5347632&#"727#"'&£ÆÆþ„PBX&!B. 9)4'(fC7¼D$eA6 I 6&0M/"NL@ÿœOR#"'&5476324'&#"3276R+4 ,'%  #©1,4 '# ! ÿØÿöÑ#+:7#"'&54767&'&5476324'&#"64/3276Ñ="I"(! *6 (MM&.*1 * L&& &1 4wR!:%/:3,6,D&>$FM1>: .'. ?ô-4)*8$=0ÿýÊG727653#5#"'&5476767654/"#5&'&#""'&547632632áQ;/..&T%"d:)b+3$" - & A /+06 .¤-F*(1'2`ýîQ2 ;*:R2 )0GB& $ )1959(S 57 ÿý5K!#327653#5#"'&5476767654/"#5&'&#""'&5476326324+-þ¬Q;/..&T%"d:)b+3$" - & A /+06 .¤-F*þ1'2`ýîQ2 ;*:R2 )0GB& $ )1959(S 57 ÿýÿü<L\#'7654'&#"76327632'&/#"'&=7&5476324'&#"3276'4'&#"3276ö+K8K%R=RX51(<3*UOGPjOZ¨  " } !  " _;usE0*m@/84I."#M^8!$:bdB8@Iþê= <.A ,"B>> ÿýÿø(B"'&567&547632#'67654'&#"73276=4'&''7ÌY03TLXmLZ+K8L% T;RS>>B1 4$E!B€"",22@(45TbB:@K†NFtw%Hw?,56E"A2%@"2 C € %5C*,ÿýÿ¥ö<L%#'3254'&'654'&#"632#"'&547&54763227654'&#"ö2 47F O$ +::KL46 &4A(: (@( PRCY_FH þÎ+ %- '†8'v ?+%OK1177D(#7#*J&6#+&0QgC8?>_#+p+- *4 ÿíí!#3#"'&547676767í?þ?C3  *J3 5zþ²—  #" !:ÿÿÿûªE%#"'&5473327654'&#"'76327654'&'&#"&547632ªM.;»- P:"¨ g3#$#$&K $ /1";"L–V+¶5BzpNEDéDB *%9/  !8!8!'*"& $ÿþè<L%"#5#"'&=7'&547632'674'&'&#"7632632#5&27654'&#"(-" GQBXhIN+I3A N98,,5. ¹' *# é! ´5K %-'gB7FIo ^>+33A0)¾°4•4A +4ÿþÿûÑ8H!##"'&5477632#"'&547&547632232767534'&#"3276Ñ.86K6 V!$G$1!(G(USBX- '( .À,1 .> ‚B743`,:(A+9#,[kB5L 1 '?þq5*;; ÿþÿûÏ,<!#4'&#"67632#"'&547&547632534/#"3276Ï-I6HR4&,G$1!(H% PA@^;5>-Á-- (4t$1$A1=-:(A+=Kþq:)6 3ÿøÍB!#5#"'&'#"'&54?&54763253276=332?&'&#"367Í-"' 9%U_;QU]/þä0#" =Ga7%+$a$ "-!+) mt9#IBþ! QP$%%$" +@*:(#%BQ(ÿþÿÿ -='674'&#"67632#"'&5&'&5476324'&#"3276  0)2?kL>A8?C%8 '@',A[PUqMO¿', '- +$:/GG>N44DP- <6 (D%3 '<[`E;MKþû. ', 'ÿÿÿööK747632#5&#"#"'&547'&'&547632'674'&#"63'"32767&º8:%.$, H># *PCYoœ 1 I>SY8*#0 '&%'ž= åÃ" (<<%+*-fC9–l0 "\>5A1@* #.19%ÿýÿûè?CS4'#"'&=7"7632'#"'&547&547632"32764'&#"3276¼!R 6!)O$ !$C'uv#%G(U^=S',4 ®+/ ,7Å&*D A(@!) j% ,7")2.19#,\q9& (0 -þÖ6)95ÿýÿÿÏ&6253#54'&#"672#"'&547&54764'&#"3276ésE..I0>Z9)d=A&6 'L"tUD–'- &/ A?þí]I)4%4I27 (C%>' -:e]4*þk- )- (ÿø×#"'&547632327654'&#"×DCfkE9@DenE:þY?2H]8)?4K^5& jUT^OflOS\LfmC6V?QgD9W>ÿþÞ87"'&547&'&547632'7654'&#"67676732753#5ÃE!F M@TwK=- 99[H71 `':!--%;$D dB8SD_H)&T==;3A# .D* A€þñC%Ù5253#5#"'&54747&'&54763276754'&#"6&èoU-/5DT73E X>:#*=7+ D7GT71$%(" YRýîL %0,9 =h:(þƒ:"." ×%/%2.?5 "ÿýs'7T25367632#"'#5#"'&547&'&5476"327654'&3276754'&#"63&ãoU.# 2*-0;N T73 F V>!  þQ:#*=7-D7FT72$%(! YR( 2 5"*þ›LC0,9?f:*0& ,%þ³:".&×%/%2-@5 " ÿø&%A253#5#"'&547"'&5476?&54763276754'&#"6;&4kY.05DT73\($ $f:X>:#*=7+ D7GU34$%! YRýîL %0,98 ' +<Vh:(þƒ:"." ×%/%0.A5 "ÿüù+;"632#"'&=7&547632#'654'&27654'&#"ìS8- &4A(9!)@( QQDXhIUDI8LN^3j+ (- %ê?3@(#7#*G'6#+&0QfC9?I‡FWqvVE†9þ?+2 *1 ÿÿ4B#'67654'&#"7632672#5&#"#5&'&'&#"#5"'&'&54763247I9?fÜ )(83  3  0#jC\ŠL@ s /(%ZBJ¹!  ) Ÿ£ ¥§ £œ;=&`Ro'-+ÿûö@"67632672#54'&#"#5&/&#"#5&547632'654'&îf6$! '%83  3   1Y[?ZjON.?>êO6I/$ ) Ÿ£ ¥§£†;d‚C/GFi,0 2P==ÿýÿðê8H!#&#"/"3632#"'&5?&5476;47632534'&#"3276ê-Qe+ *A‚B $)8B'8!)F' dO4!,MG-À'. '. sw"&!%:3) &8#*F&7")RXK)?Vþa0 +1 -ÿýÿýÕ ,9253#5#"'&54767&547654'&#"'32732?'ãoU.. FON0!WOBG7C7_‡$&>!N=-‘s#YRýîS +4#.!$!NdC7þ¢¸%/%† /3% ~1 03ŒLÿþ²!!#%7&/4763253&#"32?²/þ–nJ@TN4//6nK437 #SÉeX`d81, !Tþ9ƒ0275 :!—ÿôÀ>"6767;2753#5'%7&'&'&=&5&'&547632'654'&ÓS.0>+,+'7Gþžx! *N:JjE>, F2ê9&3  !-#7'pê@4+&5_  :[9+F@XF4V4%A7#3@+-þ&Aÿ¹®&'&#"'67632G =PN: !LVeB`7* "B- ÿÝ€3#'7€.]£Ì>"kþßþ5†ÿ#*#"'&'#"'&547632532767&'&#"32†')<*;@ ,!3+FÑ(:3þ£%912Ki-  1ÿ,þ=Ïÿ%476353'"3276532?#"'#"'&Ô0!+*%& 4(A-;& -(#@"þ£3<"!4':<.þLÿÿ8ÿâ!3674/"?2#"'&54767"þv)J! 7MC"*%&(%#''?-#2#).ÿúÿ÷R*%#"'&547632&#"7324'&#3276R0#-l=/P4MF&'@E+/>`CD1==?1 ƒ?,!gNf’G./ &K6>@87D6'(Ú 4ÿÇôHX2##'327654'67654'&'"7654'&#"632#"'&=7&547627654'&#"îlF= !# 54X#! 93I5BL46 &4A(9!)@( QQD2+ (- %G=X**%1P„# * T4%77D(#7#*G'6#+&0QfC9þ+2 *1 ÿûµ#"'&5476324'&#"3276µ>>XU><<>UV??"56HE3421II55sPPQPrpNMMNp[AA?@^_CDDCÿìe/.47632#"'&'&'&'&'&%4'&#"3276H*7P1"<)7<1(5]"?< G  4 ? 2";"e0<)6T2#,&%4 ÿô/4!#4'&#"#&'&#"3274'7#"'&547632632.,-- ,;!0%% F%TC'6?-.CT' ·(!þD¼ "E(-v%(51 rw7 /7=-ÿ÷ú3"2#"'&5476?&'&'76767674'&'3276ú-m)8//EW/: "? 4M‚[C Ie'84!C ^S/>>L,-C+9B< U] A,hþkEG #87A 8ÿù -/;G%&/#"'&54767&'&'7'&547632'4'&#"64'3276 11! ="+N'-WS #Bd:%.H(0 &`+ Š14 >u3Cu-J¢"3.N&<",20J  U!%&H*:$,=, "# þ<.H.$ÀA44E8 @Þ89#52767654'&#"#"'&'7327654'&'&547632Þ¸Jx9+6(/8 68 $:/ '#)+ 7 !B$,c6$w­u. 1NOoE0#$ 5) %C#K20ÿøå51@476325276767654'&#"7632#"'&4/"32760F?QfC6†  27654'&#"72#"'&5476ê7 /: 4D/9+2E/#9+F0= 2Bø:!"E.#:*2E0#ÿþTÚ />O_327654'&#"327654'&#""'&5476322#"'&54647632#"'&4'&#"3276T68 *<þ÷6</ApD/#-.;=\0.ý²<,..-;<..\¯9*4D/.-;;..ý/= 2: BD1+3 þID5? 8­8*4=-/\=:..//-=;-..-;=\G/":!#;-..-þŽ< 4@ 1 ÿ`Áâ G"327654'&!32764763233#5##"'&543!654/&#"#"'&Û<# '" ÂýŸkMT®hþÍP5CmD5‡55 <‡WanoˆNm;*12 >Q{B*& ,þËG+aQ.YF^20Tý‰æn6#2=d1-:S> 5OQþôsâ d327654#"!3276"'&54;#3254/&#"#5##"'&543!654/&#"#"'&54763233632˜  &6   ýŸkMT¬f¿Æ2<ÂÍ Ãø+7ž<‡WanoˆNm;*193#G F;FmD5…7!D"3 & >$þG+]þÉ?777“1 ˜æn6#2=d1-:S> 5C"@#K-&YF^20TþR<'Âÿ°þï[ÜZdq4'&#"3276676767&547632#4'&#"67632654'&##"'&547632#"'#"'&&#"676327654327&Ž"1/ 2þ#( ?Cƒ¹üb60–Sw¨ml8RF!*(3T,_Ki??AƒT2$>[9#LX?:{}T&!9b+&+ *LAÿþ…â)2#"'&5476!2#"'&5476###!#Å  D  p=þ<uþ  #   # þö¨þXä< ÿþâ0<"5476;27654'&#"2#"'&547632+"3!"327654s940'K",6)55@ I=Td<.C=Ns66 ý`& /# T9*"'\$6=1Y+%E5GK417k# /! 0ÿþœâ-^jt676;####54'&#"632"'&547632!"5476;27654'&#"2#"'&547632+"3'27654#"3254#"6 2ò‘7%Y7;&!(.?9 5%15P\-kûÝs9:.#K",6)55@ I=U_=1Jþ²'#+7 .ÿ=ËÝ.%#7#"632#"'&54763!#4'&#"3276ŒC“ÏY;.,_]'2+3f<-UGb¿´à'3!2B ÇÓA3BAC",E/(T@SrH>=þï'#+7 . þôÝiy%4'&#"#54'&#"632#"'&547632632#!"3276=3327654/4763#"'&'#"'&54763!276%"327654'&â3)6J(7<-9C)J&>$+@("Q=R33o`;.T5Lþ¨_*<%*L9079&,A(+L5B^8 8s7!g5DRR.ý´8/1*ðN:.B)3—‘N4() >#,E%9.5m?/bbUBV„@(0 :"4+7)=(/%! 58Q0"=]D(9a)I/†0 :- 7 þïôâaq2#"'&547;#"#"'&547632#&#"32767"'&547632327654'&#"632#"5476"327654'&}úV'<(8O  12 (BB!./N|;;< \C!15-+?*) I §;LZE0(N 2 '˜{gJ0 *1"âˆ>Wc8&7:B'6,D ,UC' K4L G*-?345+1h «1E4NA">'ÇNBþÝ",& $  þïôâw727654'&#"27654'&#"2#"'&547;#"#"547632676767"'&547632327654'&#"632#"5476–;)3"r;!1ªúV'<(8O  12 (BB!./NŸ5!@ #.15-+?*) I §;LZE0(N 2 '˜{g;) *& $ þó<..¢ˆ>Wc8&7:B'6,D ,„1/4 &L G*-?345+1h «1E4NA">'ÇNB þïÈâ-7™©%676;####4'&#"632"'&5476323254#"2#"'&547;#"#"'&547632#&#"32767"'&547632327654'&#"632#"5476"327654'&b 2ò‘7%Y7;&!(.?9 5%15P\-þö' 3;2þ*úV'<(8O  12 (BB!./N|;;< \C!15-+?*) I §;LZE0(N 2 '˜{gJ0 *1"ª87þseþà D"-1 D <*+T@GA ¬( /8¦ˆ>Wc8&7:B'6,D ,UC' K4L G*-?345+1h «1E4NA">'ÇNBþÝ",& $ ÿþyâ735"32="'&5476;5!#32#"'5327654+´¢Ù<,+ww_>2&®Ÿn@&>'0 $#C`VP)¬‹‹Â&1&sBì?2E7"Á6‹='.E)=+[[W&ÿþ³â#!#63233!536765&'&#"###¢‘",G/!7°6þ5…:/,7¤6â6…5&.[*­þ7@. "\)þRÿþsâ!%"'&5476;5!#3#75#"32#3ß_>2'®ŸççP)CÙ$ <,+w¢¢?2E; Á6‹7[W&ªB+ 1&w‹ þôÝ€327654'&#"4'&#"3276"'&547632632!"32?632#"'&'47#"'&54763!27654'&#"#54'&#"632T- 2(.þ’,701P^ Q=R33o`;.h#)!þ¨_*?#)%P•PYI'9=!ÆL;U;1g5DRR.3)6J(7<-9C)J&>$ˆ7 $ -# ^3- 3(nS )m?/bbUBVœ70 >!3`49!*?" 7!"1:/?a)I/=N:.B)3—‘N4() >#,E%þï¦ÝP%327654'&#"%632#"'&54?2327654'&#"##"632#"'&54763!#2? '2!¢(8b+‘z¯ÁŽ•N &C‰‚“h|+#.&=ÍZ;.2Z]'8'2e<.LLh¿µ7 -'#*,!X/=¤XJw~¾Æam£›qk@L‰5)1Œ¢A3BAD!,K0!S@TiHG=ÿþÓâ3!!6‰ýAâþS7ÿþ"äIXdp26763!###"#"'&547&#"#"'&547&#"632#"'&547632676"3254'&327654''327654¨tA<@:œ‰J' *0R+P'T.(ka‡]LAR þ,"0_+.'!.`aø`)*!â)#6þR®R‰b8'L0<ŒRR‰b8K1+'zÿäþôgâ7;G"'&5476;5!#32+"1#4'476;27654'&'"+35##"325ß_>2'®Ÿ+`1q%.òB4:0ëš/E+P)_¢¢¢Ù$ ?'-w?2E; Á6‹O1A™<91Z a$/h [W&#‹Â+ :#sÿèþôâ)!#632#"#'&76;27654'&#"###³'!R(W=$].^ f (Q('¼®þRÿþÑç3?N#"'&547&#"632#"'&5476326763!###"327654254'&#"6d9 &L,^5>‰J' *0R+P'T.(ldˆYK2O ;Ÿ<`6\`)*!þM_+,"0šR‰b8K1+'zþö`0#;ÿþ'â3!3!6¨7ýëâþS­þÿþ…â3347632#!%4'&#"32766ÍY `D=D*þB50EC °4 âþS._cXf~/¿bID"&þåD ÿûƒâ327673!3!5#"56%7&457þ`?Uâþ„.5@þS­þ7'K ÿ1’â !#57## ˆÇ‹6â6þXÓBœþRÿýþô8â8#"#'&76;27654#"#4'&#"#47632676325ŸH7?/°n;*‘,7+# 67)D)1€-Q‰^p ÿþ4â=M"632#"'&5476321327654#52#"'&74576'&'&"327654'&F?=3JU,C)3S1/HGm^KM-#`+°æG6Pa) 9ˆ?5B (¬=TnQPHK\!O!S-;¼6òwF5A/<73.;¶1: /3! ÿþ@â/?!###"#4'&#"632#"'&5476326764'&#"3276<7C3 7wVVFJb€;­þ1Q$)Z:.¶2? 1=  ÿ1>â(m%327654+%"327654'&%"37674/&!"632#"'&54763237"'&54763232+#7!567654'&þÏ*bsýt: 1< 0.,? ),þ#N?--'Q+B%/e-OOydOQNë@K0 +*242%P<"M ÍÍ1Q$)Z:. ÿþüIY2327654'52#"547676'&#"#4'&#"632#"'&547632676327654'&#"\c&M@+ ‹`8*C3L…*'A 7P+4F?=3JU,C)3S1/HGmlC :þ"5B (?âQ)6*H‹Q<@·7\EW„L:¸F J";þÅ/J"=TnQP0. þ­: /3!1þôîâ]m"632#"'&54763234763267632#!"#'&763!27654#"#4/&#"!567654'&"327654'&'N?--'Q+B%/d-PQvdOQNä7)U$ 3€.-‘+7+ # þwSG8»: 1< 0¬8(1C)4S(U.>wVVFJb€;Q*H3Œ?R‰^p4%-^ hLgí-þ´L6 /þ´1Q$)Z:.¶2? 1=  ÿþŒâ !#### ‚Š7‹6â6þR®þRþÿþL4'&#"#&547632X#.P1!%CZ9L™1 7/7%1441! NW³$ 82(Ñìâ !!5#!35äþ÷ÛŸâþïÛ¤¤ ÿþ' %547632#4'&#"67632#"'&%"327654'& ZM|®5 7X,=w@50 F!)b A$-C, 9 : *'{Ân^‰,$*ýø ~2va€thS"V (O&•a5H,< ÿþa<L"327654'&&547632#"'&547632#"'&547"7"327654'&½-7> .|8?*4A4)^>P‘nlhh§iA1L!L+9UPOVÙ4 2B -µ+<., ý†8DN-8,2e5"uu“§pq=.B\& >'1E/le^eà1 9 2-#ÿþœå8FR"632#"'&547632632'67654'&#"#"'&547&"3254'&327654'c‚J-(1Q,P']/lb‡_GIFpJF`7GCBW'$d:'6L+`7æ? 0a-Ö). b_¬@'7A'2c! O1AVO,)YSs}H<\V9;R‰d8%K2;ŒR¼4; `21M*?)(sGQ ÿþ¬ /?!####47632#4'&#"67632#"'&%"327654'&*‚Š7‹6üâZM|®5 7X,=w@50 F!)b A$-C, 9 : *'â6þR®þR}Ân^‰,$*ýø ~2va€thS"V (O&•a5H,< ÿþ¬<LV"327654'&&547632#"'&547632#"'&547"7"327654'&%!####½-7> .|8?*4A4)^>P‘nlhh§iA1L!L+9UPOVÙ4 2B -O‚Š7‹6µ+<., ý†8DN-8,2e5"uu“§pq=.B\& >'1E/le^eà1 9 2-#Ç6þR®þR ÿþ` 0@fv!###"#4'&#"632#"'&5476326764'&#"327647632#4'&#"67632#"'&%"327654'&\7C3 72'®Ÿÿ<þÅP)¨B+ 1&w‹þÝ?2E; Á6‹Áø[W&þï4â2<%4'&/&#"567632#"'&/&7676323276####þ, C)5b.{q‘¯zz6%; ie˜ydoZ‹7Œ5/O7 KC$c8I]Vjl¬ ‚i5 >t:3¡WTDM&6þR®þRäÿþ;â)-%3#'3#"'&5476;5!#!!'32=#"%#3Ú<<È<<þÍ_>2(®Ÿ¯þQN)É:,-wÙ$  ¢¢þþþþ?2E)!#Á6‹7[V&ª1&sB+ ø‹ÿþkÝ,!###"632#"'&547627654'&#" _T<ÏY;.,_]'2+3f<-UG)A %3!2Ý=þ^¢A3BAC",E/(T@SrH>þ[.&"*8 ÿûËØ25!####&'&#"#476OC3ðnNäP')N Ø* B9þ\¤þ\V4 þq¤-ÿþ'Ç !/%#"547632'3254+"";254#2#"'&5476'I$‡F$\! ½g&&g ''g4]! ŠD)GbB dA 4½-)*,­*++*;6d)!B ÿþYÇ7"3#53&547632#"'&547632'654#"327654Ó$ñ‘6"Q#hNkQR..= Hb.=u*! *2-— :"."#9'0A)•=Bfo>7+  e',Ó +O ÿþ5Ç<J47632632#4'#"'&54763267654#"#54'&#"&'&32767&'&;$+Y/:PQ$0;U_^4+€#*+>5! T6 CO E3=* €92= r0&"c322U,8*?J 61"&UGq #8) Î# 4 ÿþãŽLU"!4'&27654#"72#654'##"'&'#534767#5!27654'73&54762765!C, 3+K!E4;Y(2V RZG4C‹1 = g684 xX8!<þÂ>#þÿBA"7) €)88HÈW#)$+L \1c9+s%/:/G 8;#7J[#@P'.Eþ}6!*S ÿþPÍM47632327654'&'7#"'&5474#"#"'&547632'654#"327654'&…`)5À pp %G7 çu+z~ Q2CrIH6#1ˆ ;H.24Ye !o'£hwR(A!::#`&%þÿZ(6&#€V)$d1OOra5#V! (;Z=@Q" ÿþšÈv%27654'47632#"'&54763"3276'&'&#"#"547654'"#"'&547632'654"3254'&5476UZl8KyD2c (` F% 6- \ 2Ec'ޏ |V  Ø]>@+&9B+4 Œ«€ 98R’$ DE$&}2WA\œ+ ?M 3" ! ž5',=&°¦(3 f9 )*®PMs\1,*! /d×n$)C,,b ? xÿý#ø,727653723654'&'&'7'&'#"54767"›2 C!&.,+4$º;!oEŠ?/D+ 4?9AJI ?Œà^"B/ŽA!@ Hÿþ&>"'&53327#"'&'#"'&547&#"327653327654'&'M D4,'k,="G,*^M&y 12 CX/ ()0 qI(5+H€14 c%$F=#.Q"G &1kH+CEÿþ#Ç>"#4'&#"&547632632#"'#"54763"32765332=4Š- 40E;C!&L<"XH'A i!1WŠJ*V2 CXC## +*3 @@<$.­c @@ŽP9 H1ftVqÿûÿþ/Ç;"'&54767654#"&5476323253327654'7#"'§_ (I(3H45 #^ (K(/XC: 4##C7$i!1L%,(<;- *,77%7%0 VI ! 98U&@@ÿûÿþ1—I"&547674'&5473253327654'7"'#"'&54767674ƒ14$N(K((E(1XC85  #5Bi!(`P&&A '  *,* 2;+A$(7(41VB$8Eb @@?"-)&4 ;ÿûÿþkp"[+53254+5!2"53254+"'&'#"'&54?654#"&54763232533254'7*»» Å›€/ 0&)zF*NŠ˜šP (`U$(L&3N/5 #^ (K(VXC8FD&%$+!1H[/p7gkýÆ& @B!+*%; ;$%,77%7%HVB9%1JD$&ÿêŸË1%4'&#"23676'4'&+5!#3##"'&54767#5323-2 BAe¬(4¤pF"+QE+'" ~š-/ 'R/ù ?<89(I0+:-)0K 9ÿþðÀ;C23254'&'#53#"'#"'&547632654/&#"&57676327&#"W-*s(ˆCO6<])7yL/\H,'-+CFE 'EE"&ˆWF13DW½K.>Z4:‡UQ1EMi„.F/"&+!JF' .%þ¥++*ÿþïÌ%#654'&#"#&547#5!ï#E#<3>>1<$E#ffDSJŒY58VrC::Cr2\2\f=[RÿqÌ M2#"'&54#73!5!#"'&'#"'#"'&54767"32765332765'573275"! TE#‰ýZ¦[2$'D 6'5V$?IM'SN22 EV,r7 BV   (þr¬=’8) 5\9(99=#.E":F(1f=i26ÿüÿþrþLZ2#6/"3276533254'7#"'#"'&54?654'&#"&54763262#"'476ÇV+ N<'$2(/O(`KK4K0>(g4AWh%-S-( W7@).W/<7 $ þ=6(()="!Q>0 ?!"?<X&77Q",/'=$)5 1 /1JJ  3ÿûÿþSÈC732533254+535#533##"'#"'&74?654#"&547632`1XCVEM=WW>]VL"/i$.W7),(L&3M 25 #^ (K(Œ1VVHW:r9$‡:,F+ @@')>0$8!;)  ',74(9 ÿþ?ÇK27653#"'3253327654'7#"'#"'&54?654#"&547632qN G=&%-%;&A!XVE4- #*8%n3V[!&F%*A><$'4, *q&4+,&7 8V> F4M#FFI'1#6#1  +,& ÿöCÓ x%2767&'&2#"'&54764'&#"#4'&'#"'&547632654/"#5&"#&5476326763247632'6 -#Ci?¹ S$8$D4E HeT2-€#*!-64+6 CPG"3EC 'g! <>) 1'*T-&*3> (,9C7,Y[*:  9"&U-UF  .*)(K< .$;+#;(*&55B<Dr^476;#&#"32'654'&#"327653327654#5327654/&+532'"'&'#"'&547&)#P 1%C : )< @+1 b"$)  H%FL C. 5MJ+PA.E+&2# ,3QL!(% +—5,;E:"+;1.9hy # 6J2A•D8ÿý±Ê&"327654'&%3'&547#47632#"åP'M#d 7#þñôuC=;\ÅM`¶))*Q")p# ]$O/K;L`j>>àTX¬' h ÿþÊ"<2"'#"'&54767#5!4'ᒆ#"325332õ <w D?*;nEg -'§g5  WDWD)@8T 9( =+4fX#;;+¥ +0_a-9  VV ÿo Ê"A%4/ᒆ'&'&#"325332737#"'#"'&547#5!Ç'^_6# WDWDß#ß3w D?*nnEg# )% ‚ +2 0P4C# VVÕrró3 9( =+4–_;;%KAÿþÇJ"#4'&#"3"3273#"'&547&'&547632632#"'&54767327654'&3D* V>"(qNWW\E]*1@,D. W)4jQ4xw=#66O]! I1L2 40)7FV9+A0G (!_+W"^^\5I _:<6@ 9">).H40ÿþóÊ-4'&#!5!#"'&767327654'&+53276›9þþ6^ &DHEaë%"4¡U2->!!F G' ;; 22B;&$Ž5! 2,N2:0  ÿo Ê'+B74767#5!#"'#"'&%#"'&547632#73727654'&'&#"3253 ?v,]N / )v0W3!"/    D#h286AN;, WDŒh^';;Ci,+E+==(&   þVrc3X69L9B< VV ÿý Ê,73253327654'&#"%#"'#"'&547#5K) WDW' A5IO96 IO4% \0W3!"vv¡AVV/cA6IDØ;?x%'D->=(&@µN; ÿo Ê*.72533276'&'&#"%#"'#"'&547#5!3#‘WDW*)4MV9'¿/ )v0W3!"llT?Qþí#DDVV=b)9O5C]HE+==(&@»H;;Ls"Ír ÿþùÊ-7476323254'&'#5!#"'&'&'&#"& 8,4. -M+-Cñ%U-B%2?, "> = 6)!L(t9>D;Y/I%l2I5?%):ÿþ±Ê!#"'&54767#5"3254'&ùk, 99ZZ9:+]ÌM'++;‚9"Ê'4O"f?@B@c+06;KC'2I..¥V, ÿÿ'Í .KY%'&''&'&7676323&5432'27654'&#"4'!5&'&'7673676%3254'&#"& (H9%(WQ'# >SŠS[{$   ¨!# þÑ) /&/5" (M;(#þA ?  ô:1U2'rjcs+Ay yˆ%#   4HT.? ;/SA3)5(w92°$4 ÿþSÇ*4'&'3#"'&54763'654#"3276M2^OwoU_01A@ #4/CX9Oc@<ÿd36QA‚E:AJvS;:&8Q*h6#;7 ÿþ?aS_327#"'&7676#"'&54767"'&547632#"'53254/"3254'&#"3254'&'&y5+EW" h%.6#@#b04&.Y>   4 ‰!%Ü- <™>= " ý <>4\)‘K *.'#H+-D/98EL:8"Q_@ELGQŠ[XrZ2@ÿþ Ç3&5432#!5!254'&#"8 x‰m+~*6þþ™'CT 9Osr8Jœ+FŸB11Oÿþ ã)47"'&5432654'&#"'6323653#"'&5'"3254'&ÈE"x4=-)$F|‰E4M?!;&(+,) %X'X-V465= TœcJ2 I 2‹ $$ ÿþ!Ç;%274#""'&54767&'&5432#65&5#"367654'&'3.34*8"  Z7(ˆyH(UO:<‡)C®D/38831& 6&.€k . 5%A&7˜?4"C @ÿýÇ EO72765"2#654''&547674'&#"#47630767'476"6767&§4> + EKDU#( -&H-::A"4)", D6(#-ƒ)  "''12:4T8!—.)5-#&6--,FO.6H2 +##@ÿþ¿+73!!"'&547'72#"'&'74'&#"3276Œ=þÜ_/gE u0 >9"Ç2K4$! ‘3FB&4m@rx7#/E `ÿþ Ç"#4323!!"54?654( H|C":j83%þÛ›;l;‡d,;0E&& 9p;*;!%3@ÿþÇ/476;#"#"'&547632'4'&#"327654'&b+U-L44CA[‰8"!3F= 3 «I+'+,q0 8 A>(L68f5JA&'8 !B•("0!63PÿþÇ/%4#"32'2#"'327"'&547&54763!!"6B=O*K4A 3:@ @!(e<>##M=þ¹A@ð4o,+ %89-,C8)JI8<!<h¼ 2#"'&547627654/&#"ãU3$10FR4&=.;A%33%&2¼@-;F24?/=Q3%þÞ5 )?# #"3A%2Ò 0@72#"/4764'&#"3276#"'&'45476324'&#"3276i:(* +j((% +.+<4),ú.)H6b+ +$"7 9.3- (ÿ {lGVg#"/27"'5#"'&54763224/"#"'&5476721676737&#%27654'&5747{,%?&8 [xXavLl :*'$" A!'*0f þ6C7G "T-s! /Ž4 þÛ*"(ÕÖ;@k‹A+&$$ 8( N/* &¹Z<0†I0." 2/,<$$ÿ»c¢'&/"3767654'&'&/&'&'57237676767654/&'&/"32?"'&547632#"'&5476767633#"'&'&5476324'&#"3276   2  ?l- Zh51C N !%R§.h.$B'?#Z!L 3.$-°Z"a*BGd!I '3"V(>%&9:%-4 G )    '5")\@A# e5  4"-O E'L1 2¯ƒE  %:H2D"†A ,J'0'% HF0!,ÿþj Y|47632#"'&74'&#"3276476?676?676?2322#'"'&'&'&7276767676754'&'&+"#"'&5476724'&#"3276[&1'+    # þByà EQ#  .DxX  $A*)(  3až:JL<.b&G3V@>;(3;k^;'  ¢'+ 1   # ÷/ ) , ' $  þ˜T [-O$ & 1!0 9  o1*>l!& C05.? F03  ,:5*h, ')  $  þ¸ [R"'&/6762#'"3276767674'7#"'$476767676?4'&/"ƒ+ c'(4Ô[0< -,X.3-!AT a1Q* L*,),8 )E6@ :&_6D1þÀB>H‚m<  # '¬*'C[Y?`=$'"Y -&T , #+. :´"32?4'&4'&#";27676765276767#"'&'&'#"'&5476?2327654'&'#"'&547632#"'&5476654='4'&'&'&'&'&""'6;2'&™"­ 8 44E="  "'D #+ ( 5" . 1km;*W#". n„" !<3H5+J-8h7#½ (!S:6: A3vx&S6#6E !)(  ! +  J3RC./Fa- %&! ArRož> 2 &> P !"*4 3*4G&7"1ø"\". U!"+  A< =T\T0PB #‘Y ‹%27654'&/0;6767657"/#"'&'&#"'&'6767674'&'&#"#"'&5'47632676326+"/3276767654'&#"2óCu:/7H*76E1 5 ÊB#5V. ,*# HX*:  '=#33D 8 2(?9—k ,1,' #7! NMoA6IPXŠE"*N3 /5E`, . -ƒ F&r3#2"3¤\,,5^/  B46 #&$S4A\6A"$C )IpTS(-.3:\%4'&#"32767#"'&5476323767676767#"#"''?67654'&#"6767632%654='4'&'&'&'&'&""'6;2'&&&2# (\,BBf†@) &#,+70 ', ( `*(Y@K A  2}a5  ' © (!S:6: A3vx&S6#6E !)( e+ .%3d;MgQPS6M.12$  / )Jl_:@AC ))U5 ,/m"\". U!"+  A< =T\T0PB ?¤\n47632&'&;676765&'&'476767632#"/7?2767674'&'&'&#"672/&'&'&'&?]Fk& (I’4< *(&S-I& "4G9wNE*68M(!/ %9 Q!4]2I) 0I€ fB6 ,šR>  `)7P3  'J  (*)%ZPp4 +#G&$  @iM'K, C< #*?1DH6:!`“"327654'&76367674'&27"32?67673276767#"'#"'&'454767#"'&54763654='4'&'&'&'&'&""'6;2'&_  #  < |Dkµ["H),9'W(+ "#(B#$) ( 2/hkJ2d T804 $gk(g (!S:6: A3vx&S6#6E !)( ý   +!   I%%9P  $!%  F`Y_ZG@O T5 %I þñ"\". U!"+  A< =T\T0PB # ý:U7676?67676731#"'&'&'&'&767676767'&5474'&#"1"'&547672#"%&'4'&'&'&'&'&""'6;2^Ì:W &C / 'hFd8.390,. !Y(3 !  /"6)GI(B"r (!S:6: A3vx&S6#6E +"Fq-  &F! (5UD+ 211$&#  * %!*)V& U!"+  A< *W!_ g%%"32?4'&2674'"322'476726"'&5476?6234'&'"#'&'47632&+" 54/&'"#"'&'#47676767476n8+= * ]5 '€% W$ $=y  ;: bTU¢uƒU#w 2 /!  @$&0!(  ]2…%?bi>A# FD=|Ø, " C !0/ !!W' #9 !@-)KqG3KT‰[, 6   % .'2+k"yP @80-85 1*  K" „274'&#672#"'&'&54732#"'&5476?623&'"#'&'47632&+"27654'&/476?6?672n0 5 é)E/1#  A;!!B{p•¢uƒU#w P/!  @$&0!  ]2…%?bn.Ã';Õ? :D,+æ4",  "  %( ) 1+,+~NFKT‰[, K   % %9 2+k"y1']3~ ÿ0Âa!¹Û%27654'&'&#"67227676767267672672&#"72?#"'&547676376&/&#"#"'&'&5&#"2#"'&5#"'&'&#'67674'&'&#"'&547667677276?"'&'&7676ÕB#]4*!tW  = @#Í- O\.GSVOa?33/(r J64 6I^;# M;"–-!Y:  [–'% =Á&% F !%E >*#(*)  8Eaj96 B <J9pdA& $$0!-% £h4;  7 %%P6*ý`D.  (*3 ('&ÿ0Àaް4'&/"4?6767676%2&#"72?#"'&5476763672&/&#"#"'&#"#"'&547632;27654'&47632667677276?"'&'&7676I!G,/ I .‘WI /)*( U*< 6I^;# M4cm# H<  >;"ýA>W:)1/…, %E  :*#(*)  8Eao78  B <* <:O GjB7Z\{p[eP.!E/6/&5"…WO $ýWD.  (*3 ('+:1a!276767673"#"'&=747676;&#"%6'&'4'&'&'&/&'&'&""'6;2\ Q:&0'# / ' s—hj‚ .^(/;0!s  $*:6: A3vx&S6#5G $ :” $/3-$D@s8CcBk   !/4  /.   A= !;H@(*Xi7"'&/476767"3276765327676=&'#"'&'&547&'&/#"'&'3276767&'&'÷lA [(2&#*!2AR,B;  $!#S1 5*#)$."' "x30K-, 7$6*%(6a8"$D| m5C*yH  1 *@ $ :!*9!$VA 81;B*DRR_P$43 FMŽHV>:M€%#"'&54767#5!4'&'&'&#"#"'&547632'"2765;7276767#"'&%654='4'&'&'&'&'&""'6;2'&@*1S9:0HF !$  H‘Õ3 | 5 8B#$) (88,ÿÿô2¾ÐÙ%#"'&57#"'&/&'"'#"&'676?&747632%67632632#"'&5732765'54'&'&/"4'&'&#"6324'&#"3276%47632#'&'&'&'232767654'&'&'&74'&'&#"32767&'"Å0 ;"!  BZE:'?3"  G[F?^:?C.[~6§8;&`/ $D;(*2!H  =  96 1+ $->$,*ýº*" 4#71-‡#2G61L7 3þ£E#.›" #!"?2\p0ß8,# a& ((J; , 60 O60!ø) 70 &T #;.qÒ@ O&6l ;Z! F !"*)2!1"- - ˆ- 39#/OF2*;%%%¦E  $ %! î?!. !!Rf~"#"'&5476763267672322+"/3276767654'&'&'&#"2#"'&/&''676?674'&2327654'&'&á!3"+Q+ /59A,!%§ 4OA #:$'V%&(0B)Bs)$9EpeN:?T > !!*!š3q-GT. D 071<0>‹$*{B;9._9A-  !2*@TN`; 2* jIþ’Y#0\, Av+%ÿüð':G47'&'#"'&54767632&'"327654'&'#"'&'&327&'&'–0 UF0GÛQ* L*,),8 )E6@ :&_6D1þÀB>H‚o4?g-;"¦ / (*)  8Eam9G B< !;* þ(D.  (*3 (' :6i727673276767#"'&/#"'&547637#"%654='4'&'&'&'&'&""'6;2'&Ük? ""$B#$) ) /e%!"'$W88P5]"-’$ :( (!S:6: A3vx&S6#6E !)( –I .F4^2Y $3JJ`¾@)y$,O0!d"\". U!"+  A< =T\T0PB ‚Wt‹7676?6765'&#"#"/4767676;6767672"'7;6767674'&#"72#"'&'&'&'&;27676765&'&'x7   +# -0 1  * $A"J_]x2  L - 4QUŒ$I"@I$  ? M G8" / 5n< #J]/F Q~@-39L%8#   -17'21 -Q* L*,),8 )E6@ :&_6D1þÀBCKz‹3  # '¬*'C[Y?`=$'"Y -&T , #+. :e˜%4'&#"32767+'3767676767#"'&'&'&'&?727654'&#"47632#"'&'&'456767632654='4'&'&'&'&'&""'6;2'& #"#úM .,2:.- ( " GbD%%'7?(RC@B'8 .'2/ B^mIA¼ (!S:6: A3vx&S6#6E !)( a$ # !Â_ =W(Œ: X ,' 80 #"G1 +4 !?It??C;m"\". U!"+  A< =T\T0PB s^_#"'7127654'&/""'&547#"'47!4'0'&'&##"'&547632"327654#47632sœ!'%G"#N/"['5!V1!..o)3.hNPbP 2  " .?'-¬--/GDdb6"\4?k¾3#î, " K6E‡> 3"/ %\j-NObx;  %.499F3$%+&=kUh«9ý6€ª4'&#"37676"'&'47632#"'&5676?4'&#"327676?671"#"'&'&'4767632327654'34'4'&'&'&'&'&""'6;2è( " (K9I#%K  3(B]?/  _SSQ:&0' 3 ' s—Wpx 4("R#*o0G ÷ (!S:6: A3vx&S6#6E +"Ú32( ' X7d ;))+%,  ,5, ?-( $B! D@sCHS8DjN'  ? <(+> )*[ U!"+  A< *W!D0:¢Õ4'&#"327637676767"#"'&547?674##"#"'&54763232765&/#"'&547632#"'&'&767654'&'&#"327654'&5476?227654='4'&'&'&'&'&""'6;2'&æ! * %?!- ( 5)() 0'($8'./7s9&D/G0&UN)+7 O8)G,61/0  a ?.'"# - 1%× (!S:6: A3vx&S6#6E !)( ø" 0'#þŸ Ga)$$4  4"$yPn•N7)9 T(2 4 + 7&Ž=;–vI816D./26+* (5  1R,&!_,<-P $N*&6Hº:;‰} &   $# [X!"s 7fV,.JA *)#> OG-*7!/R:5 )'*þ:O|32767676731"#"'&=676767676374'&#"1"'&547672#"%&765'4'&'&'&'&'&""'6;2\ä Q:== / ' s—hj‚ 21&z3 !  /"6)GI(=x (!S:6: A3vx&S6#6E !):‚2$@! D@s8CcG5* %!* 69  U!"+  A< =T\ÿÿmXz%67&#732"2+&'&/&'&547676?632&'"32?4'&'&47632&'&#"&'&54767632674'&'&#5 =0š“(%4@>P? %5151*B<3J, >P/Q•'' 1?HiÂ? R '% = .'(98'=50  ‡S3I)+  /44DI344 # #1 šE% H#L,# --/9-)6 H $?#Â:–4Dj7&W$ '/Bhhz4'&#'47676322#"'&/#"'&54767#&767!4#""'&54767632#";276767653276'67674/&#"32;#-­F"#_& ( !"I_)#; M '5< — %*$$? _# 3gkSQL1)3M4,ÿ0f^v2/"#327676'476#'"'&'4'6327654'&'&76#"'&5476?676"'&'767324/&#"Ę4 ‘i$‚„!o3 HJXWA? & ]„hFW   'eOŽvu I`, O"df[+'  f> )¢1 A %. P00GEg b? KQ0%g=Iˆ 0/  ‹3'kk™ÎB -Ee L /({RK2+'/527676754'&##4''&'&#"7"/&'&547632676¡r> D¦) 4-44!#./<4&'&/3O> š"($G(,I7 ‰CIm…=0jOz.9+-M,   &/EM>? ,\ $3> #1Š: @ŠxX^{eýéþ—"+45&'&'&7676263'&'&1367&'"ýz$->(  !&(é`   ;4  þò/23P]947632'&'&'&'5327676?4'4'&'&#"3#, s  *F5!    8% Ý>'qB¡+6&    ë'21*ÿ~š"!37#&'&'&54?67#'&7076#… 9T 7*#D&U)W&/é šç-#%J:xAL‘49  ÿÊ–7"'&'&'&5476767#57'&'&'4?732?6.X(S J!B¸\_¨^Ç+5$ ) E í 48$+*(K#* h t'219a+ ! üíÕþûÕ*4'&/&#'""/&54767632/7276þÚ !|~3" 2 6)$WoI*`<$42 ?&  4# "+ 0(Q""&/ ýÕÿÛ:"7654'&#"'&547&/#""/&5476723322þ¼$)   F- "#V2E0.2 6):/: W-%Mu* $<0 ".  # "+N'2üíþúÿž(#;27632;7!"'&54763/"ýE)T*!C!€"ý½9!=% : „7")%¾HýÒ9#)E  % (üãÿÿ™+3276327&'&#"#"'&547632&#"ý 6BNQ@';/' VW&37Š+N. ;++' 0%u8 %$  ¥Býò %1"/)  ÿþoZ4E2674'&'&#"'6767632'&#"&'&54767667&'&#672§0G&D1 7*+(3 4)*-! <|3TA)P+.A-W 6@ t7t <$505þèWn>'0*#!inAR47632#"'&'&547632'&#"327654/&'&##&'&74'&#"3276ÎD*4d61XSs~Y'a`ˆY:B3)qSR[CZj>, $ %0_ Þ/$00 [I)&4MiEA\)23A…^`"  RTj_8):*:W!1:D&0 4/*ÿþBYO27654'&'47632#"/&'72767654/&#"#"'&5476372#'"À9)D ]XXBDZF+ !, E!* .K-0$   *\'\ RRm†bb<  3 5¥/  P+<'3D&  @"ÿÿÿžÿóGô&h:ÿÿ0ÿóŠô&Èr:ÿÿÿÿóGô&ç:ÿÿ0ÿóGô&ªì:ÿÿÿÿóGô&žç:ÿÿ0ÿóGô&«ì:ÿÿÿ£ÿóG„&Ÿm:ÿÿ0ÿó…„&¬m:ÿÿÿ¦ë&åÿÿ¦å&Èþÿÿþ!¦è'þëÿÿÿÙ¦ë'ªþÓÿÿþ?¦å'žÿ ÿÿ¦å'«ÿ ÿÿþÒ¦å'Ÿÿÿqÿÿÿ¦¦å'¬ÿÿqÿÿÿŒÿöÜô&V>ÿÿ'ÿöwô&È`>ÿÿÿ ÿöÜô&Õ>ÿÿ'ÿöñô&ªÚ>ÿÿÿ ÿöÜô&žÕ>ÿÿ'ÿöñô&«Ú>ÿÿþvfå'ÿ@ÿÿPfå'ÈÿJÿÿýsfå'þ=ÿÿÿCfå'ªþ=ÿÿýsfå'žþ=ÿÿÿCfå'«þ=ÿÿÿ¨ÿJòñ&r @ÿÿÿJ‹ô&Ès@ÿÿÿÿJòî&å @ÿÿÿJûî&ªä @ÿÿÿÿJòñ&žß @ÿÿÿJøô&«á@ÿÿÿ›ÿJò&Ÿe @ÿÿÿJ&¬w @ÿÿþgqå'ÿ1!ÿÿAqå'Èÿ;!ÿÿýdqå'þ.!ÿÿÿ4qå'ªþ.!ÿÿýdqå'žþ.!ÿÿÿ4qå'«þ.!ÿÿý÷qå'ŸþÂÿq!ÿÿþËqå'¬þÂÿq!ÿÿþîÿøô&¹Bÿÿ8ÿøÚô&ÈÃBÿÿþmÿøô'ÿ7Bÿÿ8ÿøSô'ªÿ<Bÿÿþmÿøô'žÿ7Bÿÿ8ÿøSô'«ÿ<Bÿÿþóÿø„&Ÿ¾BÿÿÿÇÿøÕ„&¬¾Bÿÿþk£å'ÿ5#ÿÿEVå'Èÿ?#ÿÿýh£å'þ2#ÿÿÿ8£å'ªþ2#ÿÿýh£å'žþ2#ÿÿÿ8£å'«þ2#ÿÿýû£å'ŸþÆÿq#ÿÿþÏÝå'¬þÆÿq#ÿÿÿžÿôô&hHÿÿ"ÿôŠô&ÈrHÿÿÿÿôô&çHÿÿ"ÿôô&ªìHÿÿÿÿôô&žçHÿÿ"ÿôô&«ìHÿÿþÿøÞè'ÿg)ÿÿ2ÿøÞë'Èÿ_)ÿÿý¯ÿøÞâ'þyÿþ)ÿÿÿsÿøÞß'ªþmÿû)ÿÿýëÿøÞâ'žþµÿþ)ÿÿÿ¦ÿøÞå'«þ )ÿÿÿÿòÞô&WNÿÿ(ÿòyô&ÈaNÿÿÿ ÿòÞô&ÖNÿÿ(ÿòòô&ªÛNÿÿÿ ÿòÞô&žÖNÿÿ(ÿòòô&«ÛNÿÿÿ’ÿòÞ„&Ÿ\Nÿÿ(ÿòt„&¬\Nÿÿÿþ—å'Èÿ.ÿÿÿÿþ—å'ªýû.ÿÿÿÿþ—å'«ýû.ÿÿþ˜ÿþ—å'¬þÿq.ÿÿÿüÿ÷Àô'ÆRÿÿ$ÿ÷èô'ÈÐRÿÿÿ{ÿ÷Àô&ERÿÿ$ÿ÷Àô&ªJRÿÿÿ{ÿ÷Àô&žERÿÿ$ÿ÷Àô&«JRÿÿÿ÷À„'ŸËRÿÿ$ÿ÷ã„'¬ËRÿÿþžÿÿÀâ'ÿhÿþ2ÿÿ*ÿÿÀå'Èÿr2ÿÿý¡ÿÿÀè'þk2ÿÿÿqÿÿÀè'ªþk2ÿÿýøÿÿÀâ'žþÂÿþ2ÿÿÿªÿÿÀ¾'«þ¤ÿÚ2ÿÿþCÿÿÀå'Ÿÿÿq2ÿÿÿÿÿÀî'¬ÿÿz2ÿÿ0ÿóGë'¼•:ÿÿ0ÿóGë&ÇO:ÿÿ'ÿöÜë'¼ƒ>ÿÿ'ÿöÜë&Ç=>ÿÿÿJòë'¼¢@ÿÿÿJòë&Çb@ÿÿÿûÿøë&¼æBÿÿÿûÿøë&Ç Bÿÿ"ÿôë'¼•Hÿÿ"ÿôë&ÇOHÿÿ(ÿòÞë'¼„Nÿÿ(ÿòÞë&Ç>Nÿÿ$ÿ÷Àë'¼óRÿÿ$ÿ÷Àë'Ç­RÿÿÿžÿGô&ràÿÿ0ÿŠô&ráÿÿÿÿGô&râÿÿ0ÿGô&rãÿÿÿÿGô&räÿÿ0ÿGô&råÿÿÿ£ÿG„&ræÿÿ0ÿ…„&rçÿÿÿÿñYë'¦ÿñèÿÿÿñYå'¦ÿñéÿÿþ!ÿñYè'¦ÿñêÿÿÿÙÿñYë'¦ÿñëÿÿþ?ÿñYå'¦ÿñìÿÿÿñYå'¦ÿñíÿÿþÒÿñYå'¦ÿñîÿÿÿ¦ÿñYå'¦ÿñïÿÿÿ¨ÿòñ&Ñüÿÿÿ‹ô&Ñýÿÿÿÿòî&Ñþÿÿÿûî&Ñÿÿÿÿÿòñ&Ñÿÿÿøô&Ñÿÿÿ›ÿò&Ñÿÿÿ&ÑÿÿþgÿëAå'ŽÿëÿÿAÿëAå'ŽÿëÿÿýdÿëAå'Žÿëÿÿÿ4ÿëAå'ŽÿëÿÿýdÿëAå'Žÿëÿÿÿ4ÿëAå'Žÿë ÿÿý÷ÿëAå'Žÿë ÿÿþËÿëAå'Žÿë ÿÿÿüÿ Àô'Ë4ÿÿ$ÿ èô'Ë5ÿÿÿ{ÿ Àô'Ë6ÿÿ$ÿ Àô'Ë7ÿÿÿ{ÿ Àô'Ë8ÿÿ$ÿ Àô'Ë9ÿÿÿ À„'Ë:ÿÿ$ÿ ã„'Ë;ÿÿþžÿî˜â'åÿî<ÿÿ*ÿî˜å'åÿî=ÿÿý¡ÿî˜è'åÿî>ÿÿÿqÿî˜è'åÿî?ÿÿýøÿî˜â'åÿî@ÿÿÿªÿ'åÿîAÿÿþCÿî˜å'åÿîBÿÿÿÿî˜î'åÿîCÿÿ0ÿóGÞ&ón:ÿÿ0ÿóG&qoà:ÿÿ0ÿGë&iDÿÿ0ÿG&i:ÿÿ0ÿGë&Eiÿÿ0ÿóG¿&÷rò:ÿÿ0ÿG¿&i‡ÿÿ¦¨'ó©Ìÿÿ¦g'qªªÿÿ¦å&¼ùÿÿ¦å&dzÿÿÿñYÌ'¦ÿñÿÿÿËX5Sÿuëÿÿ³²ÿ–ýÿÿÿ6Gÿ‡äÿÿÿclÔ÷ÿ^ÿÿd@o'‘£›jÿÿÿòë&ÑHÿÿÿò&Ñ@ÿÿÿòë&IÑÿÿÿJòà&÷m@ÿÿþ\hà'KÿY–ÿÿÿCfå'¼ÿ-ÿÿÿCfå'Çþçÿÿÿ4qå'¼ÿ!ÿÿÿ4qå'ÇþØ!ÿÿAÿëAÌ'Žÿë!ÿÿÿ6G×ä'¼ðÿÿÿ6G×ä'Ǫÿÿÿ6GDt'÷§ÿÿÿÍÿøÞ&ó¿BÿÿÿÛÿø&q¿àBÿÿÿßÿøz&ºÁóBÿÿÿÖÿøh&»¸îBÿÿÿÇÿø¿&÷ÂòBÿÿÿÕÿøt'÷ÿЧSÿÿÿÝ ¨'óÿÏÌ#ÿÿÿëýg'qÿϪ#ÿÿÿ8£å'¼ÿ"#ÿÿÿ8£å'ÇþÜ#ÿÿGä'¼ðÈÿÿGä'ǪÈÿÿ Gt'÷§Èÿÿ(ÿòÞÞ&ó]Nÿÿ(ÿòÞ&q^àNÿÿ(ÿòÞz&º`óNÿÿ(ÿòÞk&»LñNÿÿÿ³ÿ8ô&}Jÿÿ9ÿ8Ÿô'ȇJÿÿ(ÿòÞ¿&÷aòNÿÿ(ÿòÞv'÷c©Tÿÿÿþ—¨'ó°Ì.ÿÿÿþ—g'q±ª.ÿÿÿÿþ—å'¼þë.ÿÿÿÿþ—å'Çþ¥.ÿÿNÿÿpå'ÈÿH+ÿÿd(‡'¼$£jÿÿd3z'Ç–jÿÿPçäCÿÿ$ÿ Àë'ËPÿÿ$ÿ À'ËRÿÿ$ÿ Àë&QËÿÿ$ÿ÷À¿'÷ÐÿòRÿÿ$ÿ À¿'ËÀÿÿÿyÿøÞâ'¼ÿcÿþ)ÿÿÿ¸ÿøÞÜ'Çÿ\ÿø)ÿÿÿwÿÿÀÙ'¼ÿaÿõ2ÿÿÿžÿÿÀÁ'ÇÿBÿÝ2ÿÿ*ÿ'åÿî2ÿÿ\P-ävÿÿÆGä.ð8#5î8HHÿûð18!51ýÊ8HHÿ÷ðé8!5éü8HHAݞŠ#547673ž]L 00Ýen&S@ñÙ 356745#@]Q-0Ùer&B @ÿ€žh 73#56745#A]T00het&F@ñÙ #&'&=0 R Ùh: &d e0Ý+Å #547673#547673]L 00ž]L 00Ýen&Shen&S1Ý.Å 356745#7356745#1]Q-0 ]Q-0Åer&B her&B /ÿ€,h 7356745#7356745#/]Q-0 ]Q-0her&B her&B 1Ý.Å #&'&=3#&'&=Ž0 R ý0 R Åh: &d eh: &d e&ÿOÅ ###5353ÂXÁÁXöRý«URÏÏ&ÿOÅ#3##5#53#5353ÂÂÂXÁÁÁÁXöRþÍRÐÐR3RÏÏ2Ü,Ö2#"'&5476¯B%5!'@&4!Ö6 )?%4!(@&FÜ,Ö0FææÖ}|suh 7#5!#5!#5Ûhµhµhhhhhhhh ÿêáâ#3CSc2#"'&5476"327654'&%3#2#"'&5476"327654'&%2#"'&5476"327654'&žL,;(2K-;(21+1,4BþuB‚L,;(2K-;(21+2,NL,;(2K-;(21+2,Ø<)3H.<(3J-<*2*4 Fý +<)3H.<(3J-<*2+4 <<)3H.<(3J-<*2+4 ÿêIâ/@P`dt„2#"'&5476"327654'&%2#"'&5476"327654/&2#"'&5476"327654'&%3#2#"'&5476"327654'&KL,;(2K-;(21+2,NL,;(2K-;(21+2, ûßL,;(2K-;(21+1,4BþuB‚L,;(2K-;(21+2,<)3H.<(3J-<*2+4 <<)3H.<(3J-<*2+4 ý<)3H.<(3J-<*2*4 Fý +<)3H.<(3J-<*2+4 1¶âÌ'7U8U$$Ì(vxŽ1¶µÌ '7%'7U8U$$ U8U$$Ì(vxŽw(vxŽ1¶ˆÌ '7''7%'7`U8U$$›U8U$$ÞU8U$$Ì(vxŽw(vxŽw(vxŽ1¶âÌ/†7%%U7ÌwŽxv1¶µÌ //Y7%%U7~7%%U7ÌwŽxv(wŽxv1¶ˆÌ /%/%/Y8$$U8(8$$U8þ¯8$$U8ÌwŽxv(wŽxv(wŽxv[jó¶757[˜jjãYzSSSSUjï¶57'5ïšll=YzSSSSbD í/?K47632#"'&72#"'&5&76#&'&547632"'&547636'7'77'b  Õ   à  Õ  ݼ¼»»¼¼»»  Ü  Õ  Ü   ¼¼»»¼¼»»|æÙ #'#5#'#5Ð'STj'STÙþ®ßßRýhhqþ®ßßRýhhMýå (%#5#47632#547'7674'&JZ= U´~83? Z ZJ> hhh'F1 ÓS$+F;:/7!S ÿ BBGÿRÿìPÅ3#:þ<:Åý'ÿÿM)å'","Müå /3#'#5%#5476767674/&#"#47632#5ü'STþ¢Z#J=RU´~83? ZÙþ®ßßRýhh_72%!BBF :"@ÓS$+F;:Žhh|å .2#'#5%#5476767674'&#"#47632#5Ð'STäZ#J=%RU´~83? ZÙþ®ßßRýhh_72%!BBF:"@ÓS$+F;:Žhh0ÿO Ù32####0úgB7F 0M@R@9ÙQC\kD (þLJü¶JEÅ 2#"'&5476"327654°•o‚,&C[ZR Å߸©w6//­¯‰« ÿ8Þƒ735##5 >>>>I:jááQÅ #533##=мÌ.CC>€; þð5d™ªª FÅ"#632#"'&'3327654'&#"#7.¾&.W( D&3R* 8JI:.!4"Å4w@V*3/G<H#è?Å*"547672#&'"632'"327654'&ªš*/KV 8:R&CQ&?&.?-8 7Ïp;;H<o/= *O)ç18 /DGÅ #6767#5G&=#K/÷Å,³ºv1?4IÅ*:#"'&547&'&547632'"327654'&"327654'&ûNB%2Z*N4<"+S%#f<.91@3D2û"HJ$=(G"" @ 7 -‰, /) 2²/716FÅ-2"#"'&'32765#"'&5476"327654'&¬š*&IU!9:O)?R&?&/85< /ÅÐn=7F<i/=!)O).0 C/: ÿÿÿ*Eáëþÿÿ=ÿ8Þá{þÿÿÿ8Fátþÿÿÿ*Báuþÿÿÿ8Qáíþÿÿÿ)Fáîþÿÿÿ*?áïþÿÿÿ8Gáðþÿÿÿ*Iáñþÿÿÿ*Fáòþ[ÿé|Ù0HUa#&#"#"'&53327654/&'&547632%#327#"'&5#5353#!2#'327654/&+gXfRBPvZ4JÂX!GT 6NwT1D‘# þ2V 'Y GGSýu]-¡/?:SåÂf O"ÂzT1-F`,¢ /#/.3+]*eqDþ™&FC ŒD×þËÙv)7a94RJZ]ÿéÙ0NY#&#"#"'&53327654/&'&547632#!2#&574'&#'327654'&+ˆXfRBPvZ4JÂX!GT 6NwT1D‘# ü2]Pª) H> qPðáy& IázT1-F`,¢ /#/.3+]*eaþÆÙx!*b3 (%V` 0GAmRVB <X$%3336767676#&/!#!2ÅW^#)þ¯Wñ1  ˆW2þôWl< +œ¼þ:V'wþÕ LþÝ'ýõW!ÿéÅ/547#7367632&/"!!3#32767#"'&'&'#7OO?3F€b^ U9k, þòöÖ&ƒ6FMYkB ,S9;_KeCP?‹;;Ç& ]/GHf;!ÿêØ̓%#"'&54?#"#"'&547672#"'32767+"576?#"'&547654#"+"5476323276?632367632327676;2"6767654˜JHh L@<.yLoUD\ &!  Pd–+H±J VÒJ3.9  %;  R=:  A?™䀦~73G1UàIc9>W õQ±ÊR 0Œg U TkY¨lC4.&" 1 ×>YiyW"P  v(  /•þÕá=@6FyfE3tç] D+-ÿPΆ#&367676#"'476'4'&'&767'&'&767676776767454'&'&'&'&'76327676'&'&'&'&76767676767236ƒ[3. )%8&,1Z* W,7 *) ++',  O. -B!$0, 2="C!  % %%  )/Î €% -'K(;o!$5' MY,7   " 3 ,7:2 ,$o+J%(  (9>4!/N  G AI% /. :ÿï¸Í W76767%4732#"'&547672#"'23276?&'454767676763267654Á>~K{›6<K$+Q B~bR` &!  c Vp/%W5?†•I1›\+Q9/U<Ä iS31MTU  <3<"gC4-%" 4o-5NALY.) a„*b)E9@ÿuïÂ3~'&/&'&#"&/5&'&'&767676767676'7&76762376'&'&'&76767676#4'&#"'&'&'&ï'#+&2))  00;  Y+/%&  þO /++ J8- " =?  , F-. %#!\1 4';@'G &  [/ / /  ý+'''E&+6I<?3 3 <' # C* VY&'   ÿï ÍVbj2#"3277632327676;2"'&'+"547672;26?#"'&54767627&#"2"6765&;!EN'%T(3Ín!Q.bîd=dnGEL$ 7\-'Sj fR„ !\ EWP:V ’8(5]2þ“:H@>DL&çÁU/À;#3+B ;A6BŒ#ŒU=8N.,2& .:Rz=$/9L)ýF-$°þ¿%xC.0LÒÙ$.#52#"'&5476"327654'&'##3´îuJ- <#H. <(43,7,Ðiþ‡Xe}HHX;)3L-;)4J.9+3.4ý'Oý±Ùý¬TÿþÿïwÍ —œ267654'327676;2#"'&'&54?6765##"'&547672#"'3276?4767&#"3276?6=472#"'&'&5476763276321#6dQ6+jf! ")4* 9Q#4Q.""JGuZI_ #!  SXv[ Ž<{mrs?7B%#OG 'C,&G8@€}q…J/$!((S "K7"m F86'R£þ´ $*=O2 & q?neA2*""  . †!%€ ¾f,<9.-7 - Wa * D4" %@ O* 1% 7+   ÖJ  ‡;n8G  9?$ªÙ##5!##33#Dšw6FyC^„ƒ[C¢þ‚~77þ‚Uþ«µþ–jþKUÿÿ*ÿÿÀµ2*ÀÒ(%27654'&'5!##"'&54767#5!pƒD./.\°Ž%%šn“[Q)%[®" L?LjIc^PL&PLM†',[NQfseŒ\JD8LP;‡+0„QDÿtèÂ'&'&76767676'"/&#"6'&'&3"'&767637677676'&'&/&#4767675&/6737676767654'&E T.6`K6  !M G# GA   $ "5  ,; "K I,=J *#=W$E7E`S*‘  &+[-@.@,-I# 0UM>=1" ) &!7!!-   S3,LW*6C-  5 AA1;?!ÿÿO’Ù.ÿÿ¹‡"ÿò Ä™£32767676=472#"'&'&547676327632#"'&54767632#"32767654'#"'#"'&547672#"'327676767&#"267654'60327&#"½K(.' H  8(O2,K7@xo†I45m8VOW?! M *++.)3*.3%D5FHvZIb &!  ] Wt‰PRU?yjsr<6ï'-)%M€  $/dA.f*  MN8"9 STN/ (/. * '%?G6+%bfB3-""  2ƒ#)ÀXY?':9VL" #;5-(O®ÿóXÂw“7'&767767675&'&7676767677'#"'&76'&'76767676#"/&#"'&'&'&7676?6'&'&'&7676767&'&Œ %$4 '# p^25  hs!  $3 !C/&, V&LM  HD.  )'¡#  " +3;6%]$&Æ/   60!v$!   * H/>C ,  Y'( 9'(  *&)V9- * 8~~dF-ÿøÇÄx‚47632#"32767654'"#"632#"'32767654'"#"#"567632#"'&5476767&54767632#"'&274'&#"ì3*& &&-$*r+0()85(?%8&>\584$T,+  7-+g -[>8„,37j]T\ a! 6113 R"ó/.&3" 0 &"F!;P-   "9YM7 )*;>./8 @?3ÀiWþà9JG/Ð9)xC¬… ! $ ÿÿ=ÿì[Å'uþê'æm{ÿÿÿì[Å'uþê&tæmÿÿ=ÿì_Å'îþê!ÿÿÿì_Å'îþê&tæmÿÿÿì_Å'îþê&uæmÿÿÿì_Å'îþê&íæmÿÿ=ÿìXÅ'ïþê!ÿÿÿìXÅ'ïþê&îæmÿÿ=ÿìbÅ'ñþê!ÿÿÿìbÅ'ñþê&uæmÿÿÿìbÅ'ñþê&îæmÿÿÿìbÅ&ð'ñþêæmÿÿ=ÿì½Å&{æmÿÿdÂÙ,ÿÿdØÙ',,ÿÿdîÙ',,',,ÿÿd›Ù'9,ÿÿ…Ù9ÿÿ]Ù',›9ÿÿsÙ',±',›9ÿÿ‰Ù',Ç',±',›9ÿÿdŸÙ';,ÿÿ‰Ù;ÿÿ]Ù',›;ÿÿsÙ',±',›;ÿÿPÙ/ÿÿ0ÿé¥å&ÿÿY›Ù'ÿÿKùÙ0ÿÿB–ÙLÿÿBtÙ'LÞLÿÿBRÙ'L¼'LÞLÿÿBÄÙ'YÞLÿÿ æ Yÿÿ ŠÙ'LôYÿÿ hÙ'LÒ'LôYÿÿ FÙ'L°'LÒ'LôYÿÿB·Ù'[ÞLÿÿÙ [ÿÿŠÙ'Lô[ÿÿhÙ'LÒ'Lô[ÿÿD˜ÙOÿÿÿéÝFÿÿÿéïÙGÿÿFúP ÿñ®ÿ !&'67®üå2y#d——d#y281—#ww#—1-;Ž !#'67&'P81—#ww#—12y#d——d#y21ÿñ¿ÿ 75!&'7'6712y#d——d#y2Ü81—#ww#—1-ÿê;x 367&'781—#ww#—1xüå2y#d——d#y2ÿñÿ#!&'&'7'6767!&'&'6767‹X.%pD %li$%E:üþX.%%pD %li%E:\> †A!`}* `?\>3 †A!`}$ `?ÿêŽ$%'6767&'&'6767&'&'7ò\>3 †A!`}$ `?\> †A!`}$ `?]¾X.%%pD %li%E:ýBX.%pD %li%E:ÿðZu3!'7!#7þ[¦¦nuýÏTpoTÿñ«!!!&'&'6767«ýQQèýHM)\^&E)M~5PP5b!rZ$zP$!b'7'6767'#'#H!rZ$zP$!b5PP5m)\^&E)MýHèQQý¸-ÿìºü'7!5!7'!5!'7Á)MýHèQQý¸M)\^&E!b5PP5b!rZ$zP,ÿí<z&'&'7373!rZ$zP$!b5PP5)\^&E)M¸ýQQèýHÿìÿþ!'7'7!&'&'6767!7'!ñ8L(nD*oR&(LýÈL(nD*oR&(x‘TTýoT}_"„A'e`-"__"„A'e`-"þÃVVVÿÿÙG$Ù@À$ÿéþå#3#4'&'&'&#"'632#"'&5476"327654'&Ó%P(;P.6™›;/1§qGiÿ=ÍÙ!#!#idvþˆvÙüd7üÉÿÿiÿ=ÍÙGV@À)ÿ=´Ù !! !!5 8oþ%Mþ¨óýugþ¨Ù`þžþ…_Jm(Å  !5 þ FF2ÿõo %##5#53533!5!ÏFÏÏFÏþäÄÏÏFÏÏF@†¬(i7&'&767654#"'&'&76?6/&'&'&'&76765&'&'&6136767676'&/&'&ö  -&   `, -)   $ 22 &  ">0 `  + † '$0     , GG3"    1&,ÿÜ‘ '7Ü$˜ñ^”Á‘üPñ.!Iþt{•/<&?'&'&/'&76567667676&767'&z+%- 7 F/ 0H ,'.BU@70>V&(/O# Iþ¤U( #'=/E0t& ,$& "/&8!!2*C<'1 #)EO#A-#B*|±•-=67676'&/'&7676&'&'&767677676'&eG! KB6--@VP0?IH.#:@I.5 M$G'/ #/& g<3&!':&G)@!,%@=12P.5=/5B%) . 3@73 ! $:  $$)#;â¡!!¹)ý¾ ýZ¡%ý»7GÆ!# #GA××A^þ¢ÆBÝ7,ææ,þîÀþ‰wþ@(Üý!#54'&#"#54767632Ü7[WqqW[7]_ˆ Šfa¾mOLLOm¾´}`c_[{ (ÿïÜì3#"'&'&=332765¥7]AZ02Šfa7[WqqW[ì´}`D_[{ ´¾mOLLOmdÿ Æÿ47632&#"#"'732æ'4Q! D%%D ^!SO7GS  €ýÞh88Vdÿ ¶ÿ747632&#"#"'732'47632&#"#"'732Ö'4Q! D%%D ^ð'4Q! D%%D ^!SO7GS  €ýÞh88V„SO7GS  €ýÞh88Vdÿ Vÿ7S47632&#"#"'732'47632&#"#"'732'47632&#"#"'732v'4Q! D%%D ^È'4Q! D%%D ^È'4Q! D%%D ^!SO7GS  €ýÞh88V„SO7GS  €ýÞh88V„SO7GS  €ýÞh88Vdÿ Æÿ47632&#"#"'732æ'4Q! D%%D ^!SO7GS  €ýÞh88V£½Þ/747632#"'&%47632#"'&47632#"'&£$ ($ (˜$ ($ 'Ì$ ($ (A($ ($ ($ ("l($ ($ Ë3'&'&'676767ì%9P$p2)&B/T m73  ' !% ">K ü¶3#"/&#"#676323276Ç59'*b5T u,›U ?#ƒ E1 ÿçæ'&'&'676767''ì%9P$p2)&B/T m7q2þò33  ' !% ">Àþ_"è« ''7'7¶1’“2“’2“’1’«2’“2“’1“’1‘2Ø !5#5#5þ&hhhFF§hhphh5ÿÌG6/%#"'#7&#"'6327'&#"'63273327#"'327G‡4MG6RF%()|!%?F%()|.FG6Q G(‡#%CGß”3²ÍP„ ](P„,±Ìb”]*b ÿçæ7#537#5!73#3!'}¤9ÝL2;Ä9ýþÜL3oFfF…iFfFˆ-ÿõ %!55% þéþvŠ8CC3EÏO¡¤O-ÿõ %!55-5þéþŠþv8CCxEÏO¡¤O+ÿñÝ£ 533##5#53327654/&#"4767232"#"'&'4i6ßß6ÝÝþ÷XUw{VSXM`{V95aa‹Œddaa‹ŒddAÜ6ßß6{VSXUw{V9XM`Œddaa‹Œddaa‹+ÿñÝ£-!5!327654/&#"4767232"#"'&'4~þòýâXUw{VSXM`{V95aa‹Œddaa‹Œdd/6{VSXUw{V9XM`Œddaa‹Œddaa‹+ÿïÝ¡ #577''7!4767232"#"'&'47327654/&#"Á'œœ'œœ'œœ'œþÎaa‹Œddaa‹Œdd5XUw{VSXM`{V9ä'œ&œœ&œ'œŒddaa‹Œddaa‹{VSXUw{V9XMŒ¢%!5!3Œýƒ#7777ký•'ÿè Ï, 327654 &#"#"''7&54767632ŠþJVt\[ýÙ·Wq\?‚$[\ed‘ ‹fa%aYed‘ ˆh*þFJ\[uþ÷I\ Siqâ#[gŒ“kh[b%bf‰“khYÎè # ÀÀ>ÀÀ   ¡èþŒþŒttýT88þÈ7ò¶#"'&5476323#54'&8@ 86 ‰T‰&÷þ\2 '2 -7mC”88mfWX/ &/&f–C+ !$D&/MM3 .U,Pe62#"'&5476"327654'&¶6.7/- (- (6/ 8/9(. )0 ˜ª@^7676'&74767676%676'&76767676É %!P M *HþÀ$Y V! .W#5 2R±*:w* Jµ>”R,2 0N®!=y.  MÀ;”Fa#¿'%67#&7676737'&/&' YVÞO~m>G" Þ 73noP  !"B$)Zâ~«™sŠ›:] <*+ «sN2b0*:c|l/%676765&'&'&#"&'&'&54767636ôyjc^]xzjd[Zwˆvoea…#"‡zq ec„)¯YSkl]]WSjka_2b[x |mj`Yw%$zmj ÏXà 6 '&'&7&76îþê  þÞ /"  þjþe  ž Mþä &7676/&767¨þÆ ? þ²   õ£  þW þS! XÏè 3#3#2¼¼2¼22»»2»èþ þ ôôþ þ ôè 3#3#^¼2¼¼2‰2»»2»ôôþ þ èþ þ ô·ÿ÷¦ñ!2#!#"'&5&547632Z)!þ®  Ü ü¡)! g  ¾ÿ÷/ñ%47632#"'#"'&54763Î   Ü+ X^+ " üš   ¼2¶è %335#'3##Õ2–Èú–dKR2dü®2,¶ 73##533KÈ2––d„ü®KdRüJ¼¶è 3#¼ú] X úèÄr~=;f­2,è3#67676'&'&'&2úúT  \èü©Oz‚>=sŪÿûöù&&76?6'&/#"'&5'67½ æ ÖÌ ° ¿#Ù Êþ5Ì ± Åÿööí'%'&7676632"''&'&767š­  ˜  ¦  Ö)¡  ! þ !… ±BE Y67&&'376"#?23076767'67676'&'&''"#&'&'&767674È 5?24 8H  4‰A 1ly9QI 27&.C&j9r# +]O6TG:D/$2°EB>\ ÇeE3L!&xA“ X+?4)N#:Ae:.@"?$ .F/ T& P5 T\,"0„Zu¥[67&&'376#?27676767'67676'&'&'"5'"#&'&'&767674¼HJAH 5" Q !@'‰š @Dx" \Z ;7/7&I!+tF|*  #6zQ ?^O= F&9(=RZTnì{S?,$9-!E: *'V3 B~B&,2çM M`L/Kp“M[ž¥¦I%7'6'&'&'&%67&'&'&76‘3NAMþF?//*9-.E?/~(d< F‰Ž:9e¡¯SXRIL O%"h¯ó>"0'676'6767676'&'&'"'7767'&'&vKaFQ/=q6ph4H  0$"B%M$-Os/1µ=' )7WgN$$? "/B)" )ö9' A ÍV:†#1'676'676767676'&'&#&7767'&'&á€]pR[5Aw Cƒw6U%   8•*(T U05h …<:>+ /9]oW,(>%"7L0)1 :- A  †1#1;776767627#/&'&76'"''&?&'&Û ˆ6+A =Í/"  4= A Q"&|1« ß;% A P0b¤+5776767627#"'&76'''&7&'&° …KR¨ þÃC)( F3Ž ”8t 3 JÂ+ç;1]/@’šG7r@=þ¸(  ; G@B]1 ,1ù :+ A ˆ(eðe7&'7676'&7&'767676'&'&773767676'&'&'&'&'&767674˜<130Iþ®q ,-3y h>A2t |:¨q `' >AnO  ?  )!#7  ?M˜ B*06!.6rQ9;)C'þé7S ,WæAc=@]?)V<JYIO,'J33 ?5. w)8  !5K K35U<šn i7&'&7676'&5&'737676'&'&7"7767676'&'&'&'&'&76767&´F $-2-þP‚% 46E† †?@F ‹LÃ…i.CEsY$ ?1'&> HZ˜3- H19<". <‡º:%:)8þÚ@X 3a @¾†5@f8H PaRV 0+R=   G("=& *‘+ < $=L U<,wy‹ŽJ7'7&'&%'&'7767676/7767676'&'&'&'&'676s-Z" *.4Ÿ \$#&þh>Us? ApC@ &$.A!@' D11 p+7^/¤/Y.C—7#@p9= @ Z•˜K@ [T '8&G™O/ºÄ*C"šElY]ç° )g7&'7&''7'7&'&'&'&'7767676''7767676'&'&'&'&'676Y< ; w: = Æ.d).04®Š(&'iþ±FL&!kG@0$ Q( !D *#1E/I"F( K6 , u37d"5ö9!:%" /`= I8'?|??eL @ T²¦RGa¨\ *,7)J¦V4ÆÍ1Q#£Lw–h¤H'77&'7676767&767'&'&547676&''&'7767&ÓMº¢I >$6l‡F&P¬ŸA0^£T61K6.28Iwµ!<¯[UKW?NMCTZf"$*&‚»47ày-¤ A 9v€;" >* =33>/3S;' (!!%&-?0,6>>90 )- @ Jzÿñ¸Çc7&'7&''&'77&'7676767&"767'&'&5&767676&''&'7767&)=< x8 < þ²]’²P%?!F “M+_´ŸW/n­]=7P<41:RÀ&E·_`U^CS1E]ds%(8'É9<ì„3‚9 "!:""nA <„}P,>. E96?/3b<+,&#%) . ?2/8C5/ 1 7. @Tó;– $&'&/&'&7676767676-8f=Y TM/žEO!>" Fk  ²Mc C >¢.¢9@" +?# O¼át 97&'7&'&/&'&7676767676æ< ; w: = ž8h:*` OS¨/©ST%D$ Gmç9!:%" 2!¶J3k@C­.¯DD! !%-E% Q½u5¥b"/'&'77675367'676767&'&76Èi© ¬M"A)_d8 1‚N1 'ýÑ@%-@0!]@õ >! Š„2/# D/>0&8§z ÜrlÔâxuÆ YÇ3D7&'/77675&'&'67'676767&&'&5&768=< ‡t´8 ¹X$"A) < +kfD 5‰Aœ5 +ý£A(0@/%d9 "!ä@Ö#" X "=#—Ž6B,I2=4)>°ž ètâ! Þnâœy2F ?'&'&'&77767'&½=!~'#zÑý¯;0[ v œ³,0¤RF–Q+ @ 52T%¸@ A ƒ]lj+57&'7&'767'&'&'&7677'&8=< x8 < ýw<% Š)'‹Óþñ½A4`$k †EP³²XCP9 "!:""þœ_/ A# 77[±A A Œ>…9'&'7723&'767&'&767'&'&'&'&7676&þs& ¿r@FD$^:'’L?7I7@ ,9K^Œ!ŽN1/WCRm<@PV##4Ž @Fh u9 *>* ]lA6G 2=* (!?$ .9DZK) GrìáO7&'7&''&'7327&'767&&'&767'&'&'&7676&^> ; v;= þ¹¡&- ¸K,'A[žJ$]d'œSF=M?9=@Pf•&“K=9bDWmDI[c&&H¨9 !!:#" ´ @Ey vI+?.blr5L 74-**+# @# 0 ; v;= þïA !WidCV5R.(+tk4& 9 !!:#" Äð†­#S-I%5$v %u-(?& V T£z€6r„ B&'76'&'7727'7167'&'776767'&'&7676'a;B2" ¿!,òp A Z¶ ¯j W C|%ƒ1 < FZ:#1!;a9.¥>2 @ÎÌ@ 2*6†<% A !_/ %7K.!9mbÈ"[7&'7&'&'76'&'7763'767/77676767'&'&76764ò<< v: < ÃlA E9& šÙ* @SÖ Æk ] G‡0Š7 @#K]@&3 $?dC39"! :!" þiE 6"3@á”K"@"¯.9B' A #`0 )8O4$;#_p]UE'616763&532'"#/&'776'&'"%67'&'&'&'&'4'&76ñ‰ “A¬œA6j” *,FO¤«B0ŒP4% 7AE˜A’F|:ˆAX3 D <p»-!?5A '"Q^‡?TÛr^7&'7&'"#'76763&7452&#'&'&'73276'&'&7'&'&'&'&5&74L=< x8 < ý›”¡A±·@XWp8  + . "F_& ˆ24(‚GÖÌX”8(  #9 "!:""…@M¤œKƒIG@l8H  <*Š rO7)E& @ 1'VV•R)wa-77676&'&'&767676?'%'#'& ‘MG˜þ.ä..åR '£.n'* GÞþÔÄPƒ@?õA53: AI?+*B,3J7 1?î1¦| E7&'7&'%77676&'&'&76767'##'''< ; w: = ýû ¤LZ˜ýùô=34æ_—+  +õª5w+$:®.$‹þèù1U‹-9!:%" \A?þï$A"*B+3I>@)-J=I#V1 ,> (Lfr!<772367/&'&''623&'&%&'7676767'676Š?^F— žGE+"(d kC@„ƒ83þ—1_f/ A 3jwI (l7q,(# TA  "S @)>(LAAœ>#z]v±)#±tj+ƒ‘*8U7&'7&'772367'&'&''63&'&%&'736767#'67676Ô<< v: < þÃ?#gL£ ªLL-)*i €:JŽ=:^ þèGXƒ! A Of~D"*s8r) ?9"! :!" þ, WA %X'A->, b@]uhc>$…f~º2#µa$"Y~6f˜<&'7676?#6'&'7767676'&'&'&'76G>‹ {KAbÓ¼I'&O¿s6/L77 ‹(-ƒ·<ªW<6_;,AiL +A '?8>*‡‚…Æ&776?6"'676767676'&'&'‡¢U WA[90~!f¯-§L& a(<,06kcd²QA " XJLtU0 A .IAG5jg¶;7&'7&'776?6'676767676'&'&'3=< x8 < ý?¸Z ›]E`=4… %n¾,µV'"e-?07:qpk¾}9 "!:""ÃA%#]OSz[4 A 0L%$EM<UZþ5$%&'&'&76767;– ë^O!)*“/Œ8G%:Eeþ÷¦A@<4+8DV( <' ?!6Ro8/s.a6®17&'7&'%5$%&'&'&76767<< v: < ýUN¾ öe_%-,š"8”;O)= I‡þÎ9"! :!" @@?52?L]/ A) ? $:Ww<3|8¹O€"677'&'&'&76767&7457ÚFÐ þÿfZ#'  %–_ðïi«:, 7‚"AE-?91*6;?: A MDZ'#S7‚ÅÍ¢0¡ 97&'7&'67%'&#&'&'&76767&7453> ; v;= þÙPß þïpd'+  )£hþùfµ?/ =Œ%Aþ9 !!:#" _1@<4.<@F@ A OHa*%\9×ã:U“AZ%&'&767&'7&&''&'&'&76764'&7676%"'73676767'6766`1)J#lYq73N R,@ ?o o%42Ea8=o !þ±%j^9 @ 3`„W&zB8g<³%  &«A !A ,r_A8?D8== (! nl5&_ A IBR0 6x o**ˆ?. %9d™B682+? "; > * UlB(_ €B*)t'  "V><kMY»_%&'&76767767676&''&'&'&76766'&'&/&#5'6?5'76( D% "'2þA&)R$d‘f Z'*% :$D-I8.? G‹ ! ; 1R&'UaA.d6´ Jf D7)ú! #  ù‘„:‰ ?_ t|‡&6,C86-'KTa\"7hµµ 6~$C\ AUm¥'7'&'&76767676'67676'&'&'&3676 0f/3?6 > -wZh”…d0<"=”a—:(30sJ|]3 & _Ùþ‹ CCev{T@C2Tj|;/U4>.' Fa7+S* d7: 'Cg©¿h @:  Z5†$O ![F=3'PpM^! ýé@)A<9!ý¼K  & ð 6h @ CˆF#9% @ ‡p:8T71/ 6C J% €‹2 ø‡‡Ý"!„†_N€5gs"327654'&'2#"'&5476&"#767676'&'77676767&''&'&76767676&7476J    ) %) %‰S4 8[ ?g©¿h @`Z5†$O ![F=3'PpM^! ýé@)AN    $)$+ýzK  & ¥ @ Cˆ¾@ ‡p:8T71/ 6C J% €‹2 ø‡‡Ý"!„†r/¢;/'677676764'7&''&'&'&76767¢“ Œ;%B#d_Cc*#@Xd8F:"1†J\u6H=D’aàA=ŒQ34€X/(’1 õŸ!u{¬}¼7D[£&)„” U ÑkD7&'&''&'&7676767#'277676764'77&'B=< TCg9\3%5{‚c1LAFž|‚‡Æ’>/G$jjLj/&@ 8 < 29 "!3²¨!uȈË;.=a¯)-ˆ£A=‘S>>‰^"3!+œ ’) '" U ÃSO"327654'&&''&'&7676767#'277676764'7&7672#"h   C,h9\3%5{‚c1LAFž|‚‡Æ’>/G$jjLj/&@,")%%    Tu¯!uȈË;.=a¯)-ˆ£A=‘S>>‰^"3!+œ ’) t/ $) @Y­s 7?7&'&%'6767'&'&'772767676'&'&7&'&ª*J(L7M!þ&8:&(\T!&”0,Q9-6+T%M*0 +t0^z$X&.Ó1A.x"w&( f(&09, $,@rWL*  <57 (+<?v+nJ7; (;Î+LT7&'7&'7&'&%'6767/&'776767676'&'&7&'&À<< v: <  +O-P6N*#þ9>%)a\$) 0ˆ4V ;/;"'b%U,4"! $/}0e…$[-&½9"! :!" ’1F!4#{0'"!j)'390#&,”I}\R, C6< +1D C•+vQ7<& ;Î *7X`"327654'&'2#"'&54767&'&%'6767/&'776767676'&'&7&'&Ú    *$*$+O-P6N*#þ9>%)a\$) 0ˆ4V ;/;"'b%U,4"! $/}0e…$[-&µ   %)%)û1F!4#{0'"!j)'390#&,”I}\R, C6< +1D C•+vQ7<& L´¢Ò'7676&'&/&'&{/b:JRHV`Rœ*™HxC$ <®,lE<hx`ƒ 1NŒI   G+œÃ> 97&'7&''6767676&'&/&'&¹< ; w: = ý¶0_ =?@K[kX¤ *¡LI( "C$9!:%" þü,gE) m„g‹1ˆQ—P  O*+œÃB"327654'&'2#"'&5476'6767676&'&/&'&Ò    ) %) %ýš0_ =?@K[kX¤ *¡LI( "C$þ    $)$+þ”,gE) m„g‹1ˆQ—P  O*{l¢hIS%&#767676'&'776767&''&'&747676&'/776%76 ~L13T :]„‚IO˜ V5r:@€"l4 UB8/%T uDQ!^²ÃVþ@&Aý;  # 2 @?Æ >$ Se"P7B. :FK  0ŒA†— ït{þý‚v_NÓ„ co7&'&#767676'&'776767&/767&''&'&5&7676'45'7727274%76E< ; ¿ˆU58[ > e! OOª 0J./ ):  K :—"‚.![F=3'N|JZ!#gÒÊT ýê@)Aâ9!þ B &c A @ ”G :&?% n]7N!0 4B O Á @Fð ø‡‡Ý"!„†_NÄ„!fr"327654'&#767676'&'776767&'476367&''&'&5&7676'45'7727274%76\   ½ˆU58[ > e! OOª 0J8#&( K :—"‚.![F=3'N|JZ!#gÒÊT ýê@)AÑ    þB &c A @ ”G'+'$!?% n]7N!0 4B O Á @Fð ø‡‡Ý"!„†X;#©X%&7676763&67&''&'&'&7676'5'&'&765?3567'6Ìrk" 9UI Af¶ Åe]ƒ  E\·"›X"\B>+$;  0X{1/x;:@^$KêÕç*  ( *wngAli @y%&p8`(= &3%%µ%!E %˜ @m=˜GF306367676767'&'776767&''6767&''&'&7676tj<  R0"'Bhwki"3J&e¡A `991|& kS«h1#/U/ $I FO"M^¼ A  5Ô] 25s‡4 $=5(NH 8??`8f 1' #=ˆN5¨– e7&'&&'&'6'77634'76776767676'7#'&'&767'&#&'&'&7676766ï"=$;ýÑ  (?4{g;A:xF %)z¡58@$¹d~10#R+/#%¢7#H>É$!! =AUl^^ &>* ˆ\-R!) :A X!h7d  >43 <$%`‰“XI6767&'7676&'76?6'6767676'&'&''&'&'&76J<0T L&T 3M @Yi$?X=44A>:1 -}/55'81$8E,,5-r TLT(Ÿþó\e?KCS/ ƒ$† b3,‡q5$;ayT6F A4cO4S¸cB*)t'  $T£}#‰?O‹H676727'7676765&'&'7'&'&'&'&747&'7767&'&'7hA5c v4!E‚ IH a58_†%w=!=4*E$"-3;PjCw<¨ c8hçã,+E0L. 27CWH'0=.5+)3. #*/#!;›þˤ’yô I%765&'&''&74567676767&'7'&''67&'&'&'76'&]v<(G$0 .P=6 A(?2%?X’AC1QKNb6}!h-?1 ;)!BÒN3Iy4‘b]LcKÃ*¾e\Ä™nOi$8U3l%&sJ- :H7?(%a TVÏ%`°sP%76767654'&'&'&''&76767676767'7'&'6'67&'&'76'&e80O6%;'´gF< B-@31HX &,@ N:X Q Yo:‚!‚1U@ :."0Nö .b]I¯}c‹{WÖ!:èq\¼È…14šZn/ gi#7x-.~T3 >O7P-(€[)gï/Š1$:%&7676'4'&767767'&'&''&'&767676Ë[K23F;A`d# rR“)†CONX!Pi>Eí'  ( +&M—ø*6x^?! o*s 3j'Z*( HJz4W‰'1676/7767676'&'&'&'67&'&ÉA v:vomF(D$4[¦h¤J/"? D,/_:^9>_}>:pc;5´¾wZ BC&1`f5$?A  ,P6'5"M)P$ÜAA5;0  .+œ/67676'6767676'&'&'&76Q>9 rt4*.* & .WVA*0!9Y$*YÈ'ŸVj&@ ;þ­ / %M25fJ% 8?& T"_  ". C-(65f6šMYÙM7457767676767'"'&'&76'4'&'&#'?5'76 A&)R€jVF H  @ (.3 6"+g¢A’6—2Jf D7)À 0‘„:‰3|7, E=“ƒ' k [!&E3‡ˆ19 5¥©©¢&V\ A£"wf,77676'6767676'&'&'&''&5€+1 þǤ}_4XO•%;L :"&oÛ<^(ŸVj&@ ;þÊMJ)/ZV8) ?& 6B1- o64›‚EV<767676'67676'&'&&5'6?5'762A )E8icN'B #‡#i¦8$ (H "UeA7?7¡AR :0!‡yJ#;s +*' 8`;3Z8"=7+ 7I)# "cbÆšL=M% H AMY‡877676'67676'&'&#'6?5'76A&)RXipY,!I'”-|¹C/1T'(ayA%m6´ Jf D7)ð‘„:‰%G*- ?kE;d?(><1")@S4* 'v«®($C\ A8O¥i _%&7667676?'676'&'&'&767676654/&'&'&'&'&7676þgE 1V(þ§”I8   V!?X­¤¼+]WJ.&h,X fdI]Qj 6EBg,.26=$)$!aÅD  y0J?J)5ÂI|¤" A 28ª (b27r[C !7CB EHX:  ay8"0'1NJ,%jk±Ž 0~%7&'&%67'&'&767676'&'&66''67/7327676'&'676767'&'&'&'&'&'67&'&76ç$G#:$þW;   fQH$3 _[B)-!Î%J'¶ÀTh6z:+{º‹ns]6.Di—5 K2, >+H:,%'#<4g#ˆX ÷6.""HF¢6  !  '># #9  46(Y&5Á† A ?€w0 $*=T4K2   . 71<% ** 18pP.4”+wªS&'767767"'67667/&'2&'&'&'&7676767&'676>3d n:!@!g³' Ç\)()-9US2 \”•Q ApE mCÆÀQ€+'˜&X¡ .{+ˆAL—“F@^B (?(;dk"&9! (@5 .9GC i0¨XLKŽš57676767'&'&'&7&'"'76763676B #5Q1O1 U=P !:O³3¸[;h;Q—?,#  h…'' "_*]& 6ž#=G"2C½(žfÕ©þó 7!IÿûÛ´7&'7&'L<< v: < {9"! :!" ÿÿÿûÛ´ÝÏ,–67"#'%3''67676'457w>þ;ú6C1._ &$d%)b" "Aè*CAAJ"#!•PIP3M.D£¢?H$6767#52%''67676'&57OþxÆÙ°N,5m,*r(i%(A51VAAV$(/²^T\ 3T,SÀ5¨M¼Ñ'67676767#ÉR¬§FOo 5i8 A˜>N;M3 A™ '9 þ}vb×G'67676767#Ç]¼ºQZx 5q>AêHW ;V8I¥&œBþ?©*53!'67676767!#µA4>C›<ž>$<þ A`¯¯° ŠKQ9 =6)H» Äz#U’53!'67676767!#°Ad CJ¦s¶J+Gý¯AÂÐÐÃ9‘QY@(>=2!W×'ç(Œ£N  #5!#!!5!½ÝêPý>1_AAþ…AASÊ„ !5!!!!5!ºþúZþí‰üÏgËAAþ@AA„N46"#'%23&'7723#"/7767676'&'&''67676ÍþìD  AãÞ   =.P G   V?;„'‚6>ABrºA…oJ6 ?3 d„˜IEg 3f;HMhf˜3"5%'7%23"#/7767676'&'&''67676Ðtæ—A þû  H2XW#' fII™ (™DEzAÖÜAºeR>? "A u§·UUu3vLQˆwŒ/46'45723'77676767'"#'676†D‡‹EA$   #6$A>å ",{+/o*UiAHd˜JþMm, )=wi—qSnƒ,.rФo4ƒ'7'77%'%vºµ\:_ÇÃSþð‘:“þàuK…;„k9V%'67676767%3'67676767‹ 1s(s, .,? >,R?%)dÉ!?ÀO>+YW ©>1HY3X8 E¡ <@É^7+e^;V5(-\ÉMê‡:7&'7&''67676767%'67676767[<< v: < þ9$4v (u-2/? p,WA*/gÍ#UÑ\>,c_ N9"! :!" :C7L]3Z4Kª H@Õd@1ia&<\?*.gÝiJz"!'67676765!#'6767676Mþî(n 1v(@&ó" .q1&o*0oH~ +ˆH >‡ {DA¾\#QU$5Q0RÄK*â™ 87&'7&'!'676767!!'6767676T< ; w: = éþÔ.x 1‚,!@Xþö"2z#&v-6Z9!:%" ˆP‰ *•R F• ‰IAÊa*#W\ 4W4^Ù»£ûñ5!!5!Â9ýÀÿ°Aý²AÌ¢ŠØ–7&'7&'5!!5!J> ; v;= ývdý”+]9 !!:#" EAýˆAö™3\^#53533673#'676767##K²²AùA•™5/v,,p--õASAÉÉA‰¨!A¸pcm(0e@ ]¯ì}‘47&'7&'#5353!673#'676767!#3<< v: < þ ÃÃA@¥©81{&,t02þòAX9"! :!" ¢AÜÜH•{aAÊwgt#1gC&'i¼þÿŠQž.%%'676767677&'&7&'&ÆV/$_j9d<36dÅÊ]).F)G@$+&E>84 Q>C2Pº8 µNA.SHeA ;2> /52!!a"U"m2¾i&2<7&'7&''676767677&'&7&'&Ê<< v: < þHÊT@/fp$9h<:?mÒÖb+1L)E)$'M%>87$09"! :!" ý[=F-"(VÂ#B½QM4[L „@ ?3:M59 (e!Z'R^^$'67676767'%23&'&'&É`¼0#·Qb’þض&zP?5Cªž?4he| 6yIhÚA@ÓbR+5I4U«M4œH9`,X69t{nB;(FA0$NVš ‰E2&'6767676%7&'&ó?:'#,KH%›A'L? ý§-C".;,%Ù[S=hq26kA'(jâ"/?)0ea)%n$ÝÜ%/7&'7&''6767676%7&'&O> ; v;= /?>,%/N¤V%¢E/"SD ýv,G!"4;3£9 !!:#" èfXBmv=6pC./tò(/A/.sm(!s=™)'67676767%'6767&'&'767k. +a&/2?',`F#%Z´G!¥?W6H."SW)0P;M‡Ãw{2S3 I² ‚ @åm5*gn+7f2FN2?7`·VÿùÝÙ E7&'7&''676767676%'6767&'&'767O< ; w: = þ#.j*d& 15>‘",cG*.]¹@"¹TP5soa*4X?Wþp 9!:%" s4.IZ2W1L· U<?îpC5lr&7oGDMS@=eÏ qVf¬"!5!6'&''6767!!'67676Äþ­W[Ô Êag²—M \þ¡ &,u*&o)ôA@P "@ N`_)8\=!iî'JkŒ‡ ,]pgN#ìù%-57&'7&''6767676%7&%7&'&^= ; v;= >D,.:O¡S"¡E,!XMþ€< A þ‡0e1:(Á8 !!:#" >ébiIce28`;')o÷,]J#)t’ ,fwQZ3xD!5!!'67676'45!Ëþþ”  c 1g óöAAc:% Uu +vB=fAA9ï‡*.7&'7&'!5!!'67676'&5!`<< v: < þ}þo_þt  g 2m# þøN9"! :!" íAAl>(#Zz $*}ECl.AAyd‚#37&'&'&ºAAy;?f.c03/þ5þß)$'f.a  rD4¢&7&'7&'#37&'&'&z=< x8 < ¿AAƒ@Al .h609 "!:""}þ ^þÀ,')j /h$v7jj#5276'7%23"#'67676ÌräèsAB þº 'l 0e& ÿA]ËÖTAuMdy ,p?!"Ecµ‹î75!5!c(ýE2µAAøAAl6-ÿ67!5!&''6767"'&/7-?Sþ%i@Fy 1}F.!b½>!×m/&G•«ßUŠAA¯V9‰+87 ar%8|f-/-->02`ˆ¿ %7&'&'676767!5!&'&'#uD !;2HR ;sîÙej›þhã‚+Y@Cw*lFB…AAp"&&(e2]+$1þƒ¸•§P'6767676h?"!$F¡H#¦C0@)P ÄXF6hn/7l?,.aÌNÄ~µ7&%'6767635¹]:jþC@&e/f#!&þÖçÒ A Lk-k=A.­µp 07&'7&'7&'&%'6767674'< ; w: = Ù6Âj;C13þT@#(i/n'$79!:%" C&þõîTW  ŸLNq-tEF›.­©1 (:"327654'&'2#"'&54767&'&%'6767674c    )%)%þè6Âj;C13þT@#(i/n'$    $) %*”&þõîTW  ŸLNq-tEF›‡?%67'&'&'&5536767É8j#%9ÿg_AX"A…S]ÀÈ]_Ö–\ "@=*VÑùNþõhqJa"@žN_ÖÓie?9"! :!" þðt1[+%@ ?.\ ö]´VþõhqJa"@žN_ÖÓie?    $)$+þt1[+%@ ?.\ ö]´V ; v;= ýÉ4u7." ( w*u'þ·}'1 09 !!:#" þ¶&;. )È![3þE  1LðÄ@ 9"327654'&'2#"'&5476'67676$'&'&¼    *$*$ýÖ4u7." ( w*u'þ·}'1 0(   %)%)þ"&;. )È![3þE  1I‰^b $7&'&%'676767!5!53!!#S;3"#X-[($þs? !V,XÒþÔ,A1þÏAçt02T/W92†y47O 0O.-ûA­­Aþ(l¥!,87&'7&'7&'&'&%'676!5!53!!#ÿ> ; v;= Œ;4("`,c+'9þŽ> '"Y,a# âþ¸HALþ´Al9 !!:#" þÒx91^.]=6‚ „@:Q1V86 A¾¾Aýì(ly -8D"327654'&'2#"'&54767&'&'&%'676!5!53!!#     *$*$;4("`,c+'9þŽ> '"Y,a# âþ¸HALþ´Ax   %)%)þWx91^.]=6‚ „@:Q1V86 A¾¾Aýì‹ÂI$6767!5!&'&'7Ý|92<ý‹–(K;9|5L0t;.t&d£RA9tAA“EAU4S,~4(U5GÛP26%7'6&'&'&7&'&7&'&á´^ mµ ®UXŸ `n@E|rD6•DE~xA@®A P;K4A 7;4A;;9‡›‡$7'67676767&'7''ºq(*3?4,)[ùÍ0E0m5Uþúþ˜å¯ZaÍÑh] 7:L,œš'sG)A®^áˆ&'767&''676á@š•@ADn-b::'C)€)`ô(A( '7'7%'6767X®£`;d|1$#"T/c* þ»Ä;è0?-ÌÖi5g85V-bWYþ_dRU‹'7'7%'6767BÍÂq;v½2-&+]/p1 þzä:C9?6ñû{5}5P2P@I¦A»A  U*N,#ýÀ;.'a)c05C,7ÑVP8BK1E+ [ñ²‡O63676767'²A·[a˜ +‘L('kÅA6ý“+/2„0€26,3¾Æ3ú !#!#5òþ AuAIpþAB4ýÐ>·3(ˆ#!'67676767øAq 7B¥}¹H+5 GĤKZA.=B2!H²‹HRñ#!'67676767ÌAÇ =I´*rÇPA"=°ç(´.ScJ)=G2)/SÀ)]W‘ #3#5!533#!!#!53½½þJHAÀÀ3þÍAþ@´þëA««AþëAþùAo§zÜ%3!!55!'67¾A{üõmhŽ =èþáAA³AAvH8F@ÐGJõ67!5!'6767!5ÙýÉG3.+%P¯h©Dv0þ4rAAÁZ;.aW1;N0TyA¹g”7'676767677&'&Õ×^B-\U F.D_Û´-7&'7&'53!'67676767!#L<< v: < þuA€ "IO³}½O4 L!ý{A{9"! :!" RääÌ9¢Z`C,=@4!'\ß&5ü=¶]â ,H7&5723'77676767'#'6768ru:Aþ 2 94  Á *s(/b"H A€?å?`%$= eG‘_Hcy*-e1g›5Lû!#'676767!#'6767676<å#d1i ?ÖÏ  (c*'h' , %VJ')±þ'!=$––RM 4±&X#!5!ÆWý·ó ýô LL?4X#&'&'&/&'"'!5!34W  &9 þ ûS2#! ý Wzþ†t7 L 2Bþwþ‰9þX-)5!6767676767075&'&'&'&'!5!Ýþ\žN    "jþb¤_7 ()  "5¬L   .Ž6 'L  4= œE/E%í%#4767676767475!53!÷W %q. ýaWŸ8N:(VVr72@ 9Há•™E3."-?6X )!2&'&'&'!5ý ÓUT'3W) 9Gþ„X*?5 þÕ+3' þ@%éX#&'&'&/&'"'!5!éW  &9 þ>ÉT2#! zþ†t7 L 2B#uX.6+532767676=#5!#&'&'&'&'&/  % AT2)<ý›0! W  &;  þÔ?+L,)LH2@þ†t8 2ÅÚ!5353þÏF FFÏÏ;ÑÇ:>72;7676767453#&'&'&'&7336767676=3'3#— =$/R' 6!W^ @GRG?C-$Wc' W 3RˆGGà52  4&(Rþ®fT#?:>RþÔ  ÏÏ+#3çG;ÑÇ:>72;7676767453#&'&'&'&7336767676=3'3#— =$/R' 6!W^ @GRG?C-$Wc' W 3R±GGà52  4&(Rþ®fT#?:>RþÔ  ÏÏ+#3çG;ÑÇ:>B72;7676767453#&'&'&'&7336767676=3'73#3#— =$/R' 6!W^ @GRG?C-$Wc' W 3RÃGGÅGGà52  4&(Rþ®fT#?:>RþÔ  ÏÏ+#3GG;ÑÇ:>B72;7676767453#&'&'&'&7336767676=3'73#3#— =$/R' 6!W^ @GRG?C-$Wc' W 3RÃGGþŒGGà52  4&(Rþ®fT#?:>RþÔ  ÏÏ+#3GG:ÿ}FX#'#5&76767'367676753#3#ü0 W9 &”fä/ W: &”fþ¼¼E > %TPÒþ» =$––QM Ò %TPÒþ» =$––QM ÒƒuuGG:FX#'#5&76767'367676753#%3#ü0 W9 &”fä/ W: &”fþøGGE > %TPÒþ» =$––QM ÒÃG:6X%&'&'&'&'#533!53#• "j‹‘^1 () Jþ GGL'6 'L  4= þÒLL G±X%#73'&'&'&'&'&'4#3#B¯uÏQ > RWF"2X¿GG¬¬Ë§. L*R "þ…UG&X #!5!3#ÌWþ±ùþÇGG ýô LL·G?:X"#&'&'&/&'"'#5!33#:W  &9 ùS2#! þW€GGzþ†t7 L 2Bþwþ‰UGÇX333#pWµGGXý¨UG(X ##5!3#ÕWWþæGG ýô LL·G=:XDH"5632#"'&'&'&'336767674767475&'&'&/&'&3#: -*&HL$"  #MHIM!$ W  2 +#    3 2GG R+1AœG,!++!4@zþŒ8 "18·G ×X3'3#€WWtGGXþé#wG&ÿ8ÚX#&'&'&/&'"'#533#ÚW  &9 ²ºS2#! ûGGzý¾<7 L 2B,G9X-13#536767676767075&'&'&'&'#533#㪤N    "j¤ª_7 ()  "5¬GGL   .Ž6 'L  4= œE/EUG%!í 3##47676767675!53!âGG²W.þ[W¥.›G„*aEx1+$%)V 5á•™<9 $$0:X##532!534'&/&#3#Ö:X:NçM5U-þÖÓ#$8GG ýô L!A-;þ‰L+&%·G3FX)53&'&'&/&'43#Fþí¼  4 IMUìGGL(7L+.…%G=9XBF!"'&'&'4'!2'6767674767475&'&'&/&'"'#3#;IM!(@B $"  #MH+#    &9 £  2 GG+!:9z"1AœG,!+L "18 þØ8 G9ÿ8 X)-32#&'&'&/&'"'#3/&'&'&'%3#9×@? #! W  &9 yB"(G$+ÿGGX!2Bý¾<7 4 L$7 G?X9=3#53276767675&'&'&'"+3/&'&'4'5323#ôµ¯87 , ,;5 XB"(G%+µLB / $ #a GGL<Ž9* 4 L$: Ò5?œ&= !*›G3X 67676767670753!5!33#<.   W !"«þ&Fþ²dGGU *“š70" þóL þ½G>ÿ8&X%#5367677!5!#3#,>7h þoè 0þÏWÐGG!L*!2Lþ§G( IuýŽrUG%ïX#&'&'&/&'"'#533#ïW  &9 ÈÏT2#! þöGGzþ†t7 L 2B,G;ÑX:>72;7676767453#&'&'&'&7336767676=3'73#— =$/R' 6!W^ @GRG?C-$Wc' W 3RÃGGà52  4&(Rþ®fT#?:>RþÔ  ÏÏ+#3G#{X.26+532767676=#5!#&'&'&'&'&/3#  % AT2)<›0! W  &; GG þÔ?+L,)LH2@þ†t8 ·G>•Û333#>WOGGXý¨ÛG:6Û%&'&'&'&'#533!53#• "j‹‘^1 () JþnÈÈL'6 'L  4= þÒLLG9Û-13#536767676767075&'&'&'&'#533#㪤N    "j¤ª_7 ()  "5¬VÈÈL   .Ž6 'L  4= œE/EÛG?Û9=3#53276767675&'&'&'"+3/&'&'4'5323#ôµ¯87 , ,;5 XB"(G%+µLB / $ #aˆÈÈL<Ž9* 4 L$: Ò5?œ&= !*ÛGHFí5367676753#HWå/ W: &”fD©•þ» =$––QM Ò#ÿòòÁ!%)%5476767654'&'&#347632#3   7C„5 39/% 888þ˜hgé 3* N ˆ($+ ))" #;A{hgþ™"žZŠ ¥Jº,4J› Œ¶H‹Xú-\œ³% @€­ FD$Õ,T Z Š  ¥ Jº , 4J › Œ¶ H‹ Xú$$ †‘$H$TcCopyleft 2002, 2003 Free Software Foundation.Copyleft 2002, 2003 Free Software Foundation.FreeSansFreeSansMediumMediumFontForge 1.0 : Free Sans : 29-7-2004FontForge 1.0 : Free Sans : 29-7-2004Free SansFree SansVersion $Revision: 1.27 $ Version $Revision: 1.27 $ FreeSansFreeSansThe use of this font is granted subject to GNU General Public License.The use of this font is granted subject to GNU General Public License.http://www.gnu.org/copyleft/gpl.htmlhttp://www.gnu.org/copyleft/gpl.htmlThe quick brown fox jumps over the lazy dog.The quick brown fox jumps over the lazy dog.navadnoDovoljena je uporaba v skladu z licenco GNU General Public License.http://www.gnu.org/copyleft/gpl.html`erif bo za vajo spet kuhal doma e ~gance.ÿi2  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a¬£„…½–膎‹©¤ŠÚƒ“òó—ˆÃÞñžªõôö¢­ÉÇ®bcdËeÈÊÏÌÍÎéfÓÐѯgð‘ÖÔÕhëí‰jikmln oqprsutvwêxzy{}|¸¡~€ìîºýþ    ÿ øù !"#$%&'()*+ú×,-./0123456789:âã;<=>?@ABCDEFGHI°±JKLMNOPQRSûüäåTUVWXYZ[\]^_`abcdefghi»jklmæçnopqrstuvwxyz{|}¦~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ     ØáÛÜÝàÙß !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl›mnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëì²³¶·Äí´µÅï«Æðñòóôõö¾¿÷øù¼úûüýþÿ     Œ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`˜ab¨cdešf™ïgh¥i’jklmnœopqrstuvwx”•yz{|}¹~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOÀÁPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ softhyphenAmacronamacronAbreveabreveAogonekaogonek Ccircumflex ccircumflex Cdotaccent cdotaccentDcarondcaronDcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflex Gdotaccent gdotaccent Gcommaaccent gcommaaccent Hcircumflex hcircumflexHbarhbarItildeitildeImacronimacronIbreveibreveIogonekiogonekIJij Jcircumflex jcircumflex Kcommaaccent kcommaaccent kgreenlandicLacutelacute Lcommaaccent lcommaaccentLcaronlcaronLdotldotNacutenacute Ncommaaccent ncommaaccentNcaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautRacuteracute Rcommaaccent rcommaaccentRcaronrcaronSacutesacute Scircumflex scircumflexuni0162uni0163TcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflexZacutezacute Zdotaccent zdotaccentlongsuni0180uni0182uni0183uni0184uni0185uni0186uni0187uni0188uni0189uni018Buni018Cuni018Euni018Funi0190uni0191uni0193uni0199uni019Duni019Euni019Funi01A5uni01A7uni01A8uni01A9uni01ABuni01ADuni01AEuni01C4uni01C5uni01C6uni01C7uni01C8uni01C9uni01CAuni01CBuni01CCuni01CDuni01CEuni01CFuni01D0uni01D1uni01D2uni01D3uni01D4uni01D5uni01D6uni01D7uni01D8uni01D9uni01DAuni01DBuni01DCuni01DDuni01DEuni01DFuni01E0uni01E1uni01E2uni01E3Gcarongcaronuni01E8uni01E9uni01EAuni01EBuni01ECuni01EDuni01F0uni01F1uni01F2uni01F3uni01F4uni01F5uni01F8uni01F9 Aringacute aringacuteAEacuteaeacute Oslashacute oslashacuteuni0200uni0201uni0202uni0203uni0204uni0205uni0206uni0207uni0208uni0209uni020Auni020Buni020Cuni020Duni020Euni020Funi0210uni0211uni0212uni0213uni0214uni0215uni0216uni0217 Scommaaccent scommaaccent Tcommaaccent tcommaaccentuni021Euni021Funi0226uni0227uni0228uni0229uni022Auni022Buni022Cuni022Duni022Euni022Funi0230uni0231uni0232uni0233uni0250uni0251uni0252uni0253uni0254uni0256uni0257uni0258uni0259uni025Buni025Cuni0260uni0261uni0265uni0266uni0267uni0268uni0269uni026Auni026Duni026Funi0270uni0271uni0272uni0273uni0275uni0279uni027Auni027Buni027Cuni027Duni027Euni027Funi0282uni0283uni0284uni0285uni0287uni0288uni0289uni028Cuni028Duni028Euni0290uni029Cuni029Euni02A0uni02CAuni02CB gravecomb acutecombuni0302 tildecombuni0304uni0306uni0307uni0308uni030Auni030Buni030Cuni030Funi0311uni0312uni0313uni0314uni0326uni0327uni0328uni0374uni0375uni037Auni037Etonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammauni0394EpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsiuni03A9 IotadieresisUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronrhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonosuni0400 afii10023 afii10051 afii10052 afii10053 afii10054 afii10055 afii10056 afii10057 afii10058 afii10059 afii10060 afii10061uni040D afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097uni0450 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109uni045D afii10110 afii10193uni048Cuni048Duni048Euni048F afii10050 afii10098uni0492uni0493uni0494uni0495uni0496uni0497uni0498uni0499uni049Auni049Buni049Cuni049Duni049Euni049Funi04A0uni04A1uni04A2uni04A3uni04A4uni04A5uni04A6uni04A7uni04A8uni04A9uni04AAuni04ABuni04ACuni04ADuni04AEuni04AFuni04B0uni04B1uni04B2uni04B3uni04B4uni04B5uni04B6uni04B7uni04B8uni04B9uni04BAuni04BBuni04BCuni04BDuni04BEuni04BFuni04C0uni04C1uni04C2uni04C3uni04C4uni04C7uni04C8uni04CBuni04CCuni04D0uni04D1uni04D2uni04D3uni04D4uni04D5uni04D6uni04D7uni04D8 afii10846uni04DAuni04DBuni04DCuni04DDuni04DEuni04DFuni04E0uni04E1uni04E2uni04E3uni04E4uni04E5uni04E6uni04E7uni04E8uni04E9uni04EAuni04EBuni04ECuni04EDuni04EEuni04EFuni04F0uni04F1uni04F2uni04F3uni04F4uni04F5uni04F8uni04F9uni0531uni0532uni0533uni0534uni0535uni0536uni0537uni0538uni0539uni053Auni053Buni053Cuni053Duni053Euni053Funi0540uni0541uni0542uni0543uni0544uni0545uni0546uni0547uni0548uni0549uni054Auni054Buni054Cuni054Duni054Euni054Funi0550uni0551uni0552uni0553uni0554uni0555uni0556uni055Auni055Buni055Cuni055Duni055Euni0561uni0562uni0563uni0564uni0565uni0566uni0567uni0568uni0569uni056Auni056Buni056Cuni056Duni056Euni056Funi0570uni0571uni0572uni0573uni0574uni0575uni0576uni0577uni0578uni0579uni057Auni057Buni057Cuni057Duni057Euni057Funi0580uni0581uni0582uni0583uni0584uni0585uni0586uni0587uni0589uni058A afii57799 afii57801 afii57800 afii57802 afii57793 afii57794 afii57795 afii57798 afii57797 afii57806 afii57796 afii57807 afii57839 afii57645 afii57841 afii57842 afii57804 afii57803 afii57658uni05C4 afii57664 afii57665 afii57666 afii57667 afii57668 afii57669 afii57670 afii57671 afii57672 afii57673 afii57674 afii57675 afii57676 afii57677 afii57678 afii57679 afii57680 afii57681 afii57682 afii57683 afii57684 afii57685 afii57686 afii57687 afii57688 afii57689 afii57690uni0700uni0701uni0702uni0703uni0704uni0705uni0706uni0707uni0708uni0709uni070Auni070Buni070Cuni070Duni0710uni0711uni0712uni0713uni0714uni0715uni0716uni0717uni0718uni0719uni071Auni071Buni071Cuni071Duni071Euni071Funi0720uni0721uni0722uni0723uni0724uni0725uni0726uni0727uni0728uni0729uni072Auni072Buni072Cuni0730uni0731uni0732uni0733uni0734uni0735uni0736uni0737uni0738uni0739uni073Auni073Buni073Cuni073Duni073Euni073Funi0740uni0741uni0742uni0743uni0744uni0745uni0746uni0747uni0748uni0749uni074Auni0901uni0902uni0905uni0906uni0907uni0908uni0909uni090Auni090Buni090Duni0910uni0911uni0913uni0914uni0915uni0916uni0917uni0918uni0919uni091Auni091Buni091Cuni091Duni091Euni091Funi0920uni0921uni0922uni0923uni0924uni0925uni0926uni0927uni0928uni0929uni092Auni092Buni092Cuni092Duni092Euni092Funi0930uni0931uni0932uni0933uni0935uni0936uni0937uni0938uni0939uni093Cuni093Duni093Euni093Funi0940uni0941uni0942uni0943uni0945uni0947uni0948uni0949uni094Buni094Cuni094Duni0950uni0951uni0966uni0967uni0968uni0969uni096Auni096Buni096Cuni096Duni096Euni096Funi0970uni0981uni0982uni0983uni0985uni0986uni0987uni0988uni0989uni098Auni098Buni098Cuni098Funi0990uni0993uni0994uni0995uni0996uni0997uni0998uni0999uni099Auni099Buni099Cuni099Duni099Euni099Funi09A0uni09A1uni09A2uni00C1uni09A4uni09A5uni00C4uni09A7uni00C6uni00C8uni09ABuni09ACuni09ADuni09AEuni09AFuni09B0uni09B2uni00B6uni09B7uni09B8uni09B9uni09BCuni00DAuni09BFuni09C0uni09C1uni09C2uni09C3uni09C4uni09C7uni09C8uni09CBuni09CCuni09CDuni09D7uni09DCuni09DDuni09DFuni09E0uni09E1uni09E2uni09E3uni00F1uni00F2uni00F3uni00F4uni00F5uni00F6uni00F7uni00F8uni00F9uni00FAuni09F0uni09F1uni09F2uni09F3uni09F4uni09F5uni09F6uni09F7uni09F8uni09F9uni09FAuni0A05uni0A06uni0A07uni0A08uni0A09uni0A0Auni0A0Funi0A10uni0A13uni0A14uni0A15uni0A16uni0A17uni0A18uni0A19uni0A1Auni0A1Buni0A1Cuni0A1Duni0A1Euni0A1Funi0A20uni0A21uni0A22uni0A23uni0A24uni0A25uni0A26uni0A27uni0A28uni0A2Auni0A2Buni0A2Cuni0A2Duni0A2Euni0A2Funi0A30uni0A32uni0A33uni0A35uni0A36uni0A38uni0A39uni0A3Cuni0A3Euni0A3Funi0A40uni0A41uni0A42uni0A47uni0A48uni0A4Buni0A4Cuni0A4Duni0A59uni0A5Auni0A5Buni0A5Cuni0A5Euni0A66uni0A67uni0A68uni0A69uni0A6Auni0A6Buni0A6Cuni0A6Duni0A6Euni0A6Funi0A70uni0A72uni0A73uni0A74uni0A81uni0A82uni0A85uni0A86uni0A87uni0A88uni0A89uni0A8Auni0A8Buni0A95uni0A96uni0A97uni0A98uni0A99uni0A9Auni0A9Buni0A9Cuni0A9Duni0A9Euni0A9Funi0AA0uni0AA1uni0AA2uni0AA3uni0AA4uni0AA5uni0AA6uni0AA7uni0AA8uni0AAAuni0AABuni0AACuni0AADuni0AAEuni0AAFuni0AB0uni0AB2uni0AB3uni0AB5uni0AB6uni0AB7uni0AB8uni0AB9uni0ABDuni0ABEuni0ABFuni0AC0uni0AC1uni0AC2uni0AC3uni0AC7uni0AC8uni0ACBuni0ACCuni0AD0uni0AE6uni0AE7uni0AE8uni0AE9uni0AEAuni0AEBuni0AECuni0AEDuni0AEEuni0AEFuni0B02uni0B03uni0B05uni0B06uni0B07uni0B09uni0B0Buni0B0Funi0B13uni0B15uni0B16uni0B17uni0B18uni0B1Auni0B1Cuni0B1Duni0B1Funi0B20uni0B21uni0B2Auni0B2Buni0B2Funi0B30uni0B32uni0B33uni0B36uni0B37uni0B38uni0B39uni0B3Euni0B3Funi0B40uni0B41uni0B42uni0B43uni0B47uni0B60uni0B66uni0B67uni0B68uni0B69uni0B6Auni0B6Buni0B6Cuni0B6Duni0B6Euni0B6Funi0B82uni0B83uni0B85uni0B86uni0B87uni0B88uni0B89uni0B8Auni0B8Euni0B8Funi0B90uni0B92uni0B93uni0B94uni0B95uni0B99uni0B9Auni0B9Cuni0B9Euni0B9Funi0BA3uni0BA4uni0BA8uni0BA9uni0BAAuni0BAEuni0BAFuni0BB0uni0BB1uni0BB2uni0BB3uni0BB4uni0BB5uni0BB7uni0BB8uni0BB9uni0BBEuni0BBFuni0BC0uni0BC1uni0BC6uni0BC7uni0BC8uni0BCAuni0BCBuni0BCCuni0BCDuni0BD7uni0BDAuni0BDBuni0BDCuni0BDDuni0BE1uni0C83uni0C85uni0C86uni0C87uni0C88uni0C89uni0C8Auni0C8Euni0C8Funi0C90uni0C92uni0C93uni0C94uni0C95uni0C96uni0C97uni0C98uni0C99uni0C9Auni0C9Cuni0C9Euni0C9Funi0CA0uni0CA1uni0CA2uni0CA3uni0CA4uni0CA5uni0CA6uni0CA7uni0CA8uni0CB0uni0CB1uni0CB2uni0CB3uni0CE6uni0CE7uni0CE8uni0CE9uni0CEAuni0CEBuni0CECuni0CEDuni0CEEuni0CEFuni0D82uni0D83uni0D85uni0D89uni0D8Auni0D8Buni0D91uni0D94uni0D99uni0D9Auni0D9Buni0D9Cuni0D9Euni0DA0uni0DA1uni0DA2uni0DA4uni0DA5uni0DA7uni0DA8uni0DA9uni0DAAuni0DABuni0DADuni0DAEuni0DAFuni0DB0uni0DB1uni0DB3uni0DB4uni0DB5uni0DB6uni0DB7uni0DB8uni0DB9uni0DBAuni0DBBuni0DBDuni0DC0uni0DC1uni0DC2uni0DC3uni0DC4uni0DC5uni0DC6uni0DCAuni0DCFuni0DD0uni0DD1uni0DD2uni0DD3uni0DD4uni0DD6uni0DD8uni0DD9uni0DDFuni1F00uni1F01uni1F02uni1F03uni1F04uni1F05uni1F06uni1F07uni1F08uni1F09uni1F0Auni1F0Buni1F0Cuni1F0Duni1F0Euni1F0Funi1F10uni1F11uni1F12uni1F13uni1F14uni1F15uni1F18uni1F19uni1F1Auni1F1Buni1F1Cuni1F1Duni1F20uni1F21uni1F22uni1F23uni1F24uni1F25uni1F26uni1F27uni1F28uni1F29uni1F2Auni1F2Buni1F2Cuni1F2Duni1F2Euni1F2Funi1F30uni1F31uni1F32uni1F33uni1F34uni1F35uni1F36uni1F37uni1F38uni1F39uni1F3Auni1F3Buni1F3Cuni1F3Duni1F3Euni1F3Funi1F40uni1F41uni1F42uni1F43uni1F44uni1F45uni1F48uni1F49uni1F4Auni1F4Buni1F4Cuni1F4Duni1F50uni1F51uni1F52uni1F53uni1F54uni1F55uni1F56uni1F57uni1F59uni1F5Buni1F5Duni1F5Funi1F60uni1F61uni1F62uni1F63uni1F64uni1F65uni1F66uni1F67uni1F68uni1F69uni1F6Auni1F6Buni1F6Cuni1F6Duni1F6Euni1F6Funi1F70uni1F71uni1F72uni1F73uni1F74uni1F75uni1F76uni1F77uni1F78uni1F79uni1F7Auni1F7Buni1F7Cuni1F7Duni1F80uni1F81uni1F82uni1F83uni1F84uni1F85uni1F86uni1F87uni1F88uni1F89uni1F8Auni1F8Buni1F8Cuni1F8Duni1F8Euni1F8Funi1F90uni1F91uni1F92uni1F93uni1F94uni1F95uni1F96uni1F97uni1F98uni1F99uni1F9Auni1F9Buni1F9Cuni1F9Duni1F9Euni1F9Funi1FA0uni1FA1uni1FA2uni1FA3uni1FA4uni1FA5uni1FA6uni1FA7uni1FA8uni1FA9uni1FAAuni1FABuni1FACuni1FADuni1FAEuni1FAFuni1FB0uni1FB1uni1FB2uni1FB3uni1FB4uni1FB6uni1FB7uni1FB8uni1FB9uni1FBAuni1FBBuni1FBCuni1FBDuni1FBEuni1FBFuni1FC0uni1FC1uni1FC2uni1FC3uni1FC4uni1FC6uni1FC7uni1FC8uni1FC9uni1FCAuni1FCBuni1FCCuni1FCDuni1FCEuni1FCFuni1FD0uni1FD1uni1FD2uni1FD3uni1FD6uni1FD7uni1FD8uni1FD9uni1FDAuni1FDBuni1FDDuni1FDEuni1FDFuni1FE0uni1FE1uni1FE2uni1FE3uni1FE4uni1FE5uni1FE6uni1FE7uni1FE8uni1FE9uni1FEAuni1FEBuni1FECuni1FEDuni1FEEuni1FEFuni1FF2uni1FF3uni1FF4uni1FF6uni1FF7uni1FF8uni1FF9uni1FFAuni1FFBuni1FFCuni1FFDuni1FFEuni2010 quotereverseduni201Funi2023uni2031minuteseconduni2034uni2035uni2036uni2037uni203B exclamdbluni203Duni2047uni2048uni2049uni204B zerosuperioruni2071 foursuperior fivesuperior sixsuperior sevensuperior eightsuperior ninesuperior zeroinferior oneinferior twoinferior threeinferior fourinferior fiveinferior sixinferior seveninferior eightinferior nineinferiorpesetauni20A8 afii57636Eurouni210Buni210Cuni2110Ifrakturuni2112 afii61352uni211BRfrakturuni2126uni2127uni2128uni212Auni212Buni212Cuni212Duni2130uni2131uni2132uni2133onethird twothirdsuni2155uni2156uni2157uni2158uni2159uni215A oneeighth threeeighths fiveeighths seveneighthsuni215Funi2160uni2161uni2162uni2163uni2164uni2165uni2166uni2167uni2168uni2169uni216Auni216Buni216Cuni216Duni216Euni216Funi2170uni2171uni2172uni2173uni2174uni2175uni2176uni2177uni2178uni2179uni217Auni217Buni217Cuni217Duni217Euni217F arrowleftarrowup arrowright arrowdown arrowboth arrowupdncarriagereturn arrowdblleft arrowdblup arrowdblright arrowdbldown arrowdblboth universal existentialemptysetgradientelement notelementuni2210uni2213 asteriskmath proportionalangle logicaland logicalor intersectionunionuni222Cuni222Duni222E thereforesimilaruni223Euni2241uni2242uni2243uni2249 circleplusuni2296circlemultiply perpendicularuni2300 musicalnoteuni3001uni3002uni3003uni3005uni3007uni3008uni3009uni300Auni300Buni300Cuni300Duni300Euni300Funi3010uni3011uni3014uni3015uni3041uni3042uni3043uni3044uni3045uni3046uni3047uni3048uni3049uni304Auni304Buni304Cuni304Duni304Euni304Funi3050uni3051uni3052uni3053uni3054uni3055uni3056uni3057uni3058uni3059uni305Auni305Buni305Cuni305Duni305Euni305Funi3060uni3061uni3062uni3063uni3064uni3065uni3066uni3067uni3068uni3069uni306Auni306Buni306Cuni306Duni306Euni306Funi3070uni3071uni3072uni3073uni3074uni3075uni3076uni3077uni3078uni3079uni307Auni307Buni307Cuni307Duni307Euni307Funi3080uni3081uni3082uni3083uni3084uni3085uni3086uni3087uni3088uni3089uni308Auni308Buni308Cuni308Duni308Euni308Funi3090uni3091uni3092uni3093uni3099uni309Buni30A1uni30A2uni30A3uni30A4uni30A5uni30A6uni30A7uni30A8uni30A9uni30AAuni30ABuni30ACuni30ADuni30AEuni30AFuni30B0uni30B1uni30B2uni30B3uni30B4uni30B5uni30B6uni30B7uni30B8uni30B9uni30BAuni30BBuni30BCuni30BDuni30BEuni30BFuni30C0uni30C1uni30C2uni30C3uni30C4uni30C5uni30C6uni30C7uni30C8uni30C9uni30CAuni30CBuni30CCuni30CDuni30CEuni30CFuni30D0uni30D1uni30D2uni30D3uni30D4uni30D5uni30D6uni30D7uni30D8uni30D9uni30DAuni30DBuni30DCuni30DDuni30DEuni30DFuni30E0uni30E1uni30E2uni30E3uni30E4uni30E5uni30E6uni30E7uni30E8uni30E9uni30EAuni30EBuni30ECuni30EDuni30EEuni30EFuni30F0uni30F1uni30F2uni30F3uni30F4uni30F5uni30F6uni30F7uni30F8uni30F9uni30FAuni30FBuni30FCuni30FDuni30FEuniF639uniF63AuniF63BuniF63CuniF63DuniF63EuniF63FuniF640uniF641dotlessj commaaccent onefittedffffiffluniFB05uniFB06uniFB1DuniFB1E afii57705uniFB20uniFB21uniFB22uniFB23uniFB24uniFB25uniFB26uniFB27uniFB28uniFB29 afii57694 afii57695uniFB2CuniFB2DuniFB2EuniFB2FuniFB30uniFB31uniFB32uniFB33uniFB34 afii57723uniFB36uniFB38uniFB39uniFB3AuniFB3BuniFB3CuniFB3EuniFB40uniFB41uniFB43uniFB44uniFB46uniFB47uniFB48uniFB49uniFB4A afii57700uniFB4CuniFB4DuniFB4EuniFB4FuniFFFDÿÿ jóôõömnno !HIOP|}}~~ T†DFLTarmn&hebr2latn>ÿÿÿÿÿÿÿÿfracliga liga&liga, " ¢²ÂzJT^hô- "(MIOLILKOJLIIõMOWNW MOLL,ILVAIniL}‘…¦&Pfæ "æææ "ææ æ  0JDFLTlatnÿÿÿÿkernkernŠV2@ftš¼ú F`†”¢°¾ÌÚ$ÍÿÎÑÿ×Hÿœ $ÿù7ÿ°9ÿÒ:ÿí<ÿ¤ƒÿù†ÿù‡ÿùˆÿõÍÿÍÑÿ×Hÿ› $ÿÎ7ÿ‚9ÿ£:ÿ¾<ÿ{ƒÿΆÿ·ÿΈÿÊ$ÿ½7ÿû: <ÿ÷ƒÿ½†ÿ½‡ÿ½ˆÿ±ÿÄÿÄ$ÿ¸GÿìRÿæUÿîVÿîWÿùYÿþZ\ÿúƒÿ¸†ÿ¸‡ÿ¸ˆÿ« $ÿÌ7 9:<ƒÿ̆ÿ̇ÿ̈ÿÀ $ÿË7 9:<ƒÿˆÿˇÿˈÿ¾$7ÿµ9ÿ»:ÿÞ<ÿ¥ˆ $ÿÔ7ÿ‡9ÿ¨:ÿÄ<ÿ€ƒÿÔ†ÿÔ‡ÿÔˆÿÐ@ÿþCÿÙHÿÒ@ÿÛCÿçHÿÜ@ÿþCÿßHÿÏ@CÿÈHÿ¬@CÿæHÿ´@CÿâHÿÕ ÿ‰ÿ‰ÿ³>ÿä?ÿé@ÿ£AÿâBÿØCÿüDÿäHÿË@CÿßHÿÐ@ÿýCÿÛHÿÕ ÿ¶ÿ¶=ÿÂ>ÿ»?ÿ½@ÿ¯Aÿ½BÿÂCÿ¦Dÿ¿Eÿ¿HÿŠ}ÌÍÐÑÒâ=>?@ABCDEHÒL¢<‚¬âXŠœîd¶à6¬Ö”Êdö ²¼ÒàêJdnx¶¼Îè    È Ò   € æ j ˜ 8 f Ø N T b x † ” ® ´ º Ø Þ*8FTbp~„š¬¶È&ÿý&ÿÜ*ÿÝ2ÿß4ÿà7ÿ£8ÿÛ9ÿµ:ÿÍ<ÿDÿüEFÿõGÿøHÿðJÿöRÿóTÿøWÿðXÿôYÿáZÿë\ÿÞmÿÔ‰ÿܘÿß›ÿÛœÿÛÿÛžÿÛ©ÿöÎÿÜÏÿõÍÿ¿ÑÿÈáÿØ$ÿë2ÿù9ÿ×:ÿç<ÿÔƒÿë„ÿë…ÿë†ÿë‡ÿëˆÿë”ÿù•ÿù–ÿù˜ÿùšÿÿÿû $ÿà+ÿô.ÿö2ÿøƒÿà†ÿà‡ÿàˆÿß•ÿø˜ÿø $ÿÖ-ÿû7ÿÓ9ÿÍ:ÿã;ÿË<ÿÁ‚ÿÖƒÿÖ„ÿÖ…ÿÖ†ÿÖ‡ÿÖÿ”ÿòÿ”$ÿ»-ÿÍ2ÿêDÿßHÿèLÿöMÿôRÿëUÿÝXÿß‚ÿ»ƒÿ»„ÿ»…ÿ»†ÿ»‡ÿ»˜ÿê£ÿߦÿß§ÿߨÿã«ÿèµÿë¸ÿëºÿëÿé $ÿú7ÿÔ9ÿÎ:ÿä<ÿ‚ÿúƒÿú„ÿú…ÿú†ÿú‡ÿúˆÿý$ÿà†ÿà‡ÿàˆÿáÿÑ&ÿÍ*ÿÍ2ÿÐ6ÿÚ7DÿõHÿàRÿãXÿí\ÿ•ÿИÿЦÿõ§ÿõ¨ÿùµÿã¸ÿã¾ÿíÿÓÿƒ$&ÿ×*ÿÖ2ÿ×6ÿí7ÿ—8ÿÝ9ÿ—:ÿ¼<ÿ‡Xÿù\ÿȃ†‡ˆ‰ÿÛ”ÿוÿ×–ÿ×—ÿטÿמÿݾÿùÎÿ×"ÿíÍÿkÑÿsÿùÿù$ÿ÷&ÿý*ÿþDÿûRƒÿ÷†ÿ÷‡ÿ÷ˆÿú‰ÿý£ÿû¦ÿû§ÿû¨ÿþµ¸ºÎÿý $ÿÝ7ÿÖ9ÿÓ:ÿé;ÿÒ<ÿŃÿ݆ÿ݇ÿ݈ÿÙÿyÿØÿy$ÿ²-ÿ²DÿäHÿáRÿåƒÿ²†ÿ²‡ÿ²ˆÿª£ÿä¦ÿä§ÿä¨ÿè«ÿáµÿå¸ÿåºÿåÿäÿþ&ÿð*ÿñ2ÿó7ÿé8ÿï9ÿÙ:ÿå<ÿÕDÿñHÿôRÿ÷Xÿ÷\ÿø‰ÿð•ÿó˜ÿóžÿï£ÿñ¦ÿñ§ÿñ¨ÿô«ÿôµÿ÷¸ÿ÷¼ÿ÷¾ÿ÷ÿõÿõ $ÿê7ÿä9ÿÖ:ÿä<ÿÐWÿýƒÿê†ÿê‡ÿêˆÿê/ÿœÿ³ÿœÿ{ÿ$ÿ¡&ÿÔ*ÿÓ-ÿœ2ÿÖ6ÿè9 :<DÿœFÿ¦Hÿ¡Jÿ§LÿýMÿûRÿ¤Uÿ¤Vÿ¤Xÿ¥Yÿ¡Zÿ£\ÿœmÿ‡‚ÿ¡ƒÿ¡„ÿ¡…ÿ¡†ÿ¡‡ÿ¡ˆÿŸ”ÿÖ•ÿÖ–ÿÖ—ÿÖ˜ÿÖšÿרÿŸºÿ©ÿÝ"ÿè#ÿÄáÿ‹ ÿåÿç$ÿÜPÿüQÿüSUÿüƒÿÜ„ÿÜ…ÿ܆ÿ܇ÿ܈ÿÙ&ÿ§ÿÚÿ§ÿ¾ÿ¾$ÿ¹&ÿÕ*ÿÖ2ÿØ6ÿÝ7DÿÅHÿÇJÿÎLÿûRÿÊUÿÖXÿ×\ÿìmÿ­‚ÿ¹ƒÿ¹„ÿ¹…ÿ¹†ÿ¹‡ÿ¹ˆÿ²”ÿØ•ÿØ–ÿØ—ÿؘÿØšÿߨÿɺÿÎÏÿÕ"ÿÝáÿ°$ÿÈÿóÿÈÿÌÿË$ÿÎ&ÿé*ÿê2ÿì6ÿè7DÿÚHÿàJÿçLÿÿRÿãUÿäXÿä\ÿúmÿÆ‚ÿ΃ÿ΄ÿÎ…ÿΆÿ·ÿΈÿÈ”ÿì•ÿì–ÿì—ÿì˜ÿìšÿó¨ÿÞºÿçáÿÊ ÿÍ&ÿÐ2ÿÓ4ÿÔDÿñHÿÜRÿßXÿè\ÿØÿÓ$ÿ‘ÿ¬ÿ‘ÿ©ÿ¨$ÿ &ÿÆ*ÿÆ2ÿÈ6ÿ×7Dÿ¨Hÿ§Jÿ­LRÿªSÿÊXÿÁYÿÜmÿ…‚ÿ ƒÿ „ÿ …ÿ †ÿ ‡ÿ ˆÿ™”ÿÈ•ÿÈ–ÿÈ—ÿȘÿÈšÿʨÿ¬ºÿ®áÿ‰Yÿß\ÿÚMÿüYÿëZÿó\ÿæÍÿéYÿõZÿý\ÿñKNWÿöYÿñZÿ÷[ÿå\ÿíÍÿîDÿ÷HÿñILÿþMÿüOÿýRÿöW£ÿ÷¦ÿ÷§ÿ÷¨ÿû«ÿñµÿö¸ÿöºÿ÷ÿôDÿû¦ÿû§ÿû¨ÿÿµ¸\ÿîÍÿñ7ÿùMÿýÿ×DÿþHÿëJÿðRÿíVÿýXÿõ£ÿþ¦ÿþ§ÿþ¨«ÿëµÿí¸ÿí¾ÿú\ÿûSYÿóZÿù\ÿî7ÿ SYÿóZÿù\ÿîÍÿò7ÿWÿöYÿîZÿö[ÿå\ÿêÍÿëWÿü\ÿðFX+ÿ»ÿÑÿ»ÿêÿêDÿûFÿúGÿÿHÿõIJÿüLNORÿúSTÿýVWXYZ[\] ¢ÿû£ÿû¤ÿû¦ÿû§ÿû¨ÿÿ©ÿ÷ªÿõ«ÿõ¬ÿõ´ÿúµÿú¶ÿú¸ÿúºÿúÏÿúÿøÍWÿýÍÿêÿäÿä6ÿøDÿÿHÿòKÿýRÿô£ÿÿ¦ÿÿ§ÿÿ¨«ÿòµÿô¸ÿôÍÿÿÍÿøÿ»ÿôÿ»ÿéÿéDÿîFÿðHÿëJÿòRÿïVÿ÷¢ÿî£ÿî¤ÿî¥ÿî¦ÿî§ÿî¨ÿòªÿë«ÿë¬ÿë´ÿïµÿï¸ÿïºÿïÏÿðÿÎÿÿÿÎÿéÿéDÿñFÿùHÿôJÿúRÿ÷Vÿû¢ÿñ£ÿñ¤ÿñ¥ÿñ¦ÿñ§ÿñ¨ÿõªÿô«ÿô¬ÿô´ÿ÷µÿ÷¸ÿ÷ºÿúDÿïFÿéHÿäRÿçTÿì«ÿäÿºÿòÿºÿåÿåDÿêFÿíHÿèJÿïOÿüRÿìVÿô¢ÿê£ÿê¤ÿê¥ÿê¦ÿê§ÿê¨ÿîªÿè«ÿè¬ÿè´ÿìµÿì¸ÿìºÿí &ÿÜ*ÿÝ2ÿß4ÿà7ÿ£8ÿÛ9ÿµ:ÿÍ<ÿÿý&ÿÜ*ÿÝ2ÿß4ÿà7ÿ£8ÿÛ9ÿµ:ÿÍ<ÿDÿüEFÿõGÿøHÿðJÿöRÿóTÿøWÿðXÿôYÿáZÿë\ÿÞmÿÔÍÿ¿áÿØ &ÿÜ*ÿÝ2ÿß4ÿà7ÿ£8ÿÛ9ÿµ:ÿÍ<ÿ &ÿÜ*ÿÝ2ÿß4ÿà7ÿ£8ÿÛ9ÿµ:ÿÍ<ÿÿý&ÿÜ*ÿÝ2ÿß4ÿà7ÿ£8ÿÛ9ÿµ:ÿÍ<ÿDÿüEFÿõGÿøJÿöRÿóTÿøWÿðXÿôYÿáZÿë\ÿÞmÿÔÍÿ¿ÑÿÈáÿØÿý&ÿÜ*ÿÝ2ÿß4ÿà7ÿ£8ÿÛ9ÿµ:ÿÍ<ÿDÿüEFÿõGÿøHÿðJÿöRÿóTÿøWÿðXÿôYÿáZÿë\ÿÞmÿÔÍÿ¿ÑÿÈáÿØ$ÿá7ÿÖ9ÿÓ<ÿÅ$ÿÝ7ÿÖ9ÿÓ:ÿé<ÿÅ7ÿÖ9ÿÓ<ÿÅ7ÿÖ9ÿÓ<ÿÅ$ÿÝ7ÿÖ9ÿÓ:ÿé;ÿÒ<ÿÅ$ÿß$ÿÜÿåÿç$ÿÜPÿüQÿüSUÿü$ÿÜÿåÿç$ÿÜEPÿüQÿüSUÿüYÿëZÿó\ÿæYÿëZÿó\ÿæYÿëZÿó\ÿæYÿëZÿó\ÿæYÿðZÿö\ÿìYÿñZÿ÷\ÿíYÿñZÿ÷\ÿíYÿîZÿö\ÿêYÿîZÿö\ÿêWÿöWÿöYÿîZÿö[ÿå\ÿê$ÿà+ÿô.ÿö2ÿøKN$ÿê7ÿä9ÿÖWÿýYÿß\ÿÚ$')*-/13 5= DFHLN\‚‡,‰‰2”˜3šž8¢£=¦¨?«¬B´¶D¸¸GÎÏH""J??Krgl/inst/fonts/FreeMono.ttf0000644000176200001440000107372014100762640015407 0ustar liggesusers€`GDEF)ý3¹v´BGSUB×"ÈÛvøØOS/2eˆô¥hVcmapÚ(?Ì(cvt !y ôgaspÿÿv¬glyf:ñI$¹ÂheadÜcOì6hhea ª$$hmtx N}À locaêRÔ ø(,maxp Ë®H nameœ­è=postÊ™lü(_™FÛËc_<õè½WøÛ½WøÛýÓþÁ»" ÿ8ZXýÓÿ»| àxš@.XŠ»ŒŠ»ß1 àÿPxû€ PfEd@ ÿý ÿ8Z"?€¿ß÷°!MXXðX’X\XqXWXiXìX&X“XqXHX‡XHXâXqXqXqXTX`XiX`XˆXiXqXˆXâX‹XHX3XNX†XiX X+X?X+X+X+X?X5XqXTX+X?X XX3X+X3X+X\XHX(X XX(X3XgXXqX›XqXÿôX›XHXXTX?X?XiX?X+X\X“X?X\X X5XHXX?XTXgX+X+XXX3X3XsXÅXXÅX\XXðXqX?XgX3XXBXŒXX›X?XHXHXX›X›XHX¯XµXX+XOXâXÒX¿XšX?XXXXqX X X X X X X X?X+X+X+X+XqXqXqXqXXX3X3X3X3X3XvX(X(X(X(X(X3X+X+XHXHXHXHXHXHX XTX?X?X?X?X\X\X\X\XHX5XHXHXHXHXHXHX5X+X+X+X+X3XX3X XHX XHX XHX?XTX?XTX?XTX?XTX+X?XX?X+X?X+X?X+X?X+X?X+X?X?X?X?X?X?X?X?X?X5X+X5X+XqX\XqX\XqX\XqX\XqX\XX|XTX“X+X?XFX?X\X?X\X?X\X?X9X+X\XX5XX5XX5X5XX5X3XHX3XHX3XHX X X+XTX+XTX+XTX\XgX\XgX\XgX\XgXHX+XHX+XHX+X(X+X(X+X(X+X(X+X(X+X(X+XXX3X3X3XgXsXgXsXgXsXiXXÿæX,XX.XX?X?XTXXÿÂX:XXDX+X2X\XXWX?X0XX­XqX+X?X\X:X XX5X3X3XHXXXÿæXX<X\XgXfXQX+XX+XHX(X+XNX+XÿîX3XgXsX`XPX_XXXTXPX_X†XXXØX3XðXXXXXX|XXX X XHXqX\X3XHX(X+X(X+X(X+X(X+X(X+X?X XHX XHX X X?X?X?X?X+X?X3XHX3XHX`X_X“XXXX?X?XXXX5X XHX X X(X5XþCXþIX XHXþ1Xþ;X+X?XþCXþCXqX\XþCXþCX3XHXþSXþOX+XTXþCXþ;X(X+X\XgXHX+XoX|X5X+XgXsX XHX+X?X3XHX3XHX3XHX3XHX3X3XXXHX?XXXTXTX?X?X?X?XCXgXgX“X?X?XMX4X2X+X3X3X\X­X‡X\X\X‡X X X Xÿ½X5X6XHX XpXTXTX4XTXiXTXTX<X<XgXWXWXWXQX+X+X+XXX3XQXsXsX_X†X†X†X?XIXMXSXX?X\X?X†X†X)XXËXXûXûXûX,XÏX›X›XX›XX›XåXåX,XÏX»X»X»X»X›XúXÏXX‘X›XÖX³þCþÀþCþ9þCýßþCþ¢þ4þtþwþCþCþÀþ„þCþCþCÿ0þ§þ§þzþÀXþEþ þCýÓþ9þ4XÿñŒÿþâÿö<ÿþz +> +g53q+ E33+fH3.'Fq3?‘5­+?<=D‘z5q­F:+|HR]+++Q"+Z+H++pB%PY+++>@\qqT $323 ,+> +\33-9 533+?H2(2IÿÒ +@ HQlr7? gAAFX4AHATf3ÿø35` @ lJÿÄX??+rJg\\“"+F>3>"+l+>r>r>r \g$F$F$Fÿç 5R5Rÿó?T?THz33(3ÿîJ`J`J`ÿ¬ÿÎÿ¬ÿÎq $F5RJ` H H +?2K2K \g\g3>3>3H3H3H@J232323I` ))+"":) 4?.)k5!Z=*+@ ) \*A\G3Z 4+!,+}545IG85GBP6[G5] F5,,g5?y iHY³™™˜ÔÔÔÔÿã™dÔ1â<<…<<ª…<ª<<<<<ª…<<<<<21<3ZZZúžÑ²GGGG©©Ñ¸¸¦°çç°°¢Ë¤££‘©©©¯ä°ç°äz3°ç°Ÿ~±ü›ŸÑ´¢ç¢–n’3üÖÁiXiMŸ’3®©Víí¦v3Z H+++?T+?+?+?+?+?+?+?+?+?+?+i??5+5+5+5+5+q\q\+?+?+??\?\?\?\ 55553H3H3H3H+++T+T+T+T\g\g\g\g\gH+H+H+H+(+(+(+(+(+  (3(333gsgsgs++3Hi Hþ,þs H HþYþj H H H Hþtþt H H+?þdþk+?+?+?þkþy+?+?þtþsq\3Hþtþt3H3Hþtþt3H3H3H3Hÿ?ÿ83H3H(+þtþ[(+(+ÿ_ÿ((+(+3333þtþt33????????ÿüÿùÿ€ÿpÿ€ÿpÿ#ÿ,‘‘‘‘‘‘ÿÈÿÁÿHÿ8ÿHÿ855555555ÿèÿàÿgÿWÿgÿWÿ ÿ­­ˆˆOoÿŽÿ~ÿŽÿ~ÿ;ÿ:HHHHHHÿèÿØÿbÿPÿ‡ÿw++++++++ÿÇÿLÿ=ÿ«++++++++ÿéÿÙÿ_ÿRÿ†ÿ{ÿ<ÿJ??‘‘55­­HH++++????????ÿüÿùÿ€ÿpÿ€ÿpÿ#ÿ,55555555ÿèÿàÿgÿWÿgÿWÿ ÿ++++++++ÿéÿÙÿ_ÿRÿ†ÿ{ÿ<ÿJ??????? ÿþÿþ ÿ÷‘Œ55555ÿÆÿÆÿåÿå5ÐЀjj\Z`Zqq ÈÈ ++++++33ÿÎÿÎÿÁŒŒñ+++++ÿÜÿÚFñ÷ˆHÿô‡‡]]]]||Ê3"É]É]?%p†ÿô2Å&OÀ·µÎ·ÀͲ²±ã”ò¸º¸ÑºÃв²±ã+?< ? \!0VVu 4+3#þ÷1NN+ +^8q1!%+% (??+ )º6ººpzw€((MM(º(º)>*š*šš)E)E„iŒiŒ*)('+&;9!!»!1»)+))*J*!!888¦8¦¦ G++q++&&s&&s3qHHHqâ%&&((ˆ8n8(((\\\HHH3\333333335;5;))ÎHN‰‰3333######((((((((((((((Êf7…((((H7((ÄÇ,,,<Ü<s#ThTTºTº<< "ðÜÜÜÜÜÜÜÿïÿïÿï,,, ,,2212222222¯¯22––##¨¨TTÇÇyy##¨¨99¬­^_####Y############,–#,#,##2222Ê22222###2222####22222}}2/<xZ#222&2PP#22222222###vvv@……55mx=ll}}--lllkkkkpppppppllllkkkkppppppppê ˪¹Z<<<<<<<<H3131<<<<…<<ª…£<<<<…<<<21<3ª<<<<Œ"44 ~3B\mv‰’—™¤§¿ËÝßî"(38BDzŠŒÎÓÕÜ_djlqÄÈÌõùV†Š¹Äêôð›ùEMWY[]}´ÄÓÛïôþ   " & 7 : > F I K Ž ¤ § ª ¬!!! !!!"!'!+!2!5!o!Õ" """"0"5"7"="E"H"S"Z"a"g"l"o"w"ƒ"‡""¯"¾"Æ######*#´#·#½&& &&&&&&)&.&7&<&B&o'ë(ÿöÃûûû6û<û>ûAûDûOÿýÿÿ  $AP_oxŒ”™›¦»ÆÐßî!'35BDz„ŒŽÐÕÚdjlpŒÇËÐø1aа»Ðð   HPY[]_€¶ÆÖÝòö    % 0 9 < C H K p £ § ª ¬!!! !!!"!$!*!2!5!S!"""""'"4"7"<"A"H"P"Y"`"d"j"n"v"‚"†"•"¢"¾"Å######)#›#·#º%&&&&&&&(&.&0&9&?&i'æ(öÃûûûû8û>û@ûCûFÿýÿÿÿõÿãÿÂÿ¾ÿ±ÿ¤ÿ¢ÿ¡ÿ ÿžÿÿœÿ›ÿšÿ‡ÿÿ}ÿ|ÿnÿ]ÿTÿOÿKÿAÿ@ÿ7ÿ6ÿþøþ÷þöþõþôþðþÍþÉþÄþÃþÀþ¦þ¤þ¢þŸþþfþ\þYþ4þ3þ(þ#íxæiæeæ_æ]æ[æYæWæVæUæTæSæQæPæOæMæJæIæ8æ6æ5æ3æ*æ)æ(æ$æ#æ"åþåêåèåæååå’å‘åŒåŠåˆå…å„å‚å|åzå]å=åååååååäÿäüäúäóäîäéäçäåäääÞäÔäÒäÅäÁä³ä­ätäsäoäkäeä\ãìãêãèâ¦â¤âžâ•â”ââŒâˆâ‡â†â„â^àèàÔÕÓ½¼»º¹¸ ®)*+,-./0123456789 ;’²Ÿ À~{€utho  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a†‡‰‹“˜ž£¢¤¦¥§©«ª¬­¯®°±³µ´¶¸·¼»½¾rdeix¡pkvjˆšsgwl|¨ºcnm}b‚…—¹Áy„ŒƒŠ‘Ž•–”œ›qz!yVVVVÄöš|h"B–ìp²ÞB„ô<ºl¾ : Ð  ¾ T À  d ¤ î †Bª6¼ Šî†J¨6~òP´Úh$tæ6–zÀð2`¤¾ú”ŒŽ˜^®  R ø!v!à"p"þ#f$$$–$ö%D%¢&"&†&È'R'v((v(†(ô)Š*6*þ+œ+Ô,¾- -î.‚.ú/&/60 0,0–0ê1b1ü2:2˜3(3f3º44r4ì5®6”7¢8:8Ð9h::Æ;„B>Ü?|@<@°A&A¢B>BÀCvDDœE6EòF¬GG´HVHøI JhJüKtL&LðM¼NŽO€PpQbRnS<SôT®UnVLV´WWŽXXàY¶ZNZè[ˆ\J] ]„^^¬_<_Ò`ˆaa®bhbäc’d<eeÊf¤gZhhh4hJh`iiÊjbkkk®l,lÊlâlømŽnBnìo´pRqq&q<rrêsssÚt˜t°tÈujvvv,v„vÒvêwwŠxx„x¾yVyÚyðzf{ {¶{Æ|>|ª}}„}ø~^~t~Šz€€¸Bì‚~ƒ0ƒ®„<„Ô…L…Ê…â…ø†¼‡†ˆ ˆÜ‰œŠ6Šð‹„ŒFŒâÎŽ¼ŽÔŽêêö‘æ’Ø’î““ˆ”&”••.•D•È–<–T–j—2—蘺™zš(šÈšàšö››$›ÞœTœÆ8¤žž”žüŸ” P ` æ¡€¢*¢°£l¤¤,¤Ä¤Ú¥^¥r¥ˆ¦¦Î§J§Ü¨¨©>©úªZª¶«€¬¬j­­´®0®°®À¯d°°¼±`±ú²®³f´"´Ü´ìµŽ¶,¶¬·H·¶¸\¸ú¹Âº(ºÀ»\»º¼¼¦¼¼¼Ò½¦¾@¾Æ¿j¿€¿öÀÀRÀ®À¾Á~Â:à âÄ*ĤÅ@ÅÜÆªÆÀÆÖÆìÇÇÇ.ÇDÇZÇrLjǠǸÇÐÇèÈÈȠȸÈÎÈæÈüÉÉ(ÉÜÊʦʼÊÒÊêËËË,ËBËXËnËâÌpÌþ͜ͲÍÈÎtÎðÏÏÏ4ÏLÏbÏxÏϦϼÏÒÏîÐ Ð Ð6ÐRÐnЄКжÐÒÐèÐþÑÑ6ÑLÑbÑ~ÑšÑ°ÑÆÑâÑþÒæÓÐÔLÔêÕ®ÖpÖ†Öž×ׂט׮×Ä×Ú×òØØ Ø6ØLØbØzØØ¦Ø¼Ø¼Ø¼ÙXÙÎÚBÚàÛ\ÜܰÝLÝÊÞRßß.ßôàTá á˜â0â¶ãbãääˆåF妿æ\æîçŒçâè„é&éîê„ë"ë”ììí$í8íLíÜîFîÊïï*ïÎïäðÊñ@ñÎòHòäòøójóðôôô,ôŽõõšöHöÀöÖöì÷tøøÎùfùúúúdûû®ûÄü`ýpýÜþzþ¢þÊþòÿ0ÿnÿ²ÿô,<L°æø 8džÂJ®fÔZš¬¾Ðâô*<NÊÜî`Îèþb¤ìþ2V”Ò 6 H  Ð ^ v † ž ¶ Î æ þ  , ”  d ®  ^ ÜzÀN¦¶ÆX¼8HHàDöˆJô  6Lbx޾(ðÒ\ÒL¬xê8þhÊVøˆø `!2!°"D##2#H#^#t#Š$ $Ò$Ò$Ò%`%Ö&J&¨&¾&Ô'h'Ü(l(|(Œ(¢(²)Z)þ*+F+ø,œ-- -˜-¨-ì.P.`/(/ê0l101´2.2>2N2^2À2Ð2à2ð3R444z55~66n77z8 8°9:9J9â:p:¸;;.;ú<À=>=þ>d>Ú?L?È?Ø@:@J@Z@¦@¶AhAxAÞBbBàCdCÖD|DêEtFFžF´FÊG„GüH†H–H¦H¼HÌIlJJ¼KRKþLLŠMPMòN®ONO^OàPdQ QÒRRbRÀSS®T@UUØVÞWèXpXÚYzYøZ–[[ \ \Œ] ]Œ^ ^¼_j_z_Š`Laa\a®bbzbôcpcôdxdèeXeÞffgg’hh˜iZjkll*m0n>næo~pp¦q2qºqÐqæqürr"r2rHr^räsbsxsŽt¨uÊvâwþxÀy†zz®{†|Z|p|†|ø}j}€}–}¬}Â}Ø}î~~~0~F~\~r~ˆ~ž(¦€0€¬*¼‚‚ˆƒNƒÔ„^„¤…4…´†6†ª‡Z‡ÊˆFˆÌ‰l‰ÚЂи‹’Œ,ŒÊPÂŽBŽRŽÈ‚Ò~‘‘.‘ä’p““’””ˆ••>•¸–D–À—8—r˜˜†™ ™‚š,𦛛˜›ØœJœÆ>Žž.ž¼ŸFŸ¢Ÿþ  † – Ò¡‚¡ø¢¢Ð££n¤H¤Ì¥n¥¤¦¦Ž¦Ê§§R§Ü¨¨P¨Ž¨Ê©©@©v©âªªÂ«H«ì¬B¬Þ­"­r®®Ì¯¯|°°p°ú±š±Þ²F³³œ´>µµzµâ¶p¶Ü·†¸<¸´¹*¹ž¹¾¹ðº ºbº†º¶»»L»z»¶»ä¼¼R¼„¼È¼ø½&½j½¤½Ò½ò¾¾<¾v¾¸¾ò¿®¿ÜÀ ÀFÀ†ÀÔÁÁ*Á†Á Áî Âb”¸ÂäÃÃJÃrÚöÃîÄÄFÄhľÄôÅ$ŰÅâÆÆRƤÆÜÇÇ>ÇhÇ´ÇúÈ4ÈlÈ®ÈäÉɲÊÊdÊ~ʸÊæË.ËhË€˲ËàÌfÌæÌþÍÍ,ÍDÍ\ÍtÍŒͤͺÍÐÍæÍþÎÎ.ÎFÎ^ÎtΊ΢κÎÒÎèÏÏÏ.ÏFÏ^ÏvόϢϸÏÐÏæÏüÐÐ*ÐBÐZÐpЈРиÐÐÐèÑÑÑ0ÑHÑ^ÑvÑŽѦѾÑÖÑîÒÒÒ2ÒJÒbÒzÒ’Ò¨Ò¾ÒÔÒêÓÓÓ0ÓFÓ^ÓvÓŽÓ¦Ó¾ÓÖÓîÔÔÔ6ÔNÔdÔ|Ô’Ô¨Ô¾ÔÔÔêÕÕÕ.ÕFÕ\ÕrÕŠÕ¢Õ¸ÕÎÕæÕþÖÖ.ÖFÖ^ÖtÖŠÖ Ö¶ÖÎÖæÖþ××.×F×^×v׎צ×¾×Ö×îØØØ2ØHØ^ØvØŽؤغØÐØæØüÙÙ(Ù>ÙVÙnÙ„ÙšÙ°ÙÆÙÜÙòÚÚÚ6ÚNÚfÚ~Ú–Ú¬ÚÂÚØÚîÛÛÛ6ÛNÛdÛ|Û”Û¬ÛÄÛÜÛôÜ Ü$Ü:ÜPÜhÜ€ܘܰÜÈÜàÜøÝÝ&Ý<ÝTÝl݄ݚݰÝÆÝÞÝöÞÞ&Þ>ÞVÞnކޜ޲ÞÊÞàÞøßß(ß@ßXßn߆ßžß¶ßÎßæßþàà.àDàZàràŠà¢àºàÒàêááá2áJábázá’á¨áÀáØáðââ â8âPâhâ€â˜â®âÄâÜâôã ã"ã8ãNãdãzãã¦ã¼ãÒãèãþää.äFä^äväŽä¦ä¾äÔäêååå,åBåZåråŠå¢åºåÒåèåþææ*æ@æVælæ‚æšæ²æÊæâæúçç*çBçXçnç„çšç°çÆçÜçòè è"è:èRèjè‚èšè²èÈèÞèôé é é6éNéfé~é–é®éÆéÜéòêêê4êJê`êvêŽê¦ê¾êÖêìëëë.ëDëZëpë†ëžë¶ëÎëæëþìì.ìFì\ìrìˆìžì´ìÊìàìöí í"í8íNídízíí¦í¼íÒíèíþîî*î@îVîlî‚î˜î®îÄîÚîðïïï2ïHï^ïtïŠï ï¶ïÌïâïøðð$ð:ðPðfð|ð’ð¨ð¾ðÔðêñññ,ñBñXñnñ„ñšñ°ñÆñÜñòòòò4òJò`òxòò¦ò¦òîó,ó’ôLôbôxôŽô¤ôºôÒôêõõõ0õ öö*ö@öVölö‚ö˜ö®öÄöÚöò÷ ÷z÷ìøøø0øFø\ørøˆøžø´øÊøàøøùù(ùÀúNúŽú¤úºúÐúæúüûû,ûDû\ûrû²ûðüü@ühüxüžüÌüøý$ý4ý€ýÊþþ$þjþÊÿÿÿÎ<hxâ&’Ôè¨ÂÂŒ  $ Œ Œ Œ Œ ä ` ô 2 Ö f Æ ø X ª ô ²ÄÖèú 0BT²äB”Þ\ ªr2f.¼œ¨´ÄL¨D¨ê ¨!^!Î"#*#B#ö$R$R%,&&&"&6&Ê'Ò))ð+,@-N.J/v0Š1î364>4¾55X5´6(6~6ê7d7ê8x8ˆ99°9À9Ð9à9ð:B:–:ì;@;Âx? ?ž@N@ØAdAxAŒB B B„BæCHC¬DDDÎDäEE¦FzG<G¨H H"H8HLH®IIÆJ‚K K¾LPLàMM^MžMèMþNN*N@NÚNôO O¤P@PVPlPâPøQvRR”RöSVS´TT U"U~U~VVrWWÀWèXX–YrYÎYäZ¶ZÌ[H[À[æ\6\ž\®\¾\ö]º^0^¼_Z_¨_Ì_ö`<`„abc@dBeÔg®hBhXii†jj®k:kÆlm4n nvo o¤oºp0p®qqtqÔr:rºs<sºt>töu u"u¢u¸vv^vÌvâwdwÔxVxÄy.y˜zzlzÖzú{ {D{d{ˆ{¶{ä||P|Š|È}}f}Ä~0~n~žDDŒªÈ耀,€P€r€–€¬Dd„¤Ä‚‚`‚ª‚ăƒ`ƒzƒÆƒäƒþ„„<„V„v„¦„ð… …<…r…º…ꆆ†¬‡:‡‚‡Ê‡Ê‡îˆˆ"ˆ<ˆVˆpˆŠˆ¤ˆ¾ˆì‰‰J‰z‰²‰êŠ&ŠbЂТŠÂŠâ‹‹"‹B‹b‹‚‹¢‹Â‹âŒŒ"ŒBŒbŒˆŒ®ŒØ*T~¤ÈDŽjŽ–ŽÀŽæ 6`†¬Ö$HržÄê‘‘@‘f‘–‘Æ‘ö’&’V’†’¶’ê““R“†“¶“æ””F”v”œ””압<•b•Œ•´•ä––8–l–––À–ô——H—x—¨—Ö˜˜D˜v˜¸˜è™™T™†™´™øš>š~𨛠›"›6›L›j›€›Â›Ü›öœœœ4œNœ`œrœ˜œ¾œÔœê4Nh‚œ¶Ðêžžž8žPžhž€žœŸþ¢ª§ô¨¨(¨B¨^¨z¨š¨Ê¨ê© ©(©V©v©©¸ªbª˜ªè«6¬¬N¬š­@­V­x­’­º­Ô­ú®®@®Z®‚®š®¾®Ú¯¯¯>¯X¯|¯˜¯Â¯Ú¯ü°°>°V°x°°´°Ô±±B±Ø²²p´@´ÚµšµÔ¶(¶|¶Î· ·€·Ð·ö¸¸d¸Ø¹.¹ˆ¹Äºº6ºjº´ºþ»»0»F»^»Â»è¼¼8¼`¼–¼ê½½:½ž½Ø¾¾N¾Š¿¿t¿äÀXÀ~À¦ÀÎÀöÁÁ:ÁTÁ~ÃTèÄVĄĄÄÒÅ:ÅÎÅÞÆHÆèÇÀÈÉtÊÊöËzˬËêÌ"Ìl̨ÌðÍ2ÍŠΆÏ„ÐZÒbÓRÔÔÔ´ÕÕŠÕôÖlÖÖ× ×n×¼Ø ØdØÀÙfÚÚÚJÚ‚ÚæÛÛ†ÛðÜ‚ܼÝ ݈ÞÞ€ßߪàlà¦á átââjããäVä¾åNåàæžç0çòè²é¢éÜêDê¨ë>ë¢ì<ìÊííøîŠïïÜðlñ0ñîòÞóHóÞônõ0õ¾ö„÷>ø2øÄù„úDû0ûîüÞýÊþèÿ ÿ„ÿèzÜnü¼ °@úŒFæLÜ p * ¼ v 6  ªdÀ¤Œœ$àn*èÎbÜ„jVfú ¶!v"2"ð#Ö$Â%Ò&'v(`)r*^+n,„-À-ø.\.Ä/T/º0J0à1š22”3$3Þ4p5*5æ6Ê727Â8V99¢:\;<<œ=V>>ö?²@–A~BŽBòC‚DDÎE\FFÔG¸HPI IÆJªKjLNM8NFNØO’PPQ4QðRÔS¾TÌU”VxW`XpYZZh[|\¶]]ª^<^ö_†`@aaäbtc.cèdÎe¶fœg„h”i&iàjžk„l@m$nooØp¾q¤r´sœt¬u¾vøw†x@xþyäzž{„|l}|~: €‚ƒ„*…d†"‡‡ò‰‰êŠúŒJŽ2BV‘’’¨“â•"–ˆ–À—¤˜R˜ò™¼š(š’› ›®œ<œæ<ØžpžÌŸVŸÂ x ª¡~¢P£N¤J¥"¦¦ä§”¨`¨Þ©¤ªªˆ«^«Æ¬^­ ­¤®l¯¯ò°¼±¸²H²þ³’´fµFµ°¶f·0¸2¸²¹&¹¾!nš.±/<²í2±Ü<²í2±/<²í2²ü<²í23!%!!!MþÔ þõšýf!Xðÿñhj"#"'&54763232+"'&5476R . # $  3þºF  þ !  ! ’;Æ\ 3"'73"'’€"4’€"4\ý$$ýý$$\ÿÂü‡:>32+#"'&57##"'&=7#"54;7#"54;76323763232+3† PS[WY NQ[Y„[ [d~áæáÞ~áÞáÞ~qÿ¤çR5432632#"'&'&#"#"=&'&'#"=432327654/&'&'&'4765(2 $C%@0Y 1Q%?19'-X(<1 R%-@#@44<! /5 !CR)ww&O'4:$:G*Wÿôc/?Q%2#"'&5476"327654'&2#"'&5476"327654'&#"'&547%632iB$4 &@%4 &0 */ +“B$3 '@%4 &. *- +ëþ… { ì6 (=&5 '@%&*1 *4 7'>%5 '@%&)1 (4 åzz iÿðÞ7B!'#"'&54767&'&547632632&#"6732+32#/32‰-CD,!G-4 '!! !+ ,o+ &qi?.70@<,6T+ J =$  &E±:FS+)V¥:=#ì;l\3"'ì€"4\ý$$&ÿ„Ê\2#"'&'&5476¶dd en\±œ™´ ¨˜ª “ÿ„7\2"'&547654'&'&5476¨ end]\" ¦šª ±œ–ªqúç\-54327632#"/#"'&54?'&547632……Q RQ Q… ¶‹‹+*p pp p*H #"=#"54;543232#@´´´ÊÊÉɇÿoT‘ 73#"'&547Ï…‘ ‘þ÷H+ !"543!2õþn’âÿñvt%32+"'&5476' -& +&t% *$)qÿ¯çœ #"'&547632âþ¹ G yýH ¸qÿñçj$#"'&=476323276=4'&#"çL/@_5'M.@`4þ³0"@@"00"@@"0_d“J-^Ffd•I-^):OYhJ55IiYhJ55Iqçd32#!"54;#"'&547A‹þÁ‹„  dýÅ*TÞj*7!5432!5767654'&#"#"'&547672{:þvìY7(0H. >\R9-V€O)$M<ÞW$<)6 (I?1d4;QL2'>.9S26 (>#3$B&þä8"*D)7$+G&ˆÿñþj#2#"'&547632#"'&547232767654'&/"3276Õ=iL3(B/#-=DM8h09 =++ $ + % ÷)D9;@")D "D%1C.¦" $ " % iÿÂÞp9D%5#"'&547654'&#"327632#"'&=47632#'5"32¢ L&E.=7"P,/'IF# 9,1W56J3FT. !R$2‘7'L*/G!S;S \F9 KNk£‡L4A þë/¸36  O3 $%!32+"54;#"54;32+"54;'#¬þö6O—³xÌÅ%œLGpl¼“áýö¼%þÛ+3#07#"543!2#!"543327654'&+327654'&'&+|6Z2U?-9þÎ_“X(7!)¤ÐE%6,S•)á<%0I/-dJ.!47þ2"7#?ÿð@/5432#"'&'&#"32767632#"'&=4767632Þ@0:[<2I?RYC &LbfON6 Efeûp4#I>QGaD:F #GONeSTI J+3#7#"54;2+"54;276=4'&'&+h"ÜgD;N@XÜK–L9362L)áRHc8uK>D=KIMA2+3)!5432!"54;#"543!#"=!35432#"=¥:þ>66­þÛ‘çw á‹bÑ-ƒ-+3'32+"54;#"543!#"=!35432#"=¥Šé66ÂþÆ‘çá‹bÑ-ƒ-?ÿð2@8%#"'&=47676325432#"'&'&#"327675#"54;2#Za”I1? FccC?,6T7< d7MDF‹ÂÑ­4cB_JaL A6[.68S I…8 –5'33!32+"54;#"54;2+!5#"54;2+32+"54;µþò6Œ-x66x.6çáÑÑþqç332#!"54;#"543!2#@‹þÁ‹‹? þáTÿðG3 #"'&'543232765#"543!2#ÌC5DNOKIK+Ÿ( þ›S7+@ •‚D:$.e+<37732+"54;#"54;2+%#"54;2+32+&/&'¥Kª66ªK-vÞI)"+ 8W@5*Ý´áùùÆ8/h²9?3!5432!"54;#"54;2#ãþ=``é þ Éá Q3,%##32+"54;#"54;32+32+"54;#F.ŸJ•"cšd"•J©aþáþ¤\þá23"!#32+"54;#"54;#"54;2+õ4þÏK–"6j1J•"øþ1áþÏ3ÿð%@2#"'&5476"327654'&,nIBQGakIEQGaZ>8H;MX?9I:@]Uz€WMZVx„WM)QJdsM?PJbyL=+ó3&732+"54;#"54;2#'327654'&+¥Šé66ð_8&H8Kƒ†Q09'0•ç¾á@,9O1')4"(=&3ÿ%@1A632327632#"'&#"#"'&54?&'&547632"327654'&16())*- &#!8T Z_9.QGakIERDcZ>8H;MX?9I:(   AaN^„WMZVx‡VH$QJdsM?PJbyL=+M3)4732+"54;#"54;232+&'&/327654'&+¥Kª66øT8(‹7(& 9U7'„r^57'-™ûÒá;,5a0%:"@ œ2)3$4$\ÿðü@C5432#"'&'&#"#"'#"=432327654'&'&'&'&'47632½<#,R(R+_#=M6Kj?A,8[.-E `(3F1AVg95"E %QV0!Hp;#8 (7 $DN- H3%32+"54;##"=!#"'&=#Aiûi§È¦)áIrrI(ÿð03)#"'&5#"54;2+32765#"54;2#óI6Ha:,"•J?)6O/ J• þ¯b;,I7IQþ¯R/>+7Q O3!#"54;2+3#"54;2+ È—MºÁN–Ñ þáýöD3 3#"54;2+3#"54;2+# z<•]8p>m9`–>@ps þ$ˆþxÜýöþp(03332+"54;'32+"54;7'#"54;2+7#"54;2+E¿„>¥¤@ƒ¼³n+›™-o ÷ÖÖ÷êÉÉ3%3&%32+"54;5#"54;2+7#"54;2#Biûi³o&˜•(nþÕÕ ããgñ3)55!#"=!!5432ñþvHþó]þ¸:;ÌvŸ:þ4ÿ„½\ 32+32#AaŠŠ3ýzØqÿ¯çœ#"'&547632›G þ¹ ŠýH ¸ ›ÿ„@\ #"54;#"543aŠŠS†ý(qbçg#"/#"'&547,²  ““  gß  ¹¹  ÿôÿƒdÿµ!5dýK22›ê@"/&547632Âr r vd d Hÿð¯(7!5#"'&54763254'&#"#"'&54763232#'5&#"3276£Yf_)R6K;M<#,b]@\-6_*3g3 I0AmN +Pgr@/S=V]x [0K/?_3"H 7P;QrA0?ÿðG\*32+5#"'&5476325#"543"327654'&ö6_Go`A7J=QnH6}U5(C1?T5)D0\ýÍYiK@UeC7hìÖC2AY6(B2A\6&?ÿð¯ +%!32767632#"'&547632!&'&#"þ`T.:VE HGDnH3H:LhA§S2#@-;R2$B,NSþl:.65'aI;O`?3^6A-;S3$@.:W2"+'\16763232+"54;54'&#"32+"54;#"543¥<>Z--ƒ-&66' -„.6\þÿH >",ú÷.! ÿ \üp32#!"54;#"5437#5@ þ— v;¡þˆOÏhh“ÿFÊp#"543!+"54;2765#5¡ñB'2€B ;xþCY,6#Œhh?\)7#"54;#"54;7#"54;2+32+"54;'¹_66_­‚/Ï-ƒ´´´ þ‰“ƒÌ²\ü\32#!"54;#"543@ þ— u\ýÍ  Q¯>6763267232+4'&#"32+4'&#"32+"54;#"543p*0@!:78 "J"/0"J"27"m""¡4;GE1þæ?( Eþõ<) RþõO5¯06763232+"54;54'&'"32+"54;#"543§;2T."m"&&,7('-ƒ-"¡EB :",þ÷, ! 2ýOHÿð¯!2#"'&5476"327654'&'&,jC7LAWhD8LAWY8*E3CX8+E,9¯N>VcA9L?UdC8)C2AX6)A2A[6#ÿF¯#367632#"'32+"54;#"543"327654'&=Jj@ L1`û @.;S2%?.;V2#?ÿFG¯!3532+32+"54;5#"'&547632'"327654'&Í_66ÁbCqh@2M0[4A%/ S2%@-;V2#T«%67632"'&#"32#!"54;#"543øj:(%#)7A³þÄ`K¡f`  "*8ÝOgÿðñ¯D5432#"'&'&#"#"'#"=432327654'&'&'&'&'47632°C"R# &'V,1J4F`=<*4]*'#I\&-D,;UE0) !9C&6 S).# 2;!+ÿðó3)32+32767632#"'&5#"54;5432ºÜÜ=SE KA;e&JJ¡þõ9!?" w+ÿð¡"!5#"'&5#"54;327#"54;32#·TbS"6_,dSJs"BR@&þÒ3 Zþˆ:¡!##"54;2+3#"54;2+PF¨)—A–“D˜)xþ±O:¡ !# ##"54;2+3#"54;2+¹2[Y3To5HV3YE2oþýxþÀÿÿ@3%¡3%32+"54;'32+"54;7'#"54;2+7#"54;2+I¸ „A›D… ¸£o.†‰0nÛ²••²‚‚3ÿF%¡%!#"54;2+#"54;2+32+"54;¼s4¤¡6nÿAéxþµKý÷sé¡!5432!5##"=ÚþÑþŠ-û¡$þ¬8a$T7`Åÿ„“\.#"'&=4'&'&47676=47632B &" 7( . /& ó­0 & ­)1­-(( ­<$ ÿ„@\"542@((Aý^¢Åÿ„“\054767&'&=4'&'&'432#"54763676&" 7( . .& ­0& ­)1­-(( ­;$ \Ôü\$2#"'&'&#"#"'&547672276è1-!*%# 2* ! 8$%J ; *  4 *4ÿÿðÿ(h¡"632"'&54#"'&5476;2 . # $ ¡Fþº  æ !  ! qÿóÕv654322632#"'&'&#"327632#"=&'&547676?):W,@'2J3 8/-Z/E!ðkj$=/?$0O**qq I.7Y7?BA732765632#!"54367654'#"54;&547632#"'&#"032+¶ü#)þ½'h^9%/6, (25cZ)'4?5>U$H+'  1.O#hg_ñé6F7#"'&54?&547'&5476326327632#"/#""327654'&Ç9  8#"7  8,:9-7  7"#7  8/677?%4 (>&6¢8  8/6;+8  7##7  8/6:,8  8#"4 (@&4 'C%3%3@%32#32+"54;5#"'4;5#"'673'#"54;2+7#"54;2+32AƒƒVÕV‚‚‚t¤n'——'n¤vî<dd<÷ãã÷ÿ„@\"542"542@((((Aþõ þNþõ BÿÂ[;S#"=#"+5432327654'&/&54767&54763'&'#"6767654'&ð¨3 /G8s$+ 9"*Ï¥: L AŽ8 5")d@T# 5}>PAI[mE&!"'>: '>!oG('2$PC2 :#þÇ$.+G#-"%1 ŒÿÍc2#"'&547632#"'&5476¾!   è!  c    ÿñTB)9I54763242#"'&'&#"327632#"'&2#"'&5476"327654'&™8%.+.$*91#1) ,8E."“|WUZW{xWVYVzoLEPIctLCQJ-H,A 3"'<#/ )9*pYWxWSXXy|WU)QJdmMFSHenLE›¿>'45#"'&54763254/"#"'&54763232#'5&#"32i65C;!)-(0 7(? ?*C' 7,8 ,"  ,«D; &  ?¡'?632#"'?632#"'?Ð   Ð   ÑÅ  ¨©  ÆÅ  ¨©  H¨¶ !"543!#"5çþ|­óÿÿH+ÿñTB"-=M32+"4;5#"4;232+&/327654'&+72#"'&5476"327654'&é$`ŠA 4 '96?8K(MC|WUZW{xWVYVzoLEPIctLCQJf$$û$/3(/$w$*% «YWxWSXXy|WU)QJdmMFSHenLE›½@#"4;2¢ìì((›Z½|!2#"'&5476"327654/&,H,:'0J+9(08 /8/|:'0H,<&1F+)/9/8 H#"=#"4;543232#!2#!"4@´´´þo’þn-¢¢(¡¡(þû((¯•d(3542#5767654'&#"#"'47632Û–$æ„5$-#77"B''+{5$ $ ,- !=µû d6#"'&5472327654'&#&5476327654/#"#"'47632f:4&5*)+0 - ,&- *> ¾$47  $*   $ . +ê½#"'&54?632±r  r Wd  d +ÿ8¡"7#"5#"4;327#"4;32+5#"¥6_1eRJs"KPe9½&(þÒ< [(þ‡(;KOÿ \)332+"'47#+"54;&'&'&=476;2#5µ>bH†aA.HT8OÈÖP&;"3ý¸Hý¸ </Q*ÿû2%3!âÙv\32+"'&5476' -& +&\% *$)ÒÿSy!3#"'&5472327654+&:-$" %./2, ¿šd32+"5432#"'&5476?G²'A  dþÃ$  šÀA"2#"'&5476"327654'&'&-K+ :(1I,:'2; 1!:!2A;!G,;'1G-%0!; 0 =! ?¡'%#"'&54?'&547632#"'&54?'&5476327Ï  ŽŽ  µÏ  ŽŽ  ÐÅ  ¨©  ÆÅ  ¨©  Dd*AE32#"5432#"'&5476#"'&547632#57332+32+"54763=#G²'A  Áþ¡  ^  •€9  U )kdþà  hþb  ž þt"ÚØ$9$ ]´´=d)P #"'&547632%32+"5432#"'&54763542#5767654'&#"#"'47632åþ¡  ^ þªG²'A  Q–$æ„5$-#77"Ýþb  ž {þÃ$  ýß'+{5$ $ ,- !#Dd6H_c#"'&5472327654'&#&5476327654'&#"#"'47632!#"'&547632#57332+32+"54763=#·:4&5*)+0 - ,&-*> þ¡  ^  •€9  U )k¾$47  $*   $ . +þb  ž þt"ÚØ$9$ ]´´qÿQÒ¡$6%5432327675432"#"'&54767#"'&5476;2‹>#-:BM8h09$k* $ + % ›)D:>@ )C "D%1C.Ä! $ " %  O $5%!32+"54;#"54;32+"54;'#"/&547632¬þö6O—³xÌÅ%œLGplr r ¼“áýö¼%þÛ'd d  O $6%!32+"54;#"54;32+"54;'##"'&54?632¬þö6O—³xÌÅ%œLGplÁr  r ¼“áýö¼%þÛd  d  O $8%!32+"54;#"54;32+"54;'##"/#"'&547¬þö6O—³xÌÅ%œLGpl_„  kk  ¼“áýö¼%þÛ0l XX  Oó $E%!32+"54;#"54;32+"54;'#2#"'&#"#"'47632327676¬þö6O—³xÌÅ%œLGplæ$!4 (#'-¼“áýö¼%þÛ  $ % Où $4D%!32+"54;#"54;32+"54;'# 2#"'&547632#"'&5476¬þö6O—³xÌÅ%œLGpl!   è!  ¼“áýö¼%þÛ     O+ $4D%!32+"54;#"54;32+"54;'#2#"'&5476"327654'&¬þö6O—³xÌÅ%œLGplc6 ,3,%" %" ¼“áýö¼%þÛF-0+1! $ $ N359%#32+"54;#"543!#"=#3542"=#35432!"54;5#))h%…?ª¿N((NÓþ§42P½”á˜oÐ`è]†½$þÜ?ÿS@O#"'&5472327654+5&'&'&=47676325432#"'&'&#"32767632#=:-$" %.>"U6 EfeH@0:[<2I?RYC &AQ 2, E:`STI JEp4#I>QGaD:F #< +):!5432!"54;#"543!#"=!35432#"="/&547632¥:þ>66­þÛ‘_r r çw á‹bÑ-ƒ-üd d +);!5432!"54;#"543!#"=!35432#"=#"'&54?632¥:þ>66­þÛ‘Or  r çw á‹bÑ-ƒ-Ýd  d +)=!5432!"54;#"543!#"=!35432#"=#"/#"'&547¥:þ>66­þÛ‘„  kk  çw á‹bÑ-ƒ-l XX +ù)9I!5432!"54;#"543!#"=!35432#"=2#"'&547632#"'&5476¥:þ>66­þÛ‘!   è!  çw á‹bÑ-ƒ-é    qç(32#!"54;#"543!2#"/&547632@‹þÁ‹‹?år r  þád d qç)32#!"54;#"543!2#'#"'&54?632@‹þÁ‹‹?r  r  þáãd  d qç+32#!"54;#"543!2##"/#"'&547@‹þÁ‹‹?Ÿ„  kk   þá l XX qçù'732#!"54;#"543!2#%2#"'&547632#"'&5476@‹þÁ‹‹?þò!   é!   þáï    31#"54;5#"54;2+"54;32+3276=4'&'&#hMM"ÜcE>LBXÜ")¢¢–J9552LÑQIc8oMBáÑçC>KJKA22ó"C!#32+"54;#"54;#"54;2+'2#"'&#"#"'47632327676õ4þÏK–"6j1J•"D$!4 (#'-øþ1áþÏç $ %3ÿð%02#"'&5476"327654'&'"/&547632,nIBQGakIEQGaZ>8H;MX?9I:™r r @]Uz€WMZVx„WM)QJdsM?PJbyL=õd d 3ÿð%12#"'&5476"327654'&7#"'&54?632,nIBQGakIEQGaZ>8H;MX?9I:r  r @]Uz€WMZVx„WM)QJdsM?PJbyL=Öd  d 3ÿð%32#"'&5476"327654'&'#"/#"'&547,nIBQGakIEQGaZ>8H;MX?9I:M„  kk  @]Uz€WMZVx„WM)QJdsM?PJbyL=þl XX 3ÿð%ó@2#"'&5476"327654'&72#"'&#"#"'47632327676,nIBQGakIEQGaZ>8H;MX?9I:@$!4 (#'-@]Uz€WMZVx„WM)QJdsM?PJbyL=Ú $ %3ÿð%ù/?2#"'&5476"327654'&'2#"'&547632#"'&5476,nIBQGakIEQGaZ>8H;MX?9I:¼!   è!  @]Uz€WMZVx„WM)QJdsM?PJbyL=â    vdâÐ#7632"/#"'&54?'&5472,Ž  ŽŽ  ŽŽ   7Ž  Ž   Ž  (ÿÕ0](17#"'4?&5476327632#"'&#" 327654A EBRFaVHB FCQGaZB ;IZ>8lþß;JZ>83R  WXr…XKBS  XSx„WM€l;QJd[þ“;QJd^(ÿð0):#"'&5#"54;2+32765#"54;2#"/&547632óI6Ha:,"•J?)6O/ J•þÎr r  þ¯b;,I7IQþ¯R/>+7Qd d (ÿð0);#"'&5#"54;2+32765#"54;2#'#"'&54?632óI6Ha:,"•J?)6O/ J•„r  r  þ¯b;,I7IQþ¯R/>+7Qãd  d (ÿð0)=#"'&5#"54;2+32765#"54;2##"/#"'&547óI6Ha:,"•J?)6O/ J•é„  kk   þ¯b;,I7IQþ¯R/>+7Q l XX (ÿð0ù)9I#"'&5#"54;2+32765#"54;2#%2#"'&547632#"'&5476óI6Ha:,"•J?)6O/ J•þ¨!   è!   þ¯b;,I7IQþ¯R/>+7Qï    3%&8%32+"54;5#"54;2+7#"54;2#'#"'&54?632Biûi³o&˜•(nar  r þÕÕ ãããd  d +ó3"-732+"54;#"54;2+32#'327654'&+¥Šé66銑_8&H8Kƒ†Q09'0•ƒZá;@,9O1')4"(=&+ÿðó\B747632#"'&5472327654'&'#"547327654'&#"32+"543|:&.J+:‘:!+:-0=9=3/ :n)³A&;&1<';‹`34$> 9#-N2((7*þMHÿð(7H!5#"'&54763254'&#"#"'&54763232#'5&#"3276"/&547632£Yf_)R6K;M<#,b]@\-6_%11$" <0  6Aþ¿] ": IˆA5TÿS¯L#"'&547632327654+5&'&'45476325432#"'&'&#"327632;:-$" %-@)RS=V]??)2g3 I0AmN 7 <2, C VcA9L?UdC8)C2AX6)A2A[6#ðd d Hÿð!32#"'&5476"327654'&'&7#"'&54?632,jC7LAWhD8LAWY8*E3CX8+E,9Yr  r ¯N>VcA9L?UdC8)C2AX6)A2A[6#Ñd  d Hÿð!52#"'&5476"327654'&'&'#"/#"'&547,jC7LAWhD8LAWY8*E3CX8+E,9 „  kk  ¯N>VcA9L?UdC8)C2AX6)A2A[6#ùl XX Hÿð]!B2#"'&5476"327654'&'&72#"'&#"#"'47632327676,jC7LAWhD8LAWY8*E3CX8+E,9„$!4 (#'-¯N>VcA9L?UdC8)C2AX6)A2A[6#Õ $ %Hÿðc!1A2#"'&5476"327654'&'&'2#"'&547632#"'&5476,jC7LAWhD8LAWY8*E3CX8+E,9x!   è!  ¯N>VcA9L?UdC8)C2AX6)A2A[6#Ý    H'!"43!22#"'&54762#"'&5476õþn’ä!   !   ((Š     5ÿÕÊ(17#"'4?&5476327632#"327654&#"šB  B9LAWR>@  @;LAWPÝþþ3BY8*þ·2AY8*#D  CBSeB81B  AAVeB8Yþø(C2ADº&C2AD+ÿð"3!5#"'&5#"54;327#"54;32#"/&547632·TbS"6_,dSJs"þÜr r BR@&þÒ3 Zþˆvd d +ÿð"4!5#"'&5#"54;327#"54;32##"'&54?632·TbS"6_,dSJs"ƒr  r BR@&þÒ3 ZþˆWd  d +ÿð"6!5#"'&5#"54;327#"54;32##"/#"'&547·TbS"6_,dSJs"Þ„  kk  BR@&þÒ3 Zþˆl XX +ÿðc"2B!5#"'&5#"54;327#"54;32#2#"'&547632#"'&5476·TbS"6_,dSJs"þ³!   è!  BR@&þÒ3 Zþˆc    3ÿF%%7!#"54;2+#"54;2+32+"54;#"'&54?632¼s4¤¡6nÿAéÞr  r xþµKý÷èd  d ÿFN#367632#"'32+"54;#"543"327654'&=Jj@ L1`û¶È@.;S2%?.;V2#3ÿF%c%5E!#"54;2+#"54;2+32+"54;2#"'&547632#"'&5476¼s4¤¡6nÿAé!   è!  xþµKý÷ô     OÖ $,%!32+"54;#"54;32+"54;'##"4;2¬þö6O—³xÌÅ%œLGplðì켓áýö¼%þÛÉ((Hÿð@(7?!5#"'&54763254'&#"#"'&54763232#'5&#"3276#"4;2£Yf_)R6K;M<#,b]@\-6_+ %A 1 tL8þö6O—³xpl3ýö ) "  /0““áþ²%þÛHÿe,¯@O%3232767632#"'&54767#5#"'&54763254'&#"#"'&5476325&#"3276Ì6 T+ %A 1 =Yf_)R6K;M<#,b]@\-)QGaD:F #GONeSTI J­d  d Tÿð+=5432#"'&'&#"327632#"'&5476327#"'&54?632Ö>*3g3 I0AmN +Pgr@/S=V]r  r x [0K/?_3"H 7P;QrA0¨d  d ÿÿ?ÿð'Gÿþ™&ÿÿTÿð€&G Fÿÿ?ÿð¿&Vþ\&ÿÿTÿð-&V ÊF?ÿð/B5432#"'&'&#"32767632#"'&=4767632/&5476327632Þ@0:[<2I?RYC &LbfON6 Efej„  kk  ûp4#I>QGaD:F #GONeSTI J@m XX Tÿð+>5432#"'&'&#"327632#"'&547632/&5476327632Ö>*3g3 I0AmN +Pgr@/S=V]M„  kk  x [0K/?_3"H 7P;QrA0;m XX +#67#"54;2+"54;276=4'&'&+7'&5476327632h"ÜgD;N@XÜK–L9362L›„  kk  )áRHc8uK>D=KIMA2vm XX ?ÿðŠh*:32+5#"'&5476325#"543"327654'&%#"'&54?632ö6_Go`A7J=QnH6}U5(C1?T5)D0)T T \ýÍYiK@UeC7hìÖC2AY6(B2A\6&½~ ~ÿÿ3’?ÿðG\(832+32+5#"'&5476325#"54;5#"54;"327654'&ö666_FobA6J=RmHŠŠ6_ÜU5(C1?S6)D0þJQaL?UeC7`+ÖC2AY6(A2A\6'+Ö)1!5432!"54;#"543!#"=!35432#"=#"4;2¥:þ>66­þÛ‘lììçw á‹bÑ-ƒ-ž((?ÿð@ +3%!32767632#"'&547632!&'&#"#"4;2þ`T.:VE HGDnH66­þÛ‘ !  çw á‹bÑ-ƒ-é  ?ÿðc +;%!32767632#"'&547632!&'&#"2#"'&5476þ`T.:VE HGDnH66­þÛ‘ „  kk  çw á‹bÑ-ƒ-pm XX ?ÿð +>%!32767632#"'&547632!&'&#"7'&5476327632þ`T.:VE HGDnH3H:LhA§S2#@-;R2$B,š1@ ;%1R*NSþl:.65'aI;O`?3^6A-;S3$@.:W2"æ' ' 7 2ÿÿ?ÿð2¿&V \*ÿÿ?ÿF2-&V ÊJ?ÿ2@8H%#"'&=47676325432#"'&'&#"327675#"54;2##"'&54?632Za”I1? FccC?,6T7< d7MDF‹Â°T T Ñ­4cB_JaL A6[.68S I…8 –þÎ~ ~?ÿF2š$4D532++"54;276=#"'&547632'"327654'&7#"'&54?632¸_6+3Grt@%Bi]>3H:LhA§S2#@-;R2$B,T T NSþl:.65'aI;O`?3^6A-;S3$@.:W2"ï~ ~ÿÿ5''G™+ÿÿ+''GÿýšK5'3?C32+32+"54;5!32+"54;#"4;5#"54;2+!5#"54;2+!!Þ.6þò6Œ-x66x)þò¥(þ¬ççT(eeeD+'\=5#"54;32+6763232+"54;54'&#"32+"54;#"43|6_<>Z--ƒ-&66' -„.6ý6_(zH >",ú÷.! ÿ¬(ÿÿqç´&YW,ÿÿ\ü"&YÅóqçÖ32#!"54;#"543!2#'#"4;2@‹þÁ‹‹?)ìì þá¤((\ü@32#!"54;#"543%#"4;2@ þ— vìì¡þˆOw((ÿÿqç'U™,ÿÿ\üK&Ußóqÿeô313232767632#"'&54767!"54;#"543!2#@‹$+ %A 1 þä‹‹? þ"  /0á\ÿep,03232767632#"'&54767!"54;#"5437#5@  I + %A 1 þ» v;¡þˆ ' "  /0OÏhhqçù'32#!"54;#"543!2#'2#"'&5476@‹þÁ‹‹?Ÿ!   þáï  \ü¡32#!"54;#"543@ þ— v¡þˆOÿð;3":#"'&'543232765#"54;2#!32+"54;#"54;2#îQ#D-]_ºþm,,, þ›ƒ& 5•‚3 t eþá|ÿFãp,0#"54;+"54;2765#532+"54;#"5437#5³QzB'2€B 0;¦@«B8l;xþCY,6#ŒhhÏþˆOÏhhÿÿTÿðGð&Gdq-“ÿFÊÕ'#"543!+"54;2765#"/#"'47¡ñB'2€B s„ lj  xþCY,6#ñl XX +ÿ<37G732+"54;#"54;2+%#"54;2+32+&/&'#"'&54?632¥Kª66ªK-vÞI)"+ 8W@5*pT T Ý´áùùÆ8/h²9þy~ ~?ÿ\)97#"54;#"54;7#"54;2+32+"54;'#"'&54?632¹_66_­‚/Ï-ƒ´WT T ´´ þ‰“ƒÌ²þÄ~ ~ÿÿF¡?+!5432!"54;#"54;2#7#"'&54?632ãþ=``ér  r  þ Éáãd  d \ü$32#!"54;#"543%#"'&54?632@ þ— ur  r \ýÍ ‘d  d ?ÿ3)!5432!"54;#"54;2##"'&54?632ãþ=``éT T  þ Éáý•~ ~\ÿü\"32#!"54;#"543#"'&54?632@ þ— uœT T \ýÍ ýC~ ~?6)!5432!"54;#"54;2#7#"'&54?632ãþ=``é²T T  þ Éá~ ~\üh"32#!"54;#"543#"'&54?632@ þ— uRT T \ýÍ ~ ~ÿÿ?3&yAý/ÿÿ9ó\&y}OÝ+3/7632!5432!"54;5#"'&54?5#"54;2#↠šþ<`j  ~`é ÔP \Þ¡ÊÍ> Jå\ü\(763232#!"54;5#"'&54?5#"543?X l¢þ–ŸW ku\þû3 >ÿï2 =ì2"4!#32+"54;#"54;#"54;2+'#"'&54?632õ4þÏK–"6j1J•"Dr  r øþ1áþÏãd  d 50B6763232+"54;54'&'"32+"54;#"543%#"'&54?632§;2T."m"&&,7('-ƒ-"Ur  r ¡EB :",þ÷, ! 2ýO¶d  d ÿ23"2!#32+"54;#"54;#"54;2+#"'&54?632õ4þÏK–"6j1J•"£T T øþ1áþÏý•~ ~5ÿ¯0@6763232+"54;54'&'"32+"54;#"543#"'&54?632§;2T."m"&&,7('-ƒ-"âT T ¡EB :",þ÷, ! 2ýOýþ~ ~2"5!#32+"54;#"54;#"54;2+/&5476327632õ4þÏK–"6j1J•"É„  kk  øþ1áþÏvm XX 50C6763232+"54;54'&'"32+"54;#"5437'&5476327632§;2T."m"&&,7('-ƒ-"Є  kk  ¡EB :",þ÷, ! 2ýOIm XX 5¯06763232+"54;54'&'"32+"54;#"543§;2T."m"&&,7('-ƒ-"¡EB :",þ÷, ! 2ýOÿ9235!#32+"54;#"54;#"54;2+#"'&547232765Ì þÏK–"6j1J•";'1+  ?øþ1áþÏýÆM, 7"5ÿ9à¯74'&'"32+"54;#"54;67632#"'&54723276·&&,7('-ƒ-"K;2T.;'1+  ?*J, ! 2ýOEB :",þ©M, 73ÿð%Ö'2#"'&5476"327654'&7#"4;2,nIBQGakIEQGaZ>8H;MX?9I:)ìì@]Uz€WMZVx„WM)QJdsM?PJbyL=—((Hÿð@!)2#"'&5476"327654'&'&7#"4;2,jC7LAWhD8LAWY8*E3CX8+E,9mìì¯N>VcA9L?UdC8)C2AX6)A2A[6#’((ÿÿ3ÿð%'U™2ÿÿHÿðm&UR3ÿð%1C2#"'&5476"327654'&'#"'&54?632#"'&54?632,nIBQGakIEQGaZ>8H;MX?9I:.a  b ‚b  b @]Uz€WMZVx„WM)QJdsM?PJbyL=Ð^  ^  ^  ^ Hÿðy!3E2#"'&5476"327654'&'&'#"'&54?632#"'&54?632,jC7LAWhD8LAWY8*E3CX8+E,9a  b ‚b  b ¯N>VcA9L?UdC8)C2AX6)A2A[6#Ë^  ^  ^  ^  N3&135432!"'&54763!#"=#35432#"='#";RÓþ¹„F3Z@[;¿Nw j7557j ç\…eIl“N8šqÑ`úFChgCF ÿðB¯07G%!32767632#"'&'#"'&547632676323&'&#"#"327654'&Aþþ8"!- <+I2 'I B.*;*4A/ &/M'þÿØ8Y®2#0#0$1Çb2&  -LfKBWhC0G5$L4!A7A4A[9#?5A^8"+M)4F732+"54;#"54;232+&'&/327654'&+%#"'&54?632¥Kª66øT8(‹7(& 9U7'„r^57'-™ r  r ûÒá;,5a0%:"@ œ2)3$4$ãd  d T%767632"'&#"32#!"54;#"543%#"'&54?632øj:(%#)7A³þÄ`K-r  r ¡f`  "*8ÝO¶d  d +ÿM3)4D732+"54;#"54;232+&'&/327654'&+#"'&54?632¥Kª66øT8(‹7(& 9U7'„r^57'-™ÁT T ûÒá;,5a0%:"@ œ2)3$4$ý•~ ~Tÿ«%567632"'&#"32#!"54;#"543#"'&54?632øj:(%#)7A³þÄ`K’T T ¡f`  "*8ÝOýþ~ ~+M)4G732+"54;#"54;232+&'&/327654'&+7'&5476327632¥Kª66øT8(‹7(& 9U7'„r^57'-™‡„  kk  ûÒá;,5a0%:"@ œ2)3$4$vm XX T%867632"'&#"32#!"54;#"5437'&5476327632øj:(%#)7A³þÄ`K¨„  kk  ¡f`  "*8ÝOIm XX \ÿðüCU5432#"'&'&#"#"'#"=432327654'&'&'&'&'476327#"'&54?632½<#,R(R+_#=M6Kj?A,8[.-E `(3F1AV0r  r g95"E %QV0!Hp;#8 (7 $DN- ­d  d gÿðñDV5432#"'&'&#"#"'#"=432327654'&'&'&'&'476327#"'&54?632°C"R# &'V,1J4F`=<*4]*'#I\&-D,;U5r  r E0) !9C&6 S).# 2;!¨d  d ÿÿ\ÿðü'G™6ÿÿgÿðñ€&GV\ÿSü@^#"'&5472327654+5&'#"=432327654'&'&'&'&'476325432#"'&'&#"8:-$" %/\1A,8\.-E `(3F1AV<<#,R(R,^#=Q02, B <p;#9(7 $DN- ;g95"E %QX/gÿSñ¯c#"'&5472327654+5&'#"=432327654'&'&'&'&'476325432#"'&'&'&#"8:-$" %.T.<*4]*'#I\&-C,;V4<T! '%V,1N%/ 2, B , S).# 2; .E,) !9G%\ÿðüCV5432#"'&'&#"#"'#"=432327654'&'&'&'&'47632/&5476327632½<#,R(R+_#=M6Kj?A,8[.-E `(3F1AVK„  kk  g95"E %QV0!Hp;#8 (7 $DN- @m XX gÿðñDW5432#"'&'&#"#"'#"=432327654'&'&'&'&'47632/&5476327632°C"R# &'V,1J4F`=<*4]*'#I\&-D,;UJ„  kk  E0) !9C&6 S).# 2;!;m XX ÿÿHÿS3&z7ÿÿ+ÿCó3&zêðWH0%32+"54;##"=!#"'&=#/&5476327632Aiûi§È¦„  kk  )áIrrIvm XX +ÿðüh)932+32767632#"'&5#"54;5432%#"'&54?632ºÜÜ=SE KA;e&JJ:T T ¡þõ9!?" w+~ ~H3)32+32+"54;#"4;5##"=!#"'&=#Acciûi``§È¦Q(ÿ(¹IrrI+ÿðó355#"54;543232+32+32767632#"'&=#"43‘JJÜÜÜÜ=SE KA;e&Kewwe(~9!?"€(ÿÿ(ÿð0´&YW8ÿÿ+ÿð"&YøÅX(ÿð0Ö)1#"'&5#"54;2+32765#"54;2#'#"4;2óI6Ha:,"•J?)6O/ J•sìì þ¯b;,I7IQþ¯R/>+7Q¤((+ÿð@"*!5#"'&5#"54;327#"54;32##"4;2·TbS"6_,dSJs"`ììBR@&þÒ3 Zþˆ((ÿÿ(ÿð0'U™8ÿÿ+ÿðm&UøX(ÿð0+)9I#"'&5#"54;2+32765#"54;2#2#"'&5476"327654'&óI6Ha:,"•J?)6O/ J•é6 ,3,%" %"  þ¯b;,I7IQþ¯R/>+7Q!-0+1! $ $+ÿð•"2B!5#"'&5#"54;327#"54;32#2#"'&5476"327654'&·TbS"6_,dSJs"Ö6 *3,%" %" BR@&þÒ3 Zþˆ•-/+1! $ $(ÿð0);M#"'&5#"54;2+32765#"54;2#'#"'&54?632#"'&54?632óI6Ha:,"•J?)6O/ J•Êa  b ‚b  b  þ¯b;,I7IQþ¯R/>+7QÝ^  ^  ^  ^ +ÿðy"4F!5#"'&5#"54;327#"54;32##"'&54?632#"'&54?632·TbS"6_,dSJs"Ëa  b ‚b  b BR@&þÒ3 ZþˆQ^  ^  ^  ^ (ÿe03A327632#"'&54767#"'&5#"54;2+32765#"54;2#ó/%<, %> 1'`;+"•J?)6O/ J• þ¯Q23)" , .!I7IQþ¯R/>+7Q+ÿe,¡:3232767632#"'&54767#5#"'&5#"54;327#"543à" S+ %A 1 )TbS"6_,dSJ¡þˆ 2)"  /0BR@&þÒ3 ZÿÿD'G™:ÿÿ:€&GZÿÿ3%'G™<ÿÿ3ÿF%€&G\3%ù&6F%32+"54;5#"54;2+7#"54;2#%2#"'&547632#"'&5476Biûi³o&˜•(nþË!   è!  þÕÕ ããï    gñ')55!#"=!!5432#"'&54?632ñþvHþó]þ¸:@r  r ;ÌvŸ:þ47d  d sé%!5432!5##"=%#"'&54?632ÚþÑþŠ-û5r  r ¡$þ¬8a$T7`¶d  d gñù%)55!#"=!!54322#"'&5476ñþvHþó]þ¸:Å!  ;ÌvŸ:þ4C  séc#!5432!5##"=72#"'&5476ÚþÑþŠ-û°!  ¡$þ¬8a$T7`  gñ()55!#"=!!5432'&5476327632ñþvHþó]þ¸:É„  kk  ;ÌvŸ:þ4Êm XX sé&!5432!5##"=7'&5476327632ÚþÑþŠ-û®„  kk  ¡$þ¬8a$T7`Im XX i\%%32#!"54;#"54;547632"'&#"²þÃbXX@'3FE06"J )O=E$ /ÿð\8"327654'&%5#"54;32+672#"'#"54;#"543BU5(B1?S6)C0þæ6_ŠŠHlf@3J=RnF_66†C2AW7)B2@[7'‚+T—fM=SgC8hX¶ÿæ3 B327654'&+327654'&'&+!2#!"54;#"32#"'&5476¥“X(7!)¤ÐE%6,S•_Z2U?-9þÎ66  12947þ2"7##<%0I/-dJ.!á *6 ÿÿ,3Þÿð\/"327654'&'672#"'#"54;#"543!2#BU5(B1?S6)C0ñHlf@3J=RnF_66¨†C2AW7)B2@[7'­ëfM=SgC8hX .%N 7327654'&'&#'32#!"54;""'&54?54327272­ÐE%6,S•“­, ?-9þÎ62FJç2"7#Ì£fJ.!—# 0B%3 ÿðN>7327654'&#"5672#"'#"54;""'&54?54327272B1?S6)C0?U5(Hlf@3J=RnF_6- AOÐW7)B2@[7'C2Ê“fM=SgC8hX•  -C'7 ?ÿð@/632#"'&54723276=4'&#"#"=432wHefE: OOebL& ER ^B:F9JT6!ûEJ>X SfNNG# QJATGcA41#p?ÿð›xC547632#"'&54'&##"'&'&#"32767632#"'&=4767632Þ(7  @0:[<2I?RYC &LbfON6 Efeû1/ p4#I>QGaD:F #GONeSTI JTÿð“å?547632#"'&54'&##"'&'&#"327632#"'&547632Ö(7  >*3g3 I0AmN +Pgr@/S=V]x 1/ [0K/?_3"H 7P;QrA0ÿÿ3’ÿÂ3 673276=4'&'&+'!2+"54;#"32#"'&5476‘–L9362LogD;N@XÜ"F 22)D=KIMA2)RHc8uK>á #*6 ÿÿ:,3GÞXÀ@ÿð\/"327654'&7!"543!2+32+5#"'&547632ñW5&A2?U6'B1sþ·¨66_FnbA6K=QjJ†E2BS7*D2AX6(­ýöXhL@VhA4gÿÿDÿ4ǪJ¿Àÿÿ+3G(3À@2ÿð@ -%3276=4'&#"#"'47632"'&'&=íþnF9J[<2I?RYC &LbfON6 EÌE: ý cA4I>Q4aD:F #GONeSTI JJ>X :\ÿðü@H747675&'&5476325432#"'&'&#";2+"32767632#"=#"'&\Q?F1AV<<#,R('2?0=B,,B*7Y1?jp:$—Y(=N- ;g95"1!9D$4$pHE*ÿ£53/7#"543!#"=!35432#"=#0#"'&54723276©6ÂþÆ‘‘ <+  .@Ê‹bÑ-ƒ-ç^  :Wÿ£j532+#"'&547232765#"54;547632#"'&#"A``;'1+  ?``<(3+G wþìM, 7"WO/ 9?ÿðœxL547632#"'&54'&##"'&'&#"327675#"54;2+#"'&=4767632ß(7  ?,6T7< d7MDF‹ÂZa”I1? Fcc 1/ [.68S I…8 –­4cB_JaL A0ÿå"3 5%325&/#"54;2+7#"54;2##"'&5476,.0<'+²o&˜•(n¬* 6> ;ãBO Z$9@ããþü9.'X B#AFÿïE\F%&=4'&'&'0#"32+"54;#"54;676332765#"54;0#'&T 4#-„.6_$v,>JsI 3#)2¯1; ÿ ô4 v °3 =þÓ#P ­ÿø÷3%#"'4;327676#"'&=fD7# %C E x“þEW( 4 @qç3#5#"543!2+32+32#!"54;5#"43‹?‹dd‹þÁ‹_AÉÉ(ðð(+f3L32+&/&'32+"54;#"54;2+%#"54;2#"'&547632765&'&'öÞI)"+ 8W@5*QKª66ªK-v0 /  Æ8/h²9I´áùù' 7  ?j7747632#"'&#"7#"54;2+32+"54;'#"543<(3+G ­‚/Ï-ƒ´._)¥O/ 9铃̲'´\ü\ 5#"54;32#32#!"54;5#"43užb b þ— a:ùþÞéé(:ÿþ&f<7473'""'&54?'#"54;272722+"54; 32+"'": ºNP^U HJÝn8££5n 86 87  1 4þ0 Tþ¬ ÿòQ3=!5#"'"'&5#"54;32767#"54;327#"54;2+32#ì*0@!:78"J"/0"J"27"m""4;GE1 ¬þ/( Eþ2) Rþÿ£T3+7#"'&547232765#"54;#"54;2+#Ò <+  .6jJ•"4þï)^  : ÊþÏýöøþB5ÿH¯06763232+"54;4'&'"32+"54;#"543§;2T."m"&&,7('-ƒ-"¡EB :",þJ¯, ! 2ýOÿÿ3ÿð%@‡3ÿðU 9"327654'&327654'&#"'&547632+#"'&547632,Z>8H;MX?9I:B: 21BQGakIEQGaPQJdsM?PJbyL=  #*6 Uz€WMZVx„WMHÿðN;"327654'&'&7327654'&#"'&547632+#"'&547632,Y8*E3CX8+E,9z? 214LAWhD8LAWH†C2AX6)A2A[6# #*6 =TcA9L?UdC8ÿðR~>"327654'&763232+"54;4'&#"#"'&547632Ùi,D+>c.G*)fVWF 3M R5Kr;)T5M!r=SŠF,j?V’D)IIþá=  3n#%¡M2nLj©P3ÿðTÔ:"327654'&767232+"54;4'&#"#"'&547632ÈE&8"*E&8"$7Y:.„.3 <.?@0;M3+B.;+†J1A_4G1?a5 ;2!þÁ?< ..J?TqC.ÿæó3 9327654'&+"32#"'&5476;2+32+"54;¥†Q09'0¾6 22ð_8&H8KƒŠé6 ú4"(=& #*6 @,9O1'¾ÿFjA7327654'&#"47632#"'&#"67632#"'32+"543C0?V5'D0>W5&)<(3+G =Jj@ L1`û<ÿF3 B7327654'&+53232#&'&'&'#32#"'476;#"'4732+ªaW,6!„ƒY-^ 6% 2 %q?•--•?Ý(& +4#Il‰''uv(* Œá\ÿðü@C63232767632#"=#"'&547676767654'&#"#"=432›$S O"'<$/P);?(4C%9D$4$pHE*8N( 1>!3ggÿðñ¯C6323276=472#"=#"'&547676767654'&#"#"=432¨4Ub0.#S I#)@'3Y,=`n72,VW 9 )^.4"0 $1)S 6:!)7# * 0 EÿÿfêA™Qÿ£j8"327654'&#"'&547632327632#"'&54®%" %" O*3,L-3  +J+I $ $5/+1>)5þrF  <(3”&+ÿ9ó3;%#"'&5#"54;543232+32767632#"'&547232765ÊKSe&JJÜÜ=SE ;'1+  ?!?" wwþõ9!cM, 7"3."32#"'&54763!#"'&=#32+"54;q 22Ÿ¦iûi  #*6 rIþá+ÿðój932+32767632#"'&5#"54;547632#"'&#"ºÜÜ=SE KA;e&JJ<(3+G Î-þõ9!?" -O/ 9Hÿ93&327632#"'&5##"=!#"'&=A3  +J+§È ýÌF  <(3:IrrI(ÿðuÇ=#"'&5#"54;2+32765#"54;27654'&#"'&547632#óI6Ha:,"•J?)6O/ J• 21 þ¯b;,I7IQþ¯R/>+7Q #*6 +ÿð>5:32+5#"'&5#"54;327#"54;27654'&#"'&547632à"KTbS"6_,dSJs 21xþ±BR@&þÒ3 Z #*5 Nÿþ;F"=336767454'&'&/53"=#+&'&54767675#cÏI!5 ) \632 " Ô8+8' ) ZE17]}¯$8Q@/ !;CR2 ¯ea ,;[M>% 47d†;ae+ÿô)3###"'&5#"'4;2+3276532) 4«Ÿ51K!7&&^þ†œ€xþŠQ ?£ÿî%397#"54;2#32+"54;5#"32#"'&5476;2#—˜•(n°iûi³ 22o ããþôÕÕ  #*6 3ÿFj59 32+"54;7#"54;2+#"54;27654'&#"'&547632#üÿAéG¼s4¤¡6n 21xý÷‘xþµK #*6 gñ3!!5432!57#"4;75!#"=!32#6¨:þvžMjþó]ƒQì¶;Þ(ÆvŸ:¸(sé¡%7##"=!32+!5432!57#"43(xû^}GjþŠ’Mñ‡7`$Œ( 8a$¥(`ÿñó34!2+632#"'&547632327654'&#"'&76?##"5p?&,Z3$M5JOJ. IW]-?"-?? ´·3‹ I3Fp=+1 CJ,;X)!  ­7ÿÿPÿñã3GyCÀ@ÿÿ_ÿbµ¡G0À@Xÿ#µ¡G%'3767672'&'67665&/#"0/&76?#"'47!2+32¨c%&P F+<1 <,2U//O&,†9, -  ´È† |ˆl$ ,7- .:M o;   ­~HTÞj632#!5432!57#"4;67654'&#"#"'&547672Š5 ]J:þvÖW€M 7(0H. >\R9- %-<$M<É(L$<)6 (I?1<0*,Pÿñó30!2+632#"'&547632327654'&#"#"'5#"'4hGñI;Z3$M5JOJ. IW]-?"-??-3I3Fp=+1 CJ,;X)!»_ÿ줡8"543!2+6232#"'&76762327654'&#'&'&5zé *y& B$2a1 $Cc @),! xyO$V'= ,U L ÿÿ†ÿòç3G<3@ÀÿF¼ *%654'&#"32+"54;#"54;767232I7V0MbÁ66_3In ‹Wã;G8  <þG G(9l\Fÿ„@\"542@((Aý^¢Øÿ„€\"542"542€((€((Aý^¢ý^¢3ÿ„%\#32+32+"5#"54;5#"54;542@ÊÊÊÊ(ÊÊÊÊ(wgþágÊÿÿðÿñhj1í&8G'&54727632#55##"=335432#"54;2+"54;2=4'&'&/&+¼j VV  껀лšþ\¦¦\;&x  Xm XX ý<;ÌvŸ:þ4áý8þÌIN%& 9u$6E'&5472763235432#5##"=#"54;2+"54;2=4'&'&/&+¼j VV  ¯•ö­sþð\¦¦\;&x  àm XX «$þ¬8a$T7`þˆáý8þÌIN%& ÿð)uJ'&54727632"3654'&##"=335432!5#"'&547235#"54;¬j VV  þf:" X2¤ª{Þ¯•þ¬  > Y66_àm XX ƶ{-´*þ£O7`$þ¬8a1/ p1?Ø" ÄýÍÿðO4:35432#"54;#"54;2#!#"'&'5432765#"54;2#qYÓ((‰Ys/$ 9 _º þ Éáþ›µ7•‚4;:eÿFGp/335432!"54;#"54;2##"54;+"54;2765#5»­þ¡``éüQzB'2€B 0; þ Éá’þCY,6#Œhh|ÿFãp,#"54;+"54;2765#532+"54;#"543³QzB'2€B 0;¦@«B8xþCY,6#ŒhhýÍ ÿðO3<!#32+"54;#"54;#"54;2+7765#"54;2+#"G2£+f&Z£*u" 8/z"U8ØþQáþ(¯þ3$N#eþ›•ÿFGp"8<!#32+"54;#"54;#"54;2+#"54;+"54;2765#5‘4ÍK–"6jÍJ•"†QzB'2€B 0;èþAáþ¿’þCY,6#Œhh ÿFGp5KO6763632+"54;54'&'&#"32+"54;#"543#"54;+"54;2765#5/W+"m"9  -ƒ-"ãQzB'2€B 0;¡E@ >!*þ÷' )  ýO)þCY,6#Œhhÿÿ Oð&Hq$ÿÿHÿð^&HßDÿÿqçð&Hq,ÿÿ\ül&Hÿíóÿÿ3ÿð%ð&Hq2ÿÿHÿð^&HßRÿÿ(ÿð0ð&Hq8ÿÿ+ÿð^&HøßXÿÿ(ÿð0I'q žÿÿ+ÿð¬&qøl¾ÿÿ(ÿð0¶'vÿÂ7žÿÿ+ÿð'vÿºš¾ÿÿ(ÿð0¶'H7žÿÿ+ÿð'Hÿøš¾ÿÿ(ÿð0¶'C>7žÿÿ+ÿð'C6š¾?ÿð¯"+7!&'&#"#"'&547632#"'&'&%!3276? T.:VE HGDnH3H:LhA_67B 3Grt@$z†A-;S3$@.:W2"þJ aI;O`?3^Sþl(64(ÿÿ?ÿð2ð&H q*ÿÿ?ÿF2^&H ßJÿÿ+<ð&Hq.ÿÿ?'HšNÿÿ3ÿU%@&XÖð2ÿÿHÿU¯&XÖðRÿÿ3ÿU%ƒ&qC¬ÿÿHÿUñ&q±­ÿÿ`ÿñóý&Hà~yÿÿ_ÿbµl&Häí0“ÿF^&#"543!+"54;2765'&54727632¡ñB'2€B !„  jl xþCY,6#åm XX 13'6!#55##"=335432#"54;2+"54;2=4'&'&/&+1껀лšþ\¦¦\;&x  ;ÌvŸ:þ4áý8þÌIN%& 93%435432#5##"=#"54;2+"54;2=4'&'&/&+*¯•ö­sþð\¦¦\;&x  ¡$þ¬8a$T7`þˆáý8þÌIN%& ÿð)\ 9"3654'&##"=335432!5#"'&547235#"54;|:" X2¤ª{Þ¯•þ¬  > Y66_†¶{-´*þ£O7`$þ¬8a1/ p1?Ø" ÄýÍÿÿ?ÿð2ð&vÎq*ÿÿ?ÿF2^&vÎßJÿïD5D32765#"54;0#'&'&=#32+"54;#"54;2+35#"54;2#i,>JsI 3#¾6Œ-h&¾&h þg3 =þÓ#P 2ŸçáÑÑÿF<*763232+"54;#"54;654'&#">IqpMþÃbÁ66_C4!\;Ý,3FUMþɆ›‰þ„CC5 %ÿÿ2ð&C6q1ÿÿ5^&C<ßQÿÿ Oè'vÿÂi‡ÿÿHÿðR'vÿÈÓ§ÿÿ Nð&vÂqˆÿÿ ÿðB^&v¼ß¨ÿÿ(ÿÕ0'vÿššÿÿ5ÿÕ‡&vÀºÿÿþCOê&lq$ÿÿþIÿðX&lßDÿÿ OÝgUÇ@À$ÿÿHÿð}gUg@ÀDÿÿþ1ê&lîq(ÿÿþ;ÿðX&løßHÿÿ+ÝgUÿîÇ@À(ÿÿ?ÿð}gUÿøg@ÀHÿÿþCçê&lq,ÿÿþCüX&lßóÿÿqçÝgUÇ@À,ÿÿ\ü}gUg@ÀóÿÿþCÿð%ê&lq2ÿÿþCÿðX&lßRÿÿ3ÿð%ÝgUÇ@À2ÿÿHÿð}gUg@ÀRÿÿþSMê&lq5ÿÿþOX&l ßUÿÿ+MÝgUÇ@À5ÿÿT}gU g@ÀUÿÿþCÿð0ê&lq8ÿÿþ;ÿðX&løßXÿÿ(ÿð0ÝgUÇ@À8ÿÿ+ÿð}gUÿøg@ÀX\ÿü@CS5432#"'&'&#"#"'#"=432327654'&'&'&'&'47632#"'&54?632½<#,R(R+_#=M6Kj?A,8[.-E `(3F1AVCT T g95"E %QV0!Hp;#8 (7 $DN- ý_~ ~gÿñ¯DT5432#"'&'&#"#"'#"=432327654'&'&'&'&'47632#"'&54?632°C"R# &'V,1J4F`=<*4]*'#I\&-D,;U>T T E0) !9C&6 S).# 2;!ýð~ ~Hÿ3-%32+"54;##"=!#"'&=##"'&54?632Aiûi§È¦T T )áIrrIý•~ ~+ÿó3)932+32767632#"'&5#"54;5432#"'&54?632ºÜÜ=SE KA;e&JJ„T T ¡þõ9!?" wý‡~ ~oÿëþ@B'&'&76?67654'&#'&'&76?654'&#"#"=432632—V”"¥  £’8F '<$/P)!3g;?(4C"|ÿ‹î¯A%'&'&76?67654'&''&'&76?654'&#"#"=432632¡K@;” ”K ,‡ º 9 )^4Ub0#é$GB.%V V+!(I  f* 0 E.4",ÿÿ5'ð&Hq+ÿÿ+''HÿýšKgÿ9ñ3()55!#"=!!5432#"'&547232765ÈþŸHþó]þ¸:;'1+  ?;ÌvŸ:þ4æM, 7"sÿ9é¡&)5##"=!!5432#"'&547232765Àþ³-û^þÑ;'1+  ?$T7`$þ¬8‘M, 7"ÿÿ O¿&V\$ÿÿHÿð-&VÊDÿÿ+ÿS3&zô(ÿÿ?ÿC¯&zþðHÿÿ3ÿð%I'q ˜ÿÿHÿð¬&ql¸ÿÿ3ÿð%C'q—ÿÿHÿð¬&ql·ÿÿ3ÿð%¿&V\2ÿÿHÿð-&VÊRÿÿ3ÿð%'qÏìÿÿHÿð}&q=íÿÿ3%&qP<ÿÿ3ÿF%ÿ&q¿\Hÿò±(7632#"'327632#"'&5#"543327654'&#"ÂYf_)R6K;M<#-a]@\-6_f4-[Tÿ|¯7@%547632"'&="'&'&5476325432#"'&'&#"765&'"H6J©l9%S=V]?>*3g3 I#-J€>8DK ;gb` S7HrA07 [0K/?`3><=?ÿ9·\8"327654'&7327632#"'&=#"'&5476325#"543U5(C1?T5)D03  +J+Go`A7J=QnH6†C2AY6(B2A\6&ÖýzF  <(3‰iK@UeC7hì?ÿð»j8%4'&#"3276=47632#"'&#"32+5#"'&547632ÍD0?U5(C1?T5)<(3+G 6_Go`A7J=QnÎ\6&C2AY6(B2º‡O/ 9þ[YiK@UeC7?ÿð¯ )74767632#"'&547632327675&'&#"?(`$(lC5PE]TN1 6[l9S'.e6Ç9)\ K;PiE;&+ O)6)`%I"+?ÿð¯"+7!&'&#"#"'&547632#"'&'&%!3276? T.:VE HGDnH3H:LhAÛW2"A-;S3$@.­€O/ 9þ:.65'aI;O`?3^?ÿFá¼2"327654'&5432+"54;276=#"'&547632S2#@-;R2$B,n+3Grt@%Bi]>3H:LhA†A-;S3$@.:W2"8SþC:.65'aI;O`?3^Mÿôª6%#"'&=47676325432"'&5&'&#"3275#"'6732ßOU?"=>WT;<#+L/: &;>uªv&S.?7M90( C$ %/D6x\4ÿ7(¡&.%3#"54;2+#'&747#"54;2+274+¢2o»%)%¶o1Ÿ%Sþ{J3% 2L„þL-!!2ÿì& 3?632#"=&'&#"#"'&547&#"#"=432632632327654þ E5H*!? H4F, !V@@V"¸<# '‘S$/Z‹A#?Š[/ S99uPw5,w+ÿE'¡1#"'&=#"54;2+3276?#"54;2+32#­<>Z--ƒ-&66' -„.6»H >",ú÷.! ÿýö3'j?747632#"'&#"6763232+"54;54'&#"32+"543|<(3+G <>Z--ƒ-&66' -„)¥O/ 9sH >",ú÷.! ÿ3ÿ9ÞjF#"'&5472327654'&#"32+"54;47632#"'&#"67632Þ;'1+  ?&66' -„.<(3+G <>Z-#þ­M, 7"J.! ÿ¥O/ 9sH >"\üp$#5#"54;5#"54;32+32#!"54;>;  vŸ   þ— phhþX‡°Ÿ­ÿø÷ª%#"'4;327676#"'&=fD7# %C E x þÎW( 4 @‡Ñ¡32!"'476;#"'67!2Awþçyyxþ±O\ü\527672#"'32#!"54;5&#"#"'&5476725#"54;@.$% 1-' þ— *# 2*%už#%4 ;Æç#*  4ð\ü\+85#"54;32+32#!"54;5#"'&7&7664/"#;užŸŸ þ— 26 ,/ 2«ˆþÐÛÛ/4 e5 /" ‡ÿ9\327632#"'&5#"543@3  +J+u\ýzF  <(3c ÿòQ¡=!5#"'"'&5#"54;32767#"54;327#"54;2+32#ì*0@!:78"J"/0"J"27"m""4;GE1 þÁ( E þÄ) R þ± ÿFQ¡=5#"'"'&5#"54;32767#"54;327#"54;2+32#ì*0@!:78"J"/0"J"27"m""ºî;GE1 þÁ( E þÄ) R ý÷ ÿ9¯J#"'&5472327654'&#"32+4'&#"32+"54;#"54;67632672:'1+  ?"/0"J"27"m""J*0@!:78 CþM, 7"i( Eþõ<) RþõO4;GE1ÿ½ÿ9¯7#"'&547232765#"54;6763232+"54;54'&'"§;'1+  ?"K;2T."m"&&,7(&þªM, 7"¢EB :",þ÷, ! 5ÿ9¡¯9327632#"'&54'&'"32+"54;#"54;67632à3  +J+&&,7('-ƒ-"K;2T.'þ¯F  <(3P, ! 2ýOEB :"6¡$!#32#"'476;#"'673#"'6732#ß1þö@„-] ?ƒkþ¾Oþ•BHÿð¯!2#"'&5476&'&#"!3276,jC7LAWhD8LA H/9Y8#tþŒ G/;X8%¯N>VcA9L?UdC8ËV.C*5(S0 B* K¡&2)"'&7&763!#"=#35432#"=#35432%#;Kþ¾E+_<]5¹KKÍþá$™( l-= W7Ls4 šq‰`\óIx(pÿ6!f)532+#5#"'&=476;53#";276=4'&'#_5U%-#P"-5U%-(K"--6* #"1-6* +&1¡>(™8-ÊÊ>(™8-Åí+™++™-ÿÿTÿö¡Uq¡ÀÿÿTÿö[q¡À4ÿ9C¡3327632#"'&=#"'&5472327675#"543!2#‚3  +J+j:(%#)7 >³<xþ^F  <(3–`  "*9ÝTÿF«%67632"'&#"32#!"54;#"543øj:(%#)7A³þÄ`K¡f`  "*8þi iÿ9«.327632#"'&5#"54;67632"'&#"ø3  +J+Ktj:(%#)7AþÐF  <(3¨f`  "*8T¡)"54;5476;2+"32«þÄ`B'2€B ³ÚY,6#ÚÿÿT¡GZÀ@<¡-8732#"'476;#"'673232#&'&/3276'&'&+ª?•--ÚP0P6$2J5!qaO05!„µŒM1%)5þrF  <(3Qÿ£j627654'&#"76547632"'&#"#"'&547632®% % l;'1+  ? <(33,3cA4F  8 A2=P. ­†çA+%567654'&#"#"=76723232+"543ˆ>#-=DM8h09 =-ƒ)é9;@")D "D%1C.Îÿÿ†çAG1mÀ@ÿÿ†ÿòç3G13@À?ÿ6@/5432#"'&'&#"32767632#"'&54767632Þ@0:[<2I?RYC &LbfON6 Efeûp4#I>QþÿaD:F #GONe TI JIÿ¡%07#"'6732#!"'47637327654'&+327654'&+Ž-ãU+Kp:'0þóV]BŽ´N/$L€)O28!!K8"Ä/ 1 þ±- *MÿôuìJ547632#"'&54'&#"'&5&'&#"3275#"'6732##"'&=4767632¸(7  <#+L/: &;>uª OU?"=>WT‚ 1/ C$ %/D6x\v&S.?7M90S ¡7%#32#"'476;#"'6732#35#"'4732#32#"'476;¢è-{%j-è-j&|-Ä›O‹‹þ±ÿF"p$3#5+"'&5676;#"543!32+";2767ž;gM$% G'C!ñDm2% 0!phhý!Y+3"DOþˆ!#( .ÿÿ?\N\\À\¡35432!"'476;#"'6732ïèþsSSÍxþ±l•O?ÿF»jA%4'&#"327632+"54;5#"'&547632547632#"'&#"ÍD0?Y5B1?W5')6ÁbCqh@2M0[O/ 9†çA9%#"54;567654'&#"#"=76723232+32+"54;iiˆ>#-=DM8h09 =ii-ƒ-˜Q9;@")D "D%1C.6oÿÿ†çAG<mÀ@)ÿï9\5"7654'&3'335432!5"#&'&547635#"54;œ"(51tªÂü¯•þÌN4!3"P6_†B2Bc:H0>g6þ±O)$þ¬8a1<M>S‚>?Äÿb=\b"7654'&7!2+32#"/&7676327654'&'&#"0'&76?#32+5"'&547635#"54;Œ"(=1t† Q,7-@IK  <+ 9&1- ´Â&O[6 3"P6_†B2Be9R+9g6~P2>cA4F  8 A2=P. ­þ±1@O>S‚>?ÄËÿð3'#"54;543232+327632#"'&51JJ||3  +J+xwwëF  <(3ÿðFj973276'&7632#"'&#"#"'&=#"54;543232+§4<#9,9+B #7,7J+JJ||H 1$AG0% 1%þ¹A0&<(3ñwwûêv˜#7632KPW êŸûêv˜3#"'75&PW ˜Ÿûêv˜"/K* W˜–Ÿ,à‰•27654'#,&" 8 * $!./Ïà,•"'&54763",3/%! !*6 !!$›ê½#"/#"'&547,„  kk  l XX ›ê½'&5476327632,„  kk  êm XX ê@{ "=472@cbbÿÿ›½@qÿÿê½vÿÿ›ê@Cås¡ 32'&/&76"74?6#úd6 6 6 6 ¡p p þ_p p å s¡ 32'&/&76úd6 6¡p p ÿÿ,À‰uEþàÿÿÏÀ,uFþà» #"4;54232‚¬B(B(BB(»êo 32+"=#"4Ö¬B(Bo(BB(»êÌ54232+"=#"43(BB(BoBB(BB(»@#"4;2‚¬¬(›ê½l23276763#"'&54°1@ ;%1R*l' ' 7 2úÿ^c2#"'&5476,!  c  Ïà‰•2#"'&5476"327654'&,6 *3,%" %" •-/+1! $ $ÿe±!32767632#"'&54767”:+ %A ; !)"  /4!‘Ç] 2#"'&#"#"'47632327676³$!4 (#'-[ $ %›ê½y##"'&54?632#"'&54?632#a  b ‚b  b Q^  ^  ^  ^ Ö‚®&'&767676'&/'&'&767/  // //  //  X/  //  // //  ³ê¾˜3#"'75'3#"'75nPW fPW ˜Ÿ–ŸÿÿþCêþèCý¨ÿÿþÀêÿevý¨ÿÿþCêÿeGý¨ÿÿþ9ÿo]Yý¨ÿÿþCÿe@qý¨ýßÿÉ@!"43!2RþL´(ÿÿþCêÿelUý¨ÿÿþ¢ÿÿcVý¨ÿÿþ4ÿÿucjý¨þtàÿ1Å(#"'&=476765&'#"'&54762þè. +6/6 # + 238 /! ÿÿþwàÿ1•Wý¨ÿÿþCêÿeyZý¨ÿÿþCêÿeHý¨ÿÿþÀêþè{Iý¨þ„êÿ${ 0#"=4720#"=472Ü xcb bbbþCêÿey#&547632#"/&547632#"'þÝ  b  ï  b  Q  ^  ^  ^  ÿÿþCêÿe£'Vý¨@Uý¨ÿÿþCêÿelGUý¨V@Àÿ0xÿæ5!4'&#"'&547632+"'&5476;276B 21BB Ô#*6  þ§ÿ9ÿ‘##"'&54723276=o;'1+  ?0M, 7"*þ§ÿ9ÿ‘!327632#"'&=þÐ3  +J+*F  <(30ÿÿþzÿSÿ!zý¨ÿÿþÀÿeÿYXý¨þEÿgA#"4;2´ìì(þ ìÿ'!"43!2‹þ°Pì(þCàÿ0%""'&54?272þg ¹æ  € ýÓ¨ÿ5‹%""'&547%272ý÷ -® µ þ9ÿo] 2#"'&#"#"'47632327676¥$!4 (#'-[ $ %ÿÿþ4üÿu¶}ý¨ÿÿ9é!327632#"'&=(3  +J+*F  <(30ñÜK–62/&747+  8  ‹  ˜  ŒüͶ -62'"'&7'2#"'&547632#"'&5476C  8  M!   è!  « ˜ P    ÿÿÿýOA'|ÿ ÿ«‡ÿÿâÙv\yÿÿÿö@'IþÞÿÅ‹ÿÿ'@'IþýÿÅÿÿ<ç@'Iÿ$ÿÅÿÿÿð%@'IÿÿÅ•ÿÿÿþ%@'IþæÿÅ›ÿÿ@'IþüÿÅŸÿÿzÿø÷¶&}î¯ O3 $%!32+"54;#"54;32+"54;'#¬þö6O—³xÌÅ%œLGpl¼“áýö¼%þÛ+3#07#"543!2#!"543327654'&+327654'&'&+|6Z2U?-9þÎ_“X(7!)¤ÐE%6,S•)á<%0I/-dJ.!47þ2"7#>3732+"54;#"543!"=!¸Šê66Â(þÆ)á‹b O3)"54;#"54;32%!#4ýð³xÌÅ%þx·áýö)á+3)!5432!"54;#"543!#"=!35432#"=¥:þ>66­þÛ‘çw á‹bÑ-ƒ-gñ3)55!#"=!!5432ñþvHþó]þ¸:;ÌvŸ:þ45'33!32+"54;#"54;2+!5#"54;2+32+"54;µþò6Œ-x66x.6çáÑÑþ3ÿð%@)9%"=##"'4=67235432'2#"'&5476"327654'&Ÿ™™snIBQGakIEQGaZ>8H;MX?9I:â--†00Ø]Uz€WMZVx„WM)QJdsM?PJbyL=qç332#!"54;#"543!2#@‹þÁ‹‹? þá+<37732+"54;#"54;2+%#"54;2+32+&/&'¥Kª66ªK-vÞI)"+ 8W@5*Ý´áùùÆ8/h²9 O3 732+"54;#"54;32+"54;#lO—³xÌÅ%œL·)áýöáÿÿ Q30ÿÿ231E3 '5&'5!#"=!"=##"'4=67235432!5472!54ýþ„Ît™™þ»|þ2ˆddŽŽ¦--†00½ee3ÿð%@2#"'&5476"327654'&,nIBQGakIEQGaZ>8H;MX?9I:@]Uz€WMZVx„WM)QJdsM?PJbyL=33-%+"'&54;!32+"54;#"'&543!2#32‹5þö6  Š,Ž-Þþ" Þþ"ÿÿ+ó33fêA)57'5!#"=!!5432êþ|„þʨ¦4<÷Ô:£yâþþH3%32+"54;##"=!#"'&=#Aiûi§È¦)áIrrI3%3&%32+"54;5#"54;2+7#"54;2#Biûi³o&˜•(nþÕÕ ãã.*3 8C#";5#"'&5476;5#"543!2+32+32#!"543327654'&#"R0:'/2._8%H7K us e<)E3D.sþð2I+=,7¥5!(=&‚YA+9O2&<!,/8?&+@'1rT"'5ÿF¯+4'&'"32+"54;#"54;6763232#·&&,7('-ƒ-"K;2T."ºÚ, ! 2ýOEB :",þHqÿñçj(#"'&=47632!3276=4'&#"çL/@_5'M.@`4)þÜ0"@@"00"@@"0_d“J-^Ffd•I-^):•hJ55Ii?hJ55Ii­ÿø÷ª%#"'4;327676#"'&=fD7# %C E x þÎW( 4 @F¡(3#"54;#"54;7#"54;2+32+"54;'À_66_­‚/Ëë-ƒÐO±ˆŸ°–:ÿþ&f#32+"54; 32+"5473'#"54;2þn8££5n ºG^U 9ýîTþ¬•+ÿZª)7#"'&5#"5673327#"54;32+5#"¥4^0UQJq#JPXE¢þË&] þVcA9L?UdC8)C2AX6)A2A[6#R¡%!2+32+"54;#32+"54;#"54m~""x-è-w!"¡þ±Oþ±OÿB»0%#"'32+"54;'47676324'&'&"3276K:Qn@bÁ6M,668F )+ &”%?C.=T4%âh?1[û`cF (S"B2 &%?JV4$B/]ÿm÷©5&#6'"'&54763676'6'&''&7&762432#"5Î2:ÔT"']&#N:* 9S;9|=M;1P0³d'*I  97V–:#E+ÿòª.%4'&#"3276#"'&'&'&5476763!2¥A,;T2#@-V5&12BsP1<%<+ [A '+ÿø)¡#327676#"'&5#"567!2.D7# %C E ¾ÄwÿW( 4 @$ÿ+ÿô)¡%+#"=#"4;327676=#"54;2)5«4^ $91-1猜é(þï3!0 ãQÿFý\ K3276=4'&'+";32"+#"'&=#"'&'&=47672;547632;6* +&Y6* #"1(5=#&-!0"5=#&-!0"yþ¯+™-+™+ §&9™?&¦¦&9™?&§ÿF)¡-+32+32+"54;7#"'&54;7#"54;2)-¥’4L‘ƒ)5—˜( @œŒ1þòþ×þþñå"ÿF-\6%3276532#+#"'&=#"'&=#"4;;47632;*3 V-:()+K#)R" -(.ôM%¦¦= )ó(þå(" +ÿð(®O+#"'&'&'#"'&'&547#"4;2+3276=472327>54'#"'4;2!6 0/ #M' 7m1:"  $$:2nšS_@6N  , F9>^S(P]8-6 *ŠŠ+ ^6ZRÿÿZÿø÷;&jÎØ¯ÿÿ+ÿô);&jþØ»ÿÿHÿðt&Iúùµÿÿ+ÿô)h&Iþí»ÿÿ+ÿð(h&Ií¿pÿììf (43254'&+"32+"'&5476;2#;27654# Œ˜ET* ’¤A,9x3@2RW.ÀB#O ˜ˆDQm!P"$"MS.’N`œXF<'7ly.> DBÿñçj?32+"'&567632#"'&'#"'&5476;23276=4'&#"½‰ $ J.=`4L/@^5 !,"f@"00"@n d# …D+^):Jd“J-\,:‘5IiYhJ5¯ %ÿ6!¡&2%"+#5#"'&=#"54;;3254'&'#3276!-!0"--V&2 $\ 2b=#&-'*16)"ƒ?&ÊÊ<'öþâ*y&9™™+þ´PÿmT2'#""#"'5327654'&#&'&5476;T‚íK\^U » /  d##o ’(—[†Œ  B[a! e( )O$1Õ[7Yÿm·&#"#'#5327654/&'&54763¡—<^b!ˆO9að*732+"54;#"543!"=!7#"'&54?632¸Šê66Â(þƺr  r )á‹b¾d  d @ÿð@432767632#"'&=4767632542"5&'&#"!2#jI?R\F &MafOO6 DfdJ((@1:Z<2aD:L #GNOeSTH JEp4#I>Qÿÿ\ÿðü@6ÿÿqç3,ÿÿqç¿&jÿ\,ÿÿTÿðG3-H34?32+"54;##"'&=43232765#"54;2#327654'&#T(e=*F4Dst6$ (ø:K+=+6 ¾A,:P1$áþB5 ºçú5 '<' H37B32+"54;5#32+"54;#"54;2+35#"54;2#327654'&#K1e=*F4D‚¸\[¸[CK+=+6 ¾A,:P1$ççáÑÑçú5 '<'C69673232+"'54;54/"32+"'54;##"'5!#"'5Ø)O Š!x6k!C.6x|t â Q¥T ÐáItrL$4ð3E732+"54;#"54;2+%#"54;2+32+&'&'#"'&54?632žJª66ªJ"vþÜ~D>"8X6$:Ôr  r )áÂÂÕ"E?f³C±d  d 3%ð3D 32+"54;#"54;2+5#"54;2+32+"54;"/&547632³þò6Œ-x66x.6²r r zþóDáþ— \þ¾d d 2&Ý%=732+"54;7#"54;2+#"54;2+%23276763#"'&54ê„@jÆn*ª.pþ´1@ ;%1R*)º'þÿÓ' ' 7 23ÿ°%3-7!#"'54;2+32+#5#"'54;#"'54;2+¥6Œ-±0±.6)áþPPáÿÿ O3$,3*2#!"54;#"543!#"=!327654'&'&+9©/ <.;þÎ66¸þÐÐB&,,S•Cf!I0%á‹bÇþæ3$3%ÿÿ+3%>3732+"54;#"543!"=!·‹ê66Â(þÅ)á‹b ÿƒ63%70765#"543!2+3#"=!#"=;#ŠYcþ<–ôÕ)þ‹bb‹áþb1ÿÿ+3(P3P2+7#"54;2+32+&/&'32+"54;5#"54;6767'#"54;2+5#"543^ªV¼Q&+8%>#dP')8K2¼V«3ººÍ(7?v¦?öö%;?€ Bͺº\ÿðü@H#"'#"=432327654'&'&+"54;27654'&#"#"=432632æ< XM6Kj?A,8[.-)-=0?2'<$/P)!3g;?(3&33 32+"54;#"54;2+5#"54;2+32+"54;´þñ6Œ-x66x.6zþóDáþ— \þ3&K23276763#"'&54 32+"54;#"54;2+5#"54;2+32+"54;°1@ ;%1R*þñ6Œ-x66x.6' ' 7 2þwþóDáþ— \þ-<33732+"54;#"54;2+%#"54;2+32+&'&'¦J©66©J"vþÜ~D>"8X6$:)áÂÂÕ"E?f³C9'3.7367#"543!2+32+"54;##"'&=432b!+Q.6Í6#P !ºþáþB5ÿÿ Q30ÿÿ5'3+ÿÿ3ÿð%@23%3%!32+"54;#"543!2+32+"54;³þò6Œ-’.6 þáþÿÿ+ó33ÿÿ?ÿð@&ÿÿH372&3%732+"54;7#"54;2+#"54;2+ê„@jÆn*ª.p)º'þÿJ3 8C#";5#"'&5476;5#"543!2+32+32#!"543327654'&#BR0:'/RN_8%H7K@us@e<)E3DNsþðRI+=,7¥5!(=&‚YA+9O2&<32+"54;#"54;2#32+"54;#"54;2+327654'&#eeþ7ƒe<*F3D×e•J,=,6 þá¾@-:Q0$áçú5 '=&+ÿÿ2 &327654'&#'32#!"54;#"54;2+¥¹J,=,6ª§e<*F3Dþì66Õv"ú5 '=&)@-:Q0$á@ÿð@4!"543!54'&#""=42632#"'&547232765îþòF8JU6!((JdfD; OOfaM& GW^B:cA42#pEJ>X SeONG# TJATÿðU@+<67632#"'&'#32+"54;#"54;2+%"327654/&«P6M{8#M1@w9#JWZe.F*=a/K!9ŒI2yJi—R%uHcçáÑÞm>TF*g?V›C /3 25#"3##"54;6767&5476;2+32+"54;µ™B,B1?r„B3$79N*‹A3@ø66ªK$æ0$7#)G1e‰)0aG0%þÿÿHÿð¯DQÿïr!1&67632'&'6767635432"327654'&ä”&| 53%f@3J nBŸˆˆˆˆŸAoH> –gÿðñ¯J73277654'&#"#"=432632#"'#"=432327654'&'&'#"54è0O 9 )^4Ub0.1J4F`=<*4]*'75D÷ * 0 E.4"0  !9C&6 S).#A¡3%5#"54;2+32+"54;532+"54;#"54;2#§ -x""x-þö-w!"xxï¼3þ±ç¼+OA‡3K%5#"54;2+32+"54;532+"54;#"54;2#23276763#"'&54§ -x""x-þö-w!"x$1@ ;%1R*xï¼3þ±ç¼+O' ' 7 2F¡(3#"54;#"54;7#"54;2+32+"54;'À_66_­‚/Ëë-ƒÐO±ˆŸ°–Xÿÿ¡,725#"543!2+32+"54;##'&'5432"M""x-·"$ A7þ±OþË/ 4%¡,32+32+"54;##'#32+"54;#"54;Ÿk""m"}~(nbw¡þ±Oùùþ±OíA¡3!5#"54;2+32+"54;5!32+"54;#"54;2#§ -€**€-þö-w!"xx——þ±OÿÿHÿð¯RA¡%!2+32+"54;!32+"54;#"54\¡""x-þõ-w!"¡þ±Oþ±OÿÿÿF¯SÿÿTÿð¯Ffÿÿò¡!#"=#32+"54;##"5fŒ‡-„.ˆ¡„[þ°P[ÿÿ3ÿF%¡\ÿøÿF`=*7B5#"'&5476;5#"54;32+32+"543";3#327654'&Fg@3M2›C&1 P3%Sþ­?.;V2#ÿÿ3%¡[5ÿŠ¡')"54;#"54;2+!#"54;2+3#"5êþr"-ƒ- "m"8Oþ±Oþ±„`ú¡3367675#"54;2+32+"54;5#"'&'5#"54;2#ÆE;$"m""m"%AZ"xx¡Ÿþ±ƒ$¢ P¡3%3#"54;2+32#!"54;#"54;2+3#"54;2+Aª"m"!ýï j"«"m")Oþ±Oþ±O ÿŠL¡5)"54;#"54;2+3#"54;2#3#"54;2+3#"5#þ k#¨#k!"§!k!>Oþ±Oþ±Oþ±„@¡(32+32+"'476;##"532765&'#@æ% N Vê#p›F ]Ž¡‹B\OZõ) Q N¡5>%#"54;2+32+"543#32+"'476;#"54;232765&'#è-x""xþÙ* N VäpB›F ]Ž)Oþ±O‹B\Oþ±) Qlì¡&#32+"'476;#"54;232765&'#÷% N Vê#%q=›F ]Žx‹B\Oþ±) QJÿð¯1%!"543!&'&#"#"=432632#"'&5476323276äþð N+7V/=_tA1Q=TgO, Nld5¸`-.[ 7RPjC7LAWhD0ÜY8+E3DW9*F(¸O—b<0N>VcA9L5B3AW7)B2@[7X¡*5%#"'&5476;2+32+"54;532+"54;#"2;X^MPê"$r$À„.úšF SŽ´@ Xþ±‹‹O'Mÿÿ?ÿðl&C6íHÿÿ?ÿð'&j÷ÄH+ÿiß\H2+"54;276754/&#"32+"'54;#"'54;5#"54;32+676?Z,&3A@B % 5F4-„.666_<>†<"-ÒD3& 6!@Î,>Ö¬6_£H ræ^+#"=#32+"54;#"543!'#"'&54?632æÙ-ƒ-"Mtr  r [þ±O•d  d Jÿð¯17327632#"'&5476325432#"'&'&#"!2#t K-9lN ,Ogs@/S=V_=>*2g4¸Z+H 7Q:QrA07 [0L'2ÿÿgÿðñ¯Vÿÿ\üpLÿÿ\ü-&jÊóÿÿ“ÿFÊpM"ÿÿ6¡0;32+"54;##'&'543225#"543!2#327654'"+`\MP$”’"& "VF SJx‹@ XOþË/ 7þ±' M<¡7B32+"54;5#32+"54;#"54;2+35#"54;2#327654'"+^dMP$¢ Ä!cc!Ä ^^F SRx‹@ X››O‹‹þ±' M+'\D"32+"'54;#"'54;5#"54;32+6763232+"54;54/&:F4-„.666_<> Z,-ƒ-% ]>Ö¬6_£H <"-ÒÎ,F^(:3#"54;#"54;7#"54;2+32+"54;'#"'&54?632À_66_­‚/Ëë-ƒвr  r O±ˆŸ°–wd  d >^3D%5#"54;2+32+"54;532+"54;#"54;2#7"/&547632¤-x""x-þð-w!"x/r r xï¼3þ±ç¼+OÝd d ÿÿ3ÿF%K&Uß\>ÿ°¡-!#5#&'54;#"'54;2+!#"'54;2+32D0»""x--w!"PPOþ±Oþ±ÿð<@O547632542#"'&#"32+32767632#"'&=#32+"54;#"54;2+¤8:`p( sd,ÎÎB4D6/ &3/fD:DWZ9 jGJEpr_4EfD5.  )6 VKaçáÑP459'&763!232+&'&'32+"54;5#"54;676737#õn  &nO%#8%@ 7dP')8KT(^ä<Ú Ú'31U¦@ öö%;?€¡A,ºP37;AE332+&'&'32+"54;532+"54;#"543!2'#6767#737#dP&)8%@ 7dP'"W¡ëY-#L}¸(^ä='9>t¦@ öö%;5aá½±±µV. ºE3<%6=32#32+"'4;5&'&=#"'&54;#"'&5473+AžK#X/?iûiŒ+"Js+„0´ ²Á¬w:__ w-9—Õ„ V ÿÿ"ÿF-\¾+ó3'232+"54;#"4;5#"54;2+32#327654'&#¥ƒe<*F3Dð6666銕J,=,6“G@-:Q0$j(OO(pú5 '=&lì¡2732765&'#'5#"54;2+32+32+"'476;5#"43Ò›F ]Ž)%q%-- N Vê#-)) Q‰++(8B\ü(+õ3:674'&+327'&7676'&/+32+"54;#"54;2‹;9'0•†> fA I(4ƒŠé66ð_8&*+9=&ú =  g@  J¾á@,9OÿF¯G%654'&#"327'&7676'&/#"'32+"54;#"54;67632µ?D0>W5&C0?,$D h? D2°!32+"54;#"543!542þžŠê66š( þábræ5432!32+"54;#"543½þþ-ƒ-"¡[„þ±O>3$32+32+"54;#"4;5#"543!"=!¸Šê6556Â(þÆ‘(þÀ@(y‹bræ¡%5#"543!#"=#32+32+"54;5#"43»"MÙNN-ƒ-*!W„(ÐÐ(>ÿ£03732+"54;#"543!"=!32#"'&54723276=4'&#¸:š66Â(þƬe=*<'1+  ?=+6#úá‹b¾A,:kL- 7"e<'rÿDæ¡9732+"54;#"543!#"=#32#"'&54723276=4/"#ä-ƒ-"MÙVq*<'1+  ?J&Ä›O„[‹E&‹L- 7"…DÿnP3Q%#"=#&'&'32+"54;5#"54;6767'#"54;2+5#"54;2+7#"54;2+P*%@ 7dP')8K2¼V«d«V¼Q&+) w¦@ öö%;?€ BͺºººÍ(7?v ÿnM¡W%#"=#"54;&'&'32+"54;532+"54;67'#"54;2+5#"54;2+7#"54;2+MU%h #o#o* e/‰¶c›#o#›c¶ˆ0) wH> ––=> nBŸˆˆˆˆŸAo\ÿSü@c#"'&5472327654+5&'#"=432327654'&'&+"54;27654'&#"#"=432632æ< XM2E:-$" %.X5A,8[.-)-=0?2'<$/P)p;#8 (7!1>!3g;?(gÿSñ¯e&'#"=432327654'&'&'#"54;277654'&#"#"=432632#"'&5472327654+M5<*4]*'75D0O 9 )^4Ub0.1K/?:-$" %./ S).# * 0 E.4"0  !9D&2, $ÿn535%3#"=#&'&'32+"54;#"54;2+%#"54;2+âSI6$:Jª66ªJ"vþÜ~D>) w³CîáÂÂÕ"E?Fÿn¡*%3#"=#"54;'#"54;#"54;7#"54;2+ÊIuÐ_66_­‚/Ë) w–¿O±ˆŸ$43A32+&'&'"=0'32+"54;#"54;2+35427#"54;2+þ{C8X7n(5Jª66ªJ8(¢v1(„)3º=IZîáÂa;œF¡4%32+"54;'"=##"54;#"54;35427#"54;2+Ã-ƒ‰(_66_(l‚/Ö­~AY¿O±bFl$43?32+%#"54;2+32+&'&'32+"54;#"4;5#"54;2+žQQ"vþÜ~D>"8X6$:Jª6;;6ªJ×(gÂÕ"E?f³Cî†(3F¡432+7#"54;2+32+"54;'#"54;#"4;5#"54;À++­‚/Ëë-ƒÐ_6@@6_U(=ˆŸ°–¿(#ÿç435!2+%#"54;2+32+&'&'32+"54;##"5J"vþÜ~D>"8X6$:Jª6c3ÂÂÕ"E?f³Cîá[ ¡*37#"54;2+32+"54;'#"54;##"5 ¶­‚/Ëë-ƒÐ_6c¡±ˆŸ°–¿O[5ÿn'35%#"=#"54;5!32+"54;#"54;2+!5#"54;2+'~6þò6Œ-x66x) wççáÑÑþRÿn¡5%#"=#"54;5#32+"54;#"54;2+35#"54;2+i-è-w!"x-è-x") wO——þ±5k35#32+"54;5!32+"54;#"54;2+!5#"54;#"5Ac.6þò6Œ-x66ì þççáÑÑ„RV¡5#32+"54;5#32+"54;#"54;2+35#"54;#"5,c"x-è-w!"x-è-ãxþ±O——„ÿóÿ£d3E32+"54;#32+"54;#"543!2+32#"'&54723276=4/&#\.6Î6Œ-R\\2<'1+  ?6#úáþá¾9#+‹L- 7"…2 ÿDI¡E%32+"54;#32+"54;#"543!2+32#"'&54723276=4/"#I"x-¨-w!">"Tq*<'1+  ?J&Ä›Oþ±O‹E&‹L- 7"…Dÿÿ?ÿð@&ÿÿTÿð¯F?ÿe@G#"'&=47676325432#"'&'&#"3276763232767632#"'&54HfON6 EfeH@0:[<2I?RYC &,8:+ %A ONeSTI JEp4#I>QGaD:F #) !)"  /0Tÿe¯D#"'&5476325432#"'&'&#"32763232767632#"'&54I r@/S=V]?>*3g3 I0AmN +*6:+ %A P;QrA07 [0K/?_3"H  !)"  /0Hÿn3%#"=#"54;##"=!#"'&=#Åìi§È¦) wáIrrIþzÿmÞ¡%#"=#"54;##"=%#"=Šv.tdt( wO[„„[þ±3%3&%32+"54;5#"54;2+7#"54;2#Biûi³o&˜•(nþÕÕ ããÿ9:¡'#"54;2+3#"54;2+32+"54;·)—A–“D˜)´2Ž3#›þ±Oþe{3%30%#"4;#"54;2+7#"54;2#32+32+"54;^^³o&˜•(n°eeiûiÖ( ããþô(­þï:¡132+"54;5#"4;#"54;2+3#"54;2+32#B2Ž3aO¥)—A–“D˜)¢P#ÅÅ(sþ±Oþ((ÿn035%#"=#"54;'32+"54;7'#"54;2+7#"54;2+0u>¥¤@ƒ¼³n+›™-o³¿) wÖÖ÷êÉÉê÷3ÿn%¡5%#"=#"54;'32+"54;7'#"54;2+7#"54;2+%uA›D… ¸£o.†‰0n£¸) w••²‚‚²ÿîÿn&3+#!#"54;2+3#"=!"54;##"=!#"5d6Ž.JþfdD þáþ wá[„„ÿŠ ¡+#3#"54;2+3#"=!"54;##"=!#"5"dè"m"8þ•"cDxþ±Oþ±„[O[„„Jÿn35%#"=#"54;5#"'&'5#"54;2+23275#"54;2+~6=h%x6eK)6x) wÈ !ñè15æþ`ÿnú¡5%#"=#"54;5#"'&'5#"54;2+367675#"54;2+ú^"%AZ"x-E;$"m") wƒ$¢¡Ÿþ±J3=%675#"54;2+32+"54;5"=&'&'5#"54;2+23542<=#6x.6>(k x6 Z(ð-æþÈ ZY0ñè.j`ú¡;%"=&'&'5#"54;2+23542675#"54;2+32+"54;5B(X "x-K(8"m""m"Ž87 ¢¡99Ÿþ±ƒJ336763232+"54;5&'"#"32+"54;#"54;2+¼=h%x6eK)6x.ÍvB !ñè15æá`ú¡3%5&'&#32+"54;#"54;2+63232+"543”E;$"m""R%AZ"x)¡ŸOƒ$¢ÿ¬ÿð@ D%54'&#"#"'&547632";5476762!32767632#"'&5[’F9J[<2)&1/ &6 EÌE: þEI?RYC &LbfON3 cA4I>Q5(7  TI JJ>X :aD:F #GONeÿÎÿð¯ A7!&'&#"67632!32767632#"'&'#"'&547632"3hvQ)1i5) R;KqC þ`T.:VE HGDnG61/ ð['N#a6(Q,6f/(N:O(7  ÿ¬ÿe@ \%54'&#"#"'&=#"'&547632";5476762!3276763232767632#"'&54[’F9J[<2ã fON&1/ &6 EÌE: þEI?RYC &*3:+ %A 3 cA4I>Qþ±ONe(7  TI JJ>X :aD:F #' !)"  /0ÿÎÿe¯ Z7!&'&#"#"'&'#"'&547632";67632!3276763232767632#"'&54hvQ)1i5ànG61/  R;KqC þ`T.:VE H:+ %A ð['N#þüN:O(7  a6(Q,6f/(  !)"  /0ÿÿqç3,PÝOg2+7#"54;2+32+&'&'32+"54;5#"54;6767'#"54;2+5#"543'23276763#"'&54^«V¼Q&+8%@ 7dP')8K2¼V«J1@ ;%1R*3ººÍ(7?v¦@ öö%;?€ Bͺºª' ' 7 2 MKUm!#"54;532+"54;67'#"54;2+5#"54;2+7#"54;2+32+"54;&'&'3223276763#"'&54do#o* e/‰¶c›#o#›c¶ˆ0e%h #Ð1@ ;%1R*–=> nBŸˆˆˆˆŸAoH> –K' ' 7 2$ÿ—3C32#"'&54723276=4'&+32+"54;#"54;2+%#"54;2+ÏKv7<'1+  ?J$0€Jª66ªJ"v@H)6kL- 7"eM!îáÂÂFÿDô¡;7#"54;#"54;7#"54;2+32#"'&54723276=4/"#Á_66_­‚/·#q*<'1+  ?J&À¿O±ˆE&‡L- 7"D5ÿ93:#"'&547232765!32+"54;#"54;2+!5#"54;2#Þ;'1+  ?þò6Œ-x66x ýÆM, 7":çáÑÑRÿ9¡:#"'&54723276=#32+"54;#"54;2+35#"54;2#É;'1+  ?è-w!"x-è-xxþXM, 7"âO——Jÿm37%275#"'&'5#"54;2+23275#"54;2+32+#"5K H=h%x6eK)6x.}(È !ñè15æþw`ÿnú¡5%5#"'&'5#"54;2+367675#"54;2+32+#"=”%AZ"x-E;$"m""^)ƒ$¢¡Ÿþ±w ÿÿ OÝ&$UqÿÿHÿðY&DUíÿÿ O¿&$jÿ\ÿÿHÿð;&DjØÿÿ N3ˆÿÿ ÿðB¯¨ÿÿ+Ý&(Uîqÿÿ?ÿðY&HUøí2ÿð@ -%3276=4'&#"#"'47632"'&'&=íþnF9J[<2I?RYC &LbfON6 EÌE: ý cA4I>Q4aD:F #GONeSTI JJ>X :Kÿð¯(%&'&#"#"'&547632#"'&=!3276í K-8mN +Pgr@/S&2tA1¢þˆ S+8g3å[,H 7P;QrA R nBŸˆˆˆˆŸAoH> –-    \ÿðüÌHXh#"'#"=432327654'&'&+"54;27654'&#"#"=432632%2#"'&547632#"'&5476æ< XM6Kj?A,8[.-)-=0?2'<$/P)!3g;?(ó    gÿðñ;JZj73277654'&#"#"=432632#"'#"=432327654'&'&'#"542#"'&547632#"'&5476è0O 9 )^4Ub0.1J4F`=<*4]*'75D!   è!   ÷ * 0 E.4"0  !9C&6 S).#D    \ÿðü@H#"'#"=432327654'&'&+"54;27654'&#"#"=432632æ< XM6Kj?A,8[.-)-=0?2'<$/P)!3g;?(gÿðñ¯J73277654'&#"#"=432632#"'#"=432327654'&'&'#"54è0O 9 )^4Ub0.1J4F`=<*4]*'75D÷ * 0 E.4"0  !9C&6 S).#3%ƒ3; 32+"54;#"54;2+5#"54;2+32+"54;#"4;2³þò6Œ-x66x.6ììzþóDáþ— \þ2((>ñ3;%5#"54;2+32+"54;532+"54;#"54;2#7#"4;2¤-x""x-þð-w!"xÑììxï¼3þ±ç¼+OQ((3%¿3CS 32+"54;#"54;2+5#"54;2+32+"54;2#"'&547632#"'&5476³þò6Œ-x66x.6ö!   è!  zþóDáþ— \þ–    >-3CS%5#"54;2+32+"54;532+"54;#"54;2#'2#"'&547632#"'&5476¤-x""x-þð-w!"x!   è!   xï¼3þ±ç¼+Oµ    ÿÿ3ÿð%Ì&2jÿiÿÿHÿð;&RjØ3ÿð%@!2#"'&5476&'&#"!3276,nIBQGakIEQG0L6EZ>2ŸþaJ8FX>4@]Uz€WMZVx„WMþìuE1QBX(qF4PBHÿð¯!2#"'&5476&'&#"!3276,jC7LAWhD8LAI/:Y8$tþ F/:X9#¯N>VcA9L?UdC8ÏX0C+8(R.B)ÿÿ3ÿð%¿&j\‡ÿÿHÿð-&jʈÿÿ@ÿð¿&j\úÿÿJÿð-&jÊÿÿ2&ƒ&qCðÿÿ3ÿF%ñ&q±ÿÿ2&¿&j\ðÿÿ3ÿF%-&jÊÿÿ2&ê&Zqðÿÿ3ÿF%X&ZßÿÿI&¿&j\ôÿÿ`ú-&jÊÿÿ Q¿&j\øÿÿ N-&jÊ)ÿnD33'&'#"'&5#"54;2+32765#"54;2+13%0p:#—K>)5S1L—":i}`1;Nþ²U/L).Nþ²X:r)7C0%#!32+"54;4763232+"54;54'&#"!27þtL˜#G6Jd9(#fT!)R-Œ«mOb<-L6I99b.B*6¹+FD!1%+32+"5473'#"'&54763272'4'&#"3276FJ6ÃfCoi@1P;PpA)JF/=Z4#E/=[4#«mÉZL:Pj>.Z:A°®Y2!C-)6T1f#I4Hn;YªmOR0 K%299f;*`1:¹"ÿð030#!3276=#"54;2+#"'&5#"54;2+!20þu>)5S1e"H5Hp:#—K‹‘ÁU/L).99e<+a1:Nd"ÿö6B!1#"'&547632!"'"=423!24'&#"3276&VF`xI;VEaxI;þŠ7+((!Av8M:Mf?0M:Nh>.HvI:TE`wI:UDþW#t8(Hg=.K9Nf>.L9:ÿ°3#"/!"54;#"54;2'#!!3 Fþ¼__»4&þÚÏQ ; Eád)þ¬Q )1C)+"54;54'&#"!2#!"54;47632321fT!)R-~þ6#G6Je9'#21b.B*6þ±Ob<-M6H1 T?8E236#'#"'&5!6'&'&'&#"32+"54;47676#3276'41dD2(+.H_5/U \7'K—#K2ûå %2/&?D2B6W(Bh$cE H D1AþÅ;^D þÞ@ +*T4ÿð<3"0+#"'&'&7676;5#"54;2+325#"3276<_H5Hp:, 29—`«"_¤˜R0 >)5S1me<+`-?I3‡‡Ç>)6S0 L);35%+"54;54'&'&#32+"54;#"54;2+67632;f<"+ E2‡ñAAŒ":c\;.#°%P0;'+Õá¨QI9J%?2)"54;#"54;2+!542þ;bbíb*àþ 5ÿôP39+#"'&=#32+"54;#"54;2+33276=#"54;2PH(8b0n#f[–)9T" $f‘Ãt5\#EÅþ¬ádëM"3R9Â.ÿò&< )!"43!2#"'&5476324'&#"3276öþŒs0VF`xI;VEaxI;(M:Mf?0M:Nh>.'(þ¯vI:TE`wI:UDag=.K9Nf>.L9)133+32+"54;5#"'&=#"54;2+3276=#"54;21##Ó‡:ap:#—K>)5S1-y‘þ­•L`1;ÌÌU/L(+Bkÿìí;)%"=4'&'&#"54;27654'&+"54;2í(8"«¨c#%#!"5432;276767654'&#"32+54767632632&#"Aþ…v5.2  4,+ P9Nc-o P.6fLM"$-“þ?#GYK!=  P4&Bo<+L+9(&#*Q'FGcVM M,V#! EC)%#'"5434'&#"32+"54;54763232E¤1T!)R-$p#J5Hd9(JOb.B*611f;*L6Iþ±!94$-)"54;#"54;676;2+"3232'54/&+%þ!:JK9ÐÐ: v[<1>z+_wU\"(ED7H»)»(Lþ«ÿïK40"54/&+'&'&5#"54;2+32765#"4;2K(D3D92 #—K8(4S/L—_¸>þ²`=.) +DNþ²M2$Y+N*Zõ]9%+"543!276'&'&+"4;27654'&#"#"=42632×0 *A¼0q \_>)<$)Y. (>OV6'A1àEC+R;(*!:!7^0.9)7>/ ÿð:3)"'&5#"54;2+3276=#"54;2+BY9+X¦%7)2O-M˜"56J9INþ²J3&O**bbP=?=ÿðd;%#"'&'&547632'4'&'&+"4;2#"'&'&#"327632QnmG: RE^bM) .ÈÉS#6+8IK; !K@SaN l ZG:6$1oG N5Hþ±+ÿÃJ#3#"'%&54327"'&5476324'&#"3276C $lÖþG´W$nB5P?VnB5)H2B^7'H2BW8-g^B ƒ/_'dO>VmB4O>V]6&F1B^6&A4?C:%+"54;4'&'&'32+"54;"32+"54;54763232?¢V*F#o#S-$o#f+Jn:#O5:'þ¦ZE(499{8N&1þ±@ÿýH4-8%#!"'"=432;2767&#!"=4;232'654'&+!2HþÕg1* '=BA A&DþÒö9 $3‘`O:K³.2&)] $.f\í2)V) S0ã6Y4&Ä NC2#32+"54;4'&#"32+"54;476763232:P#—KS!)Q.L—"D,6h8"PöOa/A+6þ±O\> S3E1)ÿð13)+#"'&5#"54;2+32765#"54;21"H5Hp:#—K>)5S1L—þ²e<+`1;Nþ²U/L).N '42%+"54;5#"'&=#"54;2+327675#"54;2+32'¶^>__:+-pS$"G2!"e.±TL:K&&i-;',Î*þÿÿ\ÿðü@6*2C++"54;54'&#"32+"54;4767632322o#S"(Q.ˆÓ"D,6c9(#21d,A+6þ±O\> M6H1AR2B%+"'&5432;27654'&+"4;&'&=47632'27654'&#"42˜FD .†* C6"+üq3K+8_-;zÙC&< 'J#9"™O-f #WH*(6Q)@$2D0 .=/$A 2"<#\ö3#32+"54;#"54;2+32âû‚òGG¶FûöáÂG3)2;32#!"54;7&'&547675#"543!2+4'&'676R6Hnþúnd>/C8Voni<+)J)4W0 ÐZ0F,h;(I8JX?5''K6IY0þµ@*oKB*6T0KE&6%!32+"5435"4;5476#"'!2&'&'&76767þdoÎ6\\S:Nj;&O6JqBœ]Z$Z3&E/9c*sJK(Þk9(H/>e8'X‡(` :*:G)A&ÿÿ3ÿð%@2Zÿïþ=+4=%#5&'#"=4325&'&54767632+%5"4'&'676þR0>)Y9I!&{ 4&A!WXNVþšZ7 (=D=U)™[/:r?#ý=#23&Û '³FÒ%þÍC ÷7 ÿðQ§4%+5#"'#"'&5#"54;327#"54;327#"54;32QL54@ 69,##L# 45#L" 28"K#)8DD&+ þ».Sþ¾/Sþ4ÿB-±5%#!32+"5473#54;67676"=4'&'&!2-þœ„â56_1!O6  59/%d•W,"9 *Rk!# ;/2À+ÿBF¶#3%+36+"54;5#"'&54763232'4'&#"3276FJ6ÃdCoi@1P;PpA)JF/=Z4#E/=[4#• ùZL:Pj>.Z:A¸·Y2!C->8 /†."K5"&Y.[•´I : þÿT*A5 E#$þÿ,ÿð0<&232+5#"'&5#"4;!2#!32754Ë#LRaS"7`lþ”/cRØ;KA&*–þø; [Œ+ÿCG¶)##"'&547632532+324'&#"3276GtCoi@1P;PnC`8KF/=Z4#E/=[4#¨!ZL:Pj>.ZK*ýðsY2!C-ME"$þþÿB¶'0%#"'32+"54;#"4;632&'&#"!3276O;PnDâ88aJgƒ<)E.:\4 `þ¢ E+3T6ài>/Zù*KZl10T0D)6(K(@#4ÿð<<++#"'&'&7676;532+325#"3276<_H5Hp:, 29—K#`¤˜R0 >)5S1mže<+`-?I3¹Çž>*6S0 L)5ÿB=-%+"54;54'&#"32+"54;#"4;63232n": 1(*Ö."KMOZ-#ûA 3þA¨*ÔME"$þþIÿB¦#!"54;#"54;!2þjXVªýÅÿB==6%+50#"'&5#32+"54;#"4;332767#"4;32=L%S"d/†."K/!!7`#3A&ýî¨*–þÎ; 1*þ‚GÿðT</7476;'&54;2+32+#"'&%4/#"3276GJBW'‰ ¿‘†´ EED\ZDG¡34WP:0F4BW9,È^C=o (n( ;p[?>?AXc)*@5AR5(?18ÿB <0+"54;5#"'&5#"54;2+32767&'&54;2 àˆIRY-#n"9 @1 - L3©ÒKD"$—þp? 2 ! ýÅ5<-%+"54;54'&#"32+"54;#"4;63232n": 1(*/†.!JMOZ-#ûA 3þÿé*ÓME"$þþGÿðOa):<%+5#"'&54767'&54;'&5432+32'4'&+"3276'#OLEwnB5R/UoB% H = FQ=R©©[7(D3C\6'F1üBÿBR¶.+"54;4/&#"32+"54;#"54;63232R©+5 =3(.….#LMKV*Uª¼= 4.þÿT=ME# þ=PÝ<'%#!"54;#"54;&76;2+"3254'&+Ýþ›BAA%(¨¥?NZ:+(U! PUN*(mL:I¯­h.þ«6ÿð)=/476;2+"32+5#"'&5#"4;3275'&3" ¨š c7`ROS"7`/PSb, P þ«5¶-%+"54;54'&#"32+"54;#"4;63232n": 1(*/†."KMOZ-#ûA 3þÿT*>ME"$þþ]ÿBÅ2#!"54;#&=42;2þw0áÅD(&âã•´DFF$ þI ÿBQ¦>+"54;5#"'#"'&5#"54;327#"54;327#"54;2+32Qª^54@ 69,##L# 35"L" 28#o##ª½8DD&+þ¼.Sþ¿/SýîFÿB¶0%32#!"54;7&+"'&5&76324'&#"326/ &ªüþwVÚ:Ñ8Q?VoC3)I1BN7!ì=#ÒO8&«Ü<,nB4P>V_6%6!3+ B/5 ¶3%+"54;7654'&#"32+"54;#"4;6763232 –P;9&//†."K6,&Y.PUü4 6þÿT*>6 ?  þþ,ÿð§ %+5#"'&5#"4;327#"4;32LSbS"7`/dSKt#ME"$þþÿÿ?ÿF2¯Jy¦%#!"54;'"54;2þœXXâSþƒ ÿBP<@"32#!"543?#"'&5#"54;327#"4;6763232+4/&ª((nþún42,##L# 35"L0)-##L#Œ,þ1¿;&+þ¼.S¥*Á4&+þáD.i e,#"'&#"32+32#!"54;#"54;547632 P,LÀÀ´þ¿dYYD&/8D#C /?þ¬T?H$ ÿÿHÿð¯RYÿBþ=4=F%32+"54;5&'&'&76325&'&54767632+'5"4'&'676þS/'"+"'&5476;67676765#"'&54763!6#"'&5&'&'&'&#Ó"!<$$*Z%/*  ' ·þË>#"  5 (GþÛ%6 ZÂà'#"'&5#"'&54763##"'&5#"'&54763ÂYPYàþ4£þ4£ZÂà'#"'&=#"'&54763!#"'&5#"'&54763ðYTYàðÇþ4£ZÛÂà'#"'&=#"'&54763##"'&=#"'&54763ÂYPYàðÇðÇú;r\3"'^<4\ý$$ž;Ê\ 3"'73"'¸^<4Î^<4\ý$$ýý$$Ñÿ™‡ #377‡šššš@¶þ{¶¶/¶v¶²ÿ˜¦#"432#36pØØØØÖ#F²ÿþP{ø/ÿxGÿ™##3+þ}gOü±{Gÿ™ ##3#3+þ}BgOü±{ü…ÃGÿ™##3#"'&547632+þ}|   gOü±{þd!    Gÿ™#32#4'&+#3+þ}1.  1gOþÂ/þJ¶#þ{©ÿ™¯ #3'¯ëÄÄNþë {°þêçþ2©ÿ™¯ #3'7"42¯ëÄÄi<<Nþë {°þêçþ2ã#FÑÿ™‡ '#3'‡šššš‹¶ýX{µ/¶wµ¸ÿ˜ '#37'7 sZZdsZZdš[Fý{ENYEAEN¸ÿ˜  ''#37 sZaRZdYEAL@ý{EN¦ÿ™² #3²ðððð&ýX{þæ/wþæ°ÿ™¨%'#'55'553'¨onnnnooo„þx¨/‚„/‚óþì‚/„…‚çÿ™q %'#3'qoooo„þx{þì‚/„…‚çÿ™q #575573qoooogˆ„/‚…„/‚°ÿ™¨#57557377¨noooonnnÂþXˆ„/‚…„/‚ó‚/„‚°ÿ™¨#5755737¨noooontý¦ˆ„/‚…„/‚ó‚¢ÿ™¶ '7'#3¶¯¥Í¯ÐñÍÄ-ðÏôü³{Ët>%'7››tåå/¶·¤ÿ™´#'#3´'Îgóó{ý¦£ÿ™µ#37µöÎþÞý¦{ôõ£ÿ™µ#"54327#37›öÎÕ !þÞý¦{ôõ‘ÿ™Ç#&547537ÇÖ'$$ Áû / ýÕ- -+ÜÛäÿ™F # # 33F úú  þõ úú þög£þ]¾½þ]£þCÿ™F$).8#"'#&54736374'&'676'&"'2/F Æ>Æ ÊjkË Æ#"Æ ËlkPA//=  !"""$!0= K gLþ´RLLTþ³Mþ¬LK k(MO#b8n99WM$ /©ÿ™¯#3'¯ëÄÄþþëþ°{þêèþ0©ÿ™¯ #'#33¯ÎÎgóþ {þ«óH©ÿ™¯ #5'#335'¯ÎÎÎgÓóþ:{ÐõÅý‡‡ôНÿ™©%'#57'537©oojinnijƒþy‡ƒ/{{.‚§þY‚.{{äÿ™t#&'&547673t% &$ '^2þq ,1dþ+°ÿ™¨ %'#'53¨onno„þx¨/‚¥þ:‚çÿ™q%'#3qoo„þx{þ:‚°ÿ™¨%'#&'&547'5673¨X $>P(Chþd*J/_ qþ +Oÿ™:#3:g{äÿ™t#&'&547673t% &$ '^2þq ,1dþ+zÿáÞƒ %'757'5<››¢Â››¹åå/¶·!å/¶·.3ÿ™% #553'#%ëëëÄÄÄNþë  °°þêçþ2Îç°ÿ™¨ #5737¨noonÂþXˆ„/‚Æþ[‚çÿ™q#573qoogˆ„/‚ưÿ™¨ '#'53¨onnoc‚ü´‚.L‚ÿ™» '#37'7»„„„„b–›{›–/–›üã›–Ÿÿ™¹ #'5537¹‘nn‘¿«ý…|‚-€ÐÒ¬~ÿ Ú %577ÚñÉþÌÛ»þå/ìlå/¶±ÿ™§#3§ÚÚg7þþGþ:á3:Åüá\é#"'&5473\# ""&% * ™þg ›ý½å'737½’oo¦©©ƒ«þS…Ÿÿ™¹ '#573¹‘nn‘<¬ü±Lƒ-…©Ñÿ™‡#573‡ššgM¶/µ´ÿ™¤#&'&54767573¤% $$ šš'2þÑ0)1y¶/µþ[ +¢ÿ™¶ %#37'7'¶øøƒ[ÐÏ…¼þÝ{þÝš›ôüáôœçÿ™q #377qoooo/‚þì{þx„/‚…„¢ÿ™¶ +%#37'7'7#"'&547632#"'&547632¶øøƒ[ÐÏ…2     ¼þÝ{þÝš›ôüáôœ¥!  !  þ³"   "  –ÿ #3Âûùþô^®þ[{þŽ|þinÿ™ê #'#373꣣££gOÁÁü±{¾¾’ÿ™Æ#'57'#373ÆjCWWCj~~gOO/gg/Oü±{””3ÿ™%#&'&5336765%MB[jF=J8OcÄsNSq=›COtoUBgb  `ÿŸ¥!þõ[°°[ þߥ=G®9Š‹¾«GþÈp¿ðŠƒd¼n’ÿ™Æ #'#3735#'5'5#'Æ~~~~j(jü~~~~j(jg””{””þ×ýýûÍ••Í•–ý~~ý3ÿ™%#4'&'##47673%K8Kd=0EFbkE:etN:þú[H[uUVUý« `RÿË:3:4Å®ÿ™ª%#'5573'7ªrnnnnrrr……-ƒƒ-……/ˆü݈©ÿ™¯#3¯ëëÄgPþÐèVÿ™%##5#53#53533#3[ZZÚ\\YYÚ[ tt £þþ¾!hh!þþíLkà#"'&547632k!(!(–-)-)ÿÿí„k'cÿ8c9¦É² '#75'37²oNooNo8ƒƒ]ƒƒvÿ™â '##73âš'¶š0¶ü³Ù§Ösµ3ÿ™%+#4'&'##4767&'&53367653%K8Kd=0EFbjF=J8OcÿÿHÿðð&C>qÿÿ3ÿð%“'vÿÂÿÿHÿðð&vÂqÿÿ+óð&v¤q3ÿÿÿF^&v¯ßSÿÿ+ó¿&Vã\3ÿÿÿF-&VîÊSÿÿ+M¿&V\5ÿÿT-&V ÊUÿÿ+ÿ{M3'Vý|5ÿÿTÿ{«'V ý|Uÿÿ+ÿ{Mƒ&qCÃÿÿTÿ{ñ&q ±Äÿÿ+ÿ½M3'qý¥5ÿÿTÿ½«'q ý¥Uÿÿ\ÿðü¿&V\6ÿÿgÿðñ-&VÊVÿÿ\ÿkü@'Výl6ÿÿgÿkñ¯'VýlVÿÿ\ÿðü¡'V>ÿÿgÿðñ 'V¨ÿÿ\ÿðü¡'V>"ÿÿgÿðñ 'V¨#ÿÿ\ÿkü¿&V\Ëÿÿgÿkñ-&VÊÌÿÿH¿&V\7ÿÿ+ÿðó¿&Vã\WÿÿHÿ{3'Vý|7ÿÿ+ÿkó3'VÿãýlWÿÿHÿ½3'qý¥7ÿÿ+ÿ­ó3'qÿãý•WÿÿHÿC3'GýY7ÿÿ+ÿ3ó3'GÿãýIWÿÿ(ÿk03'jýl8ÿÿ+ÿk¡'jÿøýlXÿÿ(ÿp03'Yýl8ÿÿ+ÿp¡'YÿøýlXÿÿ(ÿ303'GýI8ÿÿ+ÿ3¡'GÿøýIXÿÿ(ÿð0q'vÿÂò*ÿÿ+ÿðß&vº`+ÿÿ(ÿð0b'jÿ,ÿÿ+ÿð¿&jø\-ÿÿ O´&YW9ÿÿ:"&YÅYÿÿ ÿ{O3'Vý|9ÿÿÿ{:¡'Vý|YÿÿDð&C>q:ÿÿ:^&C>ßZÿÿDð&vÂq:ÿÿ:^&vÂßZÿÿD¿&j\:ÿÿ:-&jÊZÿÿD¿&V\:ÿÿ:-&VÊZÿÿÿ{D3'Vý|:ÿÿÿ{:¡'Vý|Zÿÿ(0¿&V\;ÿÿ3%-&VÊ[ÿÿ(0¿&j\;ÿÿ3%-&jÊ[ÿÿ3%¿&V\<ÿÿ3ÿF%-&VÊ\ÿÿgñð&Gq=ÿÿsé^&Gß]ÿÿgÿ{ñ3'Vý|=ÿÿsÿ{é¡'Vý|]ÿÿgÿ½ñ3'qý¥=ÿÿsÿ½é¡'qý¥]ÿÿ+ÿ½'\'qÿýý¥Kÿÿ+ÿðó¿&jâ\Wÿÿ:~&WéZÿÿ3ÿF%~&Wé\ÿÿHÿð•&EàDÿÿiè'V…Aÿÿ ÿ{O3'Vý|$ÿÿHÿk¯'VýlDÿÿþ,OM'fÿ¸ˆ$ÿÿþsÿð¼&fÿ÷Dÿÿ OÒ'vÿÂS„ÿÿHÿð<'vÿȽ¤ÿÿ OÒ'C>S„ÿÿHÿð<'CE½¤ÿÿþYO"'fÿå]„ÿÿþjÿðŒ'fÿöǤÿÿ O–'Y9„ÿÿHÿð'Y£¤ÿÿ ÿ{Oð&GqÿÿHÿk^&Gßÿÿ O¿'vÿÂ@ÄÿÿHÿð'vÿÈšÅÿÿ O¿'C>@ÄÿÿHÿð'CEšÅÿÿþtO'fJÄÿÿþtÿðy'f´Åÿÿ Oƒ'Y&ÄÿÿHÿðÝ'Y€Åÿÿ ÿ{OÝ&UqÿÿHÿkK&Ußÿÿ+ÿ{3'Vÿîý|(ÿÿ?ÿk¯'VÿøýlHÿÿþdM'fÿðˆ(ÿÿþkÿð¼&f÷÷Hÿÿ+´&YîW(ÿÿ?ÿð"&YøÅHÿÿ+Ò'vÿ¯SŒÿÿ?ÿð<'vÿ¹½¬ÿÿ+Ò'C,SŒÿÿ?ÿð<'C6½¬ÿÿþk"'fÿ÷]ŒÿÿþyÿðŒ'fǬÿÿ+–'Yÿî9Œÿÿ?ÿð'Yÿø£¬ÿÿ+ÿ{ð&Gîqÿÿ?ÿk^&GøßÿÿþtçM'fˆ,ÿÿþsü¼&fÿ÷óÿÿqÿ{ç3'Vý|,ÿÿ\ÿ{üp'Vý|Lÿÿ3ÿk%@'Výl2ÿÿHÿk¯'VýlRÿÿþtÿð%M'fˆ2ÿÿþtÿð¼&f÷Rÿÿ3ÿð%Ò'vÿÂS–ÿÿHÿð<'vÿ½¶ÿÿ3ÿð%Ò'C>S–ÿÿHÿð<'C>½¶ÿÿþtÿð%"'f]–ÿÿþtÿðŒ'fǶÿÿ3ÿð%–'Y9–ÿÿHÿð'Y£¶ÿÿ3ÿk%ð&Gq1ÿÿHÿk^&Gß2ÿÿ3ÿðU'vÿÖšbÿÿHÿðØ'vÄYcÿÿ3ÿðU'CRšbÿÿHÿðNØ'CÅYcÿÿÿ?ÿðU­'fËèbÿÿÿ8ÿðN('fÄccÿÿ3ÿðUÝ'Y€bÿÿHÿð‹œ'YÄ?cÿÿ3ÿkU 'VýlbÿÿHÿdN'Výecÿÿ(ÿk03'Výl8ÿÿ+ÿk¡'VÿøýlXÿÿþtÿð0M'fˆ8ÿÿþ[ÿð¼&fç÷Xÿÿ(ÿð¨„'vëqÿÿ+ÿðqò'v´srÿÿ(ÿðu„'Cìqÿÿ+ÿð>ò'Cµsrÿÿÿ_ÿðuÔ'fëqÿÿÿ(ÿð>B'f´}rÿÿ(ÿð²H'Yëëqÿÿ+ÿð{¶'Y´Yrÿÿ(ÿduÇ'Výeqÿÿ+ÿd>5'VÿÕýerÿÿ3%ð&C>q<ÿÿ3ÿF%^&C>ß\ÿÿ3ÿ{%3'Vý|<ÿÿ3þÁ%¡'VüÂ\ÿÿþt%M'fˆ<ÿÿþtÿF%¼&f÷\ÿÿ3%´&YW<ÿÿ3ÿF%"&YÅ\ÿÿ?ÿðGŒ&ü÷§ÿÿ?ÿðGŒ&Gò÷§ÿÿ?ÿðG&Üú§ÿÿ?ÿðG&)Üú§ÿÿ?ÿðG&Üú§ÿÿ?ÿðG&*Üú§ÿÿ?ÿðGü&ë÷§ÿÿ?ÿðGü&+ë÷§ÿÿÿüO@'ÿÿ«‡ÿÿÿùO@'Gÿÿ«‡ÿÿÿ€OA'þ°ÿ«‡ÿÿÿpOA')þ¨ÿ«‡ÿÿÿ€OA'þ°ÿ«‡ÿÿÿpOA'*þ¨ÿ«‡ÿÿÿ#OV'þ£ÿQ‡ÿÿÿ,OV'+þŒÿQ‡ÿÿ‘ÿþí˜&«ÿÿ‘ÿþí˜&G«ÿÿ‘ÿþíœ&ð«ÿÿ‘ÿþíœ&)ð«ÿÿ‘ÿþíœ&ð«ÿÿ‘ÿþíœ&*ð«ÿÿÿÈ@'þÑÿ«‹ÿÿÿÁ@'GþÊÿ«‹ÿÿÿHA'þxÿ«‹ÿÿÿ8A')þpÿ«‹ÿÿÿHA'þxÿ«‹ÿÿÿ8A'*þpÿ«‹ÿÿ5ÿFŒ&÷­ÿÿ5ÿF&G&ú­ÿÿ5ÿF“&ý­ÿÿ5ÿF“&)ý­ÿÿ5ÿF“&ý­ÿÿ5ÿF“&*ý­ÿÿ5ÿFÿ&ú­ÿÿ5ÿFÿ&+ ú­ÿÿÿè'@'þñÿ«ÿÿÿà'@'Gþéÿ«ÿÿÿg'A'þ—ÿ«ÿÿÿW'A')þÿ«ÿÿÿg'A'þ—ÿ«ÿÿÿW'A'*þÿ«ÿÿÿ 'V'þÿQÿÿÿ'V'+þrÿQÿÿ­ÿø÷Œ&Ø÷¯ÿÿ­ÿø÷Œ&GÖ÷¯ÿÿÿø÷&Àú¯ÿÿˆÿø÷&)Àú¯ÿÿÿø÷&Àú¯ÿÿˆÿø÷&*Àú¯ÿÿOÿø÷ü&Ï÷¯ÿÿoÿø÷ü&+Ï÷¯ÿÿç@'ÿÿ«ÿÿç@'Gÿÿ«ÿÿÿŽçA'þ¾ÿ«ÿÿÿ~çA')þ¶ÿ«ÿÿÿŽçA'þ¾ÿ«ÿÿÿ~çA'*þ¶ÿ«ÿÿÿ;çV'þ»ÿQÿÿÿ:çV'+þšÿQÿÿHÿð‹&þöµÿÿHÿðŒ&G÷µÿÿHÿð&ñúµÿÿHÿð&)ñúµÿÿHÿð&ñúµÿÿHÿð&*ñúµÿÿÿèÿð%@'þñÿ«•ÿÿÿØÿð%@'Gþáÿ«•ÿÿÿbÿð%A'þ’ÿ«•ÿÿÿPÿð%A')þˆÿ«•ÿÿÿ‡ÿð%A'þ·ÿ«•ÿÿÿwÿð%A'*þ¯ÿ«•ÿÿ+ÿô)Œ&ú÷»ÿÿ+ÿô)Œ&G÷»ÿÿ+ÿô)&ïú»ÿÿ+ÿô)&)ïú»ÿÿ+ÿô)&ïú»ÿÿ+ÿô)&*ïú»ÿÿ+ÿô)ü&þ÷»ÿÿ+ÿô)ü&+÷÷»ÿÿÿÇ%@'GþÐÿ«›ÿÿÿL%A')þ„ÿ«›ÿÿÿ=%A'*þuÿ«›ÿÿÿ«%Á'Yÿd¯ÿÿ+ÿð(Œ&÷¿ÿÿ+ÿð(Œ&G ÷¿ÿÿ+ÿð(&÷ú¿ÿÿ+ÿð(&)óú¿ÿÿ+ÿð(&óú¿ÿÿ+ÿð(&*óú¿ÿÿ+ÿð(ü&÷¿ÿÿ+ÿð(ü&+÷¿ÿÿÿé@'þòÿ«ŸÿÿÿÙ@'Gþâÿ«Ÿÿÿÿ_A'þÿ«ŸÿÿÿRA')þŠÿ«Ÿÿÿÿ†A'þ¶ÿ«Ÿÿÿÿ{A'*þ³ÿ«Ÿÿÿÿ<@'þ¼ÿ;ŸÿÿÿJ@'+þªÿ;Ÿÿÿ?ÿðG&;ùú§ÿÿ?ÿðG&Fùú§ÿÿ‘ÿþíœ&; «ÿÿ‘ÿþíœ&F «ÿÿ5ÿF“&;-ý­ÿÿ5ÿF“&F-ý­ÿÿ­ÿø÷&;Ýú¯ÿÿ­ÿø÷&FÝú¯ÿÿHÿð&;úµÿÿHÿð&Fúµÿÿ+ÿô)&; ú»ÿÿ+ÿô)&F ú»ÿÿ+ÿð(&;ú¿ÿÿ+ÿð(&Fú¿ÿÿ?ÿGŒ&{È_ÿÿ?ÿGŒ&{È`ÿÿ?ÿG&{Èaÿÿ?ÿG&{Èbÿÿ?ÿG&{Ècÿÿ?ÿG&{Èdÿÿ?ÿGü&{Èeÿÿ?ÿGü&{ÈfÿÿÿüÿO@&ÇgÿÿÿùÿO@&Çhÿÿÿ€ÿOA&ÇiÿÿÿpÿOA&Çjÿÿÿ€ÿOA&ÇkÿÿÿpÿOA&Çlÿÿÿ#ÿOV&Çmÿÿÿ,ÿOV&Çnÿÿ5ÿŒ&{ŠÊ{ÿÿ5ÿ&{ŠÊ|ÿÿ5ÿ“&{ŠÊ}ÿÿ5ÿ“&{ŠÊ~ÿÿ5ÿ“&{ŠÊÿÿ5ÿ“&{ŠÊ€ÿÿ5ÿÿ&{ŠÊÿÿ5ÿÿ&{ŠÊ‚ÿÿÿèÿ'@&ǃÿÿÿàÿ'@&Ç„ÿÿÿgÿ'A&Ç…ÿÿÿWÿ'A&džÿÿÿgÿ'A&LJÿÿÿWÿ'A&Ljÿÿÿ ÿ'V&ljÿÿÿÿ'V&ÇŠÿÿ+ÿ(Œ&{ȳÿÿ+ÿ(Œ&{È´ÿÿ+ÿ(&{ȵÿÿ+ÿ(&{ȶÿÿ+ÿ(&{È·ÿÿ+ÿ(&{ȸÿÿ+ÿ(ü&{ȹÿÿ+ÿ(ü&{Ⱥÿÿÿéþþ@&Å»ÿÿÿÙþþ@&żÿÿÿ_þþA&ŽÿÿÿRþþA&žÿÿÿ†þþA&Å¿ÿÿÿ{þþA&ÅÀÿÿÿ<þþ@&ÅÁÿÿÿJþþ@&ÅÂÿÿ?ÿðGY&Uëí§ÿÿ?ÿðGÿ&që¿§ÿÿ?ÿG&{ÈÃÿÿ?ÿG¯&{ȧÿÿ?ÿGh&{È¢ÿÿ?ÿðG0&Ó§ÿÿ?ÿG0&{Èÿÿ Oê&U¸~‡ÿÿ O&q¸P‡ÿÿÿýOA';ÿ ÿ«‡ÿÿÿýOA'Fÿ ÿ«‡ÿÿ ÿO3&LJÿÿ9é!327632#"'&=(3  +J+*F  <(30÷àT•27654'#÷&" 8 * $!./‘Ç] 2#"'&#"#"'47632327676³$!4 (#'-[ $ %ŒÿÍÝ 0@2#"'&#"#"'476323276762#"'&547632#"'&5476³$!4 (#'-í!   è!  Û $ %x    ÿÿ5ÿ“&{ŠÊÇÿÿ5ÿ¯&{ŠÊ­ÿÿ5ÿk&{ŠÊ¤ÿÿ5ÿF3&Ö­ÿÿ5ÿ3&{ŠÊÿÿÿÅA';þÔÿ«‹ÿÿÿÅA'FþÔÿ«‹ÿÿÿä'A';þóÿ«ÿÿÿä'A'Fþóÿ«ÿÿ5ÿ'3&ÍÐܧ–!'&/&767627654'#m8 8 ˜&" 8 *‹˜ ˜ ‘ $!./Ðܧ–#62'"'&747'27654'#‡  8  &" 8 *‹  ˜   $!./ÿÿ€à¶'ÿï¨ÿÿjÿø÷Y&UÏí¯ÿÿjÿø÷ÿ&qÏ¿¯ÿÿ\ÿø÷‘&9ÐÛ¯ÿÿZÿø÷&:ÎÚ¯ÿÿ`ÿø÷0&ÏÓ¯ÿÿZÿø÷µ&ÎØ¯ÿÿqçê&U~ÿÿqç&qPÿÿ çA';ÿÿ«ÿÿ çA'Fÿÿ«Èܯ–!'&/&7676"'&54763"u8 8 K3/%! ‹˜ ˜ ‘!*6 !!$Èܯ–#62'"'&747'"'&54763"  8  23/%! ‹  ˜  !*6 !!$ÿÿ àÖ'¨Gÿÿ+ÿô)Y&Uþí»ÿÿ+ÿô)ÿ&qþ¿»ÿÿ+ÿô)’&9þÜ»ÿÿ+ÿô)&:þÚ»ÿÿÿB˜&·ÿÿÿB˜&G·ÿÿ+ÿô)0&þÓ»ÿÿ+ÿô)µ&þØ»ÿÿ3%ê&U~›ÿÿ3%&qP›ÿÿÿÍ%A';þÜÿ«›ÿÿÿÍ%A'FþÜÿ«›ÿÿÿÁó@'GþÊÿ«—ŒüͶ 0'&/&76762#"'&547632#"'&54768 8 N!   è!  «˜˜O    ŒüͶ -62'"'&7'2#"'&547632#"'&5476C  8  M!   è!  « ˜ P    ñÜK–'&/&76768 8 ‹˜ ˜ ÿÿ+ÿ(&{ÈÏÿÿ+ÿ(®&{È¿ÿÿ+ÿ(h&{ÈÄÿÿ+ÿð(0&Ó¿ÿÿ+ÿ(0&{È?ÿÿÿÛ%P';þêÿ«•ÿÿ%Q'Fÿÿ«•ÿÿÿÙA';þèÿ«ŸÿÿA'Fÿ#ÿ«ŸÿÿFÿ 3&ÑŸñÜK–62/&747+  8  ‹  ˜  ÷àT•"'&54763"T3/%! !*6 !!$ˆÐ+ !"543!2µþîH. !"543!2õþn’W. !"543!2<ýà ÿÿW.Jÿôÿ#dÿµ!5!5dýpýK22`22WÑ\ #"/‰F ‘\áï‡:T\ 3#"'&547Ï…‘ \þ÷‡ÿoT‘ 73#"'&547Ï…‘ ‘þ÷ÿÿWÑ\M]Wû\ #"/##"/³F ‰\F ‰\áïáï]Wû\ 3#"'&547%3#"'&547¥}‰ }‰ \ïáï]ÿŒû‘ 73#"'&547%3#"'&547¥}‰ }‰ ‘ïáïÿÿ]Wû\Q|ÿÁÜ\4?3543232+#"5#"|„€€€ŒŸ þdœ|ÿÂÜ\&4?3543232+32+#"=#"54;5#"|„€€€€€€€ŒŸ ÓŸŸÓÊŽQ2#"'&5476.3.6/Q-6.63ÿñ%T/72#"'&547632#"'&547632#"'&5476d!  !  Ñ!   Ó  !  T  !     "ÿ÷4f/?O_o2#"'&5476"327654'& #"'&547%6322#"'&5476"327654'&72#"'&5476"327654'&;!0":!0", ', (LþŠ v þ¶;!0":!0", ', (ü;!0":!0", ', (f2#9!1":""'. '0 Àz  z ²2#9!1":""'. '0 "2#9!1":""'. '0 ÿ÷Rf/O`q‚2#"'&5476"327654'& #"'&547%632672#"'"'"'&547632672327654'&#"4'&#"32765'4'&#"32765;!0":!0", ', (LþŠ v y!<;!0";"%8;"%8:!0";"!<;3', (, "), ', º), ', f2#9!1":""'. '0 Àz  z æ32#9!40401":"43o, '0 '0'. '0'. 'ÉWŽ\ 3#"'&547}‰ \ïÿÿ]Wû\RWW\  3#"'&547'3#"'&547%3#"'&547}‰ ‚}‰ Ö}‰ \ïáïáïÉWŽ\ #"/FF ‰\áïÿÿ]Wû\GRXÀ@WW\  #"/!#"/!#"/GF ‰EF ‰þíF ‰\áïáïáï?8¡?632#"'?Ð   ÑÅ  ¨©  %¡%#"'&54?'&547632Ï  ŽŽ  ÐÅ  ¨©  pÿñèj"3E#"'&54763232+"'&5476 #"'&54763232+"'&5476Ò . # #  Ç . # $  3þºF  þ !  ! ÞþºF  þ !  ! †ÿñçAE%32+"'&54767&5'&54763267654'&#"#"=767232#"5+ $ + %   l >#-=DM8h09 =U" $ " % ‹Î  •4; @")D "D%1C.)ÿô{d­!5dý­222Š%Ö #"'&547632þA ¿ ®þä  ÿ„“\-3#"'&=4767&'&=47632B*/ " 6&/& 9* (.»). ­0& ­:$ Åÿ„B\054'&'&'432#"54763676=&'&#&47674" 6  &/& -- 9º).­0 & ­:$ »+(*&ÿñHj"GY#"'&54763232+"'&5476%#"=67654'&#"#"=76723232+"'&54762 . #  #  þéˆ>#-=DM8h09 =++ $ + % 3þºF  þ !  ! ¢)D9;@")D "D%1C.¦" $ " % ÿñ'j"GY#"'&54763232+"'&5476%#"=67654'&#"#"=76723232+"'&5476r . # $  Iˆ>#-=DM8h09 =++ $ + % 3þºF  þ !  ! ¢)D9;@")D "D%1C.¦" $ " % ÿÿOÿ \Gx\À@À˜!#"'&=47632276=4'&"˜7?7>´@@ã:b(D&1:c(D&53<  <3<  ·˜f37332+32#"'4735#Ojj˜…7   `'˜?³âÚ >>µú¢c+67232#"'&5472327654'"#"#"'532ø) 8 8%/* *3>A. ¤?b4$H# '5KÎþ¶t"1"'&+"632"'&=47632;2765&'"µD',3G#&[ >.? ¼=&<#Z>,97D.!b$+Z9, òK* W#·þf0'&7#"'53` ^Ù@þÎ,8Àý˜n'7#"'&547&547632'"327654'&"327654'&X@0!; @;/8g7 -* * *5¼;7/:33-4p- ' . Ÿ(.* "Íþ·t ,&#&376&'&747672#"'&76765‹G'%% )3@ #&\ >&2 7G6.ýS+ =)(4?!.!e%,[:# 8/G²A¦E#'&=#"'472;547236= SSS ·`  `VV²·¦Û "'472;6ÇÉ ·±‘§ÿ"'472;6'&7&76;2#ÈÈ  É  ÉÛ I èu¨61&'&7676c P & T+§  Œ;F ‰>CãèQ§'&576'&/6õ Y(Q &§‰ƒ¹´tþ@ÿÿºÿ>“¦uþ@ÿÿÃÿ=›®vþ@ÿÿÐÿ>º´wþ@²ÿ¦ƒ#'&=#"'472;547236= SSS  `  `VV²ÿõ¦ "'472;6ÇÉ  ±ÿϧ=7"'472;6'&7&76;2#ÈÈ  É  É I ÿ&uæ%61&'&7676c P & T+å  Œ;F ‰>Cãÿ&Qå7'&576'&/6õ Y(Q &剃ëîL*Vý  .! / & (  U {& (   5  .þòá:'B%)$B<àE%47632+4763232767676'#"'&=&'&'&'&+#"'&532ó"!?Ì£*i + ~§L()‚Iþ·@!!9þðÂ’’6 þ]Ì#'J ÿð@E!2!!2!32767632#"'&'#"'4;5#"'673676325432#"'&'&#"j þÞþýO7BYC &MafNC  T@OfG@0:`;"_<b7'F #GNCX<oA1Ep4#O-ÿù>u);cp5472"'&'&#"327632#"'&547632'#"'&5476325#"'&54763254/"#"'&54763232#'5&#"32 < QFG-3?N'=$.: þ¡  ^ þð65D;!)-(0 7(? ?*C' 7=.KX- %?&0U,µþb  ž ˜-8 ,"  ,«D; &  3í^9F #"'&5476325#"'&54763254/"#"'&54763232#'5&#"32åþ¡  ^ þä65D;!)-(0 7(? ?*C' 7Ýþb  ž ¯-8 ,"  ,«D; &  ?ÿð@+1732767632#"'&=47676325432#"'&'&#"Í7>YC &LbfON6 EfeH@0:7-)<>%F #GONeSTI JEp4#þfxAYGVÿðB•P2#"'&5476"327654'&5432#"'&'&#"32767632"'&=47632p6 *3,%" %" Œ;'3_4"D6L?, &@;iG?F=[I< •-/+1! $ $yp;!T9KGiB4(! #< UKbSqJ@3 ÿôMP!K]2#"'&5476"327654'&'&5472"'&'&#"327632#"'&547632#"'&547632ºK+:(1I,:'2; 1!:!2É < QFG-3?N'=$.:þ¡  ^ ;'2G,;'1G-%0!; 0 =! 7=.KX- %?&0U,sþb  ž  ÿôMP!K]2#"'&5476"327654'&'&5472"'&'&#"327632#"'&547632#"'&547632ºK+:(1I,:'2; 1!:!2É < QFG-3?N'=$.:þ¡  ^ ;'2G,;'1G-%0!; 0 =! 7=.KX- %?&0U,sþb  ž ÿÿ\ÿðü@R!;337#"54;2+35#"54;2+32+"54;5#32+"54;3fÈ2â6x.6â2Ü)(0 ÑÑþççáþá0ÿã/8>%'&'&76767676?67'&'&'&'&7676327676@7'L-H+'  1.VB632765632#!"54367654'&/&547632#"'&#"Æ9ü#)þ½' 9%/6, (25³WF(hG'4?5>&.j H+'  1.uÿääx=676/"67632327676#"'&'&767'&'&7676úu93<*M$O:8Q.?‹ $=- 5O 0/ ;Q‰ItR޶rT€ š[MD .O h /01 ÿï.\8"327656/&3#"54;67632#"'&'!"54;#"54;¥,/O+þà6_ 0xD&*"þó<%N…,N7#"54;32+##"'&=43232%#"4;2'2#"'&5476"327654'&q6jÀÉ 4¿<$ ɈˆT1 (0 (" " Pºþ&ÚýöÚþrC Õ((ð*- *. " "ÿñTB$4D#32+"4;5#"4;2'327654'&+72#"'&5476"327654'&E?$`ŠA + q8K(M&|WUZW{xWVYVzoLEPIctLCQJf$$û$/(*% ªYWxWSXXy|WU)QJdmMFSHenLE4ÿjÆ2>%#"'3327654'&'"#"'&547&53676324'327682Sm($\$Glh= 0=..(  Yd%(X-þ C0þyNFšU p28|# Ñ,T,""K JWeCoR ¿0X3þ£AYRC@>+ó3#(732+"54;#"54;2#&+32?654¥Šé66ð_8&H8KA•† )8ç¾á@,9O1'ú ÖÂ(8<3ÿ%@1>C632327632#"'&#"#"'&54?&'&547632'327654'&#"16())*- &#!8T Z_9.QGakIERDÂ+4X?9I:M3,)H(   AaN^„WMZVx‡VHCPJbyL=þ]Mtr#M3 48327654'&+"543!232+&'&'#32+"54;3ÓD^57'-kT8(‹7(& 9U7'V²(0$3$4$;,5a0%:"@ œ2Òáþáÿÿþ÷M3'w´ÿL5óV3F32#"'4735#"'53"'5+"'4;5#'32#"'4;5#"'4;732#326Œ5Gò‚U%R S%U ;SQ< þþIjjIþòô¸¸ôþ¸¸þ1'375#!#"=!!5432!5U8þ«!þóÉþ¸:þ H)Þþ#ávŸ:þ4¶;ÌNÿþ;M#5676767654'&'##543235&'&'&547676;235432Ô+676\05: Ï}X 70BZ%&5K¯  KK@!4 Q8!¯ea4y d73 L % fB aeNÿþ;J"=##&'&54767675##"=3;67674/&'&/5G 3+ZD27U}ÏB5 " . \662%;ea )Q!$ %K) 47d=ae¯8Q-$ !CHS2¯ÿÿ+<3.ÿÿ O+‡ÿÿ+3)33À^ÿüè¤3%32=#"4;'&/#&32+5476;'&7676HaPzLd œ!? `ˆM"C Þ[@(h\ ™ î' p™^ g ÿöOd5G_%#"'&5472327654'&#&5476327654/#"#"'47632#"'&547632%32+"5432#"'&5476:4&5*)+0 - ,&-*> ^þ¡  ^ þªG²'A  ¹$47  $*   $ .+þb  ž {þÃ$  ÿöOf&\n3542#5767654'&#"#"'47632#"'&5472327654'&#&5476327654/#"#"'47632#"'&5476324–$æ„5$-#77"b:4&5*)+0 - ,&-*> Xþ¡  ^ )'+{5$ $ ,- !#ä$47  $*   $ .+þb  ž ÿôXd+=U67232#"'&5472327654'"#"#"'532'#"'&547632%32+"5432#"'&5476®) 8 8%/* *3>A. ¤Hþ¡  ^ þªG²'A  9b4$H# '5K¤þb  ž {þÃ$  ÿôXf&Rd3542#5767654'&#"#"'4763267232#"'&5472327654'"#"#"'532'#"'&5476324–$æ„5$-#77"û) 8 8%/* *3>A. ¤Hþ¡  ^ )'+{5$ $ ,- !#db4$H# '5K¤þb  ž ÿôXd6bt#"'&5472327654'&#&5476327654'&#"#"'4763267232#"'&5472327654'"#"#"'532'#"'&547632·:4&5*)+0 - ,&-*> É) 8 8%/* *3>A. ¤Hþ¡  ^ ¾$47  $*   $ . +¤b4$H# '5K¤þb  ž Dd6H_c#"'&5472327654'&#&5476327654'&#"#"'47632!#"'&547632#57332+32+"54763=#·:4&5*)+0 - ,&-*> þ¡  ^  •€9  U )k¾$47  $*   $ . +þb  ž þt"ÚØ$9$ ]´´ÿöBd)IW #"'&547632%32+"5432#"'&5476632#"'&547632'&#"327654'&#"åþ¡  ^ þªG²'A  L)3Y "^ >/>7D(E#0 ( Ýþb  ž {þÃ$  þa6_.  i#*[:+>)5@R) N 2ÿöBd+=]k67232#"'&5472327654'"#"#"'532#"'&547632632#"'&547632'&#"327654'&#"I) 8 8%/* *3>A. ¤þ¡  ^ o)3Y "^ >/>7D(E#0 ( @b4$H# '5Kcþb  ž þ½6_.  i#*[:+>)5@R) N 2ÿöHd'7Ia%#"'&547&547632'"327654'&"327654'&#"'&547632%32+"5432#"'&5476@0!; @;/8g7 -* ) *5þ¡  ^ þªG²'A  µ;7/:33-4p- ' . Ÿ&.* "9þb  ž {þÃ$  ÿöHd'7n€%#"'&547&547632'"327654'&"327654'&#"'&5472327654'&#&5476327654'&#"#"'47632!#"'&547632@0!; @;/8g7 -* ) *5þÄ:4&5*)+0 - ,&-*> þ¡  ^ µ;7/:33-4p- ' . Ÿ&.* "$47  $*   $ . +þb  ž ÿöHd+CScu67232#"'&5472327654'"#"#"'532#"'&547&547632'"327654'&"327654'&#"'&547632I) 8 8%/* *3>A. ¤@@0!; @;/8g7 -* ) *5þ¡  ^ @b4$H# '5Kþu;7/:33-4p- ' . Ÿ&.* "9þb  ž 8ÿöHf(8HZ0'&7#"'53#"'&547&547632'"327654'&"327654'&#"'&547632` ^Ù÷@0!; @;/8g7 -* ) *5þ¡  ^ @þÎ,8þO;7/:33-4p- ' . Ÿ&.* "9þb  ž 3íd) #"'&547632%32+"5432#"'&5476åþ¡  ^ þªG²'A  Ýþb  ž {þÃ$  qç332#!"54;#"543!2#@‹þÁ‹‹? þá1'3#3!2+32#!"54;#"54w——þÕ¿kkþAkk þ þá!73!2+32#!"54;#"54#3#3#<ßKKþ!KK†gg÷gg3þá)þá%33 $76#!"54;#"54;26;2' #ós‡þ956‰" fc '$(Ïu) þ á(þE¹*þáþ+,332/&'"#&54;26í#$¬ §/," Ž‹ 3þø(þE¹*%33#"'&56;26;2+32#!"5673#e- $' cf "‰65þ9‡D)  *þG»(þá .3#'%3#32#!"56"'&56;26;2+#€™þ9s_- $' OR "±(*)áþâ *þG»(þáþG3'+73##32#!"56"'&56;263!2+3Ölq)¡ þUK(' ;> " H(()áþáþáþâ *þG»(þJ32732+7#"54;2+32+"54;'32+"54;#"5437'*ð,xx(n"„2xx4ø**pB3ÉÉðñÉÉá)þñðÿÿ(03;E32732+32+"54;'32+"54;7'#"54;2+7#"54#38ñ++ø3xx2ƒ"n(xy-¸BB3þÉÉñðÉÉ)ðñJ37;#;2#!"54;'32+"54;7'#"54;2+7#"543!2+#Š||ƒ!þô ddp"||Zdd!)1 ðñÉÉñðÉÉþáþÿÿ?3/ÿÿ?ÿð@&ÿÿ+3'ÿÿ Q30)§‹#"/7632!2#Ÿb  ÄÅ  `T6  mm 5º&ž #"/&54?1#"/#"56  ln  4–b  ÄÄ   `þ¬6§‹!"543!'&547632#"/&547§þªT` ÅÄ  5 mm  º&ž %43276320'&54?6324 nl  œVþ¬`  ÄÄ  §?‹*#"/7632!'&547632#"/&54?b  ÄÅ  `6` ÅÄ  b6  mm 55 mm  6ºž,*#"/&54?"/7632'&54?6326  mm 55 mm  6¶b  ÄÅ  `þÊ` ÅÄ  bpgÐÅ'&'&/'"/'&'¶ >Ù ið ck ×>ð  zeØÅ'&'&5'&7637'#&?'&'&767vk ×=  ñ  €  >Ùhð  wmÖÌ%'&7676'&76'&7562tò  ñ ?زò  ði Ø=€màË?67674722Åò  ðh Ù>Ïò  ñ =× (Ÿ0•/'&'&76?##"/763237632#˜- $Íb  ÄÅ `à. %hZ H6  mm 5[ I(Ÿ0•03'&547632#"/&54?#'&'&76?#"54;76ý»` ÅÄ  bÒ- $x. .5 mm  6Z H[ Mž v-/#'67676763#&'&'&#&'¢1  bà Y(  '$  6=""e  Ê  ,&8'Mž v6'&/&'&#"54767676676?"'&7676767'&7¶)"=    $"  % (Y†!b "+'!   &  ,  Ê (§0‹/#"/76323763232+#"/žb  ÄÅ  `NŸ  `Õ×b   6  mm 5X 56  Yºž/#"/&54?"/"/#"=#"/&54?6  mm 5X 56  Y§b  ÄÅ  `NŸ  `Õ×b   ÿÿ(§0‹ÛX2ÀÿÿºžÜX2À)§‹)##"/763237632#"'Yºb  ÄÅ  `ºŸ  ††  6  mm 5X JJ  ÿÿ>§/‹GßXÀ@*‡6«!!#"/7612!5432#"5 þ”b  ÄÄ   `j6  ln  4aîš¾ !%#"/&54?1#"/32+"5436  ln  4aî)mb  ÄÄ   `þ•*‡6«!#"=432!'&547630#"/&54?Tj`  ÄÄ  bcîa4 nl  6š&¾2!7632'&147632#"54;2#@6  ln  4aî þ“b  ÄÄ   `kšÿ;, 432+"54#"/&54?"/7632'&54?632µîî~6  mm 55 mm  6 Àb  ÄÅ  `þÊ` ÅÄ  b)§º.!2767&+"'&5476;2#!#"/7632¡ :A&&G *)þñb  ÄÅ  .$1036  mm ÿÿE§7ºGæ`À@)§»-:547636+#"'&=##"/7632;2767&/T0= '&9µb  ÄÅ `Ü9/!3.$? ./EE6  mm 5 &.ÿÿE§7»Gè`À@§?‹C/?27676767767'&'4763"'4?'&'&'&#'&b ÄÅ  `$# !`  ÅÄ  b/  $ 6  mm 5#( 5 mm 6ŸX•@'&'&76?##"/76323763'&547632#"/&54?7- $”b  ÄÅ `§. %”` ÅÄ  bZ H6  mm 5[ I5 mm  6„4”ì76776'&76?îdÎ TÌ}Q «"  ª4\/â2þ±I  “Ý iÌþ#"'&5##"/7632ÌÅb  ÄÅ `¡þ‘F6  mm 5ÿÿŒïþGíXÀ@ÿÿiÌþGí@ÀÿÿŒïþíXÀ* 7632'&54?632!"'4763®4 nl  6þºþ”` ÆÄ  bF) þ %!#"/7632!47632 þ•` ÅÄ  bE{5 mm  6F( ‹947676762"'4'&'&'&&7632/472„ &(8,"*  &  6 ln 4–.*' ''!1,.*$( %%!þüb  ÄÆ `' ‹;763'&56?6324'&'&'&&#&'&76767636®4 nl 6 !+   *",%& –þþ` ÆÄ  b!%%($*.,1!' ' '*+g0; ("543!2/&'&''"/'&'þ1Ïþ†  *Ù  ið ¯k “ >ð  &ÿö69>!#"/?2!5432#"'#"'5432!'&7470763#"'4? þ”b  ÄÄ   `jþDj`  ÄÄ b“6 ln 4aî¼cîa4  nl 6;!-&/#'&//"'&'4723676ÓP >Ú  iB \2FuE3I7Ff-W6k  ×>%J ’>!ZAU];.X/9-276563#&'&54767'&'&?/"56?‡J)7W<3HCa†4H i  Ú>: s6B8LiFAo7J`; >×k'0!‹7632!2#!"54)Å  `Tþ:m 5 !©/&763!2#!"')  Æþ¬` 5 &ž#"/"542,l  6( Æ `þ¬Æ»&A6#"5#"'&547-5  þ:T` ÿÿ!‹Gù1À@ÿÿ1© /GúAÀ@ÿÿ%žGû;@Àÿÿ»&AGü;@À)147#"/7632!2#'&54?632#"'&54?!"543Ÿb  ÄÅ  `T:b  ÄÅ  `þ¬u6  mm 5H6  mm 5ÿÿ+/‡FÀ@ÿÿ)1GZÀ@)47#"/7632!2##"/7632!2#Ÿb  ÄÅ  `Tþªb  ÄÅ  `Tu6  mm 5 6  mm 5*&. 5#"/&54?1#"/#"5#"/&54?1#"/#"5ˆ6  ln  4 6  ln  4–b  ÄÄ   `þ¬Vb  ÄÄ   `þ¬ÿÿJ1GZÀ@ÿÿ*&. G2@À!a Ó'%#"'&54?!"543!2%7632!2#!"54Å  `þ¬ÆþÅ  `Tþ:Óm 5 m 5 ÿÿ!a ÓGAÀ@8 H%*32+#7##/?237332+3u¦¾‚.„l&  ˆŠ  $³‘(wºÀ«,&ÝÝ"   !òòHH/437'#73'&'4763"'4?##7##/?23737#8À§g"  Šˆ &²‚.„n&  ˆŠ  $µ‘(éÂ*!  "ÝÝ"   !òþ¾&8H)37'#7"'4?##7#"54;7#"54;733'&'4763½§oˆ† &²‚.„x‘¨Á‘(i$ n‚€ "ÝÝ&òò! 8“ Ÿ!2#!#/?2!2#!ˆ|þª&  ˆŠ  $Tþ†"   !¦&²ø'#"5"'&5?"/#"5@" €‚ "¨ý™@$  ‰ˆ  &ý¾8“ Ÿ7'!"543!'&'4763"'4?!"543Ðþ†T$  Šˆ &þª!  "¦&²ø %432763/47632432@"  ‚€ "vgý¿&   ˆˆ  $?ý™“HŸ"(&'4763"'4?!#/?2!7'!¬  Šˆ &þ´&  ˆŠ  $F*þlw  ""   !P¦ÿþ²$"(#"'&5?"/763/476327'7Î ""   !Pˆ  ˆˆ  &ýÆ&  ˆˆ  $5)ýz O37#"54;2+##"54;2+#3±;N–Ñ9È—M9úêqw“ýö “)þÛGÿïF#5"'4'47632#"'&547632&'"#"327654'&'&± 3BQ$A KBXeD6Ê"4@"0+5IiYSG×L ]Jsd“J-'W gKwd•I-~þS%5IiYN+-333%!+ë,ëþ:ŠÅ3ýÍ(Ù+-3!#+ë,¯ÅÅ3ýÍ þ'Ù&-;2+"'&5476;2+"!2#QL/?òònE9MA^òòv2³l3 VG^rI>^)6&ÿ¯œFM#7;2+"'#"'&54?&'&5476;763232+32#'7#"µM }Vòò##1 0U MA^s8 0ReY¾ëY`v2l4ª¹ h g.b')rI>x g½(½^)6snÐÁ ;2+"'&5476;2+"!2#œ 8ªª^'>%5ªª]J Q'1_/^ ÿÿ&G>À@&ÿ¯œ@GK?#"'&5476;7&+"'&5476;27632+#"'&54?#"'&5476;2767#73&¬ZÌßT$òò+'? ?VKC^e, $`ŸSm5º`M§F¿´ † ‡3g oJB] LW-;̤pÿÿsnÐÁGCÀ@3ÿA-+"'&54;!32+"54;#"'&543!2#32‹5þö6  Š,Ž-kký• ký•qÿû3'!!76;2!"=47&=43!2+"'ÆþÜ®¶4þ¢µ³W ÿþ·rƒM ‚H. !2#!"54c’þn.H%32+#"=#"4;5432'"43!2#@´´´´Ý’ä(¡¡(¢c((H\%%32+#"=#"4;5432'2#"'&5476@´´´´!   ä(¡¡(¢Ö  ÿÿqÿ¯çœÿÿâÙv\yt»32+ #"=43“7È̯èTB5ÒX$ýitÀ6F#"'&5472327654'&#&5476327654'&#"#"'4763232+ #"=43·:4&5*)+0 - ,&-*> R7È̯èTB$47  $*   $ . +þüÒX$ýit¼*#57332+32+"54763=#32+ #"=43§•€9  U )kY7È̯èTBÀ"ÚØ$9$ ]´´¯ÒX$ýi%†*Ô132760'&#"32+"'&'#"'&5476326;2+"0N<74 ..K ˆ86E2 =OR-@(3P<$R g0N@D0747632!2#!&'4ôýøþ  &22!# #32-ÙÙ- éþ2&ÿë2 #32þÿ ÿ-ÙÙýÎ2þé(À!#4'&#"#47632+^0@r:$+VG^rI>Ôx1L1Eþ,ÔnE9MA^(ÿõµ3327653#"'&5(+^0@r:$+VG^rI>µþ,x1L1EÔþ,nE9MA^ˆÿ±Óé.6'&'&/'&'&'&767636765476€" @25  0+è Mý®M :  + RA"8ÿ±#éO"'&/367654766/&/'&''&'&'&76763676547636m @  07" @2/;5  0+$š Mý®  + R8- Mý®M /1:  + RA"ÿ±KéBTf636/&/'&''&''&'&'&76763676547636636&'"#767654'&'"#767654º%" @2 1%*5  0+$ % @ 0h@ 0Ô Mý®M :  + RA"  & Mý®+ R& Mý®+ R&nÿ±àé@IT547636'&'&/'&'&'&76763676=&'&547667654'&/+$" @S/C)425  0U2#E,9L)<$VJ%=$ gA" Mg G/7W7"|M :  + {F0=X7#þ±8?&.N/4þÉ @$+N08ÿ±#éJS\n~ˆ54763666/&/'&''&'&'&76763676=&'&547667654'&#"'36765547"'&/63&#"327È+$7" @)3:+2/;5  062;0+'5ê#'=9"!  0 @#2. !%þtA" - Mr !6JP6ŒM /1:  + ‰5KP7þÕ,7672#"'&/"'&54767&547&'&547632654/ EE    FF  $$#% )Š~x‰*  -ˆ{†-" z`cc`baaÿÿHÿ¯ œ&ÿÿNÿ¯œ&!‰ÿôÏ>(%632#"'#"/&54?'&547632‰&  çç  !þÛ  çç —¢   Z¢   ÿÿ‰ÿôÏ>GTXÀ@3qÄ7"'&54763!2#!"3!2#Ë^'>%54þÌZ4#4qQ'1_/X'N#3qÄ%!"543!27654'&'!"543!2‚þÌ4H GþÌ4](?%qC"bQ(1_/3Ä &7!2#!"=47"'&54763!2#!"3!2#a£þ]€^'>%54þÌZ4#4%LQ'1_/X'N#ÿÿ3ÄGXMÀ@ÿñ?!'#"'&547632&'&'#5#6765#?VOnxQKWOnvQL+|!&*¹ÐÓ©$ûÓ w$xQJUOowQKUPY”/ ÓÓ»*Ó™¿ÓŽ2ÿñ?!#"'&547632&'&#"!3276?VOnxQKWOnvQL+V!0! *9?0$ …  !3ýN$   '#' ÿ : '5!#''%7!Ëþ~>/0(þ÷D7þ»P%þA!ö„ Tþ÷–ü|*~+; ÿT8M 3!73%57 '!ÉRþ¼)0ýÑ>œþ“"À%þ°Mü{–þöTYü“;,"ÿ AN3#3º^)j,‰)³û½BÐX !5Xý¨ PPåX5!5Xý¨5PPXT!5Xý¨TPP#Xs%!5Xý¨sPPX@!!Xý¨@(XT!!Xý¨TPÿ8@ 3#(( üÿ8T 3#PP üX@ 3+53#53ôdddÈÈþÔdd@((((XT 3+53#53ôdddÈÈþÔddTPPPPÿ8@  #=3#5@(((ôþpdÈÈý¨ÈÈÿ8T  #=3#5TPPPôþpdÈÈý¨ÈÈX@ #5;#!#53#53Ñ‚‚FAAþò‚‚ÈAA(((((XT #5;#!#53#53Ñ‚‚FAAþò‚‚ÈAAPPPPPÿ8@  #5#553#5@(((((;ÏÏþ²ÏÏÌggüæggÿ8T  #5#553#5TPPPPP;ÏÏþ²ÏÏÌggüæggÿ8X@!!#@þè(@(þ ÿ8XT!!#@þè(TPþ4ÿ8X@!!#TþüP@(þ ÿ8XT!!#TþüPTPþ4ÿ8@@#!5@(þè@ýøà(ÿ8@T#!5@(þèTýäÌPÿ8T@#!5TPþü@ýøà(ÿ8TT#!5TPþüTýäÌPX 3!(þ (X 3!(þ4PX 3!Pþ (X 3!Pþ4P@ !5!3@þÀ((à@ !5!3@þÀ(PÌT !5!3Tþ¬P(àT !5!3Tþ¬PPÌÿ8X 3!!(þèÈèþ (þ ÿ8X !!#3@þè((TPþ4èÿ8X #3!!#Pþè(þ (þ ÿ8X 3!!#(þüP@àþ (þ ÿ8X #3!TPPþ èþ (ÿ8X #3!!#Pþè(þ4Pþ4ÿ8X !!#33@þüP(TPþ4Ìÿ8X 3!!PþüÈèþ4Pþ4ÿ8@ #!5!3@(þè(Èà(àÿ8@ !5!3#þè((PÌüÿ8T #!5!3@(þèPþ à(àýøÿ8T 3#!5!3@Pþü(@ýøà(àÿ8T 3#!5PPþü@àüà(ÿ8T #!5!3@(þèPþ4ÌPÌýäÿ8T 3#!5!3@Pþü(TýäÌPÌÿ8T #!5!TPþü üÌPÌÿ8X@!!#!Xþè(þè@(þ àÿ8XT !!#!5!@þè(þè@@(þ ÌPÿ8XT 5!!#!5@þè(þè@Pþ4à(ÿ8XT!5!!#þèXþè(PPþ4ÿ8X@#!5!TPþüXþ à((ÿ8XT #!5!!TPþüTþ ÌP(ÿ8XT !5!5!!#þüTþüP(Pþ4ÿ8XT!!#!XþüPþüTPþ4ÌX 5!3!((àþ (X !5!3!@þÀ(PÌþ (X !5!3!!þè(þÀ(àþ4PX !!5!3@ý¨(TPPÌX 3!!5Pý¨@àþ ((X !5!3!Tþ¬PPÌþ (X !5!3!!þüPþ¬(àþ4PX !5!3!Xý¨PPÌþ4ÿ8X !5!3!!#þè(þè((àþ (þ ÿ8X 3!!#!5(þè(þèTÌþ (þ ÌPÿ8X #!5!3!@(þè(þ4à(àþ4Pÿ8X !5!3!!#þè(þè(PÌþ4Pþ4ÿ8X 3!!#!5Pþè(þè@àþ (þ à(ÿ8X #!5!3!TPþü(þ à(àþ (ÿ8X !5!3!!#þüPþüP(àþ (þ ÿ8X ##!5!3!T(þèPþ4ÌPÌþ (ÿ8X #5!5!3!!#þüPþè((àþ4Pþ4ÿ8X 3!!#!5!3@þüPþü(T(þ ÌPÌÿ8X 533!!#!5(þüPþü@Ìþ4Pþ4à(ÿ8X !5!3!!#þèPþè(PÌþ4Pþ4ÿ8X !!#!5!3@þüPþü(TPþ4ÌPÌÿ8X #!5!3!TPþüPþ ÌPÌþ (ÿ8X 3!!#!5PþüPþü@àþ4Pþ4à(ÿ8X !5!3!!#þüPþüPPÌþ4Pþ4X@#53#53Xúúþ¢úú(((XT#53#53Xúúþ¢úúPPPÿ8@ ##@((( þ>ÂýÚþ>Âðÿ8h ##hxxx þ>ÂýÚþ>ÂÜX|!!5!!Xý¨Xý¨( (Üÿ8| 3#3#Ü((x(( üèüÿ8X| !!!!@þèþèÈD(P(þ\Üÿ8X@ !####Ü|Ü(P(@(þ àþ Üÿ8X| !#+!!TÜ(P(|þ¬(þ\D(ÿ8@| #!5!5!5@(þèþè|ý¼¤(P(ÿ8|@ ####5|(P(Ü@ýøàþ à(ÿ8|| ##5!5!(ÜTþ¬|þ4¤(þ4(ý¼ÜX %3!!!(þèÜDþ\(P(ÜX !3333Xþ„(P(Üþ àþ ÜÜX  33!!T(Üþ¬Tþ„TÌþ\(Ìýä(DÜ@ %!5!5!5!3@þÀþè(Ü(P(¤| !53333|þ„Ü(P((àþ àÜ|  !53;!5!þüÜ(P(þ„TT(¤ý¼(ÿ8X 3!!!!(þèþèÈèþ\(P(þ\Üÿ8X  33#+3T(ÜÜ(P(( þ (þ èÜÿ8X  3##33!Ü(TÜ((ÜþüÈèüÌ(þ\Ìþ\(ÿ8@ #!5!5!5!@(þèþè ü¤(P(¤ÿ8|  ###533|(P(ÜÜ( üèüà(àÿ8|  #30!##!53|((þ„(ÜþüÜÈèýäþ4¤Dþ4(¤ÿ8X| !#!=!Xþè(þèX(þ\¤(P((ÿ8X@ !#####XÜ(P(Ü@(þ àþ àÿ8X| 5!##5)##0 Xþ¬(ÜTÜ(T((ýä¤((þ\ÌÜX  %!5!%5!3!Xý¨Xý¨(Ü(P(¤þ\(X !533333Xý¨Ü(P(Ü(àþ àþ ÜX  !!0!53!133Xý¨þüÜ|þü(Ü(Dþ4(¤þ4Ìþ\ÿ8X !5!3!!!!#!5!þè(þèþè(þèT(¤þ\(P(þ\¤(ÿ8X ###533333##TP(ÜÜ(P(ÜÜ(þ à(àþ àþ (þ ÿ8X ##50!##0330)533(ÜTÜ((Üþüþ¬Ü(Ȥ(þ4Ì(þ\Ìþ\((¤þ4ÿ8X@ 3#"#476ôddv%(Y1@(=(OþÔ,–-ÿÿÿ8@@GXÀ@ÿÿ@ XXÀÿÿX GX@Àÿïÿ.i*X"ý¨¾èüÿÿÿïÿ.i*GXÀ@ÿïÿ.i*  ' 7 C&"þåþå"&þÚ"",þØþ(êêþ(Ø,@!!,þÔ@(,@ 3#(( þ ÿÿ,X@,ÿÿÿ8@,þ ,T!!,þÔTP,T 3#PP þ ÿÿ,XT,ÿÿÿ8T,þ XT!5!5!!,þÔ,,þÔ(Pÿ8T 33#(P,ôþ þ ôÿÿXTG"XÀ@ÿÿÿ8T G#X@À,X !!Xý¨ þ ÿ8Xÿµ!!Xý¨K}ÿ8X25!!Xý¨2úÿ8X¯5!!Xý¨¯þ‰ÿ8X,!!Xý¨,þ ÿ8X©!!Xý¨©ýÿ8X&!!Xý¨&ýÿ8X£!!Xý¨£ü•ÿ8X !!Xý¨ üÿ8  !! ýó üÿ8 !!Âþ> üÿ8w !!wþ‰ üÿ8, !!,þÔ üÿ8á 3#áá üÿ8– 3#–– üÿ8K 3#KK ü,ÿ8X !!,,þÔ üÿ8&î #'+/37;?CGKOSW[_cgkosw%3#'3#'3#%3#'3#'3#3#'3#'3#%3#'3#'3#3#'3#'3#%3#'3#'3#%3#'3#'3#%3#'3#'3#%3#'3#'3#%3#'3#'3#22È22È22ô22È22È22,22È22È22ô22È22È22,22È22È22ô22È22È22,22È22È22ô22È22È22,22È22È22ô22È22È22222222–22222ú22222–22222^22222–22222–22222–22222–22222–22222<ÿ8Xî #'+/37;?CGKOSW[_cgkosw{ƒ‡‹“—›Ÿ£§«¯³·»¿ÃÇËÏÓ×Ûßãçëï%3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#22d22d22d22d22ô22222d22d22d22d22ô22–22d22d22d22d22ô22222d22d22d22d22ô22–22d22d22d22d22ô22222d22d22d22d22ô22–22d22d22d22d22ô22222d22d22d22d22ô22–22d22d22d22d22ô22222d22d22d22d22ô22222222222222–22222222222ú22222222222–22222222222^22222222222–22222222222–22222222222–22222222222–22222222222–22222222222xÿ8X  #'+/37;?CGKOSW[_cgkosw{ƒ‡‹“—›Ÿ£§«¯³·»¿ÃÇËÏÓ×Ûßãçëïó÷ûÿ #'+/37;?CGKOSW[_cgkosw{ƒ‡‹“—›Ÿ£§«¯³·»¿ÃÇËÏÓ×Ûß%3#'3#'3#'3#'3#%3+3#'3#'3#'3#'3#%3#3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#3#'3#'3#'3#'3#%3#3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#'3#'3#'3#'3#'3#%3#22d22d22d22d22ô22222d22d22d22d22ô22d22d22d22d22d22ô22–22d22d22d22d22ô22d22d22d22d22d22ô22222d22d22d22d22ô22–22d22d22d22d22ô22222d22d22d22d22ô22–22d22d22d22d22ô22222d22d22d22d22ô22–22d22d22d22d22ô22222d22d22d22d22ô22–22d22d22d22d22ô22222d22d22d22d22ô22–22d22d22d22d22ô22222d22d22d22d22ô22–22d22d22d22d22ô22222d22d22d22d22ô22–22d22d22d22d22ô22222d22d22d22d22ô2222222222222222222222222222222222222d22222222222222222222222,22222222222d22222222222d22222222222d22222222222d22222222222d22222222222d22222222222d22222222222d22222222222d22222222222d22222222222d22222222222d22222222222d22222222222d22222222222£X !!Xý¨ } ÿ8X 3# KK üÿ ,,!!,þÔ,ýß,ÿ X,!!,,þÔ,ýß,,N%,þÔNýßÿ XM!!!,,ý¨Mýßýßÿ XN%%,,þÔþÔ,þÔ,ýßCýßÿ XM!!!XþÔþÔMýßýÞÿ XM!!!XþÔþÔMû½",,XN%,,þÔNýßÿ XN%%,þÔ,,þÔ.ýÜDýßÿ XM!!!,,ý¨,!û¾2&ô3!2ôôþ 2&ô3!%!!2ôþ4¤þ\ôþ (¤1&ô87&'076767!00!0'&73!0767650'&'&'!00R 8$! 8þü$! (  *þü" 8"# 8þü$!/ ("  )þü2&ô 753!%!!¯úþ‰ôþ4¤þ\}úú}ôþ (¤2&ô !5%!5!!5%!5!!Z¤þ\¤þ\¤þ\¤þ\(ôYKK(Kþ§KK(Kæôþ 2&ô 73##!3##!!ÍKK(KYKK(Kæþ ô(¤þ\¤þ\¤þ\¤þ\(ô2&ô #'+/37;?C%353535#35353535#35353535#35#3#35##3!@KKKKKKK¾KKKKKKK›KKKKKKKþ§KKKKKKKKsôæKKsKKKsKKsKKsKKKsKKsKKsKKKsKKsK(KYKK(Kþòôþ 2&ô !!5+5%332ôþ '¥Þªˆþ\Þªþx¥ôþ Ì¥¥þxªÞˆã¥2&ô !#75373&þ Í¥ÞÞˆþxªÞ¥¥ôþ ô(¥¥ÞªˆÆªþx¥¥ 2&ô !$'+%3'5'7'35'7'7'?#'?#'!!žE‰(D}UUUÆUUUãD‰»Dþ D¶UUUÆUUUrD‰»D`E‰Dôþ lD`D‰DUUUÆUUU9DDE‰þØE‰¶UUUÆUUUrD`D‰aD(þ ¯©ú353¯úúú¯©ú735#53תª(ú(ªÒúú2&,3!2ô,þÔ2&,3!%!5!2ôþ4¤þ\,þÔ(Ü–Âô3!–,ôþ –Âô3!%3#–,þüÜÜôþ (¤?,3!2ô2,þÔ?,3!%!7!2ô2þ:¤&þ\,þÔ(Ü#5Æ)5ýî Æ#5Æ% !öÊÊÓýî (Nþ²(ƨ°â)7°þø„⨰â%'!7mAAÅþø„(jj(âT þ5 þ÷T %þ5þ© þ÷þ÷¿þyǬ %¬å…… Ç«%'7]n¼ä…;{@…yú %úþ…… yù%'%uÏSþ€…C‹H…#5Æ 5þøþöÆþ:Æ#5Æ! öþlÊ þ÷þ÷žþ²vþ:ƨ°â%'°„„ââ⨰â%#7'm‚A„„„ºj’ââ99Ë  ýî99ËþW  ýî ȇ¬‘ ?¬å……þö­‘757ûn¼ä…@{;þú^ß 7%^……þö_ß75%ãÏþ­€…H‹Cþú#5! ,þ÷    þ÷#5%7' ,ÑÑÑÑþ÷  8ÑÑÑþ÷  þ÷#5 %'77' ,„„„„ÑÑÑÑþ÷  „………ÑÑÑÑþ÷  þ÷#5!12#"'&54767"327654'&'&'2#"'&5476.3.6/gD9L@UeC9J.=nMJSLjsNHUMl-6.6~K?UgD8K@VcD* (RMjrNITMjrNGYÿõÿ? 77+ÔÔÒÒœœ?þÜþÚ&ââââ#5!"327654'&'&'2#"'&5476/gD9L@UeC9J.=nMJSLjsNHUMêK?UgD8K@VcD* (RMjrNITMjrNG #5-9CQaq}‡“¡2#"'&54762#"'&54762#"'4762"'&5476'"'472%"'&54763247632#"'&%47632#"'&%472"'&672"'&47632#"47632#",|òX•þêþ7¨þ²òþÉþX2òj|òPþl#5$-2#"'&547667&'67654'&0nMJSLjsNHUM{'$#P'$$LRLM IRMjrNITMjrNG)þ@˜þCÀþh)h=d hCcþ˜:` bC#51A2#"'&5476"327654'&'"327654'&'&'2#"'&5476.?%4!(A%6!'1 *0 )gD9L@UeC9J.=nMJSLjsNHUM†5!'@&5!(A%()1 )/ ŒK?UgD8K@VcD* (RMjrNITMjrNG#52#"'&54760nMJSLjsNHUMRMjrNITMjrNG#527654'&'2#"'&5476-eB9KAQnMJSLjsNHUMêþ>K@VcD:(RMjrNITMjrNG#5"32#"'&5476+aCOhD5,þÔ, qKBRIc a@5L;O# 0##567673/ f?# (VG^êM+5 qK=, 9'3#5&'&'&#-sK>(O3Bê(UF] d?*#0 %#&'&'53/sK>(N:K((UF] d?/,9 %3676753#- f?/(VG^(M9J qK=# 55&'&#"#567632 L>OhD5(VLgmNF a@5L;O qKBRIc #53#"'&'5332767 (SKbvOE(N?SaC6 oKDTGc c@3KÌ_=*SKitOHSLjqOI)ôa=/M@VdC0ÅÌN5#5#2#"'&547632767#7&'&'0nMJSLjsNHUMSc<.L@UdD2ôô M5ARMjrNITMjrNG) N3"'&7476323276=47632676320/&#"0'&#"0'&#"0'&#"ð4$!üV;CpK%!!!-2$ääS[T.L%/     ÿúP& '7'7PÃTµµTÃè=;R~Ú”’Ø ààx®%%'65472#"'47jò éÖ(ñ êÖJZÿì+!5472#"'473'7!#"'&5!2ù éÖIòêþÌ‹ êÖJñêýý+#5 04763#"'&7"327654'&'&'2#"'&5476(gD9L@UeC9J.=nMJSLjsNHUM   åK?UgD8K@VcD* (RMjrNITMjrNGÿÿ2&ôG2&ô3!%!!62#'&76762ôþ4¤þ\É Ú!\ ôþ (¤þŸ4  þ´Ž 2&ô.3!%!!'&/'&'&76?'&7676762ôþ4¤þ\îˆ ˆˆ ˆˆ ˆˆ ôþ (¤Òˆ ˆˆ ˆˆ ˆˆ &&ô!+5@K3&547#"'&54763!53#5#"'&547&547!"3!35#"";5#";®PþÌ$I+ 0$  f+ $ÀþÜ$¤¤¤#„ddÌþ\¤â4 + 8(þ (+  4 Ê _7(7_23ô *4>H#37##3!2+'!27654/327654/##327654'327654/ªPPä$*f  $/ *Ià$þܤ¤„„„‰dÌþ\ 4 9 (ô(+ 9  4¬7–_7^7Pÿì`S76#"'&=/&76?5#"'&5476;5#"'&5476;54763232+32#@T hT h´´XXXX´Z†1 <§1 <TNNTPÿì`=#"'&5476;5#"'&5476;54763232+32+#"'&5´´XXXX´´ZTNNTþ¦:S%##"'&54763235#"'&54763!2+3547632#"'&=#32#!"'&5476;ÒÒ‚,‚ÒÒ‚þÔ‚ú‚,‚ÒÒ‚þÔ‚Ò#5#'2#"'&5476'67654'&'7550nMJSLjsNHUMŒSS'K8JΦc<.A8TRMjrNITMjrNGþYu·Y8GcD3Ô‹‹Ô N2D9%/H+9&/E+†¼x†2@U7*C2BV6)(…6@#"'&5&76324763266=1,þ.& - °…ò@,%#"'&56/&'#"'&5&763247632ò9J 6=13G) ¼[04 þ®.& - °'F)2#2$5ÿþ<!#"'&5&7632#"'&5&7632æ6=1R6=1þ¬.& - Rþ.& - '5ÿþ<!%#"'&5&7632#"'&5&76325%5%æ6=1R6=1þþþþŠÜ.& - Rþ.& - ¯ŒaMam| 4'&#"67663247632àf#+>U—]WþµWGp<)Â`yl! %þªA<ÂÆ$D0E¦D!hxÿYà[ #53%à+þÃ+=+þî§Ì7mÜ7þ™93þÇ=ÿV\575375377#5#5577–YY+Ö+YYYY+Ö+YY+ÖW(°ª!¶°(þÈ(¡›!§¡(>þÈ!8lÿ„ì\ 32+32+32+32+”bŠŠbÜbŠŠbSØýzØlÿ„ì\ #"54;#"543##"54;#"543ÄbŠŠzbŠŠS†ý(†ý(}ÿ‡Û[0 #&' 672Øÿ þÀ> S þ½þ¿df}ÿ‡Û[63 "'4'4767 &'&'6€ >þÀ ÿSþšþœAC -ÿ‡+[/0 #&' 6720 #&' 672(ÿ þÀ> ›ÿ þÀ> S þ½þ¿df þ½þ¿df-ÿ‡+[/63 "'4'4767 &'&'6363 "'4'4767 &'&'60 >þÀ ÿ  >þÀ ÿSþšþœAC þšþœAC l¢é2#"'&5476ª&!$ !% $lè2#"'&5476ª'$! "# ! %lÁéû2#"'&547672"'&5476ª& $ & $! =" $ $¾!#! %kšè2#"'&5476©&!$ ! % $káé× #"'&5476322#"'&5476è# $! &>&!$ ' $! ¨!% $k½èö!2#"'&547672#"'&5476©&!$! &! $ :!%! %¼"$ $káé×0#"'&547632'2#"'&547672#"'&5476è# $! &>'$! &!$ ' $! ë"! ! &½!% $p¡í2#"'&5476®& $! !$! %¡É2#"'&5476#2#"'&5476‹' $! ­&" $ "$! %" & $ÁÉú #"'&54763272#"'&5476 # $ &&! $ ÿ' $!ö" $ $ÁÉû 02#"'&547672#"'&5476'2#"'&5476Í&!$ Î&! $ ­'$! =!% $½" $ $"# ! %áÉ×#"'&5476322#"'&5476 " $! '€'$! & &"ª"! ! &áÉ× 1#"'&5476322#"'&5476#2#"'&5476 " $ &€'"$! ®&!$ ' $"´"& &!% $áÉ× 0#"'&547632'2"'&547672#"'&5476 " $! '>& $! Î'$! & &"í!#! %½"! ! &áÉ×!1B#"'&5476327#"'&54763272#"'&5476#2#"'&5476 " $ &"$! &'"$! ®&!$ ' $"¸$! &!÷"& &!% $pží2#"'&5476®&!$ ! % $ÁÉû2#"'&5476'2#"'&5476‹' $! ­'$! >"$! %½"# ! %É!2#"'&5476#2#"'&5476‹&"$ ®& $! "& $!$! %ÁÉû 02#"'&54762#"'&547672#"'&5476‹'! $! ®&!$ '$! >"$! %!% $¾"# ! %½É÷2#"'&547672#"'&5476Í' $! Î'$! :"$! %½"# ! %áÉ×!2#"'&54763272#"'&5476'2#"'&5476 " $ &€&! $ ®&!$ ' $"÷"$ $½!% $½É÷/2#"'&547672#"'&54762#"'&5476Í' $! Î'$! ®&!$ :"$! %½"# ! %! % $áÉ×!2C#"'&54763272#"'&5476#"'&547632'2#"'&5476 " $ &€&! $ o"$! &?&!$ ' $"÷"$ $?$! &!÷!% $pÁíú 2#"'&547672#"'&5476®&!$! &!$ >!%! %¼!% $ÁÉû/2#"'&547672#"'&5476'2#"'&5476‹' $! & $ ­'$! >"$! %¼" $ $"# ! %ÁÉú 02#"'&5476#"'&54763272#"'&5476‹&! $ o# $ &&! $ =" $! $>' $!ö" $ $ÁÉû 0@2#"'&54762#"'&547672#"'&5476'2#"'&5476‹'! $! ®&!$ Î&! $ ­'$! >"$! %!% $½" $ $"# ! %áÉ× 0#"'&54763272#"'&547672#"'&5476 " $! '€&"$ '$! & &"í"& $½"! ! &áÉ×!1B#"'&54763272#"'&547672#"'&5476#2#"'&5476 " $ &€&! $ '"$! ®&!$ ' $"÷"$ $½"& &!% $áÉ× 1A#"'&54763272#"'&5476#2"'&547672#"'&5476 " $! '€&"$ ®& $! Î'$! & &"í"& $!#! %½"! ! &áÉ×!2BS#"'&54763272#"'&5476#"'&54763272#"'&5476#2#"'&5476 " $ &€&! $ o"$! &'"$! ®&!$ ' $"÷"$ $?$! &!÷"& &!% $pší2#"'&5476®&!$ ! % $áÉ× #"'&5476322#"'&5476É" $ &û&! $ ' $"´" $ $½Éö2#"'&5476'2#"'&5476‹'! $! ®&!$ :"$! %¼! % $áÉ×!12#"'&5476'2#"'&547672#"'&5476‹&"$ ®&$! &! $ ]"& $½!" ! &½" $ $šÉ2#"'&5476#2#"'&5476‹&! $ ®& $ " $ $" $ $áÉ×!22#"'&5476#"'&5476322#"'&5476‹&"$ p" $ &>&!$ ]"& $>' $"´!% $½Éö/2#"'&5476#2#"'&547672#"'&5476‹'! $! ®' $! &!$ :"$! %"$! %¼! % $áÉ×!2C2#"'&5476#"'&5476327#"'&547632'2#"'&5476‹&"$ p" $ &"$! &?&!$ ]"& $>' $"¸$! &!÷!% $páí× #"'&5476322#"'&5476í# $! &?&$! & &!´!" ! &áÉ× 0#"'&547632#"'&547632'2#"'&5476É" $ &" $! 'û&! $ ' $"u& &"7" $ $áÉ× 02#"'&5476'2#"'&547672#"'&5476‹'"$! ®& $! Î'$! ]"& &½!$! %½"! ! &áÉ×!1A2#"'&5476'2#"'&547672#"'&5476#2#"'&5476‹&"$ ®&$! Î'"$! ­&! $ ]"& $½!" ! &½"& &" $ $áÉ×/2#"'&5476#"'&5476322#"'&5476‹'"$! p" $! '€'$! ]"& &?& &"ª"! ! &áÉ×!1B2#"'&5476#"'&5476322#"'&5476#2#"'&5476‹&"$ p" $ &€'"$! ®&!$ ]"& $>' $"´"& &!% $áÉ×0@2#"'&5476#"'&547632'2"'&547672#"'&5476‹'"$! p" $! '>& $! Î'$! ]"& &?& &"í!#! %½"! ! &áÉ×!2BS2#"'&5476#"'&5476327#"'&54763272#"'&5476#2#"'&5476‹&"$ p" $ &"$! &'"$! ®&!$ ]"& $>' $"¸$! &!÷"& &!% $p½í÷!2#"'&547672#"'&5476®& $! & $! :!$! %½!$! %áÉ×!1#"'&547632'2#"'&5476'2#"'&5476É" $ &>& $ ­&! $ ' $"÷"$ $½" $ $½É÷/2#"'&547672#"'&54762#"'&5476‹'$! '$! ®&!$ :"# ! %½"# ! %! % $áÉ×!2B2#"'&547672#"'&5476#2#"'&547672#"'&5476‹&"$ &! $ ®&$! &! $ ]"& $½"$ $!" ! &½" $ $½É÷/2#"'&5476#2#"'&547672#"'&5476‹'$! ®' $! Î'$! :"# ! %"$! %½"# ! %áÉ×!2C2#"'&5476#"'&54763272#"'&5476'2#"'&5476‹&"$ p" $ &€&! $ ®&!$ ]"& $>' $"÷"$ $½!% $½É÷/?2#"'&5476#2#"'&547672#"'&54762#"'&5476‹'$! ®' $! Î'$! ®&!$ :"# ! %"$! %½"# ! %! % $áÉ×!2CT2#"'&5476#"'&54763272#"'&5476#"'&547632'2#"'&5476‹&"$ p" $ &€&! $ o"$! &?&!$ ]"& $>' $"÷"$ $?$! &!÷!% $páí× 0#"'&5476325#"'&547632'2#"'&5476í# $! &#$ &?&$! & &!¹' $! ë!" ! &áÉ×!1A#"'&547632'2#"'&54767#"'&547632'2#"'&5476É" $ &>& $ N" $! 'û&! $ ' $"÷"$ $~& &"7" $ $áÉ× 1A2#"'&547672#"'&5476#2#"'&547672#"'&5476‹'"$! &"$ ®& $! Î'$! ]"& &½"& $!$! %½"! ! &áÉ×!2BR2#"'&547672#"'&5476#2#"'&547672#"'&5476#2#"'&5476‹&"$ &! $ ®&$! Î'"$! ­&! $ ]"& $½"$ $!" ! &½"& &" $ $áÉ×0@2#"'&5476#"'&54763272#"'&547672#"'&5476‹'"$! p" $! '€&"$ '$! ]"& &?& &"í"& $½"! ! &áÉ×!2BS2#"'&5476#"'&54763272#"'&547672#"'&5476#2#"'&5476‹&"$ p" $ &€&! $ '"$! ®&!$ ]"& $>' $"÷"$ $½"& &!% $áÉ×0AQ2#"'&5476#"'&54763272#"'&5476#2"'&547672#"'&5476‹'"$! p" $! '€&"$ ®& $! Î'$! ]"& &?& &"í"& $!#! %½"! ! &áÉ×!2CSd2#"'&5476#"'&54763272#"'&5476#"'&54763272#"'&5476#2#"'&5476‹&"$ p" $ &€&! $ o"$! &'"$! ®&!$ ]"& $>' $"÷"$ $?$! &!÷"& &!% $lÿ•è72#"'&5476ª'$! "# ! %lé´7#"'&5476322"'&5476è" $ &>& $! >' $" g!#! %lÿÜèÓ72#"'&54762#"'&5476ª'! $! '$! Y"$! %z"# ! %lé´ 07#"'&5476322#"'&547672"'&5476è" $ &>& $ & $! >' $" ©"$ $¾!#! %kÿ¹èó72#"'&547672#"'&5476ª&! $ & $! 5" $ $¾!$! %ké´ 072#"'&547672#"'&54762"'&5476ª&" $ &!# & $! |" & $¾!%$z!#! %kÿÜèÓ/72#"'&54767#"'&547632'2#"'&5476ª'! $! N# $! &>'$! Y"$! %~& &!ì"# ! %ké´ 1A72#"'&547672#"'&547672#"'&547672"'&5476ª&" $ &!# &! $ & $! |" & $¾!%$¼"$ $¾!#! %ɳ%#"'&5476322#"'&5476 # $! &&! $ =& &!f" $ $É´/%#"'&5476322#"'&5476'2#"'&5476 # $ &&! $ ­'$! >' $! e" $ $"# ! %ɳ/%#"'&5476322#"'&547672#"'&5476 # $! &?&!$ Î&! $ =& &!©! % $½" $ $É´/?%#"'&5476322#"'&547672#"'&5476'2#"'&5476 # $ &?&!$ Î&! $ ­'$! >' $! ¨! % $½" $ $"# ! %ɳ 0%#"'&547632'2#"'&54762#"'&5476 # $! &?& $ Î&! $ =& &!ì"$! $z" $ $É´/?%#"'&547632'2#"'&54762#"'&5476'2#"'&5476 # $ &?' $! Î&! $ ®& ">' $! ì"$! %y" $ $!$$ɳ 0@%#"'&547632'2#"'&547672#"'&547672#"'&5476 # $! &?& $ &!$ Î&! $ =& &!ì"$! $½! % $½" $ $É´/?O%#"'&547632'2#"'&547672#"'&547672#"'&5476'2#"'&5476 # $ &?' $! &!$ Î&! $ ®& ">' $! ì"$! %¼! % $½" $ $!$$ÿÜÉÓ 72#"'&54762#"'&5476Í& $! Î&! $ Y!$! %z"$ $É´/%#"'&5476322#"'&5476'2#"'&5476 # $ &'$! ­'$! >' $! ©"# ! %½"# ! %ÿÜÉÓ 172#"'&54762#"'&5476#2#"'&5476Í& $! Î&! $ ®&$! Y!$! %z"$ $!" ! &É´/?%#"'&5476322#"'&54762#"'&547672#"'&5476 # $ &'$! ®&!$ '$! >' $! ©"# ! %! % $¾"# ! %ÿÜÉÓ072"'&54767#"'&54763272#"'&5476Í& $! N" $ &€&! $ Y!#! %' $" ì"$ $É´/?%#"'&547632'2#"'&547672#"'&5476'2#"'&5476 # $ &?' $! Î'$! ®& ">' $! ì"$! %½"# ! %½!$$ÿÜÉÓ0A72"'&54767#"'&54763272#"'&5476#"'&547632Í& $! N" $ &€&! $ o"$! &Y!#! %' $" ì"$ $?$! &!É´/?O%#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476 # $ &?' $! Î'$! ®&!$ & ">' $! ì"$! %½"# ! %! % $¾!$$ɳ/%#"'&5476322#"'&547672#"'&5476 # $! &'! $! &! $ =& &!ª"$! %¼" $ $É´/?%#"'&5476322#"'&547672#"'&5476'2#"'&5476 # $ &'$! &! $ ­'$! >' $! ©"# ! %¼" $ $"# ! %ɳ/?%#"'&5476322#"'&54762#"'&547672#"'&5476 # $! &'! $! ®&!$ Î&! $ =& &!ª"$! %! % $½" $ $É´/?O%#"'&5476322#"'&54762#"'&547672#"'&5476'2#"'&5476 # $ &'$! ®&!$ Î&! $ ­'$! >' $! ©"# ! %! % $½" $ $"# ! %ɳ 0@%#"'&547632'2#"'&547672#"'&547672#"'&5476 # $! &?& $ Î'! $! &! $ =& &!ì"$! $¾"$! %¼" $ $É´/?O%#"'&547632'2#"'&547672#"'&547672#"'&5476'2#"'&5476 # $ &?' $! Î'$! &! $ ®& ">' $! ì"$! %½"# ! %¼" $ $!$$ɳ 0@P%#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476 # $! &?& $ Î'! $! ®&!$ Î&! $ =& &!ì"$! $¾"$! %! % $½" $ $É´/?O_%#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476'2#"'&5476 # $ &?' $! Î'$! ®&!$ Î&! $ ®& ">' $! ì"$! %½"# ! %! % $½" $ $!$$ÿ¹Éó%2#"'&54762#"'&5476‹'$! ®&!$ ó"# ! %¾! % $É´/2#"'&5476#"'&5476322#"'&5476‹'! $! o# $ &>'$! :"$! %ü' $! f"# ! %ÿÜÉÓ02#"'&54762#"'&54762#"'&5476‹'"$! ®&!$! & $! "& &½!%! %z!$! %É´/?2#"'&5476#"'&5476322#"'&547672#"'&5476‹'! $! o# $ &?&!$ '$! :"$! %ü' $! ¨! % $¾"# ! %ÿ¹Éó/%2#"'&54762#"'&547672#"'&5476‹'$! ®&!$ ' $! ó"# ! %¾! % $¾"$! %É´/?2#"'&5476#"'&547632'2#"'&54762#"'&5476‹'! $! o# $ &?' $! & ":"$! %ü' $! ì"$! %z!$$ÿÜÉÓ/@2#"'&54762#"'&54767#"'&547632'2"'&5476‹'"$! ®&!$! N" $! '>& $! "& &½!%! %~& &"í!#! %É´/?O2#"'&5476#"'&547632'2#"'&547672#"'&547672#"'&5476‹'! $! o# $ &?' $! &!$ & ":"$! %ü' $! ì"$! %¼! % $¾!$$ɳ 02#"'&5476#"'&5476322#"'&5476‹&! $ o# $! &&! $ 9"$! $ü& &!f" $ $É´/?2#"'&5476#"'&5476322#"'&5476'2#"'&5476‹'! $! o# $ &&! $ ­'$! :"$! %ü' $! e" $ $"# ! %ɳ 0@2#"'&5476#"'&5476322#"'&547672#"'&5476‹&! $ o# $! &?&!$ Î&! $ 9"$! $ü& &!©! % $½" $ $É´/?O2#"'&5476#"'&5476322#"'&547672#"'&5476'2#"'&5476‹'! $! o# $ &?&!$ Î&! $ ­'$! :"$! %ü' $! ¨! % $½" $ $"# ! %ɳ 1A2#"'&5476#"'&547632'2#"'&54762#"'&5476‹&! $ o# $! &?& $ Î&! $ 9"$! $ü& &!ì"$! $z" $ $É´/?O2#"'&5476#"'&547632'2#"'&54762#"'&5476'2#"'&5476‹'! $! o# $ &?' $! Î&! $ ®& ":"$! %ü' $! ì"$! %y" $ $!$$ɳ 1AQ2#"'&5476#"'&547632'2#"'&547672#"'&547672#"'&5476‹&! $ o# $! &?& $ &!$ Î&! $ 9"$! $ü& &!ì"$! $½! % $½" $ $É´/?O_2#"'&5476#"'&547632'2#"'&547672#"'&547672#"'&5476'2#"'&5476‹'! $! o# $ &?' $! &!$ Î&! $ ®& ":"$! %ü' $! ì"$! %¼! % $½" $ $!$$ÿÜÉÓ02#"'&54762#"'&54762#"'&5476‹&"$ ®& $! Î&! $ " & $½!$! %z"$ $É´/?2#"'&5476#"'&5476322#"'&5476'2#"'&5476‹'! $! o# $ &'$! ­'$! :"$! %ü' $! ©"# ! %½"# ! %ÿÜÉÓ0A2#"'&54762#"'&54762#"'&5476#2#"'&5476‹&"$ ®& $! Î&! $ ®&$! " & $½!$! %z"$ $!" ! &É´/?2#"'&5476#"'&5476322#"'&547672#"'&5476‹'! $! o# $ &?&!$ '$! :"$! %ü' $! ¨! % $¾"# ! %ÿÜÉÓ/@2#"'&54762"'&54767#"'&54763272#"'&5476‹&"$ ®& $! N" $ &€&! $ " & $½!#! %' $" ì"$ $É´/?O2#"'&5476#"'&547632'2#"'&547672#"'&5476'2#"'&5476‹'! $! o# $ &?' $! Î'$! ®& ":"$! %ü' $! ì"$! %½"# ! %½!$$ÿÜÉÓ/@Q2#"'&54762"'&54767#"'&54763272#"'&5476#"'&547632‹&"$ ®& $! N" $ &€&! $ o"$! &" & $½!#! %' $" ì"$ $?$! &!É´/?O_2#"'&5476#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476‹'! $! o# $ &?' $! Î'$! ®&!$ & ":"$! %ü' $! ì"$! %½"# ! %! % $¾!$$ɳ 0@2#"'&5476#"'&5476322#"'&547672#"'&5476‹&! $ o# $! &'! $! &! $ 9"$! $ü& &!ª"$! %¼" $ $É´/?O2#"'&5476#"'&5476322#"'&547672#"'&5476'2#"'&5476‹'! $! o# $ &'$! &! $ ­'$! :"$! %ü' $! ©"# ! %¼" $ $"# ! %ɳ 0@P2#"'&5476#"'&5476322#"'&54762#"'&547672#"'&5476‹&! $ o# $! &'! $! ®&!$ Î&! $ 9"$! $ü& &!ª"$! %! % $½" $ $É´/?O_2#"'&5476#"'&5476322#"'&54762#"'&547672#"'&5476'2#"'&5476‹'! $! o# $ &'$! ®&!$ Î&! $ ­'$! :"$! %ü' $! ©"# ! %! % $½" $ $"# ! %ɳ 1AQ2#"'&5476#"'&547632'2#"'&547672#"'&547672#"'&5476‹&! $ o# $! &?& $ Î'! $! &! $ 9"$! $ü& &!ì"$! $¾"$! %¼" $ $É´/?O_2#"'&5476#"'&547632'2#"'&547672#"'&547672#"'&5476'2#"'&5476‹'! $! o# $ &?' $! Î'$! &! $ ®& ":"$! %ü' $! ì"$! %½"# ! %¼" $ $!$$ɳ 1AQa2#"'&5476#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476‹&! $ o# $! &?& $ Î'! $! ®&!$ Î&! $ 9"$! $ü& &!ì"$! $¾"$! %! % $½" $ $É´/?O_o2#"'&5476#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476'2#"'&5476‹'! $! o# $ &?' $! Î'$! ®&!$ Î&! $ ®& ":"$! %ü' $! ì"$! %½"# ! %! % $½" $ $!$$pÿ•ì%2#"'&5476®'$! "# ! %É´%#"'&5476322#"'&5476É# $! &û'$! >' $! f"# ! %ÿÜÉÓ %2#"'&54762"'&5476Š&!$! ­& $! Y!%! %z!#! %É´/%#"'&5476322#"'&547672#"'&5476É# $ &ü&!$ & ">' $! ¨! % $¾!$$ÿ¹Éó %2#"'&5476'2#"'&5476Š&!$ ­' $! 5! % $¾"$! %É´/%#"'&547632'2#"'&54762#"'&5476É# $ &ü' $! & ">' $! ì"$! %z!$$ÿÜÉÓ 1%2#"'&5476'#"'&547632'2"'&5476Š&!$! o" $! '>& $! Y!%! %~& &"í!#! %É´/?%#"'&547632'2#"'&547672#"'&547672#"'&5476É# $ &ü' $! &!$ & ">' $! ì"$! %¼! % $¾!$$pí³!%#"'&5476322#"'&5476ì" $! '>&!$ =& &"g!% $É´/%#"'&5476322#"'&5476'2#"'&5476É# $ &>& $ ­'$! >' $! e" $ $"# ! %ɳ/%#"'&5476322#"'&547672#"'&5476É# $!&ü&!$ Î&! $ =& %!©! % $½" $ $É´/?%#"'&5476322#"'&547672#"'&5476'2#"'&5476É# $! &ü&!$ Î&! $ ­'$! >' $! ¨! % $½" $ $"# ! %ɳ 0%#"'&547632'2#"'&54762#"'&5476É# $! &ü& $ Î&! $ =& &!ì"$! $z" $ $É´/?%#"'&547632'2#"'&54762#"'&5476'2#"'&5476É# $ &ü' $! Î&! $ ®& ">' $! ì"$! %y" $ $!$$ɳ 0@%#"'&547632'2#"'&547672#"'&547672#"'&5476É# $! &ü& $ &!$ Î&! $ =& &!ì"$! $½! % $½" $ $É´/?O%#"'&547632'2#"'&547672#"'&547672#"'&5476'2#"'&5476É# $ &ü' $! &!$ Î&! $ ®& ">' $! ì"$! %¼! % $½" $ $!$$pÿÜíÓ %2#"'&54762#"'&5476®' $! &!$ Y"$! %z! % $É´/%#"'&5476322#"'&5476'2#"'&5476É# $ &>' $! ­'$! >' $! ©"$! %½"# ! %ÿÜÉÓ 1%2#"'&54762#"'&5476#2#"'&5476Š& $ &! $ ®&$! Y!$! $z"$ $!" ! &É´/?%#"'&5476322#"'&54762#"'&547672#"'&5476É# $! &>'$! ®&!$ '$! >' $! ©"# ! %! % $¾"# ! %ÿÜÉÓ0%2#"'&5476'#"'&54763272#"'&5476Š& $! o" $ &€&! $ Y!$! %' $" ì"$ $É´/?%#"'&547632'2#"'&547672#"'&5476'2#"'&5476É# $ &ü' $! Î'$! ®& ">' $! ì"$! %½"# ! %½!$$ÿÜÉÓ0A%2#"'&5476'#"'&54763272#"'&5476#"'&547632Š& $! o" $ &€&! $ o"$! &Y!$! %' $" ì"$ $?$! &!É´/?O%#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476É# $ &ü' $! Î'$! ®&!$ & ">' $! ì"$! %½"# ! %! % $¾!$$pí³!3%#"'&5476322#"'&547672#"'&5476ì" $! '>&!$! &!$ =& &"«!%! %¼!% $É´/?%#"'&5476322#"'&547672#"'&5476'2#"'&5476É# $ &>' $! & $ ­'$! >' $! ©"$! %¼" $ $"# ! %ɳ/?%#"'&5476322#"'&54762#"'&547672#"'&5476É# $!&>'! $! ®&!$ Î&! $ =& %!ª"$! %! % $½" $ $É´/?O%#"'&5476322#"'&54762#"'&547672#"'&5476'2#"'&5476É# $! &>'$! ®&!$ Î&! $ ­'$! >' $! ©"# ! %! % $½" $ $"# ! %ɳ 0@%#"'&547632'2#"'&547672#"'&547672#"'&5476É# $! &ü& $ Î'! $! &! $ =& &!ì"$! $¾"$! %¼" $ $É´/?O%#"'&547632'2#"'&547672#"'&547672#"'&5476'2#"'&5476É# $ &ü' $! Î'$! &! $ ®& ">' $! ì"$! %½"# ! %¼" $ $!$$ɳ 0@P%#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476É# $! &ü& $ Î'! $! ®&!$ Î&! $ =& &!ì"$! $¾"$! %! % $½" $ $É´/?O_%#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476'2#"'&5476É# $ &ü' $! Î'$! ®&!$ Î&! $ ®& ">' $! ì"$! %½"# ! %! % $½" $ $!$$pÿ¹íó%2#"'&547672"'&5476®& $ & $! 5" $ $¾!#! %É´/%#"'&547632'2#"'&54762#"'&5476É# $ &>' $! ­'$! >' $! ì"$! %z"# ! %ÿÜÉÓ0%2#"'&547672#"'&5476'2#"'&5476Š&!$ '"$! ®& $! Y!%! $½"& &½!$! %É´/?%#"'&547632'2#"'&5476'2#"'&547672#"'&5476É# $! &>'! $! ®&!$ '$! >' $! ì"$! %¼! % $¾"# ! %ÿ¹Éó/%2#"'&547672#"'&5476#2#"'&5476Š&!$ '$! ®' $! 5! % $¾"# ! %"$! %É´/?%#"'&547632'2#"'&5476#2#"'&54762#"'&5476É# $ &>'! $! ®' $! & ">' $! ì"$! %"$! %z!$$ÿÜÉÓ/@%2#"'&547672#"'&5476#"'&547632'2"'&5476Š&!$! '"$! p" $! '>& $! Y!%! %½"& &?& &"í!#! %É´/?O%#"'&547632'2#"'&5476#2#"'&547672#"'&547672#"'&5476É# $ &>'! $! ®' $! &!$ & ">' $! ì"$! %"$! %¼! % $¾!$$pí³ 2%#"'&547632'2#"'&54762#"'&5476ì" $! '>&!$ &!$ =& &"í! %! $z!% $É´/?%#"'&547632'2#"'&54762#"'&5476'2#"'&5476É# $ &>' $! & $ ­'$! >' $! ì"$! %y" $ $"# ! %ɳ 0@%#"'&547632'2#"'&5476'2#"'&547672#"'&5476É# $!&>&! $ ®&!$ Î&! $ =& %!ì"$! $½! % $½" $ $É´/?O%#"'&547632'2#"'&5476'2#"'&547672#"'&5476'2#"'&5476É# $! &>'! $! ®&!$ Î&! $ ­'$! >' $! ì"$! %¼! % $½" $ $"# ! %ɳ 1A%#"'&547632'2#"'&5476#2#"'&54762#"'&5476É# $! &>&! $ ®& $ Î&! $ =& &!ì"$! $"$! $z" $ $É´/?O%#"'&547632'2#"'&5476#2#"'&54762#"'&5476'2#"'&5476É# $ &>'! $! ®' $! Î&! $ ®& ">' $! ì"$! %"$! %y" $ $!$$ɳ 1AQ%#"'&547632'2#"'&5476#2#"'&547672#"'&547672#"'&5476É# $! &>&! $ ®& $ &!$ Î&! $ =& &!ì"$! $"$! $½! % $½" $ $É´/?O_%#"'&547632'2#"'&5476#2#"'&547672#"'&547672#"'&5476'2#"'&5476É# $ &>'! $! ®' $! &!$ Î&! $ ®& ">' $! ì"$! %"$! %¼! % $½" $ $!$$pÿÜíÓ0%2#"'&54767#"'&547632'2#"'&5476®' $! O# $ &?&!$ Y"$! %' $! ë! % $É´/?%#"'&547632'2#"'&547672#"'&5476'2#"'&5476É# $ &>' $! ' $! ­'$! >' $! ì"$! %½"$! %½"# ! %ÿÜÉÓ0A%2#"'&547672#"'&547672#"'&5476#2#"'&5476Š& $ &"$ &! $ ®&$! Y!$! $½" & $½"$ $!" ! &É´/?O%#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476É# $! &>'! $! '$! ®&!$ '$! >' $! ì"$! %½"# ! %! % $¾"# ! %ÿÜÉÓ/@%2#"'&547672#"'&5476#"'&54763272#"'&5476Š& $! &"$ p" $ &€&! $ Y!$! %½" & $>' $" ì"$ $É´/?O%#"'&547632'2#"'&5476#2#"'&547672#"'&5476'2#"'&5476É# $ &>'! $! ®' $! Î'$! ®& ">' $! ì"$! %"$! %½"# ! %½!$$ÿÜÉÓ/@Q%2#"'&547672#"'&5476#"'&54763272#"'&5476#"'&547632Š& $! &"$ p" $ &€&! $ o"$! &Y!$! %½" & $>' $" ì"$ $?$! &!É´/?O_%#"'&547632'2#"'&5476#2#"'&547672#"'&54762#"'&547672#"'&5476É# $ &>'! $! ®' $! Î'$! ®&!$ & ">' $! ì"$! %"$! %½"# ! %! % $¾!$$pí³ 2D%#"'&547632'2#"'&547672#"'&547672#"'&5476ì" $! '>&!$ &!$! &!$ =& &"í! %! $¾!%! %¼!% $É´/?O%#"'&547632'2#"'&547672#"'&547672#"'&5476'2#"'&5476É# $ &>' $! ' $! & $ ­'$! >' $! ì"$! %½"$! %¼" $ $"# ! %ɳ 0@P%#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476É# $!&>&! $ '! $! ®&!$ Î&! $ =& %!ì"$! $¾"$! %! % $½" $ $É´/?O_%#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476'2#"'&5476É# $! &>'! $! '$! ®&!$ Î&! $ ­'$! >' $! ì"$! %½"# ! %! % $½" $ $"# ! %ɳ 1AQ%#"'&547632'2#"'&5476#2#"'&547672#"'&547672#"'&5476É# $! &>&! $ ®& $ Î'! $! &! $ =& &!ì"$! $"$! $¾"$! %¼" $ $É´/?O_%#"'&547632'2#"'&5476#2#"'&547672#"'&547672#"'&5476'2#"'&5476É# $ &>'! $! ®' $! Î'$! &! $ ®& ">' $! ì"$! %"$! %½"# ! %¼" $ $!$$ɳ 1AQa%#"'&547632'2#"'&5476#2#"'&547672#"'&54762#"'&547672#"'&5476É# $! &>&! $ ®& $ Î'! $! ®&!$ Î&! $ =& &!ì"$! $"$! $¾"$! %! % $½" $ $É´/?O_o%#"'&547632'2#"'&5476#2#"'&547672#"'&54762#"'&547672#"'&5476'2#"'&5476É# $ &>'! $! ®' $! Î'$! ®&!$ Î&! $ ®& ">' $! ì"$! %"$! %½"# ! %! % $½" $ $!$$ÿ•É%2#"'&5476#2"'&5476Š& $! ­& $! !$! %!#! %É´/%#"'&547632#"'&5476322#"'&5476É# $ &½# $ &?& ">' $! ' $! f!$$ÿÜÉÓ0%2#"'&5476#2#"'&54762"'&5476Š&!$! ­&!$! & $! Y!%! %!%! %z!#! %É´/?%#"'&547632#"'&5476322#"'&547672#"'&5476É# $ &½# $ &?&!$ & ">' $! ' $! ¨! % $¾!$$ÿ¹Éó 0%2#"'&5476#2#"'&547672#"'&5476Š&!$ ­&!$ ' $! 5! % $! % $¾"$! %É´/?%#"'&547632#"'&547632'2#"'&54762#"'&5476É# $ &½# $ &?' $! & ">' $! ' $! ì"$! %z!$$ÿÜÉÓ 0A%2#"'&5476#2#"'&54767#"'&547632'2"'&5476Š&!$! ­&!$! N" $! '>& $! Y!%! %!%! %~& &"í!#! %É´/?O%#"'&547632#"'&547632'2#"'&547672#"'&547672#"'&5476É# $ &½# $ &?' $! &!$ & ">' $! ' $! ì"$! %¼! % $¾!$$ɳ/%#"'&547632#"'&5476322#"'&5476É# $!&½# $! &&! $ =& %!& &!f" $ $É´/?%#"'&547632#"'&5476322#"'&5476'2#"'&5476É# $! &½# $ &&! $ ­'$! >' $! ' $! e" $ $"# ! %ɳ/?%#"'&547632#"'&5476322#"'&547672#"'&5476É# $!&½# $! &?&!$ Î&! $ =& %!& &!©! % $½" $ $É´/?O%#"'&547632#"'&5476322#"'&547672#"'&5476'2#"'&5476É# $! &½# $ &?&!$ Î&! $ ­'$! >' $! ' $! ¨! % $½" $ $"# ! %ɳ0@P%#"'&547632#"'&547632'2#"'&547672#"'&547672#"'&5476É# $! &½# $! &?& $ &!$ Î&! $ =& &!& &!ì"$! $½! % $½" $ $É´/?O%#"'&547632#"'&547632'2#"'&54762#"'&5476'2#"'&5476É# $ &½# $ &?' $! Î&! $ ®& ">' $! ' $! ì"$! %y" $ $!$$ɳ0@P%#"'&547632#"'&547632'2#"'&547672#"'&547672#"'&5476É# $! &½# $! &?& $ &!$ Î&! $ =& &!& &!ì"$! $½! % $½" $ $É´/?O_%#"'&547632#"'&547632'2#"'&547672#"'&547672#"'&5476'2#"'&5476É# $ &½# $ &?' $! &!$ Î&! $ ®& ">' $! ' $! ì"$! %¼! % $½" $ $!$$ÿÜÉÓ0%2#"'&5476#2#"'&54762#"'&5476Š& $ ­& $! Î&! $ Y!$! $!$! %z"$ $É´/?%#"'&547632#"'&5476322#"'&5476'2#"'&5476É# $! &½# $ &'$! ­'$! >' $! ' $! ©"# ! %½"# ! %ÿÜÉÓ0A%2#"'&5476#2#"'&54762#"'&5476#2#"'&5476Š& $ ­& $! Î&! $ ®&$! Y!$! $!$! %z"$ $!" ! &É´/?O%#"'&547632#"'&5476322#"'&54762#"'&547672#"'&5476É# $! &½# $ &'$! ®&!$ '$! >' $! ' $! ©"# ! %! % $¾"# ! %ÿÜÉÓ/@%2#"'&5476#2"'&54767#"'&54763272#"'&5476Š& $! ­& $! N" $ &€&! $ Y!$! %!#! %' $" ì"$ $É´/?O%#"'&547632#"'&547632'2#"'&547672#"'&5476'2#"'&5476É# $ &½# $ &?' $! Î'$! ®& ">' $! ' $! ì"$! %½"# ! %½!$$ÿÜÉÓ/@Q%2#"'&5476#2"'&54767#"'&54763272#"'&5476#"'&547632Š& $! ­& $! N" $ &€&! $ o"$! &Y!$! %!#! %' $" ì"$ $?$! &!É´/?O_%#"'&547632#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476É# $ &½# $ &?' $! Î'$! ®&!$ & ">' $! ' $! ì"$! %½"# ! %! % $¾!$$ɳ/?%#"'&547632#"'&5476322#"'&547672#"'&5476É# $!&½# $! &'! $! &! $ =& %!& &!ª"$! %¼" $ $É´/?O%#"'&547632#"'&5476322#"'&547672#"'&5476'2#"'&5476É# $! &½# $ &'$! &! $ ­'$! >' $! ' $! ©"# ! %¼" $ $"# ! %ɳ/?O%#"'&547632#"'&5476322#"'&54762#"'&547672#"'&5476É# $!&½# $! &'! $! ®&!$ Î&! $ =& %!& &!ª"$! %! % $½" $ $É´/?O_%#"'&547632#"'&5476322#"'&54762#"'&547672#"'&5476'2#"'&5476É# $! &½# $ &'$! ®&!$ Î&! $ ­'$! >' $! ' $! ©"# ! %! % $½" $ $"# ! %ɳ0@P%#"'&547632#"'&547632'2#"'&547672#"'&547672#"'&5476É# $! &½# $! &?& $ Î'! $! &! $ =& &!& &!ì"$! $¾"$! %¼" $ $É´/?O_%#"'&547632#"'&547632'2#"'&547672#"'&547672#"'&5476'2#"'&5476É# $ &½# $ &?' $! Î'$! &! $ ®& ">' $! ' $! ì"$! %½"# ! %¼" $ $!$$ɳ0@P`%#"'&547632#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476É# $! &½# $! &?& $ Î'! $! ®&!$ Î&! $ =& &!& &!ì"$! $¾"$! %! % $½" $ $É´/?O_o%#"'&547632#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476'2#"'&5476É# $ &½# $ &?' $! Î'$! ®&!$ Î&! $ ®& ">' $! ' $! ì"$! %½"# ! %! % $½" $ $!$$ÿ¹Éó/%2#"'&547672#"'&54762#"'&5476Š&!$! '$! ®&!$ 5! % $¾"# ! %¾! % $É´/?%#"'&547632'2#"'&5476#"'&5476322#"'&5476É# $! &>'! $! o# $ &>'$! >' $! ì"$! %ü' $! f"# ! %ÿÜÉÓ/@%2#"'&547672#"'&54762#"'&54762#"'&5476Š&!$ '"$! ®&!$! & $! Y!%! $½"& &½!%! %z!$! %É´/?O%#"'&547632'2#"'&5476#"'&5476322#"'&547672#"'&5476É# $! &>'! $! o# $ &?&!$ '$! >' $! ì"$! %ü' $! ¨! % $¾"# ! %ÿ¹Éó/?%2#"'&547672#"'&54762#"'&547672#"'&5476Š&!$ '$! ®&!$ ' $! 5! % $¾"# ! %¾! % $¾"$! %É´/?O%#"'&547632'2#"'&5476#"'&547632'2#"'&54762#"'&5476É# $ &>'! $! o# $ &?' $! & ">' $! ì"$! %ü' $! ì"$! %z!$$ÿÜÉÓ/?P%2#"'&547672#"'&54762#"'&54767#"'&547632'2"'&5476Š&!$! '"$! ®&!$! N" $! '>& $! Y!%! %½"& &½!%! %~& &"í!#! %É´/?O_%#"'&547632'2#"'&5476#"'&547632'2#"'&547672#"'&547672#"'&5476É# $ &>'! $! o# $ &?' $! &!$ & ">' $! ì"$! %ü' $! ì"$! %¼! % $¾!$$ɳ 0@%#"'&547632'2#"'&5476#"'&5476322#"'&5476É# $!&>&! $ o# $! &&! $ =& %!ì"$! $ü& &!f" $ $É´/?O%#"'&547632'2#"'&5476#"'&5476322#"'&5476'2#"'&5476É# $! &>'! $! o# $ &&! $ ­'$! >' $! ì"$! %ü' $! e" $ $"# ! %ɳ 0@P%#"'&547632'2#"'&5476#"'&5476322#"'&547672#"'&5476É# $!&>&! $ o# $! &?&!$ Î&! $ =& %!ì"$! $ü& &!©! % $½" $ $É´/?O_%#"'&547632'2#"'&5476#"'&5476322#"'&547672#"'&5476'2#"'&5476É# $! &>'! $! o# $ &?&!$ Î&! $ ­'$! >' $! ì"$! %ü' $! ¨! % $½" $ $"# ! %ɳ 0AQ%#"'&547632'2#"'&5476#"'&547632'2#"'&54762#"'&5476É# $! &>&! $ o# $! &?& $ Î&! $ =& &!ì"$! $ü& &!ì"$! $z" $ $É´/?O_%#"'&547632'2#"'&5476#"'&547632'2#"'&54762#"'&5476'2#"'&5476É# $ &>'! $! o# $ &?' $! Î&! $ ®& ">' $! ì"$! %ü' $! ì"$! %y" $ $!$$ɳ 0AQa%#"'&547632'2#"'&5476#"'&547632'2#"'&547672#"'&547672#"'&5476É# $! &>&! $ o# $! &?& $ &!$ Î&! $ =& &!ì"$! $ü& &!ì"$! $½! % $½" $ $É´/?O_o%#"'&547632'2#"'&5476#"'&547632'2#"'&547672#"'&547672#"'&5476'2#"'&5476É# $ &>'! $! o# $ &?' $! &!$ Î&! $ ®& ">' $! ì"$! %ü' $! ì"$! %¼! % $½" $ $!$$ÿÜÉÓ/@%2#"'&547672#"'&54762#"'&54762#"'&5476Š& $ &"$ ®& $! Î&! $ Y!$! $½" & $½!$! %z"$ $É´/?O%#"'&547632'2#"'&5476#"'&5476322#"'&5476'2#"'&5476É# $! &>'! $! o# $ &'$! ­'$! >' $! ì"$! %ü' $! ©"# ! %½"# ! %ÿÜÉÓ/@Q%2#"'&547672#"'&54762#"'&54762#"'&5476#2#"'&5476Š& $ &"$ ®& $! Î&! $ ®&$! Y!$! $½" & $½!$! %z"$ $!" ! &É´/?O_%#"'&547632'2#"'&5476#"'&5476322#"'&54762#"'&547672#"'&5476É# $! &>'! $! o# $ &'$! ®&!$ '$! >' $! ì"$! %ü' $! ©"# ! %! % $¾"# ! %ÿÜÉÓ/?P%2#"'&547672#"'&54762"'&54767#"'&54763272#"'&5476Š& $! &"$ ®& $! N" $ &€&! $ Y!$! %½" & $½!#! %' $" ì"$ $É´/?O_%#"'&547632'2#"'&5476#"'&547632'2#"'&547672#"'&5476'2#"'&5476É# $ &>'! $! o# $ &?' $! Î'$! ®& ">' $! ì"$! %ü' $! ì"$! %½"# ! %½!$$ÿÜÉÓ/?Pa%2#"'&547672#"'&54762"'&54767#"'&54763272#"'&5476#"'&547632Š& $! &"$ ®& $! N" $ &€&! $ o"$! &Y!$! %½" & $½!#! %' $" ì"$ $?$! &!É´/?O_o%#"'&547632'2#"'&5476#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476É# $ &>'! $! o# $ &?' $! Î'$! ®&!$ & ">' $! ì"$! %ü' $! ì"$! %½"# ! %! % $¾!$$ɳ 0@P%#"'&547632'2#"'&5476#"'&5476322#"'&547672#"'&5476É# $!&>&! $ o# $! &'! $! &! $ =& %!ì"$! $ü& &!ª"$! %¼" $ $É´/?O_%#"'&547632'2#"'&5476#"'&5476322#"'&547672#"'&5476'2#"'&5476É# $! &>'! $! o# $ &'$! &! $ ­'$! >' $! ì"$! %ü' $! ©"# ! %¼" $ $"# ! %ɳ 0@P`%#"'&547632'2#"'&5476#"'&5476322#"'&54762#"'&547672#"'&5476É# $!&>&! $ o# $! &'! $! ®&!$ Î&! $ =& %!ì"$! $ü& &!ª"$! %! % $½" $ $É´/?O_o%#"'&547632'2#"'&5476#"'&5476322#"'&54762#"'&547672#"'&5476'2#"'&5476É# $! &>'! $! o# $ &'$! ®&!$ Î&! $ ­'$! >' $! ì"$! %ü' $! ©"# ! %! % $½" $ $"# ! %ɳ 0AQa%#"'&547632'2#"'&5476#"'&547632'2#"'&547672#"'&547672#"'&5476É# $! &>&! $ o# $! &?& $ Î'! $! &! $ =& &!ì"$! $ü& &!ì"$! $¾"$! %¼" $ $É´/?O_o%#"'&547632'2#"'&5476#"'&547632'2#"'&547672#"'&547672#"'&5476'2#"'&5476É# $ &>'! $! o# $ &?' $! Î'$! &! $ ®& ">' $! ì"$! %ü' $! ì"$! %½"# ! %¼" $ $!$$ɳ 0AQaq%#"'&547632'2#"'&5476#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476É# $! &>&! $ o# $! &?& $ Î'! $! ®&!$ Î&! $ =& &!ì"$! $ü& &!ì"$! $¾"$! %! % $½" $ $É´/?O_o%#"'&547632'2#"'&5476#"'&547632'2#"'&547672#"'&54762#"'&547672#"'&5476'2#"'&5476É# $ &>'! $! o# $ &?' $! Î'$! ®&!$ Î&! $ ®& ">' $! ì"$! %ü' $! ì"$! %½"# ! %! % $½" $ $!$$êÿoÿÄ#"'&54?632gT T a~ ~S\-[32+"54;#"54;547632"'&#"32#!32+"54;#"54;547632"'&#"32#¶HÄSMM0 &% %(HþžHÄSMM0 &% %(Hxþ±O;E& ,;þ±O;E& ,; Ip-@D32+"54;#"54;547632"'&#"32#732+"54;#"5437#5¡HÄSMM0 %& %(HúKÁM9a;xþ±O;E& ,;)þˆOÏhh K\,?32+"54;#"54;547632"'&#"32#732+"54;#"543¡HÄSMM0 '$*& HúMÃM9xþ±O;E& );äýÍ ÿðK\'N#"54;543232+327632#"'&532+"54;#"54;547632"'&#"aJJ||3  +J+ÅHÄSMM0 &% %(xkkëF  <(3UþMO;E& ,Ëÿð3'#"54;543232+327632#"'&51JJ||3  +J+xwwëF  <(3ªsIà"%2"'&5476#"'&=#"'&54763,Y®2ðǹŸu#67676"'&'&'&76762R $8  %"O   ZqÂà%9732+"'&5476#"'&=#"'&54763!#"'&=#"'&54763ý‡‡ YTYšFðÇðÇ<ÿÿà.7#"'&5476;3676767#"'476;'"#!"'&54763ïB]€I85 "V…( ,Kþÿ)ŽþI NþÄT+<à8%676=#"'&5476;'&'32+547'&7676z`5^x | þåd5^‚| ¿%1~§a5| %7~§f4| <à!"'&54763!2##"'&5…þË·Y·þ]<á2747632#"'&#"'&5&'&'&/!"'&54763!6_½ %þÛ%/*ÿ&þÛ%7  0<ÿÿóá3!#"'&5476;6767676=&'&'&'&+"'&5476;6'"Lüü6  ) üü.*"+M ) ’7  -O’L',<i%/&76?676=!547632!ñÛ ÛþI·áÛ Û ~žu§-<á*!&'&'&'&+"'&54763!6!&76767hi ) Ÿ†%-*þE·h ì6  2JþÇ<á #"'&5&'&'&/!"'&54763!6 %þÛ%/*9þÛ%7  0ÿÿá>'"+"'&5476;67676765#"'&54763!6#"'&5&'&'&'&#Ó"!<$$*Z%/*  ' ·þË>#"  5 (GþÛ%6 H"54;543232#c´´ÉÉ3BWH2#"'&547632+3276767#"'476;!32+3#"'&5476%þæ\2Q7 "2`' 0LþÇ^5–2WwþrMþÄR*àþrŽ1:WH2#"'&547632+3276767#"'476;!32+3#"'&5476O¼\2Q7 "2`' 0LþÇ^5–2WwþrMþÄR*àþrŽ3BWHW2#"'&547632+3276767#"'476;!32+3#"'&54762"'&5476%þæ\2Q7 "2`' 0LþÇ^5–2‘WwþrMþÄR*àþrŽÒ1:WHW2#"'&547632+3276767#"'476;!32+3#"'&54762"'&5476O¼\2Q7 "2`' 0LþÇ^5–2‘WwþrMþÄR*àþrŽÒ<ÿ›àJ32+"'&54767676=#"'&5476;'&'32+547'&7676采“`5^x | þåd5^‚| <û%1~§a5| %7~§f4| <ÿ$àS#"'&5476;2##"'&5676=#"'&5476;'&'32+547'&7676.‡0c`5^x | þåd5^‚| ec‡%1~§a5| %7~§f4| <à8G%676=#"'&5476;'&'32+547'&76762"'&5476z`5^x | þåd5^‚| ¿%1~§a5| %7~§f4| þÀ<0à-<%4'&'&/#"'&5476;232#!"'&5476372"'&5476™+ËËN)+Zþ4Ü)7%+Mþðå…ÿÿÓá5C%54'&'&/#"'&5476;6#'&/'&'&74?676'2"'&5476… #!II1+$  V$.9 &*$5¹€7  *M  M  0/<à)!"'&54763!2##"'&5'2"'&5476…þË·YY·þ]ú<á2A747632#"'&#"'&5&'&'&/!"'&54763!62"'&5476_½ %þÛ%/*ßÿ&þÛ%7  0wª@à"2"'&54767#"'&5#"'&54763ÐtYÒþ4£…Óà'2"'&54767#"'4763!2##"'&5ÎM}$~©þ]ÿÿàH%2"'&54767'&'&76?3#'&'&745#"'&5476;;27676765LHs ~œ"0Lj/+5^ % j7êÍŠ ›þÇL'* (MþÇ6 ) £Û@à !2"'&54767#"'&=#"'&54763À„YfzðÇ<ÿ%óá"1"'&5&'&'&'&+"'&5476;62"'&5476ó ' üü/)Ç9þ6  'J1<ÿÿóá3B!#"'&5476;6767676=&'&'&'&+"'&5476;6'"2"'&5476Lüü6  ) üü.*"+M" ) ’7  -O’L',<i*%/&76?676=!547632!'2"'&5476ñÛ ÛþI·èáÛ Û ~žu§-2<á6E73!"'&5476;&'&'&'&+#"'&5#"'&5476;2"'&5476Š}‰?")þëì ' eh:¸ku&'JþÇ6 hþ£Ò…¯á02"'&5476!"'&54734'&'&'&+"'476;6,†þìë( $$.+þò7 +M<ÿÿàBQ;7676=&'&'&'&+"'&54763!2'#'&'&'7&7672"'&5476h ( „I ) Ÿ†%K'* PŒ-*!³·h n6 I Œ7 "0LŒO 'Nu%&^<ÿ%á6D32+5&76?#"'&54763!6#"'&5&'&'&'&#2"'&5476h¢Ë!K†%/* ' ·h:%&K 0Lþ7 }<áHV32+5&7676?#"'&54763!6!"'&547!2767676=&'&'&'&#2"'&5476h¢Ë K†%/*#0LþÜ$7 ' ·h  :K 2J’L(** ’6 u2à172"'&5476?5#"'476;!"'&547!55#"'476;Ö˜Y‚¤¤þ5¢þ·Y‚ÈM‰U“¤TR"C1ÿ%à );2"'&5476'&'&76?676=!"'&54763!%#"'&547632@¨Û Ûþ]Ìþ’,ƒ¥ ¤  µÞ8Kþ$Ü<á /#"'&5&'&'&/!"'&54763!62"'&5476 %þÛ%/*ï9þÛ%7  0w3:àH2"'&5476'32+3276767#"'476;!32+3#"'&5476–‹\2Q7 "2`' 0LþÇ^5–2ÒþrMþÄR*àþrŽÿÿáM2"'&5476''"+"'&5476;67676765#"'&54763!6#"'&5&'&'&'&#X"!<$$*Z%/*  ' ©þË>#"  5 (GþÛ%6 ª@W !2"'&5476#"'&5#"'&547632YWwþ4£<0E?32+"'&54764'&'&/#"'&5476;232#!"'&54763҇Ö+ËËN)+Zþ4Eýä7%+Mþð<ÿÿóEE32+"'&5476#"'&5476;6767676=&'&'&'&+"'&5476;6'"ɇ‡…üü6  ) üü.*"+MEý» ) ’7  -O’L',<EZ32+"'&547632+5&7676?#"'&54763!6!"'&547!2767676=&'&'&'&#采)h¢Ë K†%/*#0LþÜ$7 ' EŽh  :K 2J’L(** ’6 <i(547632676=#"'&5476;'&'&<`5^x | þỈþë%1~§a5| ·9"354767674'&#"3672#3 e##* ,9g( 2/ '**þò ]   /$?mD%á1\ þóŒüͶ 0'&/&76762#"'&547632#"'&54768 8 N!   è!  «˜˜O    Y2ZŠ ¥Vº>4n¿ ŒÚH¯X-\œ³+^¤Ñ Fh$ù,x ¥H³^ý]Ho ¹HÇH#€mïH Z Š  ¥ Vº > 4n ¿ ŒÚ H¯ X  K HY x£  H/  y H‡ \Ñ /H=‡H—@á #H 7^  áH ï 9H K •H £ íH ýj G ³H Å H  gH u$ ¿$ † Ï$H W$T ¡* ÷*H-Q-Ha  « H¹ H  [ Hi  ³ HÁCopyleft 2002, 2003 Free Software Foundation.Copyleft 2002, 2003 Free Software Foundation.FreeMonoFreeMonoMediumMediumFontForge 1.0 : Free Monospaced : 29-7-2004FontForge 1.0 : Free Monospaced : 29-7-2004Free MonospacedFree MonospacedVersion $Revision: 1.10 $ Version $Revision: 1.10 $ FreeMonoFreeMonoThe use of this font is granted subject to GNU General Public License.The use of this font is granted subject to GNU General Public License.http://www.gnu.org/copyleft/gpl.htmlhttp://www.gnu.org/copyleft/gpl.htmlThe quick brown fox jumps over the lazy dog.The quick brown fox jumps over the lazy dog.Normalhttp://www.gnu.org/copyleft/gpl.htmlZel de grum: quetxup, whisky, cafè, bon vi; ja!oby ejnéhttp://www.gnu.org/copyleft/gpl.htmlnormalhttp://www.gnu.org/copyleft/gpl.htmlStandardhttp://www.gnu.org/copyleft/gpl.htmlZwölf Boxkämpfer jagen Victor quer über den großen Sylter Deich.š±½¿½¹º¬http://www.gnu.org/copyleft/gpl.htmlNormalhttp://www.gnu.org/copyleft/gpl.htmlJovencillo emponzoñado de whisky, qué mala figurota exhibes.Normaalihttp://www.gnu.org/copyleft/gpl.htmlNormalhttp://www.gnu.org/copyleft/gpl.htmlPortez ce vieux whisky au juge blond qui fume.Normálhttp://www.gnu.org/copyleft/gpl.htmlNormalehttp://www.gnu.org/copyleft/gpl.htmlPranzo d'acqua fa volti sghembi.Standaardhttp://www.gnu.org/copyleft/gpl.htmlZweedse ex-VIP, behoorl3k gek op quantumfysica.Normalhttp://www.gnu.org/copyleft/gpl.htmlNormalnyhttp://www.gnu.org/copyleft/gpl.htmlNormalhttp://www.gnu.org/copyleft/gpl.html1KG=K9http://www.gnu.org/copyleft/gpl.html G0I0ÿÿÿÿø8Ìÿÿþ681K; F8B@CA & 4ÿÿ, =ÿÿÿÿøÀì0 àÈ,ÿÿþM:75<ÿÿÿÿ.Normálnehttp://www.gnu.org/copyleft/gpl.htmlNormalhttp://www.gnu.org/copyleft/gpl.htmlNormalhttp://www.gnu.org/copyleft/gpl.htmlnavadnoDovoljena je uporaba v skladu z licenco GNU General Public License.http://www.gnu.org/copyleft/gpl.html`erif bo za vajo spet kuhal doma e ~gance.th°¡nghttp://www.gnu.org/copyleft/gpl.htmlArruntahttp://www.gnu.org/copyleft/gpl.htmlNormalhttp://www.gnu.org/copyleft/gpl.htmlNormalhttp://www.gnu.org/copyleft/gpl.htmlNormalhttp://www.gnu.org/copyleft/gpl.htmlNormalhttp://www.gnu.org/copyleft/gpl.htmlÿœ2   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a¬£„…½–膎‹©¤ŠÚƒ“òó—ˆÃÞñžªõôö¢­ÉÇ®bcdËeÈÊÏÌÍÎéfÓÐѯgð‘ÖÔÕhëí‰jikmln oqprsutvwêxzy{}|¸¡~€ìîºýþ    ÿ øù !"#$%&'()*+ú×,-./0123456789:âã;<=>?@ABCDEFGHI°±JKLMNOPQRSûüäåTUVWXYZ[\]^_`abcdefghi»jklmæçnopqrstuvwxyz{|}~€¦‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrØástuvwxyz{|}~ÛÜÝàÙ߀‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙ›ÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijk²³lm¶·Än´µÅo‚‡p«Æqrstuvw¾¿xyz{¼|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ÷ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸Œ¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%˜&'(¨)*+,-./š™ï0123¥456’789:;œ<=>?@ABCDEFGHIJ§KLMNOPQ”•RSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrst¹uvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ                           ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  € ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ Ž ‘ ’ “ ” • – — ˜ ™ š › œ ž Ÿ   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø ÙÀÁ Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ         softhyphenAmacronamacronAbreveabreveAogonekaogonek Ccircumflex ccircumflex Cdotaccent cdotaccentDcarondcaronDcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflex Gdotaccent gdotaccent Gcommaaccent gcommaaccent Hcircumflex hcircumflexHbarhbarItildeitildeImacronimacronIbreveibreveIogonekiogonekIJij Jcircumflex jcircumflex Kcommaaccent kcommaaccent kgreenlandicLacutelacute Lcommaaccent lcommaaccentLcaronlcaronLdotldotNacutenacute Ncommaaccent ncommaaccentNcaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautRacuteracute Rcommaaccent rcommaaccentRcaronrcaronSacutesacute Scircumflex scircumflexuni0162uni0163TcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflexZacutezacute Zdotaccent zdotaccentlongsuni0180uni0181uni0182uni0183uni0184uni0185uni0186uni0187uni0188uni0189uni018Auni018Buni018Cuni018Duni018Euni018Funi0190uni0191uni0193uni0194uni0195uni0196uni0197uni0198uni0199uni019Auni019Buni019Cuni019Duni019Euni019FOhornohornuni01A2uni01A3uni01A4uni01A5uni01A6uni01A7uni01A8uni01A9uni01AAuni01ABuni01ACuni01ADuni01AEUhornuhornuni01B1uni01B2uni01B3uni01B4uni01B5uni01B6uni01B7uni01B8uni01B9uni01BAuni01BBuni01BCuni01BDuni01BEuni01BFuni01C0uni01C1uni01C2uni01C3uni01C4uni01C5uni01C6uni01C7uni01C8uni01C9uni01CAuni01CBuni01CCuni01CDuni01CEuni01CFuni01D0uni01D1uni01D2uni01D3uni01D4uni01D5uni01D6uni01D7uni01D8uni01D9uni01DAuni01DBuni01DCuni01DDuni01DEuni01DFuni01E0uni01E1uni01E2uni01E3uni01E4uni01E5Gcarongcaronuni01E8uni01E9uni01EAuni01EBuni01ECuni01EDuni01EEuni01EFuni01F0uni01F1uni01F2uni01F3uni01F4uni01F5uni01F6uni01F7uni01F8uni01F9 Aringacute aringacuteAEacuteaeacute Oslashacute oslashacuteuni0200uni0201uni0202uni0203uni0204uni0205uni0206uni0207uni0208uni0209uni020Auni020Buni020Cuni020Duni020Euni020Funi0210uni0211uni0212uni0213uni0214uni0215uni0216uni0217 Scommaaccent scommaaccent Tcommaaccent tcommaaccentuni021Cuni021Duni021Euni021Funi0224uni0225uni0226uni0227uni0228uni0229uni022Auni022Buni022Cuni022Duni022Euni022Funi0230uni0231uni0232uni0233uni0241uni0242uni0250uni0251uni0252uni0253uni0254uni0255uni0256uni0257uni0258uni0259uni025Auni025Buni025Cuni025Funi0260uni0261uni0262uni0263uni0264uni0265uni0266uni0267uni0268uni0269uni026Auni026Buni026Cuni026Duni026Funi0270uni0271uni0272uni0273uni0274uni0275uni0276uni0278uni0279uni027Auni027Buni027Cuni027Duni027Euni027Funi0280uni0281uni0282uni0283uni0284uni0285uni0286uni0287uni0288uni0289uni028Cuni028Duni028Euni028Funi0290uni0291uni0292uni0294uni0295uni0296uni0297uni0299uni029Buni029Cuni029Duni029Euni029Funi02A0uni02A1uni02A2uni02A3uni02A4uni02A6uni02A7uni02BB afii57929 afii64937uni02BEuni02BFuni02C8uni02C9uni02CAuni02CBuni02D0uni02D1uni02D2uni02D3uni02D4uni02D5uni02D6uni02D7uni02DFuni02EE gravecomb acutecombuni0302 tildecombuni0304uni0305uni0306uni0307uni0308 hookabovecombuni030Auni030Buni030Cuni030Duni030Euni030Funi0310uni0311uni031Buni0321uni0322uni0327uni0328uni0333uni0335uni0336uni0337uni0338uni0342uni0344uni037Atonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammauni0394EpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhouni03A2SigmaTauUpsilonPhiChiPsiuni03A9 IotadieresisUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronrhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonosuni03D0theta1Upsilon1uni03D3phi1uni03DAuni03DBuni03DCuni0400 afii10023 afii10051 afii10052 afii10053 afii10054 afii10055 afii10056 afii10057 afii10058 afii10059 afii10060 afii10061uni040D afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097uni0450 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109uni045D afii10110 afii10193uni0464uni046Auni046Cuni0470uni0471uni048Cuni048Duni048Euni048F afii10050 afii10098uni0492uni0493uni0494uni0495uni0496uni0497uni0498uni0499uni049Auni049Buni049Cuni049Duni049Euni049Funi04A0uni04A1uni04A2uni04A3uni04A4uni04A5uni04A6uni04A7uni04A8uni04A9uni04AAuni04ABuni04ACuni04ADuni04AEuni04AFuni04B0uni04B1uni04B2uni04B3uni04B4uni04B5uni04B6uni04B7uni04B8uni04B9uni04BAuni04BBuni04BCuni04BDuni04BEuni04BFuni04C0uni04C1uni04C2uni04C3uni04C4uni04C7uni04C8uni04CBuni04CCuni04D0uni04D1uni04D2uni04D3uni04D4uni04D5uni04D6uni04D7uni04D8 afii10846uni04DAuni04DBuni04DCuni04DDuni04DEuni04DFuni04E0uni04E1uni04E2uni04E3uni04E4uni04E5uni04E6uni04E7uni04E8uni04E9uni04EAuni04EBuni04ECuni04EDuni04EEuni04EFuni04F0uni04F1uni04F2uni04F3uni04F4uni04F5uni04F8uni04F9uni0531uni0532uni0533uni0534uni0535uni0536uni0537uni0538uni0539uni053Auni053Buni053Cuni053Duni053Euni053Funi0540uni0541uni0542uni0543uni0544uni0545uni0546uni0547uni0548uni0549uni054Auni054Buni054Cuni054Duni054Euni054Funi0550uni0551uni0552uni0553uni0554uni0555uni0556uni0561uni0562uni0563uni0564uni0565uni0566uni0567uni0568uni0569uni056Auni056Buni056Cuni056Duni056Euni056Funi0570uni0571uni0572uni0573uni0574uni0575uni0576uni0577uni0578uni0579uni057Auni057Buni057Cuni057Duni057Euni057Funi0580uni0581uni0582uni0583uni0584uni0585uni0586uni058A afii57799 afii57801 afii57800 afii57802 afii57793 afii57794 afii57795 afii57798 afii57797 afii57806 afii57796 afii57807 afii57839 afii57645 afii57841 afii57842 afii57804 afii57803 afii57658uni05C4 afii57664 afii57665 afii57666 afii57667 afii57668 afii57669 afii57670 afii57671 afii57672 afii57673 afii57674 afii57675 afii57676 afii57677 afii57678 afii57679 afii57680 afii57681 afii57682 afii57683 afii57684 afii57685 afii57686 afii57687 afii57688 afii57689 afii57690 afii57716 afii57717 afii57718uni05F3uni05F4uni16A0uni16A1uni16A2uni16A3uni16A4uni16A5uni16A6uni16A7uni16A8uni16A9uni16AAuni16ABuni16ACuni16ADuni16AEuni16AFuni16B0uni16B1uni16B2uni16B3uni16B4uni16B5uni16B6uni16B7uni16B8uni16B9uni16BAuni16BBuni16BCuni16BDuni16BEuni16BFuni16C0uni16C1uni16C2uni16C3uni16C4uni16C5uni16C6uni16C7uni16C8uni16C9uni16CAuni16CBuni16CCuni16CDuni16CEuni16CFuni16D0uni16D1uni16D2uni16D3uni16D4uni16D5uni16D6uni16D7uni16D8uni16D9uni16DAuni16DBuni16DCuni16DDuni16DEuni16DFuni16E0uni16E1uni16E2uni16E3uni16E4uni16E5uni16E6uni16E7uni16E8uni16E9uni16EAuni16EBuni16ECuni16EDuni16EEuni16EFuni16F0uni1E00uni1E01uni1E02uni1E03uni1E04uni1E05uni1E06uni1E07uni1E08uni1E09uni1E0Auni1E0Buni1E0Cuni1E0Duni1E0Euni1E0Funi1E10uni1E11uni1E12uni1E13uni1E14uni1E15uni1E16uni1E17uni1E18uni1E19uni1E1Auni1E1Buni1E1Cuni1E1Duni1E1Euni1E1Funi1E20uni1E21uni1E22uni1E23uni1E24uni1E25uni1E26uni1E27uni1E28uni1E29uni1E2Auni1E2Buni1E2Cuni1E2Duni1E2Euni1E2Funi1E30uni1E31uni1E32uni1E33uni1E34uni1E35uni1E36uni1E37uni1E38uni1E39uni1E3Auni1E3Buni1E3Cuni1E3Duni1E3Euni1E3Funi1E40uni1E41uni1E42uni1E43uni1E44uni1E45uni1E46uni1E47uni1E48uni1E49uni1E4Auni1E4Buni1E4Cuni1E4Duni1E4Euni1E4Funi1E50uni1E51uni1E52uni1E53uni1E54uni1E55uni1E56uni1E57uni1E58uni1E59uni1E5Auni1E5Buni1E5Cuni1E5Duni1E5Euni1E5Funi1E60uni1E61uni1E62uni1E63uni1E64uni1E65uni1E66uni1E67uni1E68uni1E69uni1E6Auni1E6Buni1E6Cuni1E6Duni1E6Euni1E6Funi1E70uni1E71uni1E72uni1E73uni1E74uni1E75uni1E76uni1E77uni1E78uni1E79uni1E7Auni1E7Buni1E7Cuni1E7Duni1E7Euni1E7FWgravewgraveWacutewacute Wdieresis wdieresisuni1E86uni1E87uni1E88uni1E89uni1E8Auni1E8Buni1E8Cuni1E8Duni1E8Euni1E8Funi1E90uni1E91uni1E92uni1E93uni1E94uni1E95uni1E96uni1E97uni1E98uni1E99uni1E9Auni1E9Buni1EA0uni1EA1uni1EA2uni1EA3uni1EA4uni1EA5uni1EA6uni1EA7uni1EA8uni1EA9uni1EAAuni1EABuni1EACuni1EADuni1EAEuni1EAFuni1EB0uni1EB1uni1EB2uni1EB3uni1EB4uni1EB5uni1EB6uni1EB7uni1EB8uni1EB9uni1EBAuni1EBBuni1EBCuni1EBDuni1EBEuni1EBFuni1EC0uni1EC1uni1EC2uni1EC3uni1EC4uni1EC5uni1EC6uni1EC7uni1EC8uni1EC9uni1ECAuni1ECBuni1ECCuni1ECDuni1ECEuni1ECFuni1ED0uni1ED1uni1ED2uni1ED3uni1ED4uni1ED5uni1ED6uni1ED7uni1ED8uni1ED9uni1EDAuni1EDBuni1EDCuni1EDDuni1EDEuni1EDFuni1EE0uni1EE1uni1EE2uni1EE3uni1EE4uni1EE5uni1EE6uni1EE7uni1EE8uni1EE9uni1EEAuni1EEBuni1EECuni1EEDuni1EEEuni1EEFuni1EF0uni1EF1Ygraveygraveuni1EF4uni1EF5uni1EF6uni1EF7uni1EF8uni1EF9uni1F00uni1F01uni1F02uni1F03uni1F04uni1F05uni1F06uni1F07uni1F08uni1F09uni1F0Auni1F0Buni1F0Cuni1F0Duni1F0Euni1F0Funi1F10uni1F11uni1F12uni1F13uni1F14uni1F15uni1F18uni1F19uni1F1Auni1F1Buni1F1Cuni1F1Duni1F20uni1F21uni1F22uni1F23uni1F24uni1F25uni1F26uni1F27uni1F28uni1F29uni1F2Auni1F2Buni1F2Cuni1F2Duni1F2Euni1F2Funi1F30uni1F31uni1F32uni1F33uni1F34uni1F35uni1F36uni1F37uni1F38uni1F39uni1F3Auni1F3Buni1F3Cuni1F3Duni1F3Euni1F3Funi1F40uni1F41uni1F42uni1F43uni1F44uni1F45uni1F48uni1F49uni1F4Auni1F4Buni1F4Cuni1F4Duni1F50uni1F51uni1F52uni1F53uni1F54uni1F55uni1F56uni1F57uni1F59uni1F5Buni1F5Duni1F5Funi1F60uni1F61uni1F62uni1F63uni1F64uni1F65uni1F66uni1F67uni1F68uni1F69uni1F6Auni1F6Buni1F6Cuni1F6Duni1F6Euni1F6Funi1F70uni1F71uni1F72uni1F73uni1F74uni1F75uni1F76uni1F77uni1F78uni1F79uni1F7Auni1F7Buni1F7Cuni1F7Duni1F80uni1F81uni1F82uni1F83uni1F84uni1F85uni1F86uni1F87uni1F88uni1F89uni1F8Auni1F8Buni1F8Cuni1F8Duni1F8Euni1F8Funi1F90uni1F91uni1F92uni1F93uni1F94uni1F95uni1F96uni1F97uni1F98uni1F99uni1F9Auni1F9Buni1F9Cuni1F9Duni1F9Euni1F9Funi1FA0uni1FA1uni1FA2uni1FA3uni1FA4uni1FA5uni1FA6uni1FA7uni1FA8uni1FA9uni1FAAuni1FABuni1FACuni1FADuni1FAEuni1FAFuni1FB0uni1FB1uni1FB2uni1FB3uni1FB4uni1FB6uni1FB7uni1FB8uni1FB9uni1FBAuni1FBBuni1FBCuni1FBDuni1FBEuni1FBFuni1FC0uni1FC1uni1FC2uni1FC3uni1FC4uni1FC6uni1FC7uni1FC8uni1FC9uni1FCAuni1FCBuni1FCCuni1FCDuni1FCEuni1FCFuni1FD0uni1FD1uni1FD2uni1FD3uni1FD6uni1FD7uni1FD8uni1FD9uni1FDAuni1FDBuni1FDDuni1FDEuni1FDFuni1FE0uni1FE1uni1FE2uni1FE3uni1FE4uni1FE5uni1FE6uni1FE7uni1FE8uni1FE9uni1FEAuni1FEBuni1FECuni1FEDuni1FEEuni1FEFuni1FF2uni1FF3uni1FF4uni1FF6uni1FF7uni1FF8uni1FF9uni1FFAuni1FFBuni1FFCuni1FFDuni1FFEuni2010 afii00208 underscoredbl quotereverseduni201Ftwodotenleaderuni2031minuteseconduni2034uni2035uni2036uni2037 exclamdbluni203Duni203Euni2043uni2045uni2046uni2048uni2049uni204B zerosuperioruni2071uni2072uni2073 foursuperior fivesuperior sixsuperior sevensuperior eightsuperior ninesuperioruni207Auni207Buni207Cparenleftsuperiorparenrightsuperior nsuperior zeroinferior oneinferior twoinferior threeinferior fourinferior fiveinferior sixinferior seveninferior eightinferior nineinferioruni208Auni208Buni208Cparenleftinferiorparenrightinferiorlirapeseta afii57636Eurouni2100uni2101uni2102uni2103 afii61248uni2106uni2107uni210Duni2110Ifrakturuni2112 afii61289uni2114uni2115 afii61352uni2117 weierstrassuni2119uni211Auni211D prescriptionuni2124uni2125uni2126uni2127uni212Auni212Buni2132alephonethird twothirdsuni2155uni2156uni2157uni2158uni2159uni215A oneeighth threeeighths fiveeighths seveneighthsuni215Funi2160uni2161uni2162uni2163uni2164uni2165uni2166uni2167uni2168uni2169uni216Auni216Buni216Cuni216Duni216Euni216F arrowleftarrowup arrowright arrowdown arrowboth arrowupdnuni2196uni2197uni2198uni2199uni219Auni219Buni219Cuni219Duni219Euni219Funi21A0uni21A1uni21A2uni21A3uni21A4uni21A5uni21A6uni21A7 arrowupdnbseuni21A9uni21AAuni21ABuni21ACuni21ADuni21AEuni21AFuni21B0uni21B1uni21B2uni21B3uni21B4carriagereturnuni21B6uni21B7uni21B8uni21B9uni21BAuni21BBuni21BCuni21BDuni21BEuni21BFuni21C0uni21C1uni21C2uni21C3uni21C4uni21C5uni21C6uni21C7uni21C8uni21C9uni21CAuni21CBuni21CCuni21CDuni21CEuni21CF arrowdblleft arrowdblup arrowdblright arrowdbldown arrowdblbothuni21D5 universaluni2201 existentialuni2204emptysetgradientelement notelementuni220Asuchthatuni220Cuni220Duni2213uni2214uni2215uni2219uni221Buni221C proportional orthogonal logicaland logicalor intersectionunionuni222Cuni222Duni222Euni222Funi2230 thereforeuni2235uni2237similaruni223Duni2241uni2242uni2243uni2244 congruentuni2250uni2251uni2252uni2253uni2259uni225A equivalenceuni2266uni2267uni226Auni226Buni226Cuni226Euni226Funi2276uni2277 propersubsetpropersuperset reflexsubsetreflexsuperset circleplusuni2296circlemultiplyuni2298uni2299uni229Auni229Buni229Cuni229Duni22A2uni22A3uni22A4 perpendicularuni22A6uni22A7uni22A8uni22A9uni22AAuni22ABuni22ACuni22ADuni22AEuni22AFuni22BEdotmathuni22C6uni2300houseuni2303uni2308uni2309uni230Auni230Buni230Cuni230Duni230Euni230F revlogicalnotuni2315uni231Cuni231Duni231Euni231F angleleft anglerightuni239Buni239Cuni239Duni239Euni239Funi23A0uni23A1uni23A2uni23A3uni23A4uni23A5uni23A6uni23A7uni23A8uni23A9uni23AAuni23ABuni23ACuni23ADuni23AEuni23AFuni23B0uni23B1uni23B2uni23B3uni23B4uni23B7uni23BAuni23BBuni23BCuni23BDSF100000uni2501SF110000uni2503uni2504uni2505uni2506uni2507uni2508uni2509uni250Auni250BSF010000uni250Duni250Euni250FSF030000uni2511uni2512uni2513SF020000uni2515uni2516uni2517SF040000uni2519uni251Auni251BSF080000uni251Duni251Euni251Funi2520uni2521uni2522uni2523SF090000uni2525uni2526uni2527uni2528uni2529uni252Auni252BSF060000uni252Duni252Euni252Funi2530uni2531uni2532uni2533SF070000uni2535uni2536uni2537uni2538uni2539uni253Auni253BSF050000uni253Duni253Euni253Funi2540uni2541uni2542uni2543uni2544uni2545uni2546uni2547uni2548uni2549uni254Auni254Buni254Cuni254Duni254Euni254FSF430000SF240000SF510000SF520000SF390000SF220000SF210000SF250000SF500000SF490000SF380000SF280000SF270000SF260000SF360000SF370000SF420000SF190000SF200000SF230000SF470000SF480000SF410000SF450000SF460000SF400000SF540000SF530000SF440000uni256Duni256Euni256Funi2570uni2571uni2572uni2573uni2574uni2575uni2576uni2577uni2578uni2579uni257Auni257Buni257Cuni257Duni257Euni257Fupblockuni2581uni2582uni2583dnblockuni2585uni2586uni2587blockuni2589uni258Auni258Blfblockuni258Duni258Euni258Frtblockltshadeshadedkshadeuni2594uni2595uni2596uni2597uni2598uni2599uni259Auni259Buni259Cuni259Duni259Euni259F filledboxH22073uni25A2uni25A3uni25A4uni25A5uni25A6uni25A7uni25A8uni25A9H18543H18551 filledrectuni25ADuni25AEuni25AFuni25B0uni25B1triagupuni25B3uni25B4uni25B5uni25B6uni25B7uni25B8uni25B9triagrtuni25BBtriagdnuni25BDuni25BEuni25BFuni25C0uni25C1uni25C2uni25C3triaglfuni25C5uni25C6uni25C7uni25C8uni25C9circleuni25CCuni25CDuni25CEH18533uni25D0uni25D1uni25D2uni25D3uni25D4uni25D5uni25D6uni25D7 invbullet invcircleuni25DAuni25DBuni25DCuni25DDuni25DEuni25DFuni25E0uni25E1uni25E2uni25E3uni25E4uni25E5 openbulletuni25E7uni25E8uni25E9uni25EAuni25EBuni25ECuni25EDuni25EEuni25EFuni25F0uni25F1uni25F2uni25F3uni25F4uni25F5uni25F6uni25F7uni25F8uni25F9uni25FAuni25FBuni25FCuni25FDuni25FEuni25FFuni2600uni2601uni2602uni2605uni2606uni2607uni2608uni2609uni2610uni2611uni2612uni261Cuni261Euni2626uni2628uni2629uni262Euni2630uni2631uni2632uni2633uni2634uni2635uni2636uni2637uni2639 smileface invsmilefacesununi263Ffemaleuni2641maleuni2669 musicalnotemusicalnotedbluni266Cuni266Duni266Euni266Funi27E6uni27E7uni27E8uni27E9uni27EAuni27EBuni2800uni2801uni2802uni2803uni2804uni2805uni2806uni2807uni2808uni2809uni280Auni280Buni280Cuni280Duni280Euni280Funi2810uni2811uni2812uni2813uni2814uni2815uni2816uni2817uni2818uni2819uni281Auni281Buni281Cuni281Duni281Euni281Funi2820uni2821uni2822uni2823uni2824uni2825uni2826uni2827uni2828uni2829uni282Auni282Buni282Cuni282Duni282Euni282Funi2830uni2831uni2832uni2833uni2834uni2835uni2836uni2837uni2838uni2839uni283Auni283Buni283Cuni283Duni283Euni283Funi2840uni2841uni2842uni2843uni2844uni2845uni2846uni2847uni2848uni2849uni284Auni284Buni284Cuni284Duni284Euni284Funi2850uni2851uni2852uni2853uni2854uni2855uni2856uni2857uni2858uni2859uni285Auni285Buni285Cuni285Duni285Euni285Funi2860uni2861uni2862uni2863uni2864uni2865uni2866uni2867uni2868uni2869uni286Auni286Buni286Cuni286Duni286Euni286Funi2870uni2871uni2872uni2873uni2874uni2875uni2876uni2877uni2878uni2879uni287Auni287Buni287Cuni287Duni287Euni287Funi2880uni2881uni2882uni2883uni2884uni2885uni2886uni2887uni2888uni2889uni288Auni288Buni288Cuni288Duni288Euni288Funi2890uni2891uni2892uni2893uni2894uni2895uni2896uni2897uni2898uni2899uni289Auni289Buni289Cuni289Duni289Euni289Funi28A0uni28A1uni28A2uni28A3uni28A4uni28A5uni28A6uni28A7uni28A8uni28A9uni28AAuni28ABuni28ACuni28ADuni28AEuni28AFuni28B0uni28B1uni28B2uni28B3uni28B4uni28B5uni28B6uni28B7uni28B8uni28B9uni28BAuni28BBuni28BCuni28BDuni28BEuni28BFuni28C0uni28C1uni28C2uni28C3uni28C4uni28C5uni28C6uni28C7uni28C8uni28C9uni28CAuni28CBuni28CCuni28CDuni28CEuni28CFuni28D0uni28D1uni28D2uni28D3uni28D4uni28D5uni28D6uni28D7uni28D8uni28D9uni28DAuni28DBuni28DCuni28DDuni28DEuni28DFuni28E0uni28E1uni28E2uni28E3uni28E4uni28E5uni28E6uni28E7uni28E8uni28E9uni28EAuni28EBuni28ECuni28EDuni28EEuni28EFuni28F0uni28F1uni28F2uni28F3uni28F4uni28F5uni28F6uni28F7uni28F8uni28F9uni28FAuni28FBuni28FCuni28FDuni28FEuni28FF commaaccentffuniFB05uniFB06uniFB1DuniFB1E afii57705uniFB20uniFB21uniFB22uniFB23uniFB24uniFB25uniFB26uniFB27uniFB28uniFB29 afii57694 afii57695uniFB2CuniFB2DuniFB2EuniFB2FuniFB30uniFB31uniFB32uniFB33uniFB34 afii57723uniFB36uniFB38uniFB39uniFB3AuniFB3BuniFB3CuniFB3EuniFB40uniFB41uniFB43uniFB44uniFB46uniFB47uniFB48uniFB49uniFB4A afii57700uniFB4CuniFB4DuniFB4EuniFB4FuniFFFDuni1FEEÿÿ :óôõö Ô Õ Ù Ú      0JhebrlatnÿÿÿÿligaligahR4>Hô- ×O ÖL ÕIõM ÙW ØW,ILVA ørgl/inst/useNULL/0000755000176200001440000000000014146473375013320 5ustar liggesusersrgl/inst/useNULL/README.txt0000644000176200001440000000011714100762640014777 0ustar liggesusersThis directory will contain a version of the rgl DLL that doesn't use OpenGL. rgl/inst/htmlwidgets/0000755000176200001440000000000014146473375014364 5ustar liggesusersrgl/inst/htmlwidgets/rglPlayer.js0000644000176200001440000000450214100762640016646 0ustar liggesusers/* el is the , holding x as el.rglPlayer x is the JSON encoded playwidget. instance holds x as instance.rglPlayer */ HTMLWidgets.widget({ name: 'rglPlayer', type: 'output', initialize: function(el, width, height) { return { }; }, renderValue: function(el, x, instance) { var ShowValue = function(value) { var rgldiv = document.getElementById(x.sceneId), rglinstance; x.value = value; /* We might be running before the scene exists. If so, it will have to apply our initial value. */ if (rgldiv && (rglinstance = rgldiv.rglinstance)) { rglinstance.Player(el, x); x.initialized = true; } else { if (x.initialized) rglwidgetClass.prototype.alertOnce("rgl widget '" + x.sceneId + "' not found."); x.initialized = false; instance.rglPlayer = x; } }; el.rglPlayer = x; instance.rglPlayer = x; if (x.respondTo) { var control = window[x.respondTo]; if (control) { var self = this, i, state = "idle"; /* Store the previous handler on the control, so multiple calls here don't pile up a chain of old handlers */ if (typeof control.rglOldhandler === "undefined") control.rglOldhandler = control.onchange; control.onchange = function() { var value; /* If we are called n>0 times while servicing a previous call, we want to finish the current call, then run again. But the old handler might want to see every change. */ if (state !== "idle") { state = "interrupted"; if (control.rglOldhandler !== null) control.rglOldhandler.call(this); } do { state = "busy"; if (control.rglOldhandler !== null) control.rglOldhandler.call(this); if (control.type == "checkbox") value = control.checked ? 0 : 1; else value = control.value; ShowValue(value); if (state === "busy") state = "idle"; } while (state !== "idle"); }; control.onchange(); } } ShowValue(x.value); }, resize: function(el, width, height, instance) { } }); rgl/inst/htmlwidgets/lib/0000755000176200001440000000000014146473375015132 5ustar liggesusersrgl/inst/htmlwidgets/lib/CanvasMatrix/0000755000176200001440000000000014146473375017532 5ustar liggesusersrgl/inst/htmlwidgets/lib/CanvasMatrix/CanvasMatrix.src.js0000644000176200001440000005322014100762640023242 0ustar liggesusers/* globals CanvasMatrix4: true */ /* globals WebGLFloatArray */ /* jshint eqeqeq: false */ /* * Copyright (C) 2009 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * Copyright (2016) Duncan Murdoch - fixed CanvasMatrix4.ortho, * cleaned up. */ /* CanvasMatrix4 class This class implements a 4x4 matrix. It has functions which duplicate the functionality of the OpenGL matrix stack and glut functions. IDL: [ Constructor(in CanvasMatrix4 matrix), // copy passed matrix into new CanvasMatrix4 Constructor(in sequence array) // create new CanvasMatrix4 with 16 floats (row major) Constructor() // create new CanvasMatrix4 with identity matrix ] interface CanvasMatrix4 { attribute float m11; attribute float m12; attribute float m13; attribute float m14; attribute float m21; attribute float m22; attribute float m23; attribute float m24; attribute float m31; attribute float m32; attribute float m33; attribute float m34; attribute float m41; attribute float m42; attribute float m43; attribute float m44; void load(in CanvasMatrix4 matrix); // copy the values from the passed matrix void load(in sequence array); // copy 16 floats into the matrix sequence getAsArray(); // return the matrix as an array of 16 floats WebGLFloatArray getAsCanvasFloatArray(); // return the matrix as a WebGLFloatArray with 16 values void makeIdentity(); // replace the matrix with identity void transpose(); // replace the matrix with its transpose void invert(); // replace the matrix with its inverse void translate(in float x, in float y, in float z); // multiply the matrix by passed translation values on the right void scale(in float x, in float y, in float z); // multiply the matrix by passed scale values on the right void rotate(in float angle, // multiply the matrix by passed rotation values on the right in float x, in float y, in float z); // (angle is in degrees) void multRight(in CanvasMatrix matrix); // multiply the matrix by the passed matrix on the right void multLeft(in CanvasMatrix matrix); // multiply the matrix by the passed matrix on the left void ortho(in float left, in float right, // multiply the matrix by the passed ortho values on the right in float bottom, in float top, in float near, in float far); void frustum(in float left, in float right, // multiply the matrix by the passed frustum values on the right in float bottom, in float top, in float near, in float far); void perspective(in float fovy, in float aspect, // multiply the matrix by the passed perspective values on the right in float zNear, in float zFar); void lookat(in float eyex, in float eyey, in float eyez, // multiply the matrix by the passed lookat in float ctrx, in float ctry, in float ctrz, // values on the right in float upx, in float upy, in float upz); } */ CanvasMatrix4 = function(m) { if (typeof m == 'object') { if ("length" in m && m.length >= 16) { this.load(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13], m[14], m[15]); return; } else if (m instanceof CanvasMatrix4) { this.load(m); return; } } this.makeIdentity(); }; CanvasMatrix4.prototype.load = function() { if (arguments.length == 1 && typeof arguments[0] == 'object') { var matrix = arguments[0]; if ("length" in matrix && matrix.length == 16) { this.m11 = matrix[0]; this.m12 = matrix[1]; this.m13 = matrix[2]; this.m14 = matrix[3]; this.m21 = matrix[4]; this.m22 = matrix[5]; this.m23 = matrix[6]; this.m24 = matrix[7]; this.m31 = matrix[8]; this.m32 = matrix[9]; this.m33 = matrix[10]; this.m34 = matrix[11]; this.m41 = matrix[12]; this.m42 = matrix[13]; this.m43 = matrix[14]; this.m44 = matrix[15]; return; } if (arguments[0] instanceof CanvasMatrix4) { this.m11 = matrix.m11; this.m12 = matrix.m12; this.m13 = matrix.m13; this.m14 = matrix.m14; this.m21 = matrix.m21; this.m22 = matrix.m22; this.m23 = matrix.m23; this.m24 = matrix.m24; this.m31 = matrix.m31; this.m32 = matrix.m32; this.m33 = matrix.m33; this.m34 = matrix.m34; this.m41 = matrix.m41; this.m42 = matrix.m42; this.m43 = matrix.m43; this.m44 = matrix.m44; return; } } this.makeIdentity(); }; CanvasMatrix4.prototype.getAsArray = function() { return [ this.m11, this.m12, this.m13, this.m14, this.m21, this.m22, this.m23, this.m24, this.m31, this.m32, this.m33, this.m34, this.m41, this.m42, this.m43, this.m44 ]; }; CanvasMatrix4.prototype.getAsWebGLFloatArray = function() { return new WebGLFloatArray(this.getAsArray()); }; CanvasMatrix4.prototype.makeIdentity = function() { this.m11 = 1; this.m12 = 0; this.m13 = 0; this.m14 = 0; this.m21 = 0; this.m22 = 1; this.m23 = 0; this.m24 = 0; this.m31 = 0; this.m32 = 0; this.m33 = 1; this.m34 = 0; this.m41 = 0; this.m42 = 0; this.m43 = 0; this.m44 = 1; }; CanvasMatrix4.prototype.transpose = function() { var tmp = this.m12; this.m12 = this.m21; this.m21 = tmp; tmp = this.m13; this.m13 = this.m31; this.m31 = tmp; tmp = this.m14; this.m14 = this.m41; this.m41 = tmp; tmp = this.m23; this.m23 = this.m32; this.m32 = tmp; tmp = this.m24; this.m24 = this.m42; this.m42 = tmp; tmp = this.m34; this.m34 = this.m43; this.m43 = tmp; }; CanvasMatrix4.prototype.invert = function() { // Calculate the 4x4 determinant // If the determinant is zero, // then the inverse matrix is not unique. var det = this._determinant4x4(); if (Math.abs(det) < 1e-8) return null; this._makeAdjoint(); // Scale the adjoint matrix to get the inverse this.m11 /= det; this.m12 /= det; this.m13 /= det; this.m14 /= det; this.m21 /= det; this.m22 /= det; this.m23 /= det; this.m24 /= det; this.m31 /= det; this.m32 /= det; this.m33 /= det; this.m34 /= det; this.m41 /= det; this.m42 /= det; this.m43 /= det; this.m44 /= det; }; CanvasMatrix4.prototype.translate = function(x,y,z) { if (x === undefined) x = 0; if (y === undefined) y = 0; if (z === undefined) z = 0; var matrix = new CanvasMatrix4(); matrix.m41 = x; matrix.m42 = y; matrix.m43 = z; this.multRight(matrix); }; CanvasMatrix4.prototype.scale = function(x,y,z) { if (x === undefined) x = 1; if (z === undefined) { if (y === undefined) { y = x; z = x; } else z = 1; } else if (y === undefined) y = x; var matrix = new CanvasMatrix4(); matrix.m11 = x; matrix.m22 = y; matrix.m33 = z; this.multRight(matrix); }; CanvasMatrix4.prototype.rotate = function(angle,x,y,z) { // angles are in degrees. Switch to radians angle = angle / 180 * Math.PI; angle /= 2; var sinA = Math.sin(angle); var cosA = Math.cos(angle); var sinA2 = sinA * sinA; // normalize var length = Math.sqrt(x * x + y * y + z * z); if (length === 0) { // bad vector, just use something reasonable x = 0; y = 0; z = 1; } else if (length != 1) { x /= length; y /= length; z /= length; } var mat = new CanvasMatrix4(); // optimize case where axis is along major axis if (x == 1 && y === 0 && z === 0) { mat.m11 = 1; mat.m12 = 0; mat.m13 = 0; mat.m21 = 0; mat.m22 = 1 - 2 * sinA2; mat.m23 = 2 * sinA * cosA; mat.m31 = 0; mat.m32 = -2 * sinA * cosA; mat.m33 = 1 - 2 * sinA2; mat.m14 = mat.m24 = mat.m34 = 0; mat.m41 = mat.m42 = mat.m43 = 0; mat.m44 = 1; } else if (x === 0 && y == 1 && z === 0) { mat.m11 = 1 - 2 * sinA2; mat.m12 = 0; mat.m13 = -2 * sinA * cosA; mat.m21 = 0; mat.m22 = 1; mat.m23 = 0; mat.m31 = 2 * sinA * cosA; mat.m32 = 0; mat.m33 = 1 - 2 * sinA2; mat.m14 = mat.m24 = mat.m34 = 0; mat.m41 = mat.m42 = mat.m43 = 0; mat.m44 = 1; } else if (x === 0 && y === 0 && z == 1) { mat.m11 = 1 - 2 * sinA2; mat.m12 = 2 * sinA * cosA; mat.m13 = 0; mat.m21 = -2 * sinA * cosA; mat.m22 = 1 - 2 * sinA2; mat.m23 = 0; mat.m31 = 0; mat.m32 = 0; mat.m33 = 1; mat.m14 = mat.m24 = mat.m34 = 0; mat.m41 = mat.m42 = mat.m43 = 0; mat.m44 = 1; } else { var x2 = x*x; var y2 = y*y; var z2 = z*z; mat.m11 = 1 - 2 * (y2 + z2) * sinA2; mat.m12 = 2 * (x * y * sinA2 + z * sinA * cosA); mat.m13 = 2 * (x * z * sinA2 - y * sinA * cosA); mat.m21 = 2 * (y * x * sinA2 - z * sinA * cosA); mat.m22 = 1 - 2 * (z2 + x2) * sinA2; mat.m23 = 2 * (y * z * sinA2 + x * sinA * cosA); mat.m31 = 2 * (z * x * sinA2 + y * sinA * cosA); mat.m32 = 2 * (z * y * sinA2 - x * sinA * cosA); mat.m33 = 1 - 2 * (x2 + y2) * sinA2; mat.m14 = mat.m24 = mat.m34 = 0; mat.m41 = mat.m42 = mat.m43 = 0; mat.m44 = 1; } this.multRight(mat); }; CanvasMatrix4.prototype.multRight = function(mat) { var m11 = (this.m11 * mat.m11 + this.m12 * mat.m21 + this.m13 * mat.m31 + this.m14 * mat.m41); var m12 = (this.m11 * mat.m12 + this.m12 * mat.m22 + this.m13 * mat.m32 + this.m14 * mat.m42); var m13 = (this.m11 * mat.m13 + this.m12 * mat.m23 + this.m13 * mat.m33 + this.m14 * mat.m43); var m14 = (this.m11 * mat.m14 + this.m12 * mat.m24 + this.m13 * mat.m34 + this.m14 * mat.m44); var m21 = (this.m21 * mat.m11 + this.m22 * mat.m21 + this.m23 * mat.m31 + this.m24 * mat.m41); var m22 = (this.m21 * mat.m12 + this.m22 * mat.m22 + this.m23 * mat.m32 + this.m24 * mat.m42); var m23 = (this.m21 * mat.m13 + this.m22 * mat.m23 + this.m23 * mat.m33 + this.m24 * mat.m43); var m24 = (this.m21 * mat.m14 + this.m22 * mat.m24 + this.m23 * mat.m34 + this.m24 * mat.m44); var m31 = (this.m31 * mat.m11 + this.m32 * mat.m21 + this.m33 * mat.m31 + this.m34 * mat.m41); var m32 = (this.m31 * mat.m12 + this.m32 * mat.m22 + this.m33 * mat.m32 + this.m34 * mat.m42); var m33 = (this.m31 * mat.m13 + this.m32 * mat.m23 + this.m33 * mat.m33 + this.m34 * mat.m43); var m34 = (this.m31 * mat.m14 + this.m32 * mat.m24 + this.m33 * mat.m34 + this.m34 * mat.m44); var m41 = (this.m41 * mat.m11 + this.m42 * mat.m21 + this.m43 * mat.m31 + this.m44 * mat.m41); var m42 = (this.m41 * mat.m12 + this.m42 * mat.m22 + this.m43 * mat.m32 + this.m44 * mat.m42); var m43 = (this.m41 * mat.m13 + this.m42 * mat.m23 + this.m43 * mat.m33 + this.m44 * mat.m43); var m44 = (this.m41 * mat.m14 + this.m42 * mat.m24 + this.m43 * mat.m34 + this.m44 * mat.m44); this.m11 = m11; this.m12 = m12; this.m13 = m13; this.m14 = m14; this.m21 = m21; this.m22 = m22; this.m23 = m23; this.m24 = m24; this.m31 = m31; this.m32 = m32; this.m33 = m33; this.m34 = m34; this.m41 = m41; this.m42 = m42; this.m43 = m43; this.m44 = m44; }; CanvasMatrix4.prototype.multLeft = function(mat) { var m11 = (mat.m11 * this.m11 + mat.m12 * this.m21 + mat.m13 * this.m31 + mat.m14 * this.m41); var m12 = (mat.m11 * this.m12 + mat.m12 * this.m22 + mat.m13 * this.m32 + mat.m14 * this.m42); var m13 = (mat.m11 * this.m13 + mat.m12 * this.m23 + mat.m13 * this.m33 + mat.m14 * this.m43); var m14 = (mat.m11 * this.m14 + mat.m12 * this.m24 + mat.m13 * this.m34 + mat.m14 * this.m44); var m21 = (mat.m21 * this.m11 + mat.m22 * this.m21 + mat.m23 * this.m31 + mat.m24 * this.m41); var m22 = (mat.m21 * this.m12 + mat.m22 * this.m22 + mat.m23 * this.m32 + mat.m24 * this.m42); var m23 = (mat.m21 * this.m13 + mat.m22 * this.m23 + mat.m23 * this.m33 + mat.m24 * this.m43); var m24 = (mat.m21 * this.m14 + mat.m22 * this.m24 + mat.m23 * this.m34 + mat.m24 * this.m44); var m31 = (mat.m31 * this.m11 + mat.m32 * this.m21 + mat.m33 * this.m31 + mat.m34 * this.m41); var m32 = (mat.m31 * this.m12 + mat.m32 * this.m22 + mat.m33 * this.m32 + mat.m34 * this.m42); var m33 = (mat.m31 * this.m13 + mat.m32 * this.m23 + mat.m33 * this.m33 + mat.m34 * this.m43); var m34 = (mat.m31 * this.m14 + mat.m32 * this.m24 + mat.m33 * this.m34 + mat.m34 * this.m44); var m41 = (mat.m41 * this.m11 + mat.m42 * this.m21 + mat.m43 * this.m31 + mat.m44 * this.m41); var m42 = (mat.m41 * this.m12 + mat.m42 * this.m22 + mat.m43 * this.m32 + mat.m44 * this.m42); var m43 = (mat.m41 * this.m13 + mat.m42 * this.m23 + mat.m43 * this.m33 + mat.m44 * this.m43); var m44 = (mat.m41 * this.m14 + mat.m42 * this.m24 + mat.m43 * this.m34 + mat.m44 * this.m44); this.m11 = m11; this.m12 = m12; this.m13 = m13; this.m14 = m14; this.m21 = m21; this.m22 = m22; this.m23 = m23; this.m24 = m24; this.m31 = m31; this.m32 = m32; this.m33 = m33; this.m34 = m34; this.m41 = m41; this.m42 = m42; this.m43 = m43; this.m44 = m44; }; CanvasMatrix4.prototype.ortho = function(left, right, bottom, top, near, far) { var tx = (left + right) / (left - right); var ty = (top + bottom) / (bottom - top); var tz = (far + near) / (near - far); var matrix = new CanvasMatrix4(); matrix.m11 = 2 / (right - left); matrix.m12 = 0; matrix.m13 = 0; matrix.m14 = 0; matrix.m21 = 0; matrix.m22 = 2 / (top - bottom); matrix.m23 = 0; matrix.m24 = 0; matrix.m31 = 0; matrix.m32 = 0; matrix.m33 = -2 / (far - near); matrix.m34 = 0; matrix.m41 = tx; matrix.m42 = ty; matrix.m43 = tz; matrix.m44 = 1; this.multRight(matrix); }; CanvasMatrix4.prototype.frustum = function(left, right, bottom, top, near, far) { var matrix = new CanvasMatrix4(); var A = (right + left) / (right - left); var B = (top + bottom) / (top - bottom); var C = -(far + near) / (far - near); var D = -(2 * far * near) / (far - near); matrix.m11 = (2 * near) / (right - left); matrix.m12 = 0; matrix.m13 = 0; matrix.m14 = 0; matrix.m21 = 0; matrix.m22 = 2 * near / (top - bottom); matrix.m23 = 0; matrix.m24 = 0; matrix.m31 = A; matrix.m32 = B; matrix.m33 = C; matrix.m34 = -1; matrix.m41 = 0; matrix.m42 = 0; matrix.m43 = D; matrix.m44 = 0; this.multRight(matrix); }; CanvasMatrix4.prototype.perspective = function(fovy, aspect, zNear, zFar) { var top = Math.tan(fovy * Math.PI / 360) * zNear; var bottom = -top; var left = aspect * bottom; var right = aspect * top; this.frustum(left, right, bottom, top, zNear, zFar); }; CanvasMatrix4.prototype.lookat = function(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz) { var matrix = new CanvasMatrix4(), xx, xy, xz; // Make rotation matrix // Z vector var zx = eyex - centerx; var zy = eyey - centery; var zz = eyez - centerz; var mag = Math.sqrt(zx * zx + zy * zy + zz * zz); if (mag) { zx /= mag; zy /= mag; zz /= mag; } // Y vector var yx = upx; var yy = upy; var yz = upz; // X vector = Y cross Z xx = yy * zz - yz * zy; xy = -yx * zz + yz * zx; xz = yx * zy - yy * zx; // Recompute Y = Z cross X yx = zy * xz - zz * xy; yy = -zx * xz + zz * xx; yx = zx * xy - zy * xx; // cross product gives area of parallelogram, which is < 1.0 for // non-perpendicular unit-length vectors; so normalize x, y here mag = Math.sqrt(xx * xx + xy * xy + xz * xz); if (mag) { xx /= mag; xy /= mag; xz /= mag; } mag = Math.sqrt(yx * yx + yy * yy + yz * yz); if (mag) { yx /= mag; yy /= mag; yz /= mag; } matrix.m11 = xx; matrix.m12 = xy; matrix.m13 = xz; matrix.m14 = 0; matrix.m21 = yx; matrix.m22 = yy; matrix.m23 = yz; matrix.m24 = 0; matrix.m31 = zx; matrix.m32 = zy; matrix.m33 = zz; matrix.m34 = 0; matrix.m41 = 0; matrix.m42 = 0; matrix.m43 = 0; matrix.m44 = 1; matrix.translate(-eyex, -eyey, -eyez); this.multRight(matrix); }; // Support functions CanvasMatrix4.prototype._determinant2x2 = function(a, b, c, d) { return a * d - b * c; }; CanvasMatrix4.prototype._determinant3x3 = function(a1, a2, a3, b1, b2, b3, c1, c2, c3) { return a1 * this._determinant2x2(b2, b3, c2, c3) - b1 * this._determinant2x2(a2, a3, c2, c3) + c1 * this._determinant2x2(a2, a3, b2, b3); }; CanvasMatrix4.prototype._determinant4x4 = function() { var a1 = this.m11; var b1 = this.m12; var c1 = this.m13; var d1 = this.m14; var a2 = this.m21; var b2 = this.m22; var c2 = this.m23; var d2 = this.m24; var a3 = this.m31; var b3 = this.m32; var c3 = this.m33; var d3 = this.m34; var a4 = this.m41; var b4 = this.m42; var c4 = this.m43; var d4 = this.m44; return a1 * this._determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4) - b1 * this._determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4) + c1 * this._determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4) - d1 * this._determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4); }; CanvasMatrix4.prototype._makeAdjoint = function() { var a1 = this.m11; var b1 = this.m12; var c1 = this.m13; var d1 = this.m14; var a2 = this.m21; var b2 = this.m22; var c2 = this.m23; var d2 = this.m24; var a3 = this.m31; var b3 = this.m32; var c3 = this.m33; var d3 = this.m34; var a4 = this.m41; var b4 = this.m42; var c4 = this.m43; var d4 = this.m44; // Row column labeling reversed since we transpose rows & columns this.m11 = this._determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4); this.m21 = - this._determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4); this.m31 = this._determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4); this.m41 = - this._determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4); this.m12 = - this._determinant3x3(b1, b3, b4, c1, c3, c4, d1, d3, d4); this.m22 = this._determinant3x3(a1, a3, a4, c1, c3, c4, d1, d3, d4); this.m32 = - this._determinant3x3(a1, a3, a4, b1, b3, b4, d1, d3, d4); this.m42 = this._determinant3x3(a1, a3, a4, b1, b3, b4, c1, c3, c4); this.m13 = this._determinant3x3(b1, b2, b4, c1, c2, c4, d1, d2, d4); this.m23 = - this._determinant3x3(a1, a2, a4, c1, c2, c4, d1, d2, d4); this.m33 = this._determinant3x3(a1, a2, a4, b1, b2, b4, d1, d2, d4); this.m43 = - this._determinant3x3(a1, a2, a4, b1, b2, b4, c1, c2, c4); this.m14 = - this._determinant3x3(b1, b2, b3, c1, c2, c3, d1, d2, d3); this.m24 = this._determinant3x3(a1, a2, a3, c1, c2, c3, d1, d2, d3); this.m34 = - this._determinant3x3(a1, a2, a3, b1, b2, b3, d1, d2, d3); this.m44 = this._determinant3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3); }; rgl/inst/htmlwidgets/lib/CanvasMatrix/CanvasMatrix.min.js0000644000176200001440000002471314146424754023256 0ustar liggesusersCanvasMatrix4=function(m){if("object"==typeof m){if("length"in m&&m.length>=16)return void this.load(m[0],m[1],m[2],m[3],m[4],m[5],m[6],m[7],m[8],m[9],m[10],m[11],m[12],m[13],m[14],m[15]);if(m instanceof CanvasMatrix4)return void this.load(m)}this.makeIdentity()},CanvasMatrix4.prototype.load=function(){if(1==arguments.length&&"object"==typeof arguments[0]){var matrix=arguments[0];if("length"in matrix&&16==matrix.length)return this.m11=matrix[0],this.m12=matrix[1],this.m13=matrix[2],this.m14=matrix[3],this.m21=matrix[4],this.m22=matrix[5],this.m23=matrix[6],this.m24=matrix[7],this.m31=matrix[8],this.m32=matrix[9],this.m33=matrix[10],this.m34=matrix[11],this.m41=matrix[12],this.m42=matrix[13],this.m43=matrix[14],void(this.m44=matrix[15]);if(arguments[0]instanceof CanvasMatrix4)return this.m11=matrix.m11,this.m12=matrix.m12,this.m13=matrix.m13,this.m14=matrix.m14,this.m21=matrix.m21,this.m22=matrix.m22,this.m23=matrix.m23,this.m24=matrix.m24,this.m31=matrix.m31,this.m32=matrix.m32,this.m33=matrix.m33,this.m34=matrix.m34,this.m41=matrix.m41,this.m42=matrix.m42,this.m43=matrix.m43,void(this.m44=matrix.m44)}this.makeIdentity()},CanvasMatrix4.prototype.getAsArray=function(){return[this.m11,this.m12,this.m13,this.m14,this.m21,this.m22,this.m23,this.m24,this.m31,this.m32,this.m33,this.m34,this.m41,this.m42,this.m43,this.m44]},CanvasMatrix4.prototype.getAsWebGLFloatArray=function(){return new WebGLFloatArray(this.getAsArray())},CanvasMatrix4.prototype.makeIdentity=function(){this.m11=1,this.m12=0,this.m13=0,this.m14=0,this.m21=0,this.m22=1,this.m23=0,this.m24=0,this.m31=0,this.m32=0,this.m33=1,this.m34=0,this.m41=0,this.m42=0,this.m43=0,this.m44=1},CanvasMatrix4.prototype.transpose=function(){var tmp=this.m12;this.m12=this.m21,this.m21=tmp,tmp=this.m13,this.m13=this.m31,this.m31=tmp,tmp=this.m14,this.m14=this.m41,this.m41=tmp,tmp=this.m23,this.m23=this.m32,this.m32=tmp,tmp=this.m24,this.m24=this.m42,this.m42=tmp,tmp=this.m34,this.m34=this.m43,this.m43=tmp},CanvasMatrix4.prototype.invert=function(){var det=this._determinant4x4();return Math.abs(det)<1e-8?null:(this._makeAdjoint(),this.m11/=det,this.m12/=det,this.m13/=det,this.m14/=det,this.m21/=det,this.m22/=det,this.m23/=det,this.m24/=det,this.m31/=det,this.m32/=det,this.m33/=det,this.m34/=det,this.m41/=det,this.m42/=det,this.m43/=det,void(this.m44/=det))},CanvasMatrix4.prototype.translate=function(x,y,z){void 0===x&&(x=0),void 0===y&&(y=0),void 0===z&&(z=0);var matrix=new CanvasMatrix4;matrix.m41=x,matrix.m42=y,matrix.m43=z,this.multRight(matrix)},CanvasMatrix4.prototype.scale=function(x,y,z){void 0===x&&(x=1),void 0===z?void 0===y?(y=x,z=x):z=1:void 0===y&&(y=x);var matrix=new CanvasMatrix4;matrix.m11=x,matrix.m22=y,matrix.m33=z,this.multRight(matrix)},CanvasMatrix4.prototype.rotate=function(angle,x,y,z){angle=angle/180*Math.PI,angle/=2;var sinA=Math.sin(angle),cosA=Math.cos(angle),sinA2=sinA*sinA,length=Math.sqrt(x*x+y*y+z*z);0===length?(x=0,y=0,z=1):1!=length&&(x/=length,y/=length,z/=length);var mat=new CanvasMatrix4;if(1==x&&0===y&&0===z)mat.m11=1,mat.m12=0,mat.m13=0,mat.m21=0,mat.m22=1-2*sinA2,mat.m23=2*sinA*cosA,mat.m31=0,mat.m32=-2*sinA*cosA,mat.m33=1-2*sinA2,mat.m14=mat.m24=mat.m34=0,mat.m41=mat.m42=mat.m43=0,mat.m44=1;else if(0===x&&1==y&&0===z)mat.m11=1-2*sinA2,mat.m12=0,mat.m13=-2*sinA*cosA,mat.m21=0,mat.m22=1,mat.m23=0,mat.m31=2*sinA*cosA,mat.m32=0,mat.m33=1-2*sinA2,mat.m14=mat.m24=mat.m34=0,mat.m41=mat.m42=mat.m43=0,mat.m44=1;else if(0===x&&0===y&&1==z)mat.m11=1-2*sinA2,mat.m12=2*sinA*cosA,mat.m13=0,mat.m21=-2*sinA*cosA,mat.m22=1-2*sinA2,mat.m23=0,mat.m31=0,mat.m32=0,mat.m33=1,mat.m14=mat.m24=mat.m34=0,mat.m41=mat.m42=mat.m43=0,mat.m44=1;else{var x2=x*x,y2=y*y,z2=z*z;mat.m11=1-2*(y2+z2)*sinA2,mat.m12=2*(x*y*sinA2+z*sinA*cosA),mat.m13=2*(x*z*sinA2-y*sinA*cosA),mat.m21=2*(y*x*sinA2-z*sinA*cosA),mat.m22=1-2*(z2+x2)*sinA2,mat.m23=2*(y*z*sinA2+x*sinA*cosA),mat.m31=2*(z*x*sinA2+y*sinA*cosA),mat.m32=2*(z*y*sinA2-x*sinA*cosA),mat.m33=1-2*(x2+y2)*sinA2,mat.m14=mat.m24=mat.m34=0,mat.m41=mat.m42=mat.m43=0,mat.m44=1}this.multRight(mat)},CanvasMatrix4.prototype.multRight=function(mat){var m11=this.m11*mat.m11+this.m12*mat.m21+this.m13*mat.m31+this.m14*mat.m41,m12=this.m11*mat.m12+this.m12*mat.m22+this.m13*mat.m32+this.m14*mat.m42,m13=this.m11*mat.m13+this.m12*mat.m23+this.m13*mat.m33+this.m14*mat.m43,m14=this.m11*mat.m14+this.m12*mat.m24+this.m13*mat.m34+this.m14*mat.m44,m21=this.m21*mat.m11+this.m22*mat.m21+this.m23*mat.m31+this.m24*mat.m41,m22=this.m21*mat.m12+this.m22*mat.m22+this.m23*mat.m32+this.m24*mat.m42,m23=this.m21*mat.m13+this.m22*mat.m23+this.m23*mat.m33+this.m24*mat.m43,m24=this.m21*mat.m14+this.m22*mat.m24+this.m23*mat.m34+this.m24*mat.m44,m31=this.m31*mat.m11+this.m32*mat.m21+this.m33*mat.m31+this.m34*mat.m41,m32=this.m31*mat.m12+this.m32*mat.m22+this.m33*mat.m32+this.m34*mat.m42,m33=this.m31*mat.m13+this.m32*mat.m23+this.m33*mat.m33+this.m34*mat.m43,m34=this.m31*mat.m14+this.m32*mat.m24+this.m33*mat.m34+this.m34*mat.m44,m41=this.m41*mat.m11+this.m42*mat.m21+this.m43*mat.m31+this.m44*mat.m41,m42=this.m41*mat.m12+this.m42*mat.m22+this.m43*mat.m32+this.m44*mat.m42,m43=this.m41*mat.m13+this.m42*mat.m23+this.m43*mat.m33+this.m44*mat.m43,m44=this.m41*mat.m14+this.m42*mat.m24+this.m43*mat.m34+this.m44*mat.m44;this.m11=m11,this.m12=m12,this.m13=m13,this.m14=m14,this.m21=m21,this.m22=m22,this.m23=m23,this.m24=m24,this.m31=m31,this.m32=m32,this.m33=m33,this.m34=m34,this.m41=m41,this.m42=m42,this.m43=m43,this.m44=m44},CanvasMatrix4.prototype.multLeft=function(mat){var m11=mat.m11*this.m11+mat.m12*this.m21+mat.m13*this.m31+mat.m14*this.m41,m12=mat.m11*this.m12+mat.m12*this.m22+mat.m13*this.m32+mat.m14*this.m42,m13=mat.m11*this.m13+mat.m12*this.m23+mat.m13*this.m33+mat.m14*this.m43,m14=mat.m11*this.m14+mat.m12*this.m24+mat.m13*this.m34+mat.m14*this.m44,m21=mat.m21*this.m11+mat.m22*this.m21+mat.m23*this.m31+mat.m24*this.m41,m22=mat.m21*this.m12+mat.m22*this.m22+mat.m23*this.m32+mat.m24*this.m42,m23=mat.m21*this.m13+mat.m22*this.m23+mat.m23*this.m33+mat.m24*this.m43,m24=mat.m21*this.m14+mat.m22*this.m24+mat.m23*this.m34+mat.m24*this.m44,m31=mat.m31*this.m11+mat.m32*this.m21+mat.m33*this.m31+mat.m34*this.m41,m32=mat.m31*this.m12+mat.m32*this.m22+mat.m33*this.m32+mat.m34*this.m42,m33=mat.m31*this.m13+mat.m32*this.m23+mat.m33*this.m33+mat.m34*this.m43,m34=mat.m31*this.m14+mat.m32*this.m24+mat.m33*this.m34+mat.m34*this.m44,m41=mat.m41*this.m11+mat.m42*this.m21+mat.m43*this.m31+mat.m44*this.m41,m42=mat.m41*this.m12+mat.m42*this.m22+mat.m43*this.m32+mat.m44*this.m42,m43=mat.m41*this.m13+mat.m42*this.m23+mat.m43*this.m33+mat.m44*this.m43,m44=mat.m41*this.m14+mat.m42*this.m24+mat.m43*this.m34+mat.m44*this.m44;this.m11=m11,this.m12=m12,this.m13=m13,this.m14=m14,this.m21=m21,this.m22=m22,this.m23=m23,this.m24=m24,this.m31=m31,this.m32=m32,this.m33=m33,this.m34=m34,this.m41=m41,this.m42=m42,this.m43=m43,this.m44=m44},CanvasMatrix4.prototype.ortho=function(left,right,bottom,top,near,far){var tx=(left+right)/(left-right),ty=(top+bottom)/(bottom-top),tz=(far+near)/(near-far),matrix=new CanvasMatrix4;matrix.m11=2/(right-left),matrix.m12=0,matrix.m13=0,matrix.m14=0,matrix.m21=0,matrix.m22=2/(top-bottom),matrix.m23=0,matrix.m24=0,matrix.m31=0,matrix.m32=0,matrix.m33=-2/(far-near),matrix.m34=0,matrix.m41=tx,matrix.m42=ty,matrix.m43=tz,matrix.m44=1,this.multRight(matrix)},CanvasMatrix4.prototype.frustum=function(left,right,bottom,top,near,far){var matrix=new CanvasMatrix4,A=(right+left)/(right-left),B=(top+bottom)/(top-bottom),C=-(far+near)/(far-near),D=-(2*far*near)/(far-near);matrix.m11=2*near/(right-left),matrix.m12=0,matrix.m13=0,matrix.m14=0,matrix.m21=0,matrix.m22=2*near/(top-bottom),matrix.m23=0,matrix.m24=0,matrix.m31=A,matrix.m32=B,matrix.m33=C,matrix.m34=-1,matrix.m41=0,matrix.m42=0,matrix.m43=D,matrix.m44=0,this.multRight(matrix)},CanvasMatrix4.prototype.perspective=function(fovy,aspect,zNear,zFar){var top=Math.tan(fovy*Math.PI/360)*zNear,bottom=-top,left=aspect*bottom,right=aspect*top;this.frustum(left,right,bottom,top,zNear,zFar)},CanvasMatrix4.prototype.lookat=function(eyex,eyey,eyez,centerx,centery,centerz,upx,upy,upz){var xx,xy,xz,matrix=new CanvasMatrix4,zx=eyex-centerx,zy=eyey-centery,zz=eyez-centerz,mag=Math.sqrt(zx*zx+zy*zy+zz*zz);mag&&(zx/=mag,zy/=mag,zz/=mag);var yx=upx,yy=upy,yz=upz;xx=yy*zz-yz*zy,xy=-yx*zz+yz*zx,xz=yx*zy-yy*zx,yx=zy*xz-zz*xy,yy=-zx*xz+zz*xx,yx=zx*xy-zy*xx,mag=Math.sqrt(xx*xx+xy*xy+xz*xz),mag&&(xx/=mag,xy/=mag,xz/=mag),mag=Math.sqrt(yx*yx+yy*yy+yz*yz),mag&&(yx/=mag,yy/=mag,yz/=mag),matrix.m11=xx,matrix.m12=xy,matrix.m13=xz,matrix.m14=0,matrix.m21=yx,matrix.m22=yy,matrix.m23=yz,matrix.m24=0,matrix.m31=zx,matrix.m32=zy,matrix.m33=zz,matrix.m34=0,matrix.m41=0,matrix.m42=0,matrix.m43=0,matrix.m44=1,matrix.translate(-eyex,-eyey,-eyez),this.multRight(matrix)},CanvasMatrix4.prototype._determinant2x2=function(a,b,c,d){return a*d-b*c},CanvasMatrix4.prototype._determinant3x3=function(a1,a2,a3,b1,b2,b3,c1,c2,c3){return a1*this._determinant2x2(b2,b3,c2,c3)-b1*this._determinant2x2(a2,a3,c2,c3)+c1*this._determinant2x2(a2,a3,b2,b3)},CanvasMatrix4.prototype._determinant4x4=function(){var a1=this.m11,b1=this.m12,c1=this.m13,d1=this.m14,a2=this.m21,b2=this.m22,c2=this.m23,d2=this.m24,a3=this.m31,b3=this.m32,c3=this.m33,d3=this.m34,a4=this.m41,b4=this.m42,c4=this.m43,d4=this.m44;return a1*this._determinant3x3(b2,b3,b4,c2,c3,c4,d2,d3,d4)-b1*this._determinant3x3(a2,a3,a4,c2,c3,c4,d2,d3,d4)+c1*this._determinant3x3(a2,a3,a4,b2,b3,b4,d2,d3,d4)-d1*this._determinant3x3(a2,a3,a4,b2,b3,b4,c2,c3,c4)},CanvasMatrix4.prototype._makeAdjoint=function(){var a1=this.m11,b1=this.m12,c1=this.m13,d1=this.m14,a2=this.m21,b2=this.m22,c2=this.m23,d2=this.m24,a3=this.m31,b3=this.m32,c3=this.m33,d3=this.m34,a4=this.m41,b4=this.m42,c4=this.m43,d4=this.m44;this.m11=this._determinant3x3(b2,b3,b4,c2,c3,c4,d2,d3,d4),this.m21=-this._determinant3x3(a2,a3,a4,c2,c3,c4,d2,d3,d4),this.m31=this._determinant3x3(a2,a3,a4,b2,b3,b4,d2,d3,d4),this.m41=-this._determinant3x3(a2,a3,a4,b2,b3,b4,c2,c3,c4),this.m12=-this._determinant3x3(b1,b3,b4,c1,c3,c4,d1,d3,d4),this.m22=this._determinant3x3(a1,a3,a4,c1,c3,c4,d1,d3,d4),this.m32=-this._determinant3x3(a1,a3,a4,b1,b3,b4,d1,d3,d4),this.m42=this._determinant3x3(a1,a3,a4,b1,b3,b4,c1,c3,c4),this.m13=this._determinant3x3(b1,b2,b4,c1,c2,c4,d1,d2,d4),this.m23=-this._determinant3x3(a1,a2,a4,c1,c2,c4,d1,d2,d4),this.m33=this._determinant3x3(a1,a2,a4,b1,b2,b4,d1,d2,d4),this.m43=-this._determinant3x3(a1,a2,a4,b1,b2,b4,c1,c2,c4),this.m14=-this._determinant3x3(b1,b2,b3,c1,c2,c3,d1,d2,d3),this.m24=this._determinant3x3(a1,a2,a3,c1,c2,c3,d1,d2,d3),this.m34=-this._determinant3x3(a1,a2,a3,b1,b2,b3,d1,d2,d3),this.m44=this._determinant3x3(a1,a2,a3,b1,b2,b3,c1,c2,c3)}; rgl/inst/htmlwidgets/lib/rglClass/0000755000176200001440000000000014146473375016704 5ustar liggesusersrgl/inst/htmlwidgets/lib/rglClass/shaders.src.js0000644000176200001440000004167214145703475021467 0ustar liggesusers /** * Methods related to shaders * @name ___METHODS_FOR_SHADERS___ * @memberof rglwidgetClass * @kind function * @instance */ /** * Generate the vertex shader for an object * @returns {string} * @param { number } id - Id of object */ rglwidgetClass.prototype.getVertexShader = function(obj) { var userShader = obj.userVertexShader, flags = obj.flags, type = obj.type, is_lit = this.isSet(flags, this.f_is_lit), has_texture = this.isSet(flags, this.f_has_texture), fixed_quads = this.isSet(flags, this.f_fixed_quads), sprites_3d = this.isSet(flags, this.f_sprites_3d), nclipplanes = this.countClipplanes(), fixed_size = this.isSet(flags, this.f_fixed_size), is_points = this.isSet(flags, this.f_is_points), is_twosided = this.isSet(flags, this.f_is_twosided), fat_lines = this.isSet(flags, this.f_fat_lines), is_brush = this.isSet(flags, this.f_is_brush), has_fog = this.isSet(flags, this.f_has_fog), has_normals = (typeof obj.normals !== "undefined") || obj.type === "spheres", needs_vnormal = (is_lit && !fixed_quads && !is_brush) || (is_twosided && has_normals), result; if (type === "clipplanes" || sprites_3d) return; if (typeof userShader !== "undefined") return userShader; result = " /* ****** "+type+" object "+obj.id+" vertex shader ****** */\n"+ "#ifdef GL_ES\n"+ "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"+ " precision highp float;\n"+ "#else\n"+ " precision mediump float;\n"+ "#endif\n"+ "#endif\n"+ " attribute vec3 aPos;\n"+ " attribute vec4 aCol;\n"+ " uniform mat4 mvMatrix;\n"+ " uniform mat4 prMatrix;\n"+ " varying vec4 vCol;\n"+ " varying vec4 vPosition;\n"; if (needs_vnormal) result = result + " attribute vec3 aNorm;\n"+ " uniform mat4 normMatrix;\n"+ " varying vec4 vNormal;\n"; if (has_texture || type === "text") result = result + " attribute vec2 aTexcoord;\n"+ " varying vec2 vTexcoord;\n"; if (fixed_size) result = result + " uniform vec3 textScale;\n"; if (fixed_quads) result = result + " attribute vec3 aOfs;\n"; if (is_twosided) if (has_normals) result = result + " varying float normz;\n"+ " uniform mat4 invPrMatrix;\n"; else result = result + " attribute vec3 aPos1;\n"+ " attribute vec3 aPos2;\n"+ " varying float normz;\n"; if (fat_lines) { result = result + " attribute vec3 aNext;\n"+ " attribute vec2 aPoint;\n"+ " varying vec2 vPoint;\n"+ " varying float vLength;\n"+ " uniform float uAspect;\n"+ " uniform float uLwd;\n"; } result = result + " void main(void) {\n"; if ((nclipplanes || !fixed_quads || has_fog) && !is_brush) result = result + " vPosition = mvMatrix * vec4(aPos, 1.);\n"; if (!fixed_quads && !is_brush) result = result + " gl_Position = prMatrix * vPosition;\n"; if (is_points) { var size = this.getMaterial(obj, "size"); result = result + " gl_PointSize = "+size.toFixed(1)+";\n"; } result = result + " vCol = aCol;\n"; if (needs_vnormal) /* Need to normalize the xyz part */ result = result + " vNormal = normMatrix * vec4(-aNorm, dot(aNorm, aPos));\n"+ " vNormal = vec4(normalize(vNormal.xyz), 1);\n"; if (has_texture || type === "text") result = result + " vTexcoord = aTexcoord;\n"; if (fixed_size) result = result + " vec4 pos = prMatrix * mvMatrix * vec4(aPos, 1.);\n"+ " pos = pos/pos.w;\n"+ " gl_Position = pos + vec4(aOfs*textScale, 0.);\n"; if (type === "sprites" && !fixed_size) result = result + " vec4 pos = mvMatrix * vec4(aPos, 1.);\n"+ " pos = pos/pos.w + vec4(aOfs, 0.);\n"+ " gl_Position = prMatrix*pos;\n"; if (is_twosided) if (has_normals) /* normz should be calculated *after* projection */ result = result + " normz = (invPrMatrix*vNormal).z;\n"; else result = result + " vec4 pos1 = prMatrix*(mvMatrix*vec4(aPos1, 1.));\n"+ " pos1 = pos1/pos1.w - gl_Position/gl_Position.w;\n"+ " vec4 pos2 = prMatrix*(mvMatrix*vec4(aPos2, 1.));\n"+ " pos2 = pos2/pos2.w - gl_Position/gl_Position.w;\n"+ " normz = pos1.x*pos2.y - pos1.y*pos2.x;\n"; if (fat_lines) /* This code was inspired by Matt Deslauriers' code in https://mattdesl.svbtle.com/drawing-lines-is-hard */ result = result + " vec2 aspectVec = vec2(uAspect, 1.0);\n"+ " mat4 projViewModel = prMatrix * mvMatrix;\n"+ " vec4 currentProjected = projViewModel * vec4(aPos, 1.0);\n"+ " currentProjected = currentProjected/currentProjected.w;\n"+ " vec4 nextProjected = projViewModel * vec4(aNext, 1.0);\n"+ " vec2 currentScreen = currentProjected.xy * aspectVec;\n"+ " vec2 nextScreen = (nextProjected.xy / nextProjected.w) * aspectVec;\n"+ " float len = uLwd;\n"+ " vec2 dir = vec2(1.0, 0.0);\n"+ " vPoint = aPoint;\n"+ " vLength = length(nextScreen - currentScreen)/2.0;\n"+ " vLength = vLength/(vLength + len);\n"+ " if (vLength > 0.0) {\n"+ " dir = normalize(nextScreen - currentScreen);\n"+ " }\n"+ " vec2 normal = vec2(-dir.y, dir.x);\n"+ " dir.x /= uAspect;\n"+ " normal.x /= uAspect;\n"+ " vec4 offset = vec4(len*(normal*aPoint.x*aPoint.y - dir), 0.0, 0.0);\n"+ " gl_Position = currentProjected + offset;\n"; if (is_brush) result = result + " gl_Position = vec4(aPos, 1.);\n"; result = result + " }\n"; // console.log(result); return result; }; /** * Generate the fragment shader for an object * @returns {string} * @param { number } id - Id of object */ rglwidgetClass.prototype.getFragmentShader = function(obj) { var userShader = obj.userFragmentShader, flags = obj.flags, type = obj.type, is_lit = this.isSet(flags, this.f_is_lit), has_texture = this.isSet(flags, this.f_has_texture), fixed_quads = this.isSet(flags, this.f_fixed_quads), sprites_3d = this.isSet(flags, this.f_sprites_3d), is_twosided = this.isSet(flags, this.f_is_twosided), fat_lines = this.isSet(flags, this.f_fat_lines), is_transparent = this.isSet(flags, this.f_is_transparent), is_points = this.isSet(flags, this.f_is_points), has_fog = this.isSet(flags, this.f_has_fog), nclipplanes = this.countClipplanes(), i, texture_format, nlights, result; if (type === "clipplanes" || sprites_3d) return; if (typeof userShader !== "undefined") return userShader; if (has_texture) texture_format = this.getMaterial(obj, "textype"); result = "/* ****** "+type+" object "+obj.id+" fragment shader ****** */\n"+ "#ifdef GL_ES\n"+ "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"+ " precision highp float;\n"+ "#else\n"+ " precision mediump float;\n"+ "#endif\n"+ "#endif\n"+ " varying vec4 vCol; // carries alpha\n"+ " varying vec4 vPosition;\n"; if (has_texture || type === "text") result = result + " varying vec2 vTexcoord;\n"+ " uniform sampler2D uSampler;\n"; if (has_fog) result = result + " uniform int uFogMode;\n"+ " uniform vec3 uFogColor;\n"+ " uniform vec4 uFogParms;\n"; if (is_lit && !fixed_quads) result = result + " varying vec4 vNormal;\n"; for (i = 0; i < nclipplanes; i++) result = result + " uniform vec4 vClipplane"+i+";\n"; if (is_lit) { nlights = this.countLights(); if (nlights) result = result + " uniform mat4 mvMatrix;\n"; else is_lit = false; } if (is_lit) { result = result + " uniform vec3 emission;\n"+ " uniform float shininess;\n"; for (i=0; i < nlights; i++) { result = result + " uniform vec3 ambient" + i + ";\n"+ " uniform vec3 specular" + i +"; // light*material\n"+ " uniform vec3 diffuse" + i + ";\n"+ " uniform vec3 lightDir" + i + ";\n"+ " uniform bool viewpoint" + i + ";\n"+ " uniform bool finite" + i + ";\n"; } } if (is_twosided) result = result + " uniform bool front;\n"+ " varying float normz;\n"; if (fat_lines) result = result + " varying vec2 vPoint;\n"+ " varying float vLength;\n"; result = result + " void main(void) {\n"+ " vec4 fragColor;\n"; if (fat_lines) { result = result + " vec2 point = vPoint;\n"+ " bool neg = point.y < 0.0;\n"+ " point.y = neg ? "+ " (point.y + vLength)/(1.0 - vLength) :\n"+ " -(point.y - vLength)/(1.0 - vLength);\n"; if (is_transparent && type === "linestrip") result = result+" if (neg && length(point) <= 1.0) discard;\n"; result = result + " point.y = min(point.y, 0.0);\n"+ " if (length(point) > 1.0) discard;\n"; } if (is_points) { var round = this.getMaterial(obj, "point_antialias"); if (round) result = result + " vec2 coord = gl_PointCoord - vec2(0.5);\n"+ " if (length(coord) > 0.5) discard;\n"; } for (i=0; i < nclipplanes;i++) result = result + " if (dot(vPosition, vClipplane"+i+") < 0.0) discard;\n"; if (fixed_quads) { result = result + " vec3 n = vec3(0., 0., 1.);\n"; } else if (is_lit) { result = result + " vec3 n = normalize(vNormal.xyz);\n"; } if (is_twosided) { result = result + " if ((normz <= 0.) != front) discard;\n"; } if (is_lit) { result = result + " vec3 eye = normalize(-vPosition.xyz);\n"+ " vec3 lightdir;\n"+ " vec4 colDiff;\n"+ " vec3 halfVec;\n"+ " vec4 lighteffect = vec4(emission, 0.);\n"+ " vec3 col;\n"+ " float nDotL;\n"; if (!fixed_quads) { result = result + " n = -faceforward(n, n, eye);\n"; } for (i=0; i < nlights; i++) { result = result + " colDiff = vec4(vCol.rgb * diffuse" + i + ", vCol.a);\n"+ " lightdir = lightDir" + i + ";\n"+ " if (!viewpoint" + i +")\n"+ " lightdir = (mvMatrix * vec4(lightdir, 1.)).xyz;\n"+ " if (!finite" + i + ") {\n"+ " halfVec = normalize(lightdir + eye);\n"+ " } else {\n"+ " lightdir = normalize(lightdir - vPosition.xyz);\n"+ " halfVec = normalize(lightdir + eye);\n"+ " }\n"+ " col = ambient" + i + ";\n"+ " nDotL = dot(n, lightdir);\n"+ " col = col + max(nDotL, 0.) * colDiff.rgb;\n"+ " col = col + pow(max(dot(halfVec, n), 0.), shininess) * specular" + i + ";\n"+ " lighteffect = lighteffect + vec4(col, colDiff.a);\n"; } } else { result = result + " vec4 colDiff = vCol;\n"+ " vec4 lighteffect = colDiff;\n"; } if (type === "text") result = result + " vec4 textureColor = lighteffect*texture2D(uSampler, vTexcoord);\n"; if (has_texture) { result = result + { rgb: " vec4 textureColor = lighteffect*vec4(texture2D(uSampler, vTexcoord).rgb, 1.);\n", rgba: " vec4 textureColor = lighteffect*texture2D(uSampler, vTexcoord);\n", alpha: " vec4 textureColor = texture2D(uSampler, vTexcoord);\n"+ " float luminance = dot(vec3(1.,1.,1.), textureColor.rgb)/3.;\n"+ " textureColor = vec4(lighteffect.rgb, lighteffect.a*luminance);\n", luminance: " vec4 textureColor = vec4(lighteffect.rgb*dot(texture2D(uSampler, vTexcoord).rgb, vec3(1.,1.,1.))/3., lighteffect.a);\n", "luminance.alpha":" vec4 textureColor = texture2D(uSampler, vTexcoord);\n"+ " float luminance = dot(vec3(1.,1.,1.),textureColor.rgb)/3.;\n"+ " textureColor = vec4(lighteffect.rgb*luminance, lighteffect.a*textureColor.a);\n" }[texture_format]+ " fragColor = textureColor;\n"; } else if (type === "text") { result = result + " if (textureColor.a < 0.1)\n"+ " discard;\n"+ " else\n"+ " fragColor = textureColor;\n"; } else result = result + " fragColor = lighteffect;\n"; if (has_fog) { // uFogParms elements: x = near, y = far, z = fogscale, w = (1-sin(FOV/2))/(1+sin(FOV/2)) // In Exp and Exp2: use density = density/far // fogF will be the proportion of fog // Initialize it to the linear value result = result + " float fogF;\n"+ " if (uFogMode > 0) {\n"+ " fogF = (uFogParms.y - vPosition.z/vPosition.w)/(uFogParms.y - uFogParms.x);\n"+ " if (uFogMode > 1)\n"+ " fogF = mix(uFogParms.w, 1.0, fogF);\n"+ " fogF = fogF*uFogParms.z;\n"+ " if (uFogMode == 2)\n"+ " fogF = 1.0 - exp(-fogF);\n"+ // Docs are wrong: use (density*c)^2, not density*c^2 // https://gitlab.freedesktop.org/mesa/mesa/-/blob/master/src/mesa/swrast/s_fog.c#L58 " else if (uFogMode == 3)\n"+ " fogF = 1.0 - exp(-fogF*fogF);\n"+ " fogF = clamp(fogF, 0.0, 1.0);\n"+ " gl_FragColor = vec4(mix(fragColor.rgb, uFogColor, fogF), fragColor.a);\n"+ // " if (fogF < 0.) gl_FragColor = vec4(1.0,0.0,0.0,1.0); else if (fogF < 1.0) gl_FragColor = vec4(mix(fragColor.rgb, uFogColor, fogF), fragColor.a);else gl_FragColor = vec4(0.0,1.0,0.0,1.0);\n"+ " } else gl_FragColor = fragColor;\n"; } else result = result + " gl_FragColor = fragColor;\n"; //if (fat_lines) // result = result + " gl_FragColor = vec4(0.0, abs(point.x), abs(point.y), 1.0);" result = result + " }\n"; // console.log(result); return result; }; /** * Call gl functions to create and compile shader * @returns {Object} * @param { number } shaderType - gl code for shader type * @param { string } code - code for the shader */ rglwidgetClass.prototype.getShader = function(shaderType, code) { var gl = this.gl, shader; shader = gl.createShader(shaderType); gl.shaderSource(shader, code); gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS) && !gl.isContextLost()) alert(gl.getShaderInfoLog(shader)); return shader; }; rgl/inst/htmlwidgets/lib/rglClass/utils.src.js0000644000176200001440000004355014145464133021166 0ustar liggesusers /** * Utility methods * @name ___UTILITY_METHODS___ * @memberof rglwidgetClass * @kind function * @instance */ /** * Multiply matrix by vector * @returns {number[]} * @param M {number[][]} Left operand * @param v {number[]} Right operand */ rglwidgetClass.prototype.multMV = function(M, v) { return [ M.m11 * v[0] + M.m12 * v[1] + M.m13 * v[2] + M.m14 * v[3], M.m21 * v[0] + M.m22 * v[1] + M.m23 * v[2] + M.m24 * v[3], M.m31 * v[0] + M.m32 * v[1] + M.m33 * v[2] + M.m34 * v[3], M.m41 * v[0] + M.m42 * v[1] + M.m43 * v[2] + M.m44 * v[3] ]; }; /** * Multiply row vector by Matrix * @returns {number[]} * @param v {number[]} left operand * @param M {number[][]} right operand */ rglwidgetClass.prototype.multVM = function(v, M) { return [ M.m11 * v[0] + M.m21 * v[1] + M.m31 * v[2] + M.m41 * v[3], M.m12 * v[0] + M.m22 * v[1] + M.m32 * v[2] + M.m42 * v[3], M.m13 * v[0] + M.m23 * v[1] + M.m33 * v[2] + M.m43 * v[3], M.m14 * v[0] + M.m24 * v[1] + M.m34 * v[2] + M.m44 * v[3] ]; }; /** * Euclidean length of a vector * @returns {number} * @param v {number[]} */ rglwidgetClass.prototype.vlen = function(v) { return Math.sqrt(this.dotprod(v, v)); }; /** * Dot product of two vectors * @instance rglwidgetClass * @returns {number} * @param a {number[]} * @param b {number[]} */ rglwidgetClass.prototype.dotprod = function(a, b) { return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; }; /** * Cross product of two vectors * @returns {number[]} * @param a {number[]} * @param b {number[]} */ rglwidgetClass.prototype.xprod = function(a, b) { return [a[1]*b[2] - a[2]*b[1], a[2]*b[0] - a[0]*b[2], a[0]*b[1] - a[1]*b[0]]; }; /** * Bind vectors or matrices by columns * @returns {number[][]} * @param a {number[][]} * @param b {number[]|number[][]} */ rglwidgetClass.prototype.cbind = function(a, b) { if (b.length < a.length) b = this.repeatToLen(b, a.length); else if (a.length < b.length) a = this.repeatToLen(a, b.length); return a.map(function(currentValue, index) { return currentValue.concat(b[index]); }); }; /** * Swap elements * @returns {any[]} * @param a {any[]} * @param i {number} Element to swap * @param j {number} Other element to swap */ rglwidgetClass.prototype.swap = function(a, i, j) { var temp = a[i]; a[i] = a[j]; a[j] = temp; }; /** * Flatten a matrix into a vector * @returns {any[]} * @param a {any[][]} */ rglwidgetClass.prototype.flatten = function(arr, result) { var value; if (typeof result === "undefined") result = []; for (var i = 0, length = arr.length; i < length; i++) { value = arr[i]; if (Array.isArray(value)) { this.flatten(value, result); } else { result.push(value); } } return result; }; /** * set element of 1d or 2d array as if it was flattened. * Column major, zero based! * @returns {any[]|any[][]} * @param {any[]|any[][]} a - array * @param {number} i - element * @param {any} value */ rglwidgetClass.prototype.setElement = function(a, i, value) { if (Array.isArray(a[0])) { var dim = a.length, col = Math.floor(i/dim), row = i % dim; a[row][col] = value; } else { a[i] = value; } }; /** * Transpose an array * @returns {any[][]} * @param {any[][]} a */ rglwidgetClass.prototype.transpose = function(a) { var newArray = [], n = a.length, m = a[0].length, i; for(i = 0; i < m; i++){ newArray.push([]); } for(i = 0; i < n; i++){ for(var j = 0; j < m; j++){ newArray[j].push(a[i][j]); } } return newArray; }; /** * Calculate sum of squares of a numeric vector * @returns {number} * @param {number[]} x */ rglwidgetClass.prototype.sumsq = function(x) { var result = 0, i; for (i=0; i < x.length; i++) result += x[i]*x[i]; return result; }; /** * Convert a matrix to a CanvasMatrix4 * @returns {CanvasMatrix4} * @param {number[][]|number[]} mat */ rglwidgetClass.prototype.toCanvasMatrix4 = function(mat) { if (mat instanceof CanvasMatrix4) return mat; var result = new CanvasMatrix4(); mat = this.flatten(this.transpose(mat)); result.load(mat); return result; }; /** * Convert an R-style numeric colour string to an rgb vector * @returns {number[]} * @param {string} s */ /* jshint bitwise:false */ rglwidgetClass.prototype.stringToRgb = function(s) { s = s.replace("#", ""); var bigint = parseInt(s, 16); return [((bigint >> 16) & 255)/255, ((bigint >> 8) & 255)/255, (bigint & 255)/255]; }; /* jshint bitwise:true */ /** * Which list does a particular id come from? * @returns { string } * @param {number} id The id to look up. */ rglwidgetClass.prototype.whichList = function(id) { var obj = this.getObj(id), flags = obj.flags; if (obj.type === "light") return "lights"; if (this.isSet(flags, this.f_is_subscene)) return "subscenes"; if (this.isSet(flags, this.f_is_clipplanes)) return "clipplanes"; if (this.isSet(flags, this.f_is_transparent)) return "transparent"; return "opaque"; }; /** * Take a component-by-component product of two 3 vectors * @returns {number[]} * @param {number[]} x * @param {number[]} y */ rglwidgetClass.prototype.componentProduct = function(x, y) { if (typeof y === "undefined") { this.alertOnce("Bad arg to componentProduct"); } var result = new Float32Array(3), i; for (i = 0; i<3; i++) result[i] = x[i]*y[i]; return result; }; /** * Get next higher power of two * @returns { number } * @param { number } value - input value */ rglwidgetClass.prototype.getPowerOfTwo = function(value) { var pow = 1; while(pow= -windHeight && rect.left >= -windWidth && rect.bottom <= 2*windHeight && rect.right <= 2*windWidth); }; rglwidgetClass.prototype.keydiff = function(obj1, obj2) { var keys = Object.keys(obj1), i, result = []; for (i=0;i= 2 && cross(lower[lower.length - 2], lower[lower.length - 1], points[i]) <= 0) { lower.pop(); } lower.push(points[i]); } for (i = points.length - 1; i >= 0; i--) { while (upper.length >= 2 && cross(upper[upper.length - 2], upper[upper.length - 1], points[i]) <= 0) { upper.pop(); } upper.push(points[i]); } upper.pop(); lower.pop(); return lower.concat(upper); }; /** * Round number to given precision * @param { number } x * @param { number } digits * @returns { number } */ rglwidgetClass.prototype.signif = function(x, digits) { return parseFloat(x.toPrecision(digits)); }; /** * Check for NA, NaN, undefined, or null * @param x * @returns { bool } */ rglwidgetClass.prototype.missing = function(x) { return x !== "-Inf" && x !== "Inf" && (isNaN(x) || x === null || typeof(x) === "undefined"); }; /** * Write matrix to log * @param M */ rglwidgetClass.prototype.logMatrix = function(M) { console.log("matrix(c("+M.m11+","+M.m12+","+M.m13+","+M.m14+",\n"+ M.m21+","+M.m22+","+M.m23+","+M.m24+",\n"+ M.m31+","+M.m32+","+M.m33+","+M.m34+",\n"+ M.m41+","+M.m42+","+M.m43+","+M.m44+"), byrow=TRUE, ncol=4)"); }; /** * Write vector to log * @param {3 vector} v */ rglwidgetClass.prototype.logVec3 = function(v) { console.log("c("+v[0]+","+v[1]+","+v[2]+")"); }; /** * Sum two vectors * @param {vector} x * @param {vector} y */ rglwidgetClass.prototype.vsum = function(x, y) { var i, result = [].concat(x); for (i = 0; i < y.length; i++) result[i] += y[i]; return result; }; /** * difference of two vectors * @param {vector} x * @param {vector} y */ rglwidgetClass.prototype.vdiff = function(x, y) { return this.vsum(x, this.vscale(y, -1)); }; /** * Scale a vector * @param {number} s * @param {vector} x */ rglwidgetClass.prototype.vscale = function(x, s) { var i, result = [].concat(x); for (i = 0; i < x.length; i++) result[i] *= s; return result; }; /** * Normalize a vector * @param {vector} v */ rglwidgetClass.prototype.normalize = function(v) { return this.vscale(v, 1/this.vlen(v)); }; rgl/inst/htmlwidgets/lib/rglClass/rglClass.min.js0000644000176200001440000035627614146424755021617 0ustar liggesusersrglwidgetClass=function(){this.canvas=null,this.userMatrix=new CanvasMatrix4,this.types=[],this.prMatrix=new CanvasMatrix4,this.mvMatrix=new CanvasMatrix4,this.vp=null,this.prmvMatrix=null,this.origs=null,this.gl=null,this.scene=null,this.select={state:"inactive",subscene:null,region:{p1:{x:0,y:0},p2:{x:0,y:0}}},this.drawing=!1},rglwidgetClass.prototype.f_is_lit=1,rglwidgetClass.prototype.f_is_smooth=2,rglwidgetClass.prototype.f_has_texture=4,rglwidgetClass.prototype.f_depth_sort=8,rglwidgetClass.prototype.f_fixed_quads=16,rglwidgetClass.prototype.f_is_transparent=32,rglwidgetClass.prototype.f_is_lines=64,rglwidgetClass.prototype.f_sprites_3d=128,rglwidgetClass.prototype.f_is_subscene=256,rglwidgetClass.prototype.f_is_clipplanes=512,rglwidgetClass.prototype.f_fixed_size=1024,rglwidgetClass.prototype.f_is_points=2048,rglwidgetClass.prototype.f_is_twosided=4096,rglwidgetClass.prototype.f_fat_lines=8192,rglwidgetClass.prototype.f_is_brush=16384,rglwidgetClass.prototype.f_has_fog=32768,rglwidgetClass.prototype.fogNone=0,rglwidgetClass.prototype.fogLinear=1,rglwidgetClass.prototype.fogExp=2,rglwidgetClass.prototype.fogExp2=3,rglwidgetClass.prototype.start=function(){"undefined"!=typeof this.prefix&&(this.debugelement=document.getElementById(this.prefix+"debug"),this.debug("")),this.drag=0,this.drawScene()},rglwidgetClass.prototype.multMV=function(M,v){return[M.m11*v[0]+M.m12*v[1]+M.m13*v[2]+M.m14*v[3],M.m21*v[0]+M.m22*v[1]+M.m23*v[2]+M.m24*v[3],M.m31*v[0]+M.m32*v[1]+M.m33*v[2]+M.m34*v[3],M.m41*v[0]+M.m42*v[1]+M.m43*v[2]+M.m44*v[3]]},rglwidgetClass.prototype.multVM=function(v,M){return[M.m11*v[0]+M.m21*v[1]+M.m31*v[2]+M.m41*v[3],M.m12*v[0]+M.m22*v[1]+M.m32*v[2]+M.m42*v[3],M.m13*v[0]+M.m23*v[1]+M.m33*v[2]+M.m43*v[3],M.m14*v[0]+M.m24*v[1]+M.m34*v[2]+M.m44*v[3]]},rglwidgetClass.prototype.vlen=function(v){return Math.sqrt(this.dotprod(v,v))},rglwidgetClass.prototype.dotprod=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]},rglwidgetClass.prototype.xprod=function(a,b){return[a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0]]},rglwidgetClass.prototype.cbind=function(a,b){return b.lengthi;i++)value=arr[i],Array.isArray(value)?this.flatten(value,result):result.push(value);return result},rglwidgetClass.prototype.setElement=function(a,i,value){if(Array.isArray(a[0])){var dim=a.length,col=Math.floor(i/dim),row=i%dim;a[row][col]=value}else a[i]=value},rglwidgetClass.prototype.transpose=function(a){var i,newArray=[],n=a.length,m=a[0].length;for(i=0;m>i;i++)newArray.push([]);for(i=0;n>i;i++)for(var j=0;m>j;j++)newArray[j].push(a[i][j]);return newArray},rglwidgetClass.prototype.sumsq=function(x){var i,result=0;for(i=0;i>16&255)/255,(bigint>>8&255)/255,(255&bigint)/255]},rglwidgetClass.prototype.whichList=function(id){var obj=this.getObj(id),flags=obj.flags;return"light"===obj.type?"lights":this.isSet(flags,this.f_is_subscene)?"subscenes":this.isSet(flags,this.f_is_clipplanes)?"clipplanes":this.isSet(flags,this.f_is_transparent)?"transparent":"opaque"},rglwidgetClass.prototype.componentProduct=function(x,y){"undefined"==typeof y&&this.alertOnce("Bad arg to componentProduct");var i,result=new Float32Array(3);for(i=0;3>i;i++)result[i]=x[i]*y[i];return result},rglwidgetClass.prototype.getPowerOfTwo=function(value){for(var pow=1;value>pow;)pow*=2;return pow},rglwidgetClass.prototype.unique=function(arr){return arr=[].concat(arr),arr.filter(function(value,index,self){return self.indexOf(value)===index})},rglwidgetClass.prototype.equalArrays=function(a,b){return a===b||a&&b&&a.length===b.length&&a.every(function(v,i){return v===b[i]})},rglwidgetClass.prototype.repeatToLen=function(arr,len){if(arr=[].concat(arr),!arr.length)throw new RangeError("array is length 0");for(;arr.length=-windHeight&&rect.left>=-windWidth&&rect.bottom<=2*windHeight&&rect.right<=2*windWidth},rglwidgetClass.prototype.keydiff=function(obj1,obj2){var i,keys=Object.keys(obj1),result=[];for(i=0;i=2&&cross(lower[lower.length-2],lower[lower.length-1],points[i])<=0;)lower.pop();lower.push(points[i])}for(i=points.length-1;i>=0;i--){for(;upper.length>=2&&cross(upper[upper.length-2],upper[upper.length-1],points[i])<=0;)upper.pop();upper.push(points[i])}return upper.pop(),lower.pop(),lower.concat(upper)},rglwidgetClass.prototype.signif=function(x,digits){return parseFloat(x.toPrecision(digits))},rglwidgetClass.prototype.missing=function(x){return"-Inf"!==x&&"Inf"!==x&&(isNaN(x)||null===x||"undefined"==typeof x)},rglwidgetClass.prototype.logMatrix=function(M){console.log("matrix(c("+M.m11+","+M.m12+","+M.m13+","+M.m14+",\n"+M.m21+","+M.m22+","+M.m23+","+M.m24+",\n"+M.m31+","+M.m32+","+M.m33+","+M.m34+",\n"+M.m41+","+M.m42+","+M.m43+","+M.m44+"), byrow=TRUE, ncol=4)")},rglwidgetClass.prototype.logVec3=function(v){console.log("c("+v[0]+","+v[1]+","+v[2]+")")},rglwidgetClass.prototype.vsum=function(x,y){var i,result=[].concat(x);for(i=0;i64&&91>nChr?nChr-65:nChr>96&&123>nChr?nChr-71:nChr>47&&58>nChr?nChr+4:43===nChr?62:47===nChr?63:0},rglwidgetClass.prototype.base64DecToArr=function(sBase64,nBlocksSize){for(var nMod3,nMod4,sB64Enc=sBase64.replace(/[^A-Za-z0-9\+\/]/g,""),nInLen=sB64Enc.length,nOutLen=nBlocksSize?Math.ceil((3*nInLen+1>>2)/nBlocksSize)*nBlocksSize:3*nInLen+1>>2,taBytes=new Uint8Array(nOutLen),nUint24=0,nOutIdx=0,nInIdx=0;nInLen>nInIdx;nInIdx++)if(nMod4=3&nInIdx,nUint24|=this.b64ToUint6(sB64Enc.charCodeAt(nInIdx))<<6*(3-nMod4),3===nMod4||nInLen-nInIdx===1){for(nMod3=0;3>nMod3&&nOutLen>nOutIdx;nMod3++,nOutIdx++)taBytes[nOutIdx]=nUint24>>>(16>>>nMod3&24)&255;nUint24=0}return taBytes},rglwidgetClass.prototype.getArrayBuffer=function(base64){return this.base64DecToArr(base64,4).buffer},rglwidgetClass.prototype.getBufferedData=function(v){var bytes,values,row,i,j,k,typeSignedByte=5120,typeUnsignedByte=5121,typeSignedShort=5122,typeUnsignedShort=5123,typeSignedInt=5124,typeUnsignedInt=5125,typeFloat=5126,typeDouble=5130,buf=this.scene.buffer,accessor=buf.accessors[parseInt(v,10)],bufferView=buf.bufferViews[accessor.bufferView],buffer=buf.buffers[bufferView.buffer],lens={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},rowsizes={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:2,MAT3:3,MAT4:4},offset=0,len=lens[accessor.type],rowsize=rowsizes[accessor.type],count=len*accessor.count,nrows=count/rowsize,arr=[];switch("string"==typeof buffer.bytes&&(buffer.bytes=this.getArrayBuffer(buffer.bytes)),bytes=buffer.bytes,"undefined"!=typeof accessor.byteOffset&&(offset+=accessor.byteOffset),"undefined"!=typeof bufferView.byteOffset&&(offset+=bufferView.byteOffset),accessor.componentType){case typeSignedByte:values=new Int8Array(buffer.bytes,offset,count);break;case typeUnsignedByte:values=new Uint8Array(buffer.bytes,offset,count);break;case typeSignedShort:values=new Int16Array(buffer.bytes,offset,count);break;case typeUnsignedShort:values=new Uint16Array(buffer.bytes,offset,count);break;case typeSignedInt:values=new Int32Array(buffer.bytes,offset,count);break;case typeUnsignedInt:values=new Uint32Array(buffer.bytes,offset,count);break;case typeFloat:values=new Float32Array(buffer.bytes,offset,count);break;case typeDouble:values=new Float64Array(buffer.bytes,offset,count)}for(k=0,i=0;nrows>i;i++){for(row=[],j=0;rowsize>j;j++)row.push(values[k++]);arr.push(row)}return arr},rglwidgetClass.prototype.expandBufferedFields=function(obj){var i,field,fields=["vertices","normals","indices","texcoords","colors","centers"];for(i=0;i-1},rglwidgetClass.prototype.translateCoords=function(subsceneid,coords){var viewport=this.getObj(subsceneid).par3d.viewport;return{x:coords.x-viewport.x*this.canvas.width,y:coords.y-viewport.y*this.canvas.height}},rglwidgetClass.prototype.inViewport=function(coords,subsceneid){var viewport=this.getObj(subsceneid).par3d.viewport,x0=coords.x-viewport.x*this.canvas.width,y0=coords.y-viewport.y*this.canvas.height;return x0>=0&&x0<=viewport.width*this.canvas.width&&y0>=0&&y0<=viewport.height*this.canvas.height},rglwidgetClass.prototype.whichSubscene=function(coords){var self=this,recurse=function(subsceneid){var i,id,subscenes=self.getChildSubscenes(subsceneid);for(i=0;i-1&&(thesub.objects.splice(i,1),thelist=this.whichList(id),i=thesub[thelist].indexOf(id),thesub[thelist].splice(i,1))},rglwidgetClass.prototype.setSubsceneEntries=function(ids,subsceneid){var sub=this.getObj(subsceneid);sub.objects=ids,this.initSubscene(subsceneid)},rglwidgetClass.prototype.getSubsceneEntries=function(subscene){return this.getObj(subscene).objects},rglwidgetClass.prototype.getChildSubscenes=function(subscene){return this.getObj(subscene).subscenes},rglwidgetClass.prototype.useid=function(subsceneid,type){var sub=this.getObj(subsceneid);return"inherit"===sub.embeddings[type]?this.useid(sub.parent,type):subsceneid},rglwidgetClass.prototype.getBBoxDeco=function(sub){var i,obj,objects=sub.objects;for(i=0;ii;i++)result=result+" uniform vec4 vClipplane"+i+";\n";if(is_lit&&(nlights=this.countLights(),nlights?result+=" uniform mat4 mvMatrix;\n":is_lit=!1),is_lit)for(result+=" uniform vec3 emission;\n uniform float shininess;\n",i=0;nlights>i;i++)result=result+" uniform vec3 ambient"+i+";\n uniform vec3 specular"+i+"; // light*material\n uniform vec3 diffuse"+i+";\n uniform vec3 lightDir"+i+";\n uniform bool viewpoint"+i+";\n uniform bool finite"+i+";\n";if(is_twosided&&(result+=" uniform bool front;\n varying float normz;\n"),fat_lines&&(result+=" varying vec2 vPoint;\n varying float vLength;\n"),result+=" void main(void) {\n vec4 fragColor;\n",fat_lines&&(result+=" vec2 point = vPoint;\n bool neg = point.y < 0.0;\n point.y = neg ? (point.y + vLength)/(1.0 - vLength) :\n -(point.y - vLength)/(1.0 - vLength);\n",is_transparent&&"linestrip"===type&&(result+=" if (neg && length(point) <= 1.0) discard;\n"),result+=" point.y = min(point.y, 0.0);\n if (length(point) > 1.0) discard;\n"),is_points){var round=this.getMaterial(obj,"point_antialias");round&&(result+=" vec2 coord = gl_PointCoord - vec2(0.5);\n if (length(coord) > 0.5) discard;\n")}for(i=0;nclipplanes>i;i++)result=result+" if (dot(vPosition, vClipplane"+i+") < 0.0) discard;\n";if(fixed_quads?result+=" vec3 n = vec3(0., 0., 1.);\n":is_lit&&(result+=" vec3 n = normalize(vNormal.xyz);\n"),is_twosided&&(result+=" if ((normz <= 0.) != front) discard;\n"),is_lit)for(result+=" vec3 eye = normalize(-vPosition.xyz);\n vec3 lightdir;\n vec4 colDiff;\n vec3 halfVec;\n vec4 lighteffect = vec4(emission, 0.);\n vec3 col;\n float nDotL;\n",fixed_quads||(result+=" n = -faceforward(n, n, eye);\n"),i=0;nlights>i;i++)result=result+" colDiff = vec4(vCol.rgb * diffuse"+i+", vCol.a);\n lightdir = lightDir"+i+";\n if (!viewpoint"+i+")\n lightdir = (mvMatrix * vec4(lightdir, 1.)).xyz;\n if (!finite"+i+") {\n halfVec = normalize(lightdir + eye);\n } else {\n lightdir = normalize(lightdir - vPosition.xyz);\n halfVec = normalize(lightdir + eye);\n }\n col = ambient"+i+";\n nDotL = dot(n, lightdir);\n col = col + max(nDotL, 0.) * colDiff.rgb;\n col = col + pow(max(dot(halfVec, n), 0.), shininess) * specular"+i+";\n lighteffect = lighteffect + vec4(col, colDiff.a);\n";else result+=" vec4 colDiff = vCol;\n vec4 lighteffect = colDiff;\n";return"text"===type&&(result+=" vec4 textureColor = lighteffect*texture2D(uSampler, vTexcoord);\n"),has_texture?result=result+{rgb:" vec4 textureColor = lighteffect*vec4(texture2D(uSampler, vTexcoord).rgb, 1.);\n",rgba:" vec4 textureColor = lighteffect*texture2D(uSampler, vTexcoord);\n",alpha:" vec4 textureColor = texture2D(uSampler, vTexcoord);\n float luminance = dot(vec3(1.,1.,1.), textureColor.rgb)/3.;\n textureColor = vec4(lighteffect.rgb, lighteffect.a*luminance);\n",luminance:" vec4 textureColor = vec4(lighteffect.rgb*dot(texture2D(uSampler, vTexcoord).rgb, vec3(1.,1.,1.))/3., lighteffect.a);\n","luminance.alpha":" vec4 textureColor = texture2D(uSampler, vTexcoord);\n float luminance = dot(vec3(1.,1.,1.),textureColor.rgb)/3.;\n textureColor = vec4(lighteffect.rgb*luminance, lighteffect.a*textureColor.a);\n"}[texture_format]+" fragColor = textureColor;\n":result+="text"===type?" if (textureColor.a < 0.1)\n discard;\n else\n fragColor = textureColor;\n":" fragColor = lighteffect;\n",result+=has_fog?" float fogF;\n if (uFogMode > 0) {\n fogF = (uFogParms.y - vPosition.z/vPosition.w)/(uFogParms.y - uFogParms.x);\n if (uFogMode > 1)\n fogF = mix(uFogParms.w, 1.0, fogF);\n fogF = fogF*uFogParms.z;\n if (uFogMode == 2)\n fogF = 1.0 - exp(-fogF);\n else if (uFogMode == 3)\n fogF = 1.0 - exp(-fogF*fogF);\n fogF = clamp(fogF, 0.0, 1.0);\n gl_FragColor = vec4(mix(fragColor.rgb, uFogColor, fogF), fragColor.a);\n } else gl_FragColor = fragColor;\n":" gl_FragColor = fragColor;\n",result+=" }\n"}},rglwidgetClass.prototype.getShader=function(shaderType,code){var shader,gl=this.gl;return shader=gl.createShader(shaderType),gl.shaderSource(shader,code),gl.compileShader(shader),gl.getShaderParameter(shader,gl.COMPILE_STATUS)||gl.isContextLost()||alert(gl.getShaderInfoLog(shader)),shader},rglwidgetClass.prototype.getTexFilter=function(filter){var gl=this.gl||this.initGL();switch(filter){case"nearest":return gl.NEAREST;case"linear":return gl.LINEAR;case"nearest.mipmap.nearest":return gl.NEAREST_MIPMAP_NEAREST;case"linear.mipmap.nearest":return gl.LINEAR_MIPMAP_NEAREST;case"nearest.mipmap.linear":return gl.NEAREST_MIPMAP_LINEAR;case"linear.mipmap.linear":return gl.LINEAR_MIPMAP_LINEAR;default:console.error("Unknown filter: "+filter)}},rglwidgetClass.prototype.handleLoadedTexture=function(texture,textureCanvas){var gl=this.gl||this.initGL();gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,!0),gl.bindTexture(gl.TEXTURE_2D,texture),gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,textureCanvas),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR_MIPMAP_NEAREST),gl.generateMipmap(gl.TEXTURE_2D),gl.bindTexture(gl.TEXTURE_2D,null)},rglwidgetClass.prototype.getMaxTexSize=function(){var gl=this.gl||this.initGL();return Math.min(4096,gl.getParameter(gl.MAX_TEXTURE_SIZE))},rglwidgetClass.prototype.loadImageToTexture=function(uri,texture){var canvas=this.textureCanvas,ctx=canvas.getContext("2d"),image=new Image,self=this;image.onload=function(){for(var w=image.width,h=image.height,canvasX=self.getPowerOfTwo(w),canvasY=self.getPowerOfTwo(h),maxTexSize=self.getMaxTexSize();canvasX>1&&canvasY>1&&(canvasX>maxTexSize||canvasY>maxTexSize);)canvasX/=2,canvasY/=2;canvas.width=canvasX,canvas.height=canvasY,ctx.imageSmoothingEnabled=!0,ctx.drawImage(image,0,0,canvasX,canvasY),self.handleLoadedTexture(texture,canvas),self.drawScene()},image.src=uri},rglwidgetClass.prototype.drawTextToCanvas=function(text,cex,family,font){var canvasX,canvasY,i,width,offsetx,line,scaling=20,textColour="white",backgroundColour="rgba(0,0,0,0)",canvas=this.textureCanvas,ctx=canvas.getContext("2d"),textHeight=0,textHeights=[],widths=[],offsety=0,lines=[],offsetsx=[],offsetsy=[],lineoffsetsy=[],fontStrings=[],maxTexSize=this.getMaxTexSize(),getFontString=function(i){textHeights[i]=scaling*cex[i];var fontString=textHeights[i]+"px",family0=family[i],font0=font[i];return"sans"===family0?family0="sans-serif":"mono"===family0&&(family0="monospace"),fontString=fontString+" "+family0,(2===font0||4===font0)&&(fontString="bold "+fontString),(3===font0||4===font0)&&(fontString="italic "+fontString),fontString};for(cex=this.repeatToLen(cex,text.length),family=this.repeatToLen(family,text.length),font=this.repeatToLen(font,text.length),canvasX=1,line=-1,offsetx=maxTexSize,i=0;imaxTexSize&&(offsety+=2*textHeight,line>=0&&(lineoffsetsy[line]=offsety),line+=1,offsety>maxTexSize&&console.error("Too many strings for texture."),textHeight=0,offsetx=0),textHeight=Math.max(textHeight,textHeights[i]),offsetsx[i]=offsetx,offsetx+=width,canvasX=Math.max(canvasX,offsetx),lines[i]=line;for(offsety=lineoffsetsy[line]=offsety+2*textHeight,i=0;i=radius&&(radius=1);var hlen,observer=subscene.par3d.observer,distance=observer[2],FOV=subscene.par3d.FOV,ortho=0===FOV,t=ortho?1:Math.tan(FOV*Math.PI/360),near=distance-radius,far=distance+radius,aspect=this.vp.width/this.vp.height,z=subscene.par3d.zoom,userProjection=subscene.par3d.userProjection;0>far&&(far=1),far/100>near&&(near=far/100),this.frustum={near:near,far:far},hlen=t*near,ortho?aspect>1?this.prMatrix.ortho(-hlen*aspect*z,hlen*aspect*z,-hlen*z,hlen*z,near,far):this.prMatrix.ortho(-hlen*z,hlen*z,-hlen*z/aspect,hlen*z/aspect,near,far):aspect>1?this.prMatrix.frustum(-hlen*aspect*z,hlen*aspect*z,-hlen*z,hlen*z,near,far):this.prMatrix.frustum(-hlen*z,hlen*z,-hlen*z/aspect,hlen*z/aspect,near,far),this.prMatrix.multRight(userProjection)}},rglwidgetClass.prototype.setmvMatrix=function(id){var observer=this.getObj(id).par3d.observer;this.mvMatrix.makeIdentity(),this.setmodelMatrix(id),this.mvMatrix.translate(-observer[0],-observer[1],-observer[2])},rglwidgetClass.prototype.setmodelMatrix=function(id){var subscene=this.getObj(id),embedding=subscene.embeddings.model;if("inherit"!==embedding){var scale=subscene.par3d.scale,bbox=subscene.par3d.bbox,center=[(bbox[0]+bbox[1])/2,(bbox[2]+bbox[3])/2,(bbox[4]+bbox[5])/2];this.mvMatrix.translate(-center[0],-center[1],-center[2]),this.mvMatrix.scale(scale[0],scale[1],scale[2]),this.mvMatrix.multRight(subscene.par3d.userMatrix)}"replace"!==embedding&&this.setmodelMatrix(subscene.parent)},rglwidgetClass.prototype.setnormMatrix2=function(){this.normMatrix=new CanvasMatrix4(this.mvMatrix),this.normMatrix.invert(),this.normMatrix.transpose()},rglwidgetClass.prototype.setprmvMatrix=function(){this.prmvMatrix=new CanvasMatrix4(this.mvMatrix),this.prmvMatrix.multRight(this.prMatrix)},rglwidgetClass.prototype.setInvPrMatrix=function(){this.invPrMatrix=new CanvasMatrix4(this.prMatrix),this.invPrMatrix.invert(),this.invPrMatrix.transpose()},rglwidgetClass.prototype.getCursor=function(mode){switch(mode){case"none":return"none";case"trackball":case"xAxis":case"yAxis":case"zAxis":case"polar":return"grab";case"selecting":return"crosshair";case"fov":case"zoom":return"zoom-in";case"user":return"default"}return"dragging"},rglwidgetClass.prototype.setMouseMode=function(mode,button,subscene,stayActive){var sub=this.getObj(subscene),which=["none","left","right","middle","wheel"][button];stayActive||"selecting"!==sub.par3d.mouseMode[which]||this.clearBrush(null),sub.par3d.mouseMode[which]=mode,(1===button||0===button&&"none"!==mode)&&(this.canvas.style.cursor=this.getCursor(mode)),0===button&&"none"!==mode&&(sub.needsBegin=mode) },rglwidgetClass.prototype.relMouseCoords=function(event){var rect=this.canvas.getBoundingClientRect();return{x:event.clientX-rect.left,y:event.clientY-rect.top}},rglwidgetClass.prototype.recordSelection=function(subid){var result={};"undefined"!=typeof this.select&&"undefined"!=typeof this.select.state&&"inactive"!==this.select.state?(result={subscene:subid,state:this.select.state,region:this.select.region},this.setmvMatrix(subid),result.model=this.mvMatrix,this.setprMatrix(subid),result.proj=this.prMatrix,this.getViewport(subid),result.view=this.vp):result.state="inactive",Shiny.setInputValue(this.scene.selectionInput+":shinyMouse3d",result)},rglwidgetClass.prototype.setMouseHandlers=function(){var activeSubscene,handler,self=this,handlers={},drag=0;handlers.rotBase=0,self.screenToVector=function(x,y){var viewport=self.getObj(activeSubscene).par3d.viewport,width=viewport.width*self.canvas.width,height=viewport.height*self.canvas.height,radius=Math.max(width,height)/2,cx=width/2,cy=height/2,px=(x-cx)/radius,py=(y-cy)/radius,plen=Math.sqrt(px*px+py*py);plen>1e-6&&(px/=plen,py/=plen);var angle=(Math.SQRT2-plen)/Math.SQRT2*Math.PI/2,z=Math.sin(angle),zlen=Math.sqrt(1-z*z);return px*=zlen,py*=zlen,[px,py,z]},handlers.trackballdown=function(x,y){var i,activeSub=self.getObj(activeSubscene),activeModel=self.getObj(self.useid(activeSub.id,"model")),l=activeModel.par3d.listeners;for(handlers.rotBase=self.screenToVector(x,y),self.saveMat=[],i=0;ij;j++)changepos[j]=-(dragCurrent[j]-handlers.dragBase[j]);activeSub.par3d.userMatrix.makeIdentity(),activeSub.par3d.userMatrix.rotate(180*changepos[0]/Math.PI,0,-1,0),activeSub.par3d.userMatrix.multRight(objects[l[i]].saveMat),activeSub.par3d.userMatrix.rotate(180*changepos[1]/Math.PI,-1,0,0)}self.drawScene()},handlers.polarend=0,handlers.axisdown=function(x){handlers.rotBase=self.screenToVector(x,self.canvas.height/2);var i,activeSub=self.getObj(activeSubscene),activeModel=self.getObj(self.useid(activeSub.id,"model")),l=activeModel.par3d.listeners;for(i=0;i1){var coords=self.relMouseCoords(touch),new_dist=handlers.get_finger_dist(ev);coords.y=self.canvas.height*Math.log(handlers.finger_dist0/new_dist)+handlers.y0zoom,handlers.zoommove(coords.x,coords.y)}else mouseEvent=new MouseEvent("mousemove",{clientX:touch.clientX,clientY:touch.clientY}),self.dispatchEvent(mouseEvent)},self.canvas.addEventListener("DOMMouseScroll",handlers.wheelHandler,!1),self.canvas.addEventListener("mousewheel",handlers.wheelHandler,!1),self.canvas.addEventListener("touchstart",handlers.touchstart,{passive:!1}),self.canvas.addEventListener("touchend",handlers.touchend,{passive:!1}),self.canvas.addEventListener("touchmove",handlers.touchmove,{passive:!1})},rglwidgetClass.prototype.initGL0=function(){return window.WebGLRenderingContext?void 0:void this.alertOnce("Your browser does not support WebGL. See http://get.webgl.org")},rglwidgetClass.prototype.initGL=function(){var self=this,success=!1;if(this.gl){if(this.drawing||!this.gl.isContextLost())return this.gl;this.restartCanvas()}this.canvas.addEventListener("webglcontextrestored",this.onContextRestored,!1),this.canvas.addEventListener("webglcontextlost",this.onContextLost,!1),this.gl=this.canvas.getContext("webgl",this.webGLoptions)||this.canvas.getContext("experimental-webgl",this.webGLoptions),success=!!(this.gl&&this.gl instanceof WebGLRenderingContext),success||this.alertOnce("Your browser does not support WebGL. See http://get.webgl.org"),this.index_uint=this.gl.getExtension("OES_element_index_uint");var save=this.startDrawing();return Object.keys(this.scene.objects).forEach(function(key){self.initObjId(parseInt(key,10))}),this.stopDrawing(save),this.gl},rglwidgetClass.prototype.resize=function(el){this.canvas.width=el.width,this.canvas.height=el.height},rglwidgetClass.prototype.initSphere=function(sections,segments){var i,j,k,ind,mod1,pole,v=[],phi=[],theta=[],it=[],centers=[],result={};for(i=0;sections-1>i;i++)phi.push((i+1)/sections-.5);for(j=0;segments>j;j++)for(theta.push(2*j/segments),i=0;sections-1>i;i++)v.push([Math.sin(Math.PI*theta[j])*Math.cos(Math.PI*phi[i]),Math.sin(Math.PI*phi[i]),Math.cos(Math.PI*theta[j])*Math.cos(Math.PI*phi[i]),theta[j]/2,phi[i]+.5]);for(pole=v.length,v.push([0,-1,0,0,0]),v.push([0,1,0,0,1]),result.values=new Float32Array(this.flatten(v)),result.vertexCount=v.length,mod1=segments*(sections-1),j=0;segments>j;j++){for(i=0;sections-2>i;i++)ind=i+(sections-1)*j,it.push([ind%mod1,(ind+sections-1)%mod1,(ind+sections)%mod1]),it.push([ind%mod1,(ind+sections)%mod1,(ind+1)%mod1]);it.push([pole,(j+1)*(sections-1)%mod1,((j+1)*(sections-1)-sections+1)%mod1]),it.push([pole+1,((j+1)*(sections-1)-1)%mod1,((j+1)*(sections-1)+sections-2)%mod1])}for(result.it=new Uint16Array(this.flatten(it)),i=0;ij;j++)for(k=0;3>k;k++)centers[i][j]+=v[it[i][k]][j]/3;result.centers=centers,result.vOffsets={vofs:0,cofs:-1,nofs:0,radofs:-1,oofs:-1,tofs:3,nextofs:-1,pointofs:-1,stride:5},result.f=[],result.indices={},result.colorCount=1,result.type="sphere",this.sphere=result,this.initShapeGL(this.sphere)},rglwidgetClass.prototype.initCube=function(){var i,j,k,i0,i1,i2,normal,v=[[0,0,0],[1,0,0],[0,1,0],[1,1,0],[0,0,1],[1,0,1],[0,1,1],[1,1,1]],ib=[[0,2,3,1],[2,6,7,3],[1,3,7,5],[0,4,6,2],[0,1,5,4],[4,5,7,6]],centers=[],result={};for(i=0;ij;j++)for(k=0;4>k;k++)centers[i][j]+=v[ib[i][k]][j]/4;for(result.centers=centers,result.values=new Float32Array(144),result.vertexCount=24,result.vertices=new Array(24),result.normals=new Array(24),i=0;6>i;i++){for(j=0;4>j;j++)for(i0=ib[i][j],result.vertices[4*i+j]=v[i0],i1=ib[i][(j+1)%4],i2=ib[i][(j+2)%4],0===j&&(normal=this.normalize(this.xprod(this.vdiff(v[i1],v[i0]),this.vdiff(v[i2],v[i0])))),result.normals[4*i+j]=normal,k=0;3>k;k++)result.values[24*i+6*j+k]=v[i0][k],result.values[24*i+6*j+3+k]=normal[k];for(j=0;4>j;j++)ib[i][j]=4*i+j}result.ib=new Uint16Array(this.flatten(ib)),result.vOffsets={vofs:0,cofs:-1,nofs:3,radofs:-1,oofs:-1,tofs:-1,nextofs:-1,pointofs:-1,stride:6},result.f=[],result.indices={},result.colorCount=1,result.type="quads",this.cube=result,this.initShapeGL(this.cube)},rglwidgetClass.prototype.initShapeGL=function(shape){var gl=this.gl||this.initGL();gl.isContextLost()||(shape.buf=gl.createBuffer(),gl.bindBuffer(gl.ARRAY_BUFFER,shape.buf),gl.bufferData(gl.ARRAY_BUFFER,shape.values,gl.STATIC_DRAW),shape.ibuf=[gl.createBuffer(),gl.createBuffer()])},rglwidgetClass.prototype.initShapeFromObj=function(shape,obj){var i,pass,f,mode,self=this,is_back=function(i){var normal=shape.normals[i],pt=shape.vertices[i];return normal.push(-self.dotprod(normal,pt)),normal=self.multVM(normal,self.normMatrix),normal[2]<0};if(shape.ofsLoc=obj.ofsLoc,shape.texLoc=obj.texLoc,shape.sampler=obj.sampler,shape.uFogMode=obj.uFogMode,shape.uFogColor=obj.uFogColor,shape.uFogParms=obj.uFogParms,shape.userAttribLocations=obj.userAttribLocations,shape.userUniformLocations=obj.userUniformLocations,shape.normLoc=obj.normLoc,shape.invPrMatLoc=obj.invPrMatLoc,shape.clipLoc=obj.clipLoc,shape.nextLoc=obj.nextLoc,shape.pointLoc=obj.pointLoc,shape.aspectLoc=obj.aspectLoc,shape.lwdLoc=obj.lwdLoc,shape.prog=obj.prog,shape.material=obj.material,shape.flags=obj.flags,shape.someHidden=obj.someHidden,shape.fastTransparency=obj.fastTransparency,shape.nlights=obj.nlights,shape.emission=obj.emission,shape.emissionLoc=obj.emissionLoc,shape.shininess=obj.shininess,shape.shininessLoc=obj.shininessLoc,shape.ambient=obj.ambient,shape.ambientLoc=obj.ambientLoc,shape.specular=obj.specular,shape.specularLoc=obj.specularLoc,shape.diffuse=obj.diffuse,shape.diffuseLoc=obj.diffuseLoc,shape.lightDir=obj.lightDir,shape.lightDirLoc=obj.lightDirLoc,shape.viewpoint=obj.viewpoint,shape.viewpointLoc=obj.viewpointLoc,shape.finite=obj.finite,shape.finiteLoc=obj.finiteLoc,shape.prMatLoc=obj.prMatLoc,shape.mvMatLoc=obj.mvMatLoc,shape.normMatLoc=obj.normMatLoc,shape.frontLoc=obj.frontLoc,shape.index_uint=!1,shape.is_transparent=obj.is_transparent,shape.ignoreExtent=obj.ignoreExtent,shape.passes!==obj.passes||JSON.stringify(shape.pmode)!==JSON.stringify(obj.pmode))for(shape.passes=obj.passes,shape.pmode=obj.pmode,pass=0;pass1?[obj.colors[1]]:[obj.colors[0]],axes:obj.axes,initialized:!1},this.scene.objects[obj.ticks.id]=obj.ticks,obj.labels={id:obj.id+.3,type:"text",flags:this.f_has_fog+this.f_fixed_size+this.f_fixed_quads,material:{lit:!1},colors:obj.colors.length>1?[obj.colors[1]]:[obj.colors[0]],cex:[[1]],family:[["sans"]],font:[[1]],adj:[[.5,.5,.5]],ignoreExtent:!0,initialized:!1},this.scene.objects[obj.labels.id]=obj.labels,obj.initialized=!0},rglwidgetClass.prototype.initObjId=function(id){return"number"!=typeof id&&this.alertOnce("initObj id is "+typeof id),this.initObj(this.getObj(id))},rglwidgetClass.prototype.initObj=function(obj){var polygon_offset,texinfo,drawtype,nclipplanes,f,nrows,oldrows,i,j,v,v1,v2,mat,uri,matobj,pass,pmode,dim,nx,nz,nrow,flags=obj.flags,type=obj.type,is_lit=this.isSet(flags,this.f_is_lit),fat_lines=this.isSet(flags,this.f_fat_lines),has_texture=this.isSet(flags,this.f_has_texture),fixed_quads=this.isSet(flags,this.f_fixed_quads),is_transparent=this.isSet(flags,this.f_is_transparent),depth_sort=this.isSet(flags,this.f_depth_sort),sprites_3d=this.isSet(flags,this.f_sprites_3d),fixed_size=this.isSet(flags,this.f_fixed_size),is_twosided=this.isSet(flags,this.f_is_twosided),is_brush=this.isSet(flags,this.f_is_brush),has_fog=this.isSet(flags,this.f_has_fog),has_normals="undefined"!=typeof obj.normals||"spheres"===obj.type,has_indices="undefined"!=typeof obj.indices,gl=this.gl||this.initGL();if(obj.initialized=!0,obj.someHidden=!1,obj.is_transparent=is_transparent,this.expandBufferedFields(obj),"subscene"!==type){if("bboxdeco"===type)return this.initBBox(obj);if("spheres"===type&&"undefined"==typeof this.sphere&&this.initSphere(16,16),"light"===type)return obj.ambient=new Float32Array(obj.colors[0].slice(0,3)),obj.diffuse=new Float32Array(obj.colors[1].slice(0,3)),obj.specular=new Float32Array(obj.colors[2].slice(0,3)),void(obj.lightDir=new Float32Array(obj.vertices[0]));if("clipplanes"===type)return void(obj.vClipplane=this.flatten(this.cbind(obj.normals,obj.offsets)));if("background"===type&&"undefined"!=typeof obj.ids)return void(obj.quad=this.flatten([].concat(obj.ids)));if(polygon_offset=this.getMaterial(obj,"polygon_offset"),(0!==polygon_offset[0]||0!==polygon_offset[1])&&(obj.polygon_offset=polygon_offset),is_transparent&&(depth_sort=["triangles","quads","surface","spheres","sprites","text"].indexOf(type)>=0),is_brush&&this.initSelection(obj.id),"undefined"==typeof obj.vertices&&(obj.vertices=[]),v=obj.vertices,obj.vertexCount=has_indices?obj.indices.length:v.length,obj.vertexCount){if(is_twosided&&!has_normals){if("undefined"==typeof obj.userAttributes&&(obj.userAttributes={}),v1=Array(v.length),v2=Array(v.length),"triangles"===obj.type||"quads"===obj.type)for(nrow="triangles"===obj.type?3:4,i=0;ij;j++)v1[nrow*i+j]=v[nrow*i+(j+1)%nrow],v2[nrow*i+j]=v[nrow*i+(j+2)%nrow];else if("surface"===obj.type)for(dim=obj.dim[0],nx=dim[0],nz=dim[1],j=0;nx>j;j++)for(i=0;nz>i;i++)nz>i+1&&nx>j+1?(v2[j+nx*i]=v[j+nx*(i+1)],v1[j+nx*i]=v[j+1+nx*(i+1)]):nz>i+1?(v2[j+nx*i]=v[j-1+nx*i],v1[j+nx*i]=v[j+nx*(i+1)]):(v2[j+nx*i]=v[j+nx*(i-1)],v1[j+nx*i]=v[j-1+nx*(i-1)]);obj.userAttributes.aPos1=v1,obj.userAttributes.aPos2=v2}if(!sprites_3d){if(gl.isContextLost())return;"undefined"!=typeof obj.prog&&(gl.deleteProgram(obj.prog),obj.prog=void 0),obj.prog=gl.createProgram(),gl.attachShader(obj.prog,this.getShader(gl.VERTEX_SHADER,this.getVertexShader(obj))),gl.attachShader(obj.prog,this.getShader(gl.FRAGMENT_SHADER,this.getFragmentShader(obj))),gl.bindAttribLocation(obj.prog,0,"aPos"),gl.bindAttribLocation(obj.prog,1,"aCol"),gl.linkProgram(obj.prog);var linked=gl.getProgramParameter(obj.prog,gl.LINK_STATUS);if(!linked){var lastError=gl.getProgramInfoLog(obj.prog);return console.warn("Error in program linking:"+lastError),void gl.deleteProgram(obj.prog)}}"text"===type&&(texinfo=this.drawTextToCanvas(obj.texts,this.flatten(obj.cex),this.flatten(obj.family),this.flatten(obj.family))),fixed_quads&&!sprites_3d&&(obj.ofsLoc=gl.getAttribLocation(obj.prog,"aOfs")),(has_texture||"text"===type)&&(obj.texture||(obj.texture=gl.createTexture(),gl.bindTexture(gl.TEXTURE_2D,obj.texture),gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,1,1,0,gl.RGBA,gl.UNSIGNED_BYTE,new Uint8Array([255,255,255,255]))),obj.texLoc=gl.getAttribLocation(obj.prog,"aTexcoord"),obj.sampler=gl.getUniformLocation(obj.prog,"uSampler")),has_fog&&!sprites_3d&&(obj.uFogMode=gl.getUniformLocation(obj.prog,"uFogMode"),obj.uFogColor=gl.getUniformLocation(obj.prog,"uFogColor"),obj.uFogParms=gl.getUniformLocation(obj.prog,"uFogParms")),has_texture&&(mat=obj.material,"undefined"!=typeof mat.uri?uri=mat.uri:"undefined"==typeof mat.uriElementId?(matobj=this.getObj(mat.uriId),uri="undefined"!=typeof matobj?matobj.material.uri:""):uri=document.getElementById(mat.uriElementId).rglinstance.getObj(mat.uriId).material.uri,this.loadImageToTexture(uri,obj.texture)),"text"===type&&this.handleLoadedTexture(obj.texture,this.textureCanvas);var nc,cofs,nofs,radofs,oofs,tofs,vnew,fnew,alias,colors,key,selection,filter,adj,offset,attr,last,options,stride=3,nextofs=-1,pointofs=-1;if(obj.alias=void 0,colors=obj.colors,j=this.scene.crosstalk.id.indexOf(obj.id),j>=0){for(key=this.scene.crosstalk.key[j],options=this.scene.crosstalk.options[j],colors=colors.slice(0),i=0;i1?(cofs=stride,stride+=4,v=this.cbind(v,colors)):(cofs=-1,obj.onecolor=this.flatten(colors)),has_normals&&"spheres"!==obj.type?(nofs=stride,stride+=3,v=this.cbind(v,"undefined"!=typeof obj.pnormals?obj.pnormals:obj.normals)):nofs=-1,"undefined"!=typeof obj.radii?(radofs=stride,stride+=1,obj.radii.length===v.length?v=this.cbind(v,obj.radii):1===obj.radii.length&&(v=v.map(function(row){return row.concat(obj.radii[0])}))):radofs=-1,has_indices)for(f=Array(obj.indices.length),i=0;ij;j++)v1=vnew[fnew[4*i+j]],v1[tofs+2]=2*(v1[tofs]-v1[tofs+2])*texinfo.widths[i],v1[tofs+3]=2*(v1[tofs+1]-v1[tofs+3])*texinfo.textHeights[i],v1[tofs]=(texinfo.offsetsx[i]+v1[tofs]*texinfo.widths[i])/texinfo.canvasX,v1[tofs+1]=1-(texinfo.offsetsy[i]-v1[tofs+1]*texinfo.textHeights[i])/texinfo.canvasY,vnew[fnew[4*i+j]]=v1;v=vnew,obj.vertexCount=v.length,obj.f=[fnew,fnew]}else"undefined"!=typeof obj.texcoords?(tofs=stride,stride+=2,oofs=-1,v=this.cbind(v,obj.texcoords)):(tofs=-1,oofs=-1);else{tofs=stride,stride+=2,oofs=stride,stride+=3,vnew=new Array(4*v.length),fnew=new Array(4*v.length),alias=new Array(v.length);var rescale=fixed_size?72:1,size=obj.radii,s=rescale*size[0]/2;for(last=v.length,f=obj.f[0],obj.adj=this.flatten(obj.adj),"undefined"!=typeof obj.pos?(obj.pos=this.flatten(obj.pos),offset=obj.adj[0]):offset=0,i=0;i1&&(s=rescale*size[i]/2),adj[0]=2*s*(adj[0]-.5),adj[1]=2*s*(adj[1]-.5),adj[2]=2*s*(adj[2]-.5),vnew[i]=v[i].concat([0,0]).concat([-s-adj[0],-s-adj[1],-adj[2]]),fnew[4*i]=f[i],vnew[last]=v[i].concat([1,0]).concat([s-adj[0],-s-adj[1],-adj[2]]),fnew[4*i+1]=last++,vnew[last]=v[i].concat([1,1]).concat([s-adj[0],s-adj[1],-adj[2]]),fnew[4*i+2]=last++,vnew[last]=v[i].concat([0,1]).concat([-s-adj[0],s-adj[1],-adj[2]]),fnew[4*i+3]=last++,alias[i]=[last-3,last-2,last-1];v=vnew,obj.vertexCount=v.length,obj.f=[fnew,fnew]}if(obj.alias=alias,"undefined"!=typeof obj.userAttributes){obj.userAttribOffsets={},obj.userAttribLocations={},obj.userAttribSizes={};for(attr in obj.userAttributes)obj.userAttribLocations[attr]=gl.getAttribLocation(obj.prog,attr),obj.userAttribLocations[attr]>=0&&(obj.userAttribOffsets[attr]=stride,v=this.cbind(v,obj.userAttributes[attr]),stride=v[0].length,obj.userAttribSizes[attr]=stride-obj.userAttribOffsets[attr])}if("undefined"!=typeof obj.userUniforms){obj.userUniformLocations={};for(attr in obj.userUniforms)obj.userUniformLocations[attr]=gl.getUniformLocation(obj.prog,attr)}if(sprites_3d)for(obj.userMatrix=new CanvasMatrix4,obj.userMatrix.load(this.flatten(obj.usermatrix)),obj.objects=this.flatten([].concat(obj.ids)),is_lit=!1,obj.adj=this.flatten(obj.adj),"undefined"!=typeof obj.pos?(obj.pos=this.flatten(obj.pos),obj.offset=obj.adj[0]):obj.offset=0,i=0;ii;i++)obj.clipLoc[i]=gl.getUniformLocation(obj.prog,"vClipplane"+i);if(is_lit)for(obj.emissionLoc=gl.getUniformLocation(obj.prog,"emission"),obj.emission=new Float32Array(this.stringToRgb(this.getMaterial(obj,"emission"))),obj.shininessLoc=gl.getUniformLocation(obj.prog,"shininess"),obj.shininess=this.getMaterial(obj,"shininess"),obj.nlights=this.countLights(),obj.ambientLoc=[],obj.ambient=new Float32Array(this.stringToRgb(this.getMaterial(obj,"ambient"))),obj.specularLoc=[],obj.specular=new Float32Array(this.stringToRgb(this.getMaterial(obj,"specular"))),obj.diffuseLoc=[],obj.lightDirLoc=[],obj.viewpointLoc=[],obj.finiteLoc=[],i=0;ii;i++)fnew[6*i]=f[3*i],fnew[6*i+1]=f[3*i+1],fnew[6*i+2]=f[3*i+1],fnew[6*i+3]=f[3*i+2],fnew[6*i+4]=f[3*i+2],fnew[6*i+5]=f[3*i]}else if("spheres"===type);else if("surface"===type)if(dim=obj.dim[0],nx=dim[0],nz=dim[1],"filled"===pmode)for(fnew=[],j=0;nx-1>j;j++)for(i=0;nz-1>i;i++)fnew.push(f[j+nx*i],f[j+nx*(i+1)],f[j+1+nx*(i+1)],f[j+nx*i],f[j+1+nx*(i+1)],f[j+1+nx*i]);else if("lines"===pmode)for(fnew=[],j=0;nx>j;j++)for(i=0;nz>i;i++)nz>i+1&&fnew.push(f[j+nx*i],f[j+nx*(i+1)]),nx>j+1&&fnew.push(f[j+nx*i],f[j+1+nx*i])}else if(nrows=Math.floor(obj.vertexCount/4),"filled"===pmode)for(fnew=Array(6*nrows),i=0;nrows>i;i++)fnew[6*i]=f[4*i],fnew[6*i+1]=f[4*i+1],fnew[6*i+2]=f[4*i+2],fnew[6*i+3]=f[4*i],fnew[6*i+4]=f[4*i+2],fnew[6*i+5]=f[4*i+3];else for(fnew=Array(8*nrows),i=0;nrows>i;i++)fnew[8*i]=f[4*i],fnew[8*i+1]=f[4*i+1],fnew[8*i+2]=f[4*i+1],fnew[8*i+3]=f[4*i+2],fnew[8*i+4]=f[4*i+2],fnew[8*i+5]=f[4*i+3],fnew[8*i+6]=f[4*i+3],fnew[8*i+7]=f[4*i];obj.f[pass]=fnew,drawtype=depth_sort?"DYNAMIC_DRAW":"STATIC_DRAW"}if(fat_lines){for(alias=void 0,obj.nextLoc=gl.getAttribLocation(obj.prog,"aNext"),obj.pointLoc=gl.getAttribLocation(obj.prog,"aPoint"),obj.aspectLoc=gl.getUniformLocation(obj.prog,"uAspect"),obj.lwdLoc=gl.getUniformLocation(obj.prog,"uLwd"),pass=0;passj;j++)vnew[k][nextofs+j]=vnew[f[i+1]][j];for(vnew[k][pointofs]=-1,vnew[k][pointofs+1]=-1,fnew[ind]=k,last++,vnew[last]=vnew[k].slice(),vnew[last][pointofs]=1,fnew[ind+1]=last,alias[f[i]].push(last-1,last),last++,k=last,vnew[k]=vnew[f[i+1]].slice(),j=0;3>j;j++)vnew[k][nextofs+j]=vnew[f[i]][j];vnew[k][pointofs]=-1,vnew[k][pointofs+1]=1,fnew[ind+2]=k,fnew[ind+3]=fnew[ind+1],last++,vnew[last]=vnew[k].slice(),vnew[last][pointofs]=1,fnew[ind+4]=last,fnew[ind+5]=fnew[ind+2],ind+=6,alias[f[i+1]].push(last-1,last)}if(vnew.length=last+1,v=vnew,obj.vertexCount=v.length,"undefined"!=typeof alias&&"undefined"!=typeof obj.alias){var oldalias=obj.alias,newalias=Array(obj.alias.length);for(i=0;i65535?this.index_uint?(obj.f[pass]=new Uint32Array(obj.f[pass]),obj.index_uint=!0):this.alertOnce("Object has "+obj.vertexCount+" vertices, not supported in this browser."):(obj.f[pass]=new Uint16Array(obj.f[pass]),obj.index_uint=!1);stride!==v[0].length&&this.alertOnce("problem in stride calculation"),obj.vOffsets={vofs:0,cofs:cofs,nofs:nofs,radofs:radofs,oofs:oofs,tofs:tofs,nextofs:nextofs,pointofs:pointofs,stride:stride},obj.values=new Float32Array(this.flatten(v)),"spheres"===type||sprites_3d||(obj.buf=gl.createBuffer(),gl.bindBuffer(gl.ARRAY_BUFFER,obj.buf),gl.bufferData(gl.ARRAY_BUFFER,obj.values,gl.STATIC_DRAW),obj.ibuf=Array(obj.passes),obj.ibuf[0]=gl.createBuffer(),gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,obj.ibuf[0]),gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,obj.f[0],gl[drawtype]),is_twosided&&(obj.ibuf[1]=gl.createBuffer(),gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,obj.ibuf[1]),gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,obj.f[1],gl[drawtype]))),sprites_3d||(obj.mvMatLoc=gl.getUniformLocation(obj.prog,"mvMatrix"),obj.prMatLoc=gl.getUniformLocation(obj.prog,"prMatrix")),fixed_size&&(obj.textScaleLoc=gl.getUniformLocation(obj.prog,"textScale")),is_lit&&!sprites_3d&&(obj.normMatLoc=gl.getUniformLocation(obj.prog,"normMatrix")),is_twosided&&(obj.frontLoc=gl.getUniformLocation(obj.prog,"front"),has_normals&&(obj.invPrMatLoc=gl.getUniformLocation(obj.prog,"invPrMatrix")))}}},rglwidgetClass.prototype.initialize=function(el,x){if(this.textureCanvas=document.createElement("canvas"),this.textureCanvas.style.display="block",this.scene=x,this.normMatrix=new CanvasMatrix4,this.invPrMatrix=new CanvasMatrix4,this.saveMat={},this.distance=null,this.posLoc=0,this.colLoc=1,el&&(el.rglinstance=this,this.el=el,this.webGLoptions=el.rglinstance.scene.webGLoptions,this.initCanvas()),"undefined"!=typeof Shiny){var self=this;Shiny.addCustomMessageHandler("shinyGetPar3d",function(message){var i,param,subscene=self.getObj(message.subscene),parameters=[].concat(message.parameters),result={tag:message.tag,subscene:message.subscene};if("undefined"!=typeof subscene)for(i=0;ii;i++)z=this.prmvMatrix.m13*obj.centers[i][0]+this.prmvMatrix.m23*obj.centers[i][1]+this.prmvMatrix.m33*obj.centers[i][2]+this.prmvMatrix.m43,w=this.prmvMatrix.m14*obj.centers[i][0]+this.prmvMatrix.m24*obj.centers[i][1]+this.prmvMatrix.m34*obj.centers[i][2]+this.prmvMatrix.m44,depth=z/w,result[i]={context:context,objid:objid,subid:subid,index:i,depth:depth};return result},rglwidgetClass.prototype.getSpherePieces=function(context,subid,obj){return obj.fastTransparency?0===subid?this.getPieces(context,obj.id,-1,obj):[]:this.getPieces(context,obj.id,subid,this.sphere)},rglwidgetClass.prototype.getCubePieces=function(context,obj){return this.getPieces(context,obj.id,0,this.cube)},rglwidgetClass.prototype.mergePieces=function(pieces){var result=[];if(pieces.length>0){var i,thiscontext=pieces[0].context,thisobjid=pieces[0].objid,thissubid=pieces[0].subid,indices=[];for(i=0;i0;)diff=c1.pop()-c2.pop();0===diff&&(diff=j.objid-i.objid),0===diff&&(diff=j.subid-i.subid)}return diff},result=[];return pieces.length&&(result=pieces.sort(compare)),result},rglwidgetClass.prototype.startDrawing=function(){var value=this.drawing;return this.drawing=!0,value},rglwidgetClass.prototype.stopDrawing=function(saved){this.drawing=saved,!saved&&this.gl&&this.gl.isContextLost()&&this.restartCanvas()},rglwidgetClass.prototype.planeUpdateTriangles=function(obj,bbox){var x,xrow,elem,A,d,nhits,i,j,k,u,v,w,intersect,which,v0,v2,vx,reverse,perms=[[0,0,1],[1,2,2],[2,1,0]],face1=[],face2=[],normals=[],nPlanes=obj.normals.length;for(obj.bbox=bbox,obj.vertices=[],obj.initialized=!1,elem=0;nPlanes>elem;elem++){for(x=[],A=obj.normals[elem],d=obj.offsets[elem][0],nhits=0,i=0;3>i;i++)for(j=0;2>j;j++)for(k=0;2>k;k++)u=perms[0][i],v=perms[1][i],w=perms[2][i],0!==A[w]&&(intersect=-(d+A[u]*bbox[j+2*u]+A[v]*bbox[k+2*v])/A[w],bbox[2*w]3)for(i=0;nhits-2>i;i++){for(which=0,j=i+1;nhits>j;j++)if(face1[i]===face1[j]||face1[i]===face2[j]||face2[i]===face1[j]||face2[i]===face2[j]){which=j;break}which>i+1&&(this.swap(x,i+1,which),this.swap(face1,i+1,which),this.swap(face2,i+1,which))}if(nhits>=3)for(v0=[x[0][0]-x[1][0],x[0][1]-x[1][1],x[0][2]-x[1][2]],v2=[x[2][0]-x[1][0],x[2][1]-x[1][1],x[2][2]-x[1][2]],vx=this.xprod(v0,v2),reverse=this.dotprod(vx,A)>0,i=0;nhits-2>i;i++)for(obj.vertices.push(x[0]),normals.push(A),j=1;3>j;j++)obj.vertices.push(x[i+(reverse?3-j:j)]),normals.push(A)}obj.pnormals=normals},rglwidgetClass.prototype.mode4type={points:"POINTS",linestrip:"LINE_STRIP",abclines:"LINES",lines:"LINES",sprites:"TRIANGLES",planes:"TRIANGLES",text:"TRIANGLES",quads:"TRIANGLES",surface:"TRIANGLES",triangles:"TRIANGLES",sphere:"TRIANGLES"},rglwidgetClass.prototype.disableArrays=function(obj,enabled){var i,attr,gl=this.gl||this.initGL(),objLocs=["normLoc","texLoc","ofsLoc","pointLoc","nextLoc"],thisLocs=["posLoc","colLoc"];for(i=0;i=0?(gl.enableVertexAttribArray(obj.normLoc),gl.vertexAttribPointer(obj.normLoc,3,gl.FLOAT,!1,4*obj.vOffsets.stride,4*obj.vOffsets.nofs),!0):!1},rglwidgetClass.prototype.doTexture=function(obj){var gl=this.gl,is_spheres="spheres"===obj.type;return gl.enableVertexAttribArray(obj.texLoc),is_spheres?gl.vertexAttribPointer(obj.texLoc,2,gl.FLOAT,!1,4*this.sphere.vOffsets.stride,4*this.sphere.vOffsets.tofs):gl.vertexAttribPointer(obj.texLoc,2,gl.FLOAT,!1,4*obj.vOffsets.stride,4*obj.vOffsets.tofs),gl.activeTexture(gl.TEXTURE0),gl.bindTexture(gl.TEXTURE_2D,obj.texture),gl.uniform1i(obj.sampler,0),!0},rglwidgetClass.prototype.doUserAttributes=function(obj){if("undefined"!=typeof obj.userAttributes){var gl=this.gl;for(var attr in obj.userAttribSizes)gl.enableVertexAttribArray(obj.userAttribLocations[attr]),gl.vertexAttribPointer(obj.userAttribLocations[attr],obj.userAttribSizes[attr],gl.FLOAT,!1,4*obj.vOffsets.stride,4*obj.userAttribOffsets[attr])}},rglwidgetClass.prototype.doUserUniforms=function(obj){if("undefined"!=typeof obj.userUniforms){var gl=this.gl;for(var attr in obj.userUniformLocations){var loc=obj.userUniformLocations[attr];if(null!==loc){var uniform=obj.userUniforms[attr];if("undefined"==typeof uniform.length)gl.uniform1f(loc,uniform);else if("undefined"==typeof uniform[0].length)switch(uniform=new Float32Array(uniform),uniform.length){case 2:gl.uniform2fv(loc,uniform);break;case 3:gl.uniform3fv(loc,uniform);break;case 4:gl.uniform4fv(loc,uniform);break;default:console.warn("bad uniform length")}else 4===uniform.length&&4===uniform[0].length?gl.uniformMatrix4fv(loc,!1,new Float32Array(uniform.getAsArray())):console.warn("unsupported uniform matrix")}}}},rglwidgetClass.prototype.doLoadIndices=function(obj,pass,indices){var fnew,step,gl=this.gl,f=obj.f[pass],type=obj.type,fat_lines=this.isSet(obj.flags,this.f_fat_lines);switch(type){case"points":step=1;break;case"abclines":case"lines":step=fat_lines?6:2;break;case"linestrip":step=fat_lines?6:1;break;case"sphere":case"planes":case"triangles":step=3;break;case"text":case"sprites":case"quads":case"surface":step=6;break;default:return console.error("loadIndices for "+type),0}fnew=obj.index_uint?new Uint32Array(step*indices.length):new Uint16Array(step*indices.length);for(var i=0;ij;j++)fnew[step*i+j]=f[step*indices[i]+j];return gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,fnew,gl.DYNAMIC_DRAW),fnew.length},rglwidgetClass.prototype.doMasking=function(mask){var gl=this.gl;gl.depthMask(mask)},rglwidgetClass.prototype.doBlending=function(blend){var gl=this.gl;blend?(gl.blendFuncSeparate(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA,gl.ONE,gl.ONE),gl.enable(gl.BLEND)):gl.disable(gl.BLEND)},rglwidgetClass.prototype.doFog=function(obj,subscene){var fogmode,color,gl=this.gl,observer=subscene.par3d.observer[2],sintheta=Math.sin(subscene.par3d.FOV*Math.PI/180/2),parms=[this.frustum.near-2*observer,this.frustum.far-2*observer,this.fogScale,(1-sintheta)/(1+sintheta)];switch("undefined"==typeof this.fogType&&(this.fogType="none"),"undefined"==typeof this.fogScale&&(parms[2]=1),0===sintheta&&(parms[3]=1/3),this.fogType){case"none":fogmode=0;break;case"linear":fogmode=1;break;case"exp":fogmode=2;break;case"exp2":fogmode=3;break;default:console.error("Unknown fogtype "+this.fogType)}gl.uniform1i(obj.uFogMode,fogmode),color=this.fogColor,gl.uniform3f(obj.uFogColor,color[0],color[1],color[2]),gl.uniform4f(obj.uFogParms,parms[0],parms[1],parms[2],parms[3])},rglwidgetClass.prototype.drawSimple=function(obj,subscene,context){var count,pass,mode,pmode,flags=obj.flags,type=obj.type,is_lit=this.isSet(flags,this.f_is_lit),has_texture=this.isSet(flags,this.f_has_texture),is_transparent=this.isSet(flags,this.f_is_transparent),fixed_size=this.isSet(flags,this.f_fixed_size),fixed_quads=this.isSet(flags,this.f_fixed_quads),is_lines=this.isSet(flags,this.f_is_lines),fat_lines=this.isSet(flags,this.f_fat_lines),is_twosided=this.isSet(flags,this.f_is_twosided),has_fog=this.isSet(flags,this.f_has_fog),has_normals="undefined"!=typeof obj.normals||"sphere"===obj.type,gl=this.gl||this.initGL(),enabled={};if(obj.initialized||this.initObj(obj),count=obj.vertexCount,!count)return[];if(is_transparent=is_transparent||obj.someHidden,is_transparent&&this.opaquePass)return this.getPieces(context,obj.id,0,obj);for(this.doDepthTest(obj),this.doMasking(this.getMaterial(obj,"depth_mask")),gl.useProgram(obj.prog),this.doPolygonOffset(obj),gl.bindBuffer(gl.ARRAY_BUFFER,obj.buf),gl.uniformMatrix4fv(obj.prMatLoc,!1,new Float32Array(this.prMatrix.getAsArray())),gl.uniformMatrix4fv(obj.mvMatLoc,!1,new Float32Array(this.mvMatrix.getAsArray())),this.doClipping(obj,subscene),is_lit&&this.doLighting(obj,subscene),has_fog&&this.doFog(obj,subscene),this.doUserAttributes(obj),this.doUserUniforms(obj),gl.enableVertexAttribArray(this.posLoc),enabled.posLoc=!0,(has_texture||"text"===obj.type)&&(enabled.texLoc=this.doTexture(obj)),enabled.colLoc=this.doColors(obj),is_lit&&(enabled.normLoc=this.doNormals(obj)),fixed_size&&gl.uniform3f(obj.textScaleLoc,.75/this.vp.width,.75/this.vp.height,1),fixed_quads&&(gl.enableVertexAttribArray(obj.ofsLoc),enabled.ofsLoc=!0,gl.vertexAttribPointer(obj.ofsLoc,3,gl.FLOAT,!1,4*obj.vOffsets.stride,4*obj.vOffsets.oofs)),pass=0;passi;i++)sphereMV=new CanvasMatrix4,idx=this.opaquePass?i:obj.fastTransparency?indices[i]:context.subid,"undefined"==typeof idx&&console.error("idx is undefined"),baseofs=idx*obj.vOffsets.stride,ofs=baseofs+obj.vOffsets.radofs,sscale=obj.values[ofs],sphereMV.scale(sscale/scale[0],sscale/scale[1],sscale/scale[2]),sphereMV.translate(obj.values[baseofs],obj.values[baseofs+1],obj.values[baseofs+2]),sphereMV.multRight(saveMV),this.mvMatrix=sphereMV,this.setnormMatrix2(),this.setprmvMatrix(),drawing?(nc>1&&(this.sphere.onecolor=obj.values.slice(baseofs+obj.vOffsets.cofs,baseofs+obj.vOffsets.cofs+4)),this.drawSimple(this.sphere,subscene,context)):result=result.concat(this.getSpherePieces(context,i,obj));return drawing&&this.disableArrays(obj,enabled),this.normMatrix=saveNorm,this.mvMatrix=saveMV,this.prmvMatrix=savePRMV,result},rglwidgetClass.prototype.drawClipplanes=function(obj){for(var count=obj.offsets.length,IMVClip=[],i=0;count>i;i++)IMVClip[i]=this.multMV(this.invMatrix,obj.vClipplane.slice(4*i,4*(i+1)));return obj.IMVClip=IMVClip,[]},rglwidgetClass.prototype.drawLinestrip=function(obj,subscene,context){var origIndices,i,j,margin=obj.material.margin;if("undefined"!=typeof margin&&!this.marginVecToDataVec(obj,subscene))return[];if(this.opaquePass)return this.drawSimple(obj,subscene,context);for(origIndices=context.indices.slice(),i=0;iiOrig;iOrig++)for(j=this.opaquePass?iOrig:context.subid,pos=this.multVM([].concat(obj.vertices[j]).concat(1),origMV),radius=obj.radii.length>1?obj.radii[j][0]:obj.radii[0][0],this.mvMatrix=new CanvasMatrix4(userMatrix),adj=this.getAdj(obj,j,offset),this.mvMatrix.translate(1-2*adj[0],1-2*adj[1],1-2*adj[2]),this.mvMatrix.scale(radius),this.mvMatrix.translate(pos[0]/pos[3],pos[1]/pos[3],pos[2]/pos[3]),this.setprmvMatrix(),i=0;i0)for(this.invMatrix=new CanvasMatrix4(this.mvMatrix),this.invMatrix.invert(),i=0;i0;)switch(objid=context.pop(),obj=this.getObj(objid),type=obj.type){case"subscene":this.drawSubscene(objid,!1);break;case"sprites":result=result.concat(context.pop());break;case"spheres":break;case"bboxdeco":result=result.concat(context.pop());break;default:console.error("bad type '",type,"' in setContext")}return result},rglwidgetClass.prototype.drawPieces=function(pieces){var i,context,prevcontext=[];for(this.doBlending(!0),i=0;i=i;i++)adds=adds.concat(control.subsets[i]);else adds=adds.concat(control.subsets[value]);for(deletes=fullset.filter(function(x){return adds.indexOf(x)<0}),i=0;ivalue-svals[j-1]&&(j-=1);break}if(obj=this.getObj(control.objid),"undefined"!=typeof obj.vOffsets){for(varies=!0,k=0;ncol>k;k++)if(attrib=attributes[k],"undefined"!=typeof attrib&&(ofs=obj.vOffsets[ofss[attrib]],0>ofs)){switch(attrib){case"alpha":case"red":case"green":case"blue":obj.colors=[obj.colors[0],obj.colors[0]]}varies=!1}varies||this.initObjId(control.objid)}for(propvals=obj.values,aliases=obj.alias,"undefined"==typeof aliases&&(aliases=[]),k=0;ncol>k;k++)if(newval=direct?value:interp?p*values[j-1][k]+(1-p)*values[j][k]:values[j][k],attrib=attributes[k],vertex=vertices[k],alias=aliases[vertex],("planes"===obj.type||"clipplanes"===obj.type)&&(ofs=["nx","ny","nz","offset"].indexOf(attrib),ofs>=0))3>ofs?obj.normals[vertex][ofs]!==newval&&(obj.normals[vertex][ofs]=newval,obj.initialized=!1):obj.offsets[vertex][0]!==newval&&(obj.offsets[vertex][0]=newval,obj.initialized=!1);else if(ofs=obj.vOffsets[ofss[attrib]],0>ofs)this.alertOnce("Attribute '"+attrib+"' not found in object "+control.objid);else if(stride=obj.vOffsets.stride,ofs+=pos[attrib],entry=vertex*stride+ofs,propvals[entry]=newval,"undefined"!=typeof alias)for(a=0;ai;i++)if(null!==births[i]){for(age=time-births[i],j0=1;age>ages[j0];j0++);p[i]=1/0===ages[j0]?1:ages[j0]>ages[j0-1]?(ages[j0]-age)/(ages[j0]-ages[j0-1]):0,j[i]=j0}for(l=0;nobjs>l;l++)if(objid=objids[l],obj=this.getObj(objid),varies=!0,"undefined"!=typeof obj.vOffsets){for(k=0;kofs)){switch(attribs[k]){case"colors":case"alpha":case"red":case"green":case"blue":obj.colors=[obj.colors[0],obj.colors[0]]}varies=!1}varies||this.initObjId(objid)}for(l=0;nobjs>l;l++)if(objid=objids[l],obj=this.getObj(objid),"undefined"!=typeof obj.vOffsets){for(aliases=obj.alias,"undefined"==typeof aliases&&(aliases=[]),propvals=obj.values,stride=obj.vOffsets.stride,k=0;k=0){for(dim=dims[k],ofs+=pos[k],i=0;steps>i;i++)if(alias=aliases[i],null!==births[i])for(d=0;dim>d;d++)if(propvals[i*stride+ofs+d]=p[i]*attrib[dim*(j[i]-1)+d]+(1-p[i])*attrib[dim*j[i]+d],"undefined"!=typeof alias)for(a=0;a=0){for(keys=this.scene.crosstalk.key[j],obj=this.getObj(id),someHidden=!1,k=0;k=xmin&&xmax>=x&&y>=ymin&&ymax>=y&&z>=-1&&1>=z?selection.push(keys[k]):someHidden=!0);obj.someHidden=someHidden&&(filter||selection.length),obj.initialized=!1,this.equalArrays(selection,this.scene.crosstalk.selection)||(handle=this.scene.crosstalk.sel_handle[j],handle.set(selection,{rglSubsceneId:this.select.subscene}))}},rglwidgetClass.prototype.selection=function(event,filter){var i,j,ids,obj,keys,selection,someHidden,crosstalk=this.scene.crosstalk;for(crosstalk=this.scene.crosstalk,filter?(filter=crosstalk.filter=event.value,selection=crosstalk.selection):(selection=crosstalk.selection=event.value,filter=crosstalk.filter),ids=crosstalk.id,i=0;ithis.stopTime+this.stepSize/2||this.value=1.5*h+.5)?1/(1+h):1.5/(1+h5),i_small=dx10&&(cell=9+cell/10),cell*=shrink_sml,min_n>1&&(cell/=min_n)):(cell=dx,ndiv>1&&(cell/=ndiv)),20*DBL_MIN>cell?cell=20*DBL_MIN:10*cell>DBL_MAX&&(cell=.1*DBL_MAX),base=Math.pow(10,Math.floor(Math.log10(cell))),unit=base,(U=2*base)-cell1||!i_small)&&(0!==lo?lo*=1-DBL_EPSILON:lo=-DBL_MIN,0!==up?up*=1+DBL_EPSILON:up=+DBL_MIN);ns*unit>lo+rounding_eps*unit;)ns--;for(;up-rounding_eps*unit>nu*unit;)nu++;return k=Math.floor(.5+nu-ns),min_n>k?(k=min_n-k,ns>=0?(nu+=k/2,ns-=k/2+k%2):(ns-=k/2,nu+=k/2+k%2),ndiv=min_n):ndiv=k,return_bounds?(lo>ns*unit&&(lo=ns*unit),nu*unit>up&&(up=nu*unit)):(lo=ns,up=nu),{lo:lo,up:up,ndiv:ndiv,unit:unit}},rglwidgetClass.prototype.getTickEdges=function(prmv){var dim,i,j,k,edges,hull,step,vertices=[[0,0,0,1],[0,0,1,1],[0,1,0,1],[0,1,1,1],[1,0,0,1],[1,0,1,1],[1,1,0,1],[1,1,1,1]],result=[],proj=[];for(i=0;idim;dim++){for(edges=[],step=Math.pow(2,2-dim),i=0;4>i;i++)for(j=0===dim?i:1===dim?i+2*(i>1):2*i,k=0;knewval&&(best=j,best2=edges[i][1],val=newval);"undefined"!=typeof best?(result[dim]=vertices[best].slice(0,3),result[dim][dim]=void 0):result[dim]=void 0}}return result},rglwidgetClass.prototype.getTickLocations=function(obj){var dim,i,limits,value,len,delta,range,locations=[],result=[[],[],[]],bbox=obj.bbox;for(obj.needsAxisCallback=!1,dim=0;3>dim;dim++)switch(limits=bbox.slice(2*dim,2*dim+2),range=limits[1]-limits[0],obj.axes.mode[dim]){case"custom":for(i=0;ii;i++)result[dim].push(i*delta);break;case"fixednum":for(len=obj.axes.nticks[dim],delta=len>1?range/(len-1):0,i=0;len>i;i++)result[dim].push(i*delta/range);break;case"pretty":for(locations=this.R_pretty(limits[0],limits[1],5,2,.75,[1.5,2.75],0,0),i=locations.lo;i<=locations.up;i++)value=(i*locations.unit-limits[0])/range,value>0&&1>value&&result[dim].push(value);break;case"user":obj.needsAxisCallback=!0}return result},rglwidgetClass.prototype.getTickVertices=function(ticks){var dim,i,j,locations,edge,vertices=[],edges=ticks.edges;for(dim=0;3>dim;dim++)if(locations=ticks.locations[dim],locations.length)for(i=0;ij;j++)(2>dim&&j===1-dim||2===dim&&0===j)&&(edge[j]+=2*(edge[j]-.5)/ticks.axes.marklen[dim]);vertices.push(edge)}ticks.vertices=vertices,ticks.vertexCount=vertices.length,ticks.values=new Float32Array(this.flatten(vertices)),ticks.initialized=!1},rglwidgetClass.prototype.placeTickLabels=function(obj){var i,j,k,vertex,locations,dim,ticks=obj.ticks,labels=obj.labels,vertices=[],tickvertices=ticks.vertices,edges=obj.ticks.edges;for(j=0,dim=0;3>dim;dim++)if("undefined"!=typeof edges[dim]&&(locations=ticks.locations[dim],locations.length))for(i=0;i=tickvertices.length)break;for(vertex=tickvertices[j].slice(),k=0;3>k;k++)vertex[k]+=2*(tickvertices[j+1][k]-vertex[k]);vertices.push(vertex),j+=2}labels.vertices=vertices,labels.centers=labels.vertices,labels.initialized=!1},rglwidgetClass.prototype.setTickLabels=function(obj){var mode,locations,nticks,dim,i,limits,range,values,max,ticks=obj.ticks,labels=[],start=0,edges=obj.ticks.edges;for(dim=0;3>dim;dim++)if("undefined"!=typeof edges[dim]){if(mode=obj.axes.mode[dim],nticks=obj.axes.nticks[dim],"custom"===mode)labels=labels.concat(obj.texts.slice(start,start+nticks));else{for(limits=obj.bbox.slice(2*dim,2*(dim+1)),range=limits[1]-limits[0],locations=ticks.locations[dim],max=-1/0,values=[],i=0;ii;i++)expand=obj.axes.expand[i],center[i]=(bbox[2*i]+bbox[2*i+1])/2,bbox[2*i]=center[i]-expand*(bbox[2*i+1]-center[i]),bbox[2*i+1]=center[i]+expand*(bbox[2*i+1]-center[i]);obj.bbox=bbox,obj.center=center},rglwidgetClass.prototype.setBBoxMatrices=function(obj){var bboxNorm,bboxMV,scale,saved={normMatrix:new CanvasMatrix4(this.normMatrix),mvMatrix:new CanvasMatrix4(this.mvMatrix)},bbox=obj.bbox;return bboxNorm=new CanvasMatrix4,scale=[bbox[1]-bbox[0],bbox[3]-bbox[2],bbox[5]-bbox[4]],bboxNorm.scale(1/scale[0],1/scale[1],1/scale[2]),bboxNorm.multRight(saved.normMatrix),this.normMatrix=bboxNorm,bboxMV=new CanvasMatrix4,bboxMV.scale(scale[0],scale[1],scale[2]),bboxMV.translate(bbox[0],bbox[2],bbox[4]),bboxMV.multRight(saved.mvMatrix),this.mvMatrix=obj.mvMatrix=bboxMV,saved.prmvMatrix=null===this.prmvMatrix?null:new CanvasMatrix4(this.prmvMatrix),this.setprmvMatrix(),obj.prmvMatrix=this.prmvMatrix,saved},rglwidgetClass.prototype.restoreBBoxMatrices=function(saved){this.normMatrix=saved.normMatrix,this.mvMatrix=saved.mvMatrix,this.prmvMatrix=saved.prmvMatrix},rglwidgetClass.prototype.getMarginParameters=function(bboxdeco,material){var saved,edges,i,line,level,trans,scale,bbox=bboxdeco.bbox,edge=[].concat(material.edge),at=material.margin;if(material.floating){if(saved=this.setBBoxMatrices(bboxdeco),edges=this.getTickEdges(this.prmvMatrix)[at],this.restoreBBoxMatrices(saved),"undefined"==typeof edges)return void 0;for(i=0;3>i;i++)edges[i]<1&&(edges[i]=-1),edge[i]=edge[i]*edges[i]}switch(at){case 0:line=1,level=2;break;case 1:line=0,level=2;break;case 2:line=0,level=1}return scale=[edge[0]*(bbox[1]-bbox[0])/bboxdeco.axes.marklen[0],edge[1]*(bbox[3]-bbox[2])/bboxdeco.axes.marklen[1],edge[2]*(bbox[5]-bbox[4])/bboxdeco.axes.marklen[2]],trans=[1===edge[0]?bbox[1]:bbox[0],1===edge[1]?bbox[3]:bbox[2],1===edge[2]?bbox[5]:bbox[4]],{at:at,line:line,level:level,trans:trans,scale:scale}},rglwidgetClass.prototype.fixVertex=function(orig,parms,center,bbox){var vertex=[0,0,0];return vertex[parms.at]=this.missing(orig[0])?center[parms.at]:"-Inf"===orig[0]?bbox[2*parms.at]:"Inf"===orig[0]?bbox[2*parms.at+1]:orig[0],vertex[parms.line]=parms.scale[parms.line]*orig[1]+parms.trans[parms.line],vertex[parms.level]=parms.scale[parms.level]*orig[2]+parms.trans[parms.level],vertex},rglwidgetClass.prototype.fixNormal=function(orig,parms){var vertex=[0,0,0];return vertex[parms.at]=orig[0],vertex[parms.line]=orig[1]/parms.scale[parms.line],vertex[parms.level]=orig[2]/parms.scale[parms.level],vertex},rglwidgetClass.prototype.marginVecToDataVec=function(obj,subscene){var center,bbox,parms,parmsjson,i,vertex,bboxdeco=this.getBBoxDeco(subscene),orig=obj.orig,vertices=[],normals=[],centers=[];if("undefined"==typeof orig&&(orig={vert:obj.vertices,norm:obj.normals,cent:obj.centers,doNormals:"undefined"!=typeof obj.normals,doCenters:"undefined"!=typeof obj.centers,parms:""},obj.orig=orig),"undefined"!=typeof bboxdeco){if(this.setBbox(bboxdeco,subscene),center=bboxdeco.center,bbox=bboxdeco.bbox,parms=this.getMarginParameters(bboxdeco,obj.material),"undefined"==typeof parms)return!1;if(parmsjson=JSON.stringify(parms),parmsjson===orig.parms)return!0;for(orig.parms=parmsjson,i=0;ii;i++)if("user"===obj.axes.mode[i]&&(axis=["x","y","z"][i],"undefined"!=typeof obj.callbacks&&"undefined"!=typeof(code=obj.callbacks[axis]))){if("undefined"!=typeof edges[i])for(j=0;3>j;j++)"undefined"!=typeof edges[i][j]&&(axis+=edges[i][j]>0?"+":"-");fn=Function('"use strict";return ('+code+")")(),fn.call(this,axis)}}; rgl/inst/htmlwidgets/lib/rglClass/controls.src.js0000644000176200001440000005164714122351532021670 0ustar liggesusers /** * Methods related to controls * @name ___METHODS_FOR_CONTROLS___ * @memberof rglwidgetClass * @kind function * @instance */ /** * Change the displayed subset * @param { Object } el - Element of the control; not used. * @param { Object } control - The subset control data. */ rglwidgetClass.prototype.subsetSetter = function(el, control) { if (typeof control.subscenes === "undefined" || control.subscenes === null) control.subscenes = this.scene.rootSubscene; var value = Math.round(control.value), subscenes = [].concat(control.subscenes), fullset = [].concat(control.fullset), i, j, subsceneid, adds = [], deletes = []; if (this.missing(value)) value = control.value = 0; if (control.accumulate) for (i=0; i <= value; i++) adds = adds.concat(control.subsets[i]); else adds = adds.concat(control.subsets[value]); deletes = fullset.filter(function(x) { return adds.indexOf(x) < 0; }); for (i = 0; i < subscenes.length; i++) { subsceneid = subscenes[i]; if (typeof this.getObj(subsceneid) === "undefined") this.alertOnce("typeof object is undefined"); for (j = 0; j < adds.length; j++) this.addToSubscene(adds[j], subsceneid); for (j = 0; j < deletes.length; j++) this.delFromSubscene(deletes[j], subsceneid); } }; /** * Change the requested property * @param { Object } el - Element of the control; not used. * @param { Object } control - The property setter control data. */ rglwidgetClass.prototype.propertySetter = function(el, control) { var value = control.value, values = [].concat(control.values), svals = [].concat(control.param), direct = values[0] === null, entries = [].concat(control.entries), ncol = entries.length, nrow = values.length/ncol, properties = this.repeatToLen(control.properties, ncol), objids = this.repeatToLen(control.objids, ncol), property, objid = objids[0], obj = this.getObj(objid), propvals, i, j, v1, v2, p, entry, gl, needsBinding, newprop, newid, getPropvals = function() { if (property === "userMatrix") return obj.par3d.userMatrix.getAsArray(); else if (property === "scale" || property === "FOV" || property === "zoom") return [].concat(obj.par3d[property]); else return [].concat(obj[property]); }, putPropvals = function(newvals) { if (newvals.length === 1) newvals = newvals[0]; if (property === "userMatrix") obj.par3d.userMatrix.load(newvals); else if (property === "scale" || property === "FOV" || property === "zoom") obj.par3d[property] = newvals; else obj[property] = newvals; }; if (direct && typeof value === "undefined") return; if (control.interp) { values = values.slice(0, ncol).concat(values). concat(values.slice(ncol*(nrow-1), ncol*nrow)); svals = [-Infinity].concat(svals).concat(Infinity); for (i = 1; i < svals.length; i++) { if (value <= svals[i]) { if (svals[i] === Infinity) p = 1; else p = (svals[i] - value)/(svals[i] - svals[i-1]); break; } } } else if (!direct) { value = Math.round(value); } for (j=0; j value - svals[j-1]) j = j - 1; } break; } } obj = this.getObj(control.objid); // First, make sure color attributes vary in original if (typeof obj.vOffsets !== "undefined") { varies = true; for (k = 0; k < ncol; k++) { attrib = attributes[k]; if (typeof attrib !== "undefined") { ofs = obj.vOffsets[ofss[attrib]]; if (ofs < 0) { switch(attrib) { case "alpha": case "red": case "green": case "blue": obj.colors = [obj.colors[0], obj.colors[0]]; break; } varies = false; } } } if (!varies) this.initObjId(control.objid); } propvals = obj.values; aliases = obj.alias; if (typeof aliases === "undefined") aliases = []; for (k=0; k= 0) { if (ofs < 3) { if (obj.normals[vertex][ofs] !== newval) { // Assume no aliases here... obj.normals[vertex][ofs] = newval; obj.initialized = false; } } else { if (obj.offsets[vertex][0] !== newval) { obj.offsets[vertex][0] = newval; obj.initialized = false; } } continue; } } // Not a plane setting... ofs = obj.vOffsets[ofss[attrib]]; if (ofs < 0) this.alertOnce("Attribute '"+attrib+"' not found in object "+control.objid); else { stride = obj.vOffsets.stride; ofs = ofs + pos[attrib]; entry = vertex*stride + ofs; propvals[entry] = newval; if (typeof alias !== "undefined") for (a = 0; a < alias.length; a++) propvals[alias[a]*stride + ofs] = newval; } } if (typeof obj.buf !== "undefined") { var gl = this.gl || this.initGL(); gl.bindBuffer(gl.ARRAY_BUFFER, obj.buf); gl.bufferData(gl.ARRAY_BUFFER, propvals, gl.STATIC_DRAW); } }; /** * Change the requested vertex properties by age * @param { Object } el - Element of the control; not used. * @param { Object } control - The age setter control data. */ rglwidgetClass.prototype.ageSetter = function(el, control) { var objids = [].concat(control.objids), nobjs = objids.length, time = control.value, births = [].concat(control.births), ages = [].concat(control.ages), steps = births.length, j = Array(steps), p = Array(steps), i, k, l, age, j0, propvals, stride, ofs, objid, obj, attrib, dim, varies, alias, aliases, a, d, attribs = ["colors", "alpha", "radii", "vertices", "normals", "origins", "texcoords", "x", "y", "z", "red", "green", "blue"], ofss = ["cofs", "cofs", "radofs", "vofs", "nofs", "oofs", "tofs", "vofs", "vofs", "vofs", "cofs", "cofs", "cofs"], dims = [3,1,1,3, 3,2,2, 1,1,1, 1,1,1], pos = [0,3,0,0, 0,0,0, 0,1,2, 0,1,2]; /* Infinity doesn't make it through JSON */ ages[0] = -Infinity; ages[ages.length-1] = Infinity; for (i = 0; i < steps; i++) { if (births[i] !== null) { // NA in R becomes null age = time - births[i]; for (j0 = 1; age > ages[j0]; j0++); if (ages[j0] === Infinity) p[i] = 1; else if (ages[j0] > ages[j0-1]) p[i] = (ages[j0] - age)/(ages[j0] - ages[j0-1]); else p[i] = 0; j[i] = j0; } } // First, make sure color attributes vary in original for (l = 0; l < nobjs; l++) { objid = objids[l]; obj = this.getObj(objid); varies = true; if (typeof obj.vOffsets === "undefined") continue; for (k = 0; k < attribs.length; k++) { attrib = control[attribs[k]]; if (typeof attrib !== "undefined") { ofs = obj.vOffsets[ofss[k]]; if (ofs < 0) { switch(attribs[k]) { case "colors": case "alpha": case "red": case "green": case "blue": obj.colors = [obj.colors[0], obj.colors[0]]; break; } varies = false; } } } if (!varies) this.initObjId(objid); } for (l = 0; l < nobjs; l++) { objid = objids[l]; obj = this.getObj(objid); if (typeof obj.vOffsets === "undefined") continue; aliases = obj.alias; if (typeof aliases === "undefined") aliases = []; propvals = obj.values; stride = obj.vOffsets.stride; for (k = 0; k < attribs.length; k++) { attrib = control[attribs[k]]; if (typeof attrib !== "undefined") { ofs = obj.vOffsets[ofss[k]]; if (ofs >= 0) { dim = dims[k]; ofs = ofs + pos[k]; for (i = 0; i < steps; i++) { alias = aliases[i]; if (births[i] !== null) { for (d=0; d < dim; d++) { propvals[i*stride + ofs + d] = p[i]*attrib[dim*(j[i]-1) + d] + (1-p[i])*attrib[dim*j[i] + d]; if (typeof alias !== "undefined") for (a=0; a < alias.length; a++) propvals[alias[a]*stride + ofs + d] = propvals[i*stride + ofs + d]; } } } } else this.alertOnce("\'"+attribs[k]+"\' property not found in object "+objid); } } obj.values = propvals; if (typeof obj.buf !== "undefined") { var gl = this.gl || this.initGL(); gl.bindBuffer(gl.ARRAY_BUFFER, obj.buf); gl.bufferData(gl.ARRAY_BUFFER, obj.values, gl.STATIC_DRAW); } } }; /** * Bridge to old style control * @param { Object } el - Element of the control; not used. * @param { Object } control - The bridge control data. */ rglwidgetClass.prototype.oldBridge = function(el, control) { var attrname, global = window[control.prefix + "rgl"]; if (global) for (attrname in global) this[attrname] = global[attrname]; window[control.prefix + "rgl"] = this; }; /** * Set up a player control * @param { Object } el - The player control element * @param { Object } control - The player data. */ rglwidgetClass.prototype.Player = function(el, control) { var self = this, components = [].concat(control.components), buttonLabels = [].concat(control.buttonLabels), Tick = function() { /* "this" will be a timer */ var i, nominal = this.value, slider = this.Slider, labels = this.outputLabels, output = this.Output, step; if (typeof slider !== "undefined" && nominal !== slider.value) slider.value = nominal; if (typeof output !== "undefined") { step = Math.round((nominal - output.sliderMin)/output.sliderStep); if (labels !== null) { output.innerHTML = labels[step]; } else { step = step*output.sliderStep + output.sliderMin; output.innerHTML = step.toPrecision(output.outputPrecision); } } for (i=0; i < this.actions.length; i++) { this.actions[i].value = nominal; } self.applyControls(el, this.actions, false); self.drawScene(); }, OnSliderInput = function() { /* "this" will be the slider */ this.rgltimer.value = Number(this.value); this.rgltimer.Tick(); }, addSlider = function(min, max, step, value) { var slider = document.createElement("input"); slider.type = "range"; slider.min = min; slider.max = max; slider.step = step; slider.value = value; slider.oninput = OnSliderInput; slider.sliderActions = control.actions; slider.sliderScene = this; slider.className = "rgl-slider"; slider.id = el.id + "-slider"; el.rgltimer.Slider = slider; slider.rgltimer = el.rgltimer; el.appendChild(slider); }, addLabel = function(labels, min, step, precision) { var output = document.createElement("output"); output.sliderMin = min; output.sliderStep = step; output.outputPrecision = precision; output.className = "rgl-label"; output.id = el.id + "-label"; el.rgltimer.Output = output; el.rgltimer.outputLabels = labels; el.appendChild(output); }, addButton = function(which, label, active) { var button = document.createElement("input"), onclicks = {Reverse: function() { this.rgltimer.reverse();}, Play: function() { this.rgltimer.play(); this.value = this.rgltimer.enabled ? this.inactiveValue : this.activeValue; }, Slower: function() { this.rgltimer.slower(); }, Faster: function() { this.rgltimer.faster(); }, Reset: function() { this.rgltimer.reset(); }, Step: function() { this.rgltimer.step(); } }; button.rgltimer = el.rgltimer; button.type = "button"; button.value = label; button.activeValue = label; button.inactiveValue = active; if (which === "Play") button.rgltimer.PlayButton = button; button.onclick = onclicks[which]; button.className = "rgl-button"; button.id = el.id + "-" + which; el.appendChild(button); }; if (typeof control.reinit !== "undefined" && control.reinit !== null) { control.actions.reinit = control.reinit; } el.rgltimer = new rgltimerClass(Tick, control.start, control.interval, control.stop, control.step, control.value, control.rate, control.loop, control.actions); for (var i=0; i < components.length; i++) { switch(components[i]) { case "Slider": addSlider(control.start, control.stop, control.step, control.value); break; case "Label": addLabel(control.labels, control.start, control.step, control.precision); break; default: addButton(components[i], buttonLabels[i], control.pause); } } el.rgltimer.Tick(); }; /** * Apply all registered controls * @param { Object } el - DOM element of the control * @param { Object } x - List of actions to apply * @param { boolean } [draw=true] - Whether to redraw after applying */ rglwidgetClass.prototype.applyControls = function(el, x, draw) { var self = this, reinit = x.reinit, i, control, type; for (i = 0; i < x.length; i++) { control = x[i]; type = control.type; self[type](el, control); } if (typeof reinit !== "undefined" && reinit !== null) { reinit = [].concat(reinit); for (i = 0; i < reinit.length; i++) self.getObj(reinit[i]).initialized = false; } if (typeof draw === "undefined" || draw) self.drawScene(); }; /** * Handler for scene change * @param { Object } message - What sort of scene change to do? */ rglwidgetClass.prototype.sceneChangeHandler = function(message) { var self = document.getElementById(message.elementId).rglinstance, objs = message.objects, mat = message.material, root = message.rootSubscene, initSubs = message.initSubscenes, redraw = message.redrawScene, skipRedraw = message.skipRedraw, deletes, subs, allsubs = [], i,j; if (typeof message.delete !== "undefined") { deletes = [].concat(message.delete); if (typeof message.delfromSubscenes !== "undefined") subs = [].concat(message.delfromSubscenes); else subs = []; for (i = 0; i < deletes.length; i++) { for (j = 0; j < subs.length; j++) { self.delFromSubscene(deletes[i], subs[j]); } delete self.scene.objects[deletes[i]]; } } if (typeof objs !== "undefined") { Object.keys(objs).forEach(function(key){ key = parseInt(key, 10); self.scene.objects[key] = objs[key]; self.initObjId(key); var obj = self.getObj(key), subs = [].concat(obj.inSubscenes), k; allsubs = allsubs.concat(subs); for (k = 0; k < subs.length; k++) self.addToSubscene(key, subs[k]); }); } if (typeof mat !== "undefined") { self.scene.material = mat; } if (typeof root !== "undefined") { self.scene.rootSubscene = root; } if (typeof initSubs !== "undefined") allsubs = allsubs.concat(initSubs); allsubs = self.unique(allsubs); for (i = 0; i < allsubs.length; i++) { self.initSubscene(allsubs[i]); } if (typeof skipRedraw !== "undefined") { root = self.getObj(self.scene.rootSubscene); root.par3d.skipRedraw = skipRedraw; } if (redraw) self.drawScene(); }; rgl/inst/htmlwidgets/lib/rglClass/selection.src.js0000644000176200001440000001060714122333063022000 0ustar liggesusers /** * Methods related to selection * @name ___METHODS_FOR_SELECTION___ * @memberof rglwidgetClass * @kind function * @instance */ /** * Respond to brush change */ rglwidgetClass.prototype.selectionChanged = function() { var i, j, k, id, subid = this.select.subscene, subscene, objids, obj, p1 = this.select.region.p1, p2 = this.select.region.p2, filter, selection = [], handle, keys, xmin, x, xmax, ymin, y, ymax, z, v, someHidden; if (!subid) return; subscene = this.getObj(subid); objids = subscene.objects; filter = this.scene.crosstalk.filter; this.setmvMatrix(subid); this.setprMatrix(subid); this.setprmvMatrix(); xmin = Math.min(p1.x, p2.x); xmax = Math.max(p1.x, p2.x); ymin = Math.min(p1.y, p2.y); ymax = Math.max(p1.y, p2.y); for (i = 0; i < objids.length; i++) { id = objids[i]; j = this.scene.crosstalk.id.indexOf(id); if (j >= 0) { keys = this.scene.crosstalk.key[j]; obj = this.getObj(id); someHidden = false; for (k = 0; k < keys.length; k++) { if (filter && filter.indexOf(keys[k]) < 0) { someHidden = true; continue; } v = [].concat(obj.vertices[k]).concat(1.0); v = this.multVM(v, this.prmvMatrix); x = v[0]/v[3]; y = v[1]/v[3]; z = v[2]/v[3]; if (xmin <= x && x <= xmax && ymin <= y && y <= ymax && -1.0 <= z && z <= 1.0) { selection.push(keys[k]); } else someHidden = true; } obj.someHidden = someHidden && (filter || selection.length); obj.initialized = false; /* Who should we notify? Only shared data in the current subscene, or everyone? */ if (!this.equalArrays(selection, this.scene.crosstalk.selection)) { handle = this.scene.crosstalk.sel_handle[j]; handle.set(selection, {rglSubsceneId: this.select.subscene}); } } } }; /** * Respond to selection or filter change from crosstalk * @param { Object } event - crosstalk event * @param { boolean } filter - filter or selection? */ rglwidgetClass.prototype.selection = function(event, filter) { var i, j, ids, obj, keys, crosstalk = this.scene.crosstalk, selection, someHidden; // Record the message and find out if this event makes some objects have mixed values: crosstalk = this.scene.crosstalk; if (filter) { filter = crosstalk.filter = event.value; selection = crosstalk.selection; } else { selection = crosstalk.selection = event.value; filter = crosstalk.filter; } ids = crosstalk.id; for (i = 0; i < ids.length ; i++) { obj = this.getObj(ids[i]); obj.initialized = false; keys = crosstalk.key[i]; someHidden = false; for (j = 0; j < keys.length && !someHidden; j++) { if ((filter && filter.indexOf(keys[j]) < 0) || (selection.length && selection.indexOf(keys[j]) < 0)) someHidden = true; } obj.someHidden = someHidden; } this.drawScene(); }; /** * Clear the selection brush * @param { number } except - Subscene that should ignore this request */ rglwidgetClass.prototype.clearBrush = function(except) { if (this.select.subscene !== except) { this.select.region = {p1: {x:Infinity, y:Infinity}, p2: {x:Infinity, y:Infinity}}; this.selectionChanged(); this.select.state = "inactive"; this.delFromSubscene(this.scene.brushId, this.select.subscene); } this.drawScene(); }; /** * Set the vertices in the selection box object */ rglwidgetClass.prototype.initSelection = function(id) { if (typeof this.select.region === "undefined") return; var obj = this.getObj(id), p1 = this.select.region.p1, p2 = this.select.region.p2; obj.vertices = [[p1.x, p1.y, 0.0], [p2.x, p1.y, 0.0], [p2.x, p2.y, 0.0], [p1.x, p2.y, 0.0], [p1.x, p1.y, 0.0]]; }; rgl/inst/htmlwidgets/lib/rglClass/textures.src.js0000644000176200001440000001373414145464133021712 0ustar liggesusers /** * Methods related to textures * @name ___METHODS_FOR_TEXTURES___ * @memberof rglwidgetClass * @kind function * @instance */ rglwidgetClass.prototype.getTexFilter = function(filter) { var gl = this.gl || this.initGL(); switch(filter) { case "nearest": return gl.NEAREST; case "linear": return gl.LINEAR; case "nearest.mipmap.nearest": return gl.NEAREST_MIPMAP_NEAREST; case "linear.mipmap.nearest": return gl.LINEAR_MIPMAP_NEAREST; case "nearest.mipmap.linear": return gl.NEAREST_MIPMAP_LINEAR; case "linear.mipmap.linear": return gl.LINEAR_MIPMAP_LINEAR; default: console.error("Unknown filter: "+filter); } }; /** * Handle a texture after its image has been loaded * @param { Object } texture - the gl texture object * @param { Object } textureCanvas - the canvas holding the image */ rglwidgetClass.prototype.handleLoadedTexture = function(texture, textureCanvas) { var gl = this.gl || this.initGL(); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureCanvas); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST); gl.generateMipmap(gl.TEXTURE_2D); gl.bindTexture(gl.TEXTURE_2D, null); }; /** * Get maximum dimension of texture in current browser. * @returns {number} */ rglwidgetClass.prototype.getMaxTexSize = function() { var gl = this.gl || this.initGL(); return Math.min(4096, gl.getParameter(gl.MAX_TEXTURE_SIZE)); }; /** * Load an image to a texture * @param { string } uri - The image location * @param { Object } texture - the gl texture object */ rglwidgetClass.prototype.loadImageToTexture = function(uri, texture) { var canvas = this.textureCanvas, ctx = canvas.getContext("2d"), image = new Image(), self = this; image.onload = function() { var w = image.width, h = image.height, canvasX = self.getPowerOfTwo(w), canvasY = self.getPowerOfTwo(h), maxTexSize = self.getMaxTexSize(); while (canvasX > 1 && canvasY > 1 && (canvasX > maxTexSize || canvasY > maxTexSize)) { canvasX /= 2; canvasY /= 2; } canvas.width = canvasX; canvas.height = canvasY; ctx.imageSmoothingEnabled = true; ctx.drawImage(image, 0, 0, canvasX, canvasY); self.handleLoadedTexture(texture, canvas); self.drawScene(); }; image.src = uri; }; /** * Draw text to the texture canvas * @returns { Object } object with text measurements * @param { string } text - the text * @param { number } cex - expansion * @param { string } family - font family * @param { number } font - font number */ rglwidgetClass.prototype.drawTextToCanvas = function(text, cex, family, font) { var canvasX, canvasY, scaling = 20, textColour = "white", backgroundColour = "rgba(0,0,0,0)", canvas = this.textureCanvas, ctx = canvas.getContext("2d"), i, textHeight = 0, textHeights = [], width, widths = [], offsetx, offsety = 0, line, lines = [], offsetsx = [], offsetsy = [], lineoffsetsy = [], fontStrings = [], maxTexSize = this.getMaxTexSize(), getFontString = function(i) { textHeights[i] = scaling*cex[i]; var fontString = textHeights[i] + "px", family0 = family[i], font0 = font[i]; if (family0 === "sans") family0 = "sans-serif"; else if (family0 === "mono") family0 = "monospace"; fontString = fontString + " " + family0; if (font0 === 2 || font0 === 4) fontString = "bold " + fontString; if (font0 === 3 || font0 === 4) fontString = "italic " + fontString; return fontString; }; cex = this.repeatToLen(cex, text.length); family = this.repeatToLen(family, text.length); font = this.repeatToLen(font, text.length); canvasX = 1; line = -1; offsetx = maxTexSize; for (i = 0; i < text.length; i++) { ctx.font = fontStrings[i] = getFontString(i); width = widths[i] = ctx.measureText(text[i]).width; if (offsetx + width > maxTexSize) { offsety = offsety + 2*textHeight; if (line >= 0) lineoffsetsy[line] = offsety; line += 1; if (offsety > maxTexSize) console.error("Too many strings for texture."); textHeight = 0; offsetx = 0; } textHeight = Math.max(textHeight, textHeights[i]); offsetsx[i] = offsetx; offsetx += width; canvasX = Math.max(canvasX, offsetx); lines[i] = line; } offsety = lineoffsetsy[line] = offsety + 2*textHeight; for (i = 0; i < text.length; i++) { offsetsy[i] = lineoffsetsy[lines[i]]; } canvasX = this.getPowerOfTwo(canvasX); canvasY = this.getPowerOfTwo(offsety); canvas.width = canvasX; canvas.height = canvasY; ctx.fillStyle = backgroundColour; ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); ctx.textBaseline = "alphabetic"; for(i = 0; i < text.length; i++) { ctx.font = fontStrings[i]; ctx.fillStyle = textColour; ctx.textAlign = "left"; ctx.fillText(text[i], offsetsx[i], offsetsy[i]); } return {canvasX:canvasX, canvasY:canvasY, widths:widths, textHeights:textHeights, offsetsx:offsetsx, offsetsy:offsetsy}; }; rgl/inst/htmlwidgets/lib/rglClass/projection.src.js0000644000176200001440000001173514145464133022202 0ustar liggesusers /** * Methods related to projections * @name ___METHODS_FOR_PROJECTIONS___ * @memberof rglwidgetClass * @kind function * @instance */ /** * Get the viewport */ rglwidgetClass.prototype.getViewport = function(id) { var vp = this.getObj(id).par3d.viewport, x = vp.x*this.canvas.width, y = vp.y*this.canvas.height, width = vp.width*this.canvas.width, height = vp.height*this.canvas.height; this.vp = {x:x, y:y, width:width, height:height}; }; /** * Set the gl viewport and scissor test * @param { number } id - id of subscene */ rglwidgetClass.prototype.setViewport = function(id) { var gl = this.gl || this.initGL(); this.getViewport(id); gl.viewport(this.vp.x, this.vp.y, this.vp.width, this.vp.height); gl.scissor(this.vp.x, this.vp.y, this.vp.width, this.vp.height); gl.enable(gl.SCISSOR_TEST); }; /** * Set the projection matrix for a subscene * @param { number } id - id of subscene */ rglwidgetClass.prototype.setprMatrix = function(id) { var subscene = this.getObj(id), embedding = subscene.embeddings.projection; if (embedding === "replace") this.prMatrix.makeIdentity(); else this.setprMatrix(subscene.parent); if (embedding === "inherit") return; // This is based on the Frustum::enclose code from geom.cpp var bbox = subscene.par3d.bbox, scale = subscene.par3d.scale, ranges = [(bbox[1]-bbox[0])*scale[0]/2, (bbox[3]-bbox[2])*scale[1]/2, (bbox[5]-bbox[4])*scale[2]/2], radius = Math.sqrt(this.sumsq(ranges))*1.1; // A bit bigger to handle labels if (radius <= 0) radius = 1; var observer = subscene.par3d.observer, distance = observer[2], FOV = subscene.par3d.FOV, ortho = FOV === 0, t = ortho ? 1 : Math.tan(FOV*Math.PI/360), near = distance - radius, far = distance + radius, hlen, aspect = this.vp.width/this.vp.height, z = subscene.par3d.zoom, userProjection = subscene.par3d.userProjection; if (far < 0.0) far = 1.0; if (near < far/100.0) near = far/100.0; this.frustum = {near:near, far:far}; hlen = t*near; if (ortho) { if (aspect > 1) this.prMatrix.ortho(-hlen*aspect*z, hlen*aspect*z, -hlen*z, hlen*z, near, far); else this.prMatrix.ortho(-hlen*z, hlen*z, -hlen*z/aspect, hlen*z/aspect, near, far); } else { if (aspect > 1) this.prMatrix.frustum(-hlen*aspect*z, hlen*aspect*z, -hlen*z, hlen*z, near, far); else this.prMatrix.frustum(-hlen*z, hlen*z, -hlen*z/aspect, hlen*z/aspect, near, far); } this.prMatrix.multRight(userProjection); }; /** * Set the model-view matrix for a subscene * @param { number } id - id of the subscene */ rglwidgetClass.prototype.setmvMatrix = function(id) { var observer = this.getObj(id).par3d.observer; this.mvMatrix.makeIdentity(); this.setmodelMatrix(id); this.mvMatrix.translate(-observer[0], -observer[1], -observer[2]); }; /** * Set the model matrix for a subscene * @param { number } id - id of the subscene */ rglwidgetClass.prototype.setmodelMatrix = function(id) { var subscene = this.getObj(id), embedding = subscene.embeddings.model; if (embedding !== "inherit") { var scale = subscene.par3d.scale, bbox = subscene.par3d.bbox, center = [(bbox[0]+bbox[1])/2, (bbox[2]+bbox[3])/2, (bbox[4]+bbox[5])/2]; this.mvMatrix.translate(-center[0], -center[1], -center[2]); this.mvMatrix.scale(scale[0], scale[1], scale[2]); this.mvMatrix.multRight( subscene.par3d.userMatrix ); } if (embedding !== "replace") this.setmodelMatrix(subscene.parent); }; /** * Set the normals matrix for a subscene * @param { number } subsceneid - id of the subscene */ rglwidgetClass.prototype.setnormMatrix2 = function() { this.normMatrix = new CanvasMatrix4(this.mvMatrix); this.normMatrix.invert(); this.normMatrix.transpose(); }; /** * Set the combined projection-model-view matrix */ rglwidgetClass.prototype.setprmvMatrix = function() { this.prmvMatrix = new CanvasMatrix4( this.mvMatrix ); this.prmvMatrix.multRight( this.prMatrix ); }; rglwidgetClass.prototype.setInvPrMatrix = function() { this.invPrMatrix = new CanvasMatrix4( this.prMatrix ); this.invPrMatrix.invert(); this.invPrMatrix.transpose(); }; rgl/inst/htmlwidgets/lib/rglClass/JSDoc.json0000644000176200001440000000076614100762640020534 0ustar liggesusers{ "opts": { "encoding" : "utf8", "destination" : ".JSDoc/rglClass" }, "templates": { "systemName" : "rglClass", "systemSummary" : "Javascript support for `rglwidget`", "copyright" : "rglClass copyright Duncan Murdoch", "includeDate" : false, "dateFormat" : "DD MMM YYYY", "collapseSymbols" : false, "sort" : "source,name", "outputSourceFiles" : true } } rgl/inst/htmlwidgets/lib/rglClass/init.src.js0000644000176200001440000012722214145464133020770 0ustar liggesusers /** * Methods related to initialization * @name ___METHODS_FOR_INITIALIZATION___ * @memberof rglwidgetClass * @kind function * @instance */ /** * Initial test for WebGL */ rglwidgetClass.prototype.initGL0 = function() { if (!window.WebGLRenderingContext){ this.alertOnce("Your browser does not support WebGL. See http://get.webgl.org"); return; } }; /** * Initialize WebGL * @returns { Object } the WebGL context */ rglwidgetClass.prototype.initGL = function() { var self = this, success = false; if (this.gl) { if (!this.drawing && this.gl.isContextLost()) this.restartCanvas(); else return this.gl; } // if (!this.isInBrowserViewport()) return; Return what??? At this point we know this.gl is null. this.canvas.addEventListener("webglcontextrestored", this.onContextRestored, false); this.canvas.addEventListener("webglcontextlost", this.onContextLost, false); this.gl = this.canvas.getContext("webgl", this.webGLoptions) || this.canvas.getContext("experimental-webgl", this.webGLoptions); success = !!(this.gl && this.gl instanceof WebGLRenderingContext); if (!success) this.alertOnce("Your browser does not support WebGL. See http://get.webgl.org"); this.index_uint = this.gl.getExtension("OES_element_index_uint"); var save = this.startDrawing(); Object.keys(this.scene.objects).forEach(function(key){ self.initObjId(parseInt(key, 10)); }); this.stopDrawing(save); return this.gl; }; /** * Resize the display to match element * @param { Object } el - DOM element to match */ rglwidgetClass.prototype.resize = function(el) { this.canvas.width = el.width; this.canvas.height = el.height; }; /** * Initialize the sphere object */ rglwidgetClass.prototype.initSphere = function(sections, segments) { var v = [], phi = [], theta = [], it = [], centers = [], i, j, k, ind, mod1, pole, result = {}; for (i = 0; i < sections - 1; i++) { phi.push((i + 1)/sections - 0.5); } for (j = 0; j < segments; j++) { theta.push(2*j/segments); for (i = 0; i < sections - 1; i++) { /* These are [x,y,z,s,t]: */ v.push([Math.sin(Math.PI*theta[j]) * Math.cos(Math.PI*phi[i]), Math.sin(Math.PI*phi[i]), Math.cos(Math.PI*theta[j]) * Math.cos(Math.PI*phi[i]), theta[j]/2, phi[i] + 0.5]); } } pole = v.length; v.push([0, -1, 0, 0, 0]); v.push([0, 1, 0, 0, 1]); result.values = new Float32Array(this.flatten(v)); result.vertexCount = v.length; mod1 = segments*(sections - 1); for (j = 0; j < segments; j++) { for (i = 0; i < sections - 2; i++) { ind = i + (sections - 1)*j; it.push([ind % mod1, (ind + sections - 1) % mod1, (ind + sections) % mod1]); it.push([ind % mod1, (ind + sections) % mod1, (ind + 1) % mod1]); } it.push([pole, ((j + 1)*(sections - 1)) % mod1, ((j + 1)*(sections - 1) - sections + 1) % mod1]); it.push([pole + 1, ((j + 1)*(sections - 1) - 1) % mod1, ((j + 1)*(sections - 1) + sections - 2) % mod1]); } result.it = new Uint16Array(this.flatten(it)); for (i = 0; i < it.length; i++) { centers.push([0,0,0]); for (j = 0; j < 3; j++) { // x,y,z for (k = 0; k < 3; k++) {// vertices centers[i][j] += v[it[i][k]][j]/3; } } } result.centers = centers; result.vOffsets = {vofs:0, cofs:-1, nofs:0, radofs:-1, oofs:-1, tofs:3, nextofs:-1, pointofs:-1, stride:5}; result.f = []; result.indices = {}; result.colorCount = 1; result.type = "sphere"; this.sphere = result; this.initShapeGL(this.sphere); }; /** * Initialize the cube object */ rglwidgetClass.prototype.initCube = function() { var v = [[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0], [0, 0, 1], [1, 0, 1], [0, 1, 1], [1, 1, 1]], ib = [[0, 2, 3, 1], [2, 6, 7, 3], [1, 3, 7, 5], [0, 4, 6, 2], [0, 1, 5, 4], [4, 5, 7, 6]], centers = [], i, j, k, i0, i1, i2, normal, result = {}; for (i = 0; i < ib.length; i++) { centers.push([0,0,0]); for (j = 0; j < 3; j++) { // x,y,z for (k = 0; k < 4; k++) {// vertices centers[i][j] += v[ib[i][k]][j]/4; } } } result.centers = centers; result.values = new Float32Array(6*4*3*2); result.vertexCount = 24; result.vertices = new Array(24); result.normals = new Array(24); for (i=0; i < 6; i++) { for (j=0; j < 4; j++) { i0 = ib[i][j]; result.vertices[4*i + j] = v[i0]; i1 = ib[i][(j + 1) % 4]; i2 = ib[i][(j + 2) % 4]; if (j === 0) normal = this.normalize(this.xprod(this.vdiff(v[i1], v[i0]), this.vdiff(v[i2], v[i0]))); result.normals[4*i + j] = normal; for (k=0; k < 3; k++) { result.values[i*24 + j*6 + k] = v[i0][k]; result.values[i*24 + j*6 + 3 + k] = normal[k]; } } for (j=0; j<4; j++) ib[i][j] = 4*i + j; } result.ib = new Uint16Array(this.flatten(ib)); result.vOffsets = {vofs:0, cofs:-1, nofs:3, radofs:-1, oofs:-1, tofs:-1, nextofs:-1, pointofs:-1, stride:6}; result.f = []; result.indices = {}; result.colorCount = 1; result.type = "quads"; this.cube = result; this.initShapeGL(this.cube); }; /** * Do the gl part of initializing the sphere and cube */ rglwidgetClass.prototype.initShapeGL = function(shape) { var gl = this.gl || this.initGL(); if (gl.isContextLost()) return; shape.buf = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, shape.buf); gl.bufferData(gl.ARRAY_BUFFER, shape.values, gl.STATIC_DRAW); shape.ibuf = [gl.createBuffer(), gl.createBuffer()]; return; }; /* Initialize common sphere object from spheres object */ rglwidgetClass.prototype.initShapeFromObj = function(shape, obj) { var i, pass, f, mode, self = this, is_back = function(i) { var normal = shape.normals[i], pt = shape.vertices[i]; normal.push(-self.dotprod(normal, pt)); normal = self.multVM(normal, self.normMatrix); return normal[2] < 0; }; shape.ofsLoc = obj.ofsLoc; shape.texLoc = obj.texLoc; shape.sampler = obj.sampler; shape.uFogMode = obj.uFogMode; shape.uFogColor = obj.uFogColor; shape.uFogParms = obj.uFogParms; shape.userAttribLocations = obj.userAttribLocations; shape.userUniformLocations = obj.userUniformLocations; shape.normLoc = obj.normLoc; shape.invPrMatLoc = obj.invPrMatLoc; shape.clipLoc = obj.clipLoc; shape.nextLoc = obj.nextLoc; shape.pointLoc = obj.pointLoc; shape.aspectLoc = obj.aspectLoc; shape.lwdLoc = obj.lwdLoc; shape.prog = obj.prog; shape.material = obj.material; shape.flags = obj.flags; shape.someHidden = obj.someHidden; shape.fastTransparency = obj.fastTransparency; shape.nlights = obj.nlights; shape.emission = obj.emission; shape.emissionLoc = obj.emissionLoc; shape.shininess = obj.shininess; shape.shininessLoc = obj.shininessLoc; shape.ambient = obj.ambient; shape.ambientLoc = obj.ambientLoc; shape.specular = obj.specular; shape.specularLoc = obj.specularLoc; shape.diffuse = obj.diffuse; shape.diffuseLoc = obj.diffuseLoc; shape.lightDir = obj.lightDir; shape.lightDirLoc = obj.lightDirLoc; shape.viewpoint = obj.viewpoint; shape.viewpointLoc = obj.viewpointLoc; shape.finite = obj.finite; shape.finiteLoc = obj.finiteLoc; shape.prMatLoc = obj.prMatLoc; shape.mvMatLoc = obj.mvMatLoc; shape.normMatLoc = obj.normMatLoc; shape.frontLoc = obj.frontLoc; shape.index_uint = false; shape.is_transparent = obj.is_transparent; shape.ignoreExtent = obj.ignoreExtent; if (shape.passes !== obj.passes || JSON.stringify( shape.pmode) !== JSON.stringify(obj.pmode)) { shape.passes = obj.passes; shape.pmode = obj.pmode; for (pass = 0; pass < obj.passes; pass++) { mode = shape.pmode[pass]; if (typeof shape.indices[mode] === "undefined") { f = []; switch (mode) { case "culled": break; case "points": f.length = shape.vertexCount; for (i=0; i < f.length; i++) f[i] = i; break; case "lines": if (typeof shape.it !== "undefined") { f.length = 2* shape.it.length; for (i=0; i < shape.it.length/3; i++) { f[6*i] = shape.it[3*i]; f[6*i + 1] = shape.it[3*i + 1]; f[6*i + 2] = shape.it[3*i + 1]; f[6*i + 3] = shape.it[3*i + 2]; f[6*i + 4] = shape.it[3*i + 2]; f[6*i + 5] = shape.it[3*i]; } } else { f.length = 2*shape.ib.length; for (i=0; i < shape.ib.length/4; i++) { f[8*i] = shape.ib[4*i]; f[8*i + 1] = shape.ib[4*i + 1]; f[8*i + 2] = shape.ib[4*i + 1]; f[8*i + 3] = shape.ib[4*i + 2]; f[8*i + 4] = shape.ib[4*i + 2]; f[8*i + 5] = shape.ib[4*i + 3]; f[8*i + 6] = shape.ib[4*i + 3]; f[8*i + 7] = shape.ib[4*i]; } } break; case "filled": if (typeof shape.it !== "undefined") f = shape.it; else if (typeof shape.ib !== "undefined") { f.length = 1.5*shape.ib.length; for (i=0; i < shape.ib.length/4; i++) { f[6*i] = shape.ib[4*i]; f[6*i+1] = shape.ib[4*i + 1]; f[6*i+2] = shape.ib[4*i + 2]; f[6*i+3] = shape.ib[4*i]; f[6*i+4] = shape.ib[4*i + 2]; f[6*i+5] = shape.ib[4*i + 3]; } } break; } shape.indices[mode] = new Uint16Array(f); } } } for (pass = 0; pass < obj.passes; pass++) { mode = shape.pmode[pass]; shape.f[pass] = shape.indices[mode]; if (typeof obj.draw_front !== "undefined" && !obj.draw_front) { shape.f[pass] = shape.f[pass].filter(is_back); } } // console.log("Names in shapes not in shape:"+JSON.stringify(this.keydiff(obj, shape))); shape.initialized = true; }; /** * Initialize a subscene * @param { number } id - id of subscene. */ rglwidgetClass.prototype.initSubscene = function(id) { var sub = this.getObj(id), i, obj; if (sub.type !== "subscene") return; sub.par3d.userMatrix = this.toCanvasMatrix4(sub.par3d.userMatrix); sub.par3d.userProjection = this.toCanvasMatrix4(sub.par3d.userProjection); sub.par3d.userProjection.transpose(); sub.par3d.listeners = [].concat(sub.par3d.listeners); sub.backgroundId = undefined; sub.subscenes = []; sub.clipplanes = []; sub.transparent = []; sub.opaque = []; sub.lights = []; sub.needsBegin = true; for (i=0; i < sub.objects.length; i++) { obj = this.getObj(sub.objects[i]); if (typeof obj === "undefined") { sub.objects.splice(i, 1); i--; } else if (obj.type === "background") sub.backgroundId = obj.id; else sub[this.whichList(obj.id)].push(obj.id); } }; rglwidgetClass.prototype.initBBox = function(obj) { if (!this.cube) this.initCube(); obj.cube = {id: obj.id + 0.1, type: "quads", flags: obj.flags, material: obj.material, colors: [obj.colors[0]], vertices: this.cube.vertices, normals: this.cube.normals, draw_front: obj.draw_front, initialized: false }; if (this.getMaterial(obj.cube, "front") !== this.getMaterial(obj.cube, "back")) /* jshint bitwise: false */ obj.cube.flags |= this.f_is_twosided; /* jshint bitwise: true */ this.scene.objects[obj.cube.id] = obj.cube; obj.ticks = {id: obj.id + 0.2, type: "lines", flags: this.f_has_fog, material: obj.material, colors: (obj.colors.length > 1 ? [obj.colors[1]] : [obj.colors[0]]), axes: obj.axes, initialized: false }; this.scene.objects[obj.ticks.id] = obj.ticks; obj.labels = {id: obj.id + 0.3, type: "text", flags: this.f_has_fog + this.f_fixed_size + this.f_fixed_quads, material: {lit: false}, colors: (obj.colors.length > 1 ? [obj.colors[1]] : [obj.colors[0]]), cex: [[1]], family: [["sans"]], font: [[1]], adj: [[0.5, 0.5, 0.5]], ignoreExtent: true, initialized: false }; this.scene.objects[obj.labels.id] = obj.labels; obj.initialized = true; }; /** * Initialize object for display * @param { number } id - id of object to initialize */ rglwidgetClass.prototype.initObjId = function(id) { if (typeof id !== "number") { this.alertOnce("initObj id is "+typeof id); } return this.initObj(this.getObj(id)); }; /** * Initialize object for display * @param { Object } obj - object to initialize */ rglwidgetClass.prototype.initObj = function(obj) { var flags = obj.flags, type = obj.type, is_lit = this.isSet(flags, this.f_is_lit), fat_lines = this.isSet(flags, this.f_fat_lines), has_texture = this.isSet(flags, this.f_has_texture), fixed_quads = this.isSet(flags, this.f_fixed_quads), is_transparent = this.isSet(flags, this.f_is_transparent), depth_sort = this.isSet(flags, this.f_depth_sort), sprites_3d = this.isSet(flags, this.f_sprites_3d), fixed_size = this.isSet(flags, this.f_fixed_size), is_twosided = this.isSet(flags, this.f_is_twosided), is_brush = this.isSet(flags, this.f_is_brush), has_fog = this.isSet(flags, this.f_has_fog), has_normals = (typeof obj.normals !== "undefined") || obj.type === "spheres", has_indices = typeof obj.indices !== "undefined", gl = this.gl || this.initGL(), polygon_offset, texinfo, drawtype, nclipplanes, f, nrows, oldrows, i,j,v,v1,v2, mat, uri, matobj, pass, pmode, dim, nx, nz, nrow; obj.initialized = true; obj.someHidden = false; // used in selection obj.is_transparent = is_transparent; this.expandBufferedFields(obj); if (type === "subscene") return; if (type === "bboxdeco") return this.initBBox(obj); if (type === "spheres" && typeof this.sphere === "undefined") this.initSphere(16, 16); if (type === "light") { obj.ambient = new Float32Array(obj.colors[0].slice(0,3)); obj.diffuse = new Float32Array(obj.colors[1].slice(0,3)); obj.specular = new Float32Array(obj.colors[2].slice(0,3)); obj.lightDir = new Float32Array(obj.vertices[0]); return; } if (type === "clipplanes") { obj.vClipplane = this.flatten(this.cbind(obj.normals, obj.offsets)); return; } if (type === "background" && typeof obj.ids !== "undefined") { obj.quad = this.flatten([].concat(obj.ids)); return; } polygon_offset = this.getMaterial(obj, "polygon_offset"); if (polygon_offset[0] !== 0 || polygon_offset[1] !== 0) obj.polygon_offset = polygon_offset; if (is_transparent) { depth_sort = ["triangles", "quads", "surface", "spheres", "sprites", "text"].indexOf(type) >= 0; } if (is_brush) this.initSelection(obj.id); if (typeof obj.vertices === "undefined") obj.vertices = []; v = obj.vertices; if (has_indices) obj.vertexCount = obj.indices.length; else obj.vertexCount = v.length; if (!obj.vertexCount) return; if (is_twosided && !has_normals) { if (typeof obj.userAttributes === "undefined") obj.userAttributes = {}; v1 = Array(v.length); v2 = Array(v.length); if (obj.type === "triangles" || obj.type === "quads") { if (obj.type === "triangles") nrow = 3; else nrow = 4; for (i=0; i= 0) { key = this.scene.crosstalk.key[j]; options = this.scene.crosstalk.options[j]; colors = colors.slice(0); for (i = 0; i < v.length; i++) colors[i] = obj.colors[i % obj.colors.length].slice(0); if ( (selection = this.scene.crosstalk.selection) && (selection.length || !options.selectedIgnoreNone) ) for (i = 0; i < v.length; i++) { if (!selection.includes(key[i])) { if (options.deselectedColor) colors[i] = options.deselectedColor.slice(0); colors[i][3] = colors[i][3]*options.deselectedFade; /* default: mostly transparent if not selected */ } else if (options.selectedColor) colors[i] = options.selectedColor.slice(0); } if ( (filter = this.scene.crosstalk.filter) ) for (i = 0; i < v.length; i++) if (!filter.includes(key[i])) { if (options.filteredColor) colors[i] = options.filteredColor.slice(0); colors[i][3] = colors[i][3]*options.filteredFade; /* default: completely hidden if filtered */ } } nc = obj.colorCount = colors.length; if (nc > 1) { cofs = stride; stride = stride + 4; v = this.cbind(v, colors); } else { cofs = -1; obj.onecolor = this.flatten(colors); } if (has_normals && obj.type !== "spheres") { nofs = stride; stride = stride + 3; v = this.cbind(v, typeof obj.pnormals !== "undefined" ? obj.pnormals : obj.normals); } else nofs = -1; if (typeof obj.radii !== "undefined") { radofs = stride; stride = stride + 1; // FIXME: always concat the radii? if (obj.radii.length === v.length) { v = this.cbind(v, obj.radii); } else if (obj.radii.length === 1) { v = v.map(function(row) { return row.concat(obj.radii[0]);}); } } else radofs = -1; // Add default indices if (has_indices) { f = Array(obj.indices.length); for (i = 0; i < f.length; i++) f[i] = obj.indices[i] - 1; } else { f = Array(v.length); for (i = 0; i < v.length; i++) f[i] = i; } obj.f = [f,f]; if (type === "sprites" && !sprites_3d) { tofs = stride; stride += 2; oofs = stride; stride += 3; vnew = new Array(4*v.length); fnew = new Array(4*v.length); alias = new Array(v.length); var rescale = fixed_size ? 72 : 1, size = obj.radii, s = rescale*size[0]/2; last = v.length; f = obj.f[0]; obj.adj = this.flatten(obj.adj); if (typeof obj.pos !== "undefined") { obj.pos = this.flatten(obj.pos); offset = obj.adj[0]; } else offset = 0; for (i=0; i < v.length; i++) { adj = this.getAdj(obj, i, offset); if (size.length > 1) s = rescale*size[i]/2; adj[0] = 2*s*(adj[0] - 0.5); adj[1] = 2*s*(adj[1] - 0.5); adj[2] = 2*s*(adj[2] - 0.5); vnew[i] = v[i].concat([0,0]).concat([-s-adj[0], -s-adj[1], -adj[2]]); fnew[4*i] = f[i]; vnew[last]= v[i].concat([1,0]).concat([s-adj[0], -s-adj[1], -adj[2]]); fnew[4*i+1] = last++; vnew[last]= v[i].concat([1,1]).concat([s-adj[0], s-adj[1], -adj[2]]); fnew[4*i+2] = last++; vnew[last]= v[i].concat([0,1]).concat([-s-adj[0], s-adj[1], -adj[2]]); fnew[4*i+3] = last++; alias[i] = [last-3, last-2, last-1]; } v = vnew; obj.vertexCount = v.length; obj.f = [fnew, fnew]; } else if (type === "text") { tofs = stride; stride += 2; oofs = stride; stride += 3; vnew = new Array(4*v.length); f = obj.f[0]; fnew = new Array(4*f.length); alias = new Array(v.length); last = v.length; adj = this.flatten(obj.adj); if (typeof obj.pos !== "undefined") { obj.pos = this.flatten(obj.pos); offset = adj[0]; } else offset = 0; for (i=0; i < v.length; i++) { adj = this.getAdj(obj, i, offset, obj.texts[i]); vnew[i] = v[i].concat([0,-0.5]).concat(adj); fnew[4*i] = f[i]; vnew[last] = v[i].concat([1,-0.5]).concat(adj); fnew[4*i+1] = last++; vnew[last] = v[i].concat([1, 1.5]).concat(adj); fnew[4*i+2] = last++; vnew[last] = v[i].concat([0, 1.5]).concat(adj); fnew[4*i+3] = last++; alias[i] = [last-3, last-2, last-1]; for (j=0; j < 4; j++) { v1 = vnew[fnew[4*i+j]]; v1[tofs+2] = 2*(v1[tofs]-v1[tofs+2])*texinfo.widths[i]; v1[tofs+3] = 2*(v1[tofs+1]-v1[tofs+3])*texinfo.textHeights[i]; v1[tofs] = (texinfo.offsetsx[i] + v1[tofs]*texinfo.widths[i])/texinfo.canvasX; v1[tofs+1] = 1.0-(texinfo.offsetsy[i] - v1[tofs+1]*texinfo.textHeights[i])/texinfo.canvasY; vnew[fnew[4*i+j]] = v1; } } v = vnew; obj.vertexCount = v.length; obj.f = [fnew, fnew]; } else if (typeof obj.texcoords !== "undefined") { tofs = stride; stride += 2; oofs = -1; v = this.cbind(v, obj.texcoords); } else { tofs = -1; oofs = -1; } obj.alias = alias; if (typeof obj.userAttributes !== "undefined") { obj.userAttribOffsets = {}; obj.userAttribLocations = {}; obj.userAttribSizes = {}; for (attr in obj.userAttributes) { obj.userAttribLocations[attr] = gl.getAttribLocation(obj.prog, attr); if (obj.userAttribLocations[attr] >= 0) { // Attribute may not have been used obj.userAttribOffsets[attr] = stride; v = this.cbind(v, obj.userAttributes[attr]); stride = v[0].length; obj.userAttribSizes[attr] = stride - obj.userAttribOffsets[attr]; } } } if (typeof obj.userUniforms !== "undefined") { obj.userUniformLocations = {}; for (attr in obj.userUniforms) obj.userUniformLocations[attr] = gl.getUniformLocation(obj.prog, attr); } if (sprites_3d) { obj.userMatrix = new CanvasMatrix4(); obj.userMatrix.load(this.flatten(obj.usermatrix)); obj.objects = this.flatten([].concat(obj.ids)); is_lit = false; obj.adj = this.flatten(obj.adj); if (typeof obj.pos !== "undefined") { obj.pos = this.flatten(obj.pos); obj.offset = obj.adj[0]; } else obj.offset = 0; for (i=0; i < obj.objects.length; i++) this.initObjId(obj.objects[i]); } if (is_lit && !fixed_quads) { obj.normLoc = gl.getAttribLocation(obj.prog, "aNorm"); } nclipplanes = this.countClipplanes(); if (nclipplanes && !sprites_3d) { obj.clipLoc = []; for (i=0; i < nclipplanes; i++) obj.clipLoc[i] = gl.getUniformLocation(obj.prog,"vClipplane" + i); } if (is_lit) { obj.emissionLoc = gl.getUniformLocation(obj.prog, "emission"); obj.emission = new Float32Array(this.stringToRgb(this.getMaterial(obj, "emission"))); obj.shininessLoc = gl.getUniformLocation(obj.prog, "shininess"); obj.shininess = this.getMaterial(obj, "shininess"); obj.nlights = this.countLights(); obj.ambientLoc = []; obj.ambient = new Float32Array(this.stringToRgb(this.getMaterial(obj, "ambient"))); obj.specularLoc = []; obj.specular = new Float32Array(this.stringToRgb(this.getMaterial(obj, "specular"))); obj.diffuseLoc = []; obj.lightDirLoc = []; obj.viewpointLoc = []; obj.finiteLoc = []; for (i=0; i < obj.nlights; i++) { obj.ambientLoc[i] = gl.getUniformLocation(obj.prog, "ambient" + i); obj.specularLoc[i] = gl.getUniformLocation(obj.prog, "specular" + i); obj.diffuseLoc[i] = gl.getUniformLocation(obj.prog, "diffuse" + i); obj.lightDirLoc[i] = gl.getUniformLocation(obj.prog, "lightDir" + i); obj.viewpointLoc[i] = gl.getUniformLocation(obj.prog, "viewpoint" + i); obj.finiteLoc[i] = gl.getUniformLocation(obj.prog, "finite" + i); } } obj.passes = is_twosided + 1; obj.pmode = new Array(obj.passes); for (pass = 0; pass < obj.passes; pass++) { if (type === "triangles" || type === "quads" || type === "surface" || type === "spheres") pmode = this.getMaterial(obj, (pass === 0) ? "front" : "back"); else pmode = "filled"; obj.pmode[pass] = pmode; } if (type !== "spheres") { obj.f.length = obj.passes; for (pass = 0; pass < obj.passes; pass++) { f = fnew = obj.f[pass]; pmode = obj.pmode[pass]; if (pmode === "culled") f = []; else if (pmode === "points") { // stay with default } else if ((type === "quads" || type === "text" || type === "sprites") && !sprites_3d) { nrows = Math.floor(obj.vertexCount/4); if (pmode === "filled") { fnew = Array(6*nrows); for (i=0; i < nrows; i++) { fnew[6*i] = f[4*i]; fnew[6*i+1] = f[4*i + 1]; fnew[6*i+2] = f[4*i + 2]; fnew[6*i+3] = f[4*i]; fnew[6*i+4] = f[4*i + 2]; fnew[6*i+5] = f[4*i + 3]; } } else { fnew = Array(8*nrows); for (i=0; i < nrows; i++) { fnew[8*i] = f[4*i]; fnew[8*i+1] = f[4*i + 1]; fnew[8*i+2] = f[4*i + 1]; fnew[8*i+3] = f[4*i + 2]; fnew[8*i+4] = f[4*i + 2]; fnew[8*i+5] = f[4*i + 3]; fnew[8*i+6] = f[4*i + 3]; fnew[8*i+7] = f[4*i]; } } } else if (type === "triangles") { nrows = Math.floor(obj.vertexCount/3); if (pmode === "filled") { fnew = Array(3*nrows); for (i=0; i < fnew.length; i++) { fnew[i] = f[i]; } } else if (pmode === "lines") { fnew = Array(6*nrows); for (i=0; i < nrows; i++) { fnew[6*i] = f[3*i]; fnew[6*i + 1] = f[3*i + 1]; fnew[6*i + 2] = f[3*i + 1]; fnew[6*i + 3] = f[3*i + 2]; fnew[6*i + 4] = f[3*i + 2]; fnew[6*i + 5] = f[3*i]; } } } else if (type === "spheres") { // default } else if (type === "surface") { dim = obj.dim[0]; nx = dim[0]; nz = dim[1]; if (pmode === "filled") { fnew = []; for (j=0; j 65535) { if (this.index_uint) { obj.f[pass] = new Uint32Array(obj.f[pass]); obj.index_uint = true; } else this.alertOnce("Object has "+obj.vertexCount+" vertices, not supported in this browser."); } else { obj.f[pass] = new Uint16Array(obj.f[pass]); obj.index_uint = false; } } if (stride !== v[0].length) { this.alertOnce("problem in stride calculation"); } obj.vOffsets = {vofs:0, cofs:cofs, nofs:nofs, radofs:radofs, oofs:oofs, tofs:tofs, nextofs:nextofs, pointofs:pointofs, stride:stride}; obj.values = new Float32Array(this.flatten(v)); if (type !== "spheres" && !sprites_3d) { obj.buf = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, obj.buf); gl.bufferData(gl.ARRAY_BUFFER, obj.values, gl.STATIC_DRAW); // obj.ibuf = Array(obj.passes); obj.ibuf[0] = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, obj.ibuf[0]); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, obj.f[0], gl[drawtype]); if (is_twosided) { obj.ibuf[1] = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, obj.ibuf[1]); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, obj.f[1], gl[drawtype]); } } if (!sprites_3d) { obj.mvMatLoc = gl.getUniformLocation(obj.prog, "mvMatrix"); obj.prMatLoc = gl.getUniformLocation(obj.prog, "prMatrix"); } if (fixed_size) { obj.textScaleLoc = gl.getUniformLocation(obj.prog, "textScale"); } if (is_lit && !sprites_3d) { obj.normMatLoc = gl.getUniformLocation(obj.prog, "normMatrix"); } if (is_twosided) { obj.frontLoc = gl.getUniformLocation(obj.prog, "front"); if (has_normals) obj.invPrMatLoc = gl.getUniformLocation(obj.prog, "invPrMatrix"); } }; /** * Initialize the DOM object * @param { Object } el - the DOM object * @param { Object } x - the scene data sent by JSON from R */ rglwidgetClass.prototype.initialize = function(el, x) { this.textureCanvas = document.createElement("canvas"); this.textureCanvas.style.display = "block"; this.scene = x; this.normMatrix = new CanvasMatrix4(); this.invPrMatrix = new CanvasMatrix4(); this.saveMat = {}; this.distance = null; this.posLoc = 0; this.colLoc = 1; if (el) { el.rglinstance = this; this.el = el; this.webGLoptions = el.rglinstance.scene.webGLoptions; this.initCanvas(); } if (typeof Shiny !== "undefined") { var self = this; Shiny.addCustomMessageHandler("shinyGetPar3d", function(message) { var i, param, subscene = self.getObj(message.subscene), parameters = [].concat(message.parameters), result = {tag: message.tag, subscene: message.subscene}; if (typeof subscene !== "undefined") { for (i = 0; i < parameters.length; i++) { param = parameters[i]; result[param] = subscene.par3d[param]; } } else { console.log("subscene "+message.subscene+" undefined."); } Shiny.setInputValue("par3d:shinyPar3d", result, {priority: "event"}); }); Shiny.addCustomMessageHandler("shinySetPar3d", function(message) { var param = message.parameter, subscene = self.getObj(message.subscene); if (typeof subscene !== "undefined") { subscene.par3d[param] = message.value; subscene.initialized = false; self.drawScene(); } else { console.log("subscene "+message.subscene+" undefined."); } }); Shiny.addCustomMessageHandler("resetBrush", function(message) { if (message === self.scene.selectionInput) { self.clearBrush(null); self.recordSelection(0); } }); } }; /** * Restart the WebGL canvas */ rglwidgetClass.prototype.restartCanvas = function() { var newcanvas = document.createElement("canvas"), self = this; newcanvas.width = this.el.width; newcanvas.height = this.el.height; newcanvas.addEventListener("webglcontextrestored", this.onContextRestored, false); newcanvas.addEventListener("webglcontextlost", this.onContextLost, false); while (this.el.firstChild) { this.el.removeChild(this.el.firstChild); } this.el.appendChild(newcanvas); this.canvas = newcanvas; if (this.scene.javascript) { /* jshint evil:true */ Function('"use strict";' + this.scene.javascript)(); /* jshint evil:false */ } this.setMouseHandlers(); if (this.gl) Object.keys(this.scene.objects).forEach(function(key){ self.getObj(parseInt(key, 10)).texture = undefined; }); this.gl = null; }; /** * Initialize the WebGL canvas */ rglwidgetClass.prototype.initCanvas = function() { this.restartCanvas(); var objs = this.scene.objects, self = this; Object.keys(objs).forEach(function(key){ self.initSubscene(parseInt(key, 10)); }); this.onContextRestored = function() { self.initGL(); self.drawScene(); }; this.onContextLost = function(event) { if (!self.drawing) this.gl = null; event.preventDefault(); }; this.initGL0(); this.lazyLoadScene = function() { if (typeof self.slide === "undefined") self.slide = self.getSlide(); if (self.isInBrowserViewport()) { if (!self.gl || self.gl.isContextLost()) self.initGL(); self.drawScene(); } }; window.addEventListener("DOMContentLoaded", this.lazyLoadScene, false); window.addEventListener("load", this.lazyLoadScene, false); window.addEventListener("resize", this.lazyLoadScene, false); window.addEventListener("scroll", this.lazyLoadScene, false); this.slide = this.getSlide(); if (this.slide) { if (typeof this.slide.rgl === "undefined") this.slide.rgl = [this]; else this.slide.rgl.push(this); if (this.scene.context.rmarkdown) if (this.scene.context.rmarkdown === "ioslides_presentation") { this.slide.setAttribute("slideenter", "this.rgl.forEach(function(scene) { scene.lazyLoadScene.call(window);})"); } else if (this.scene.context.rmarkdown === "slidy_presentation") { // This method would also work in ioslides, but it gets triggered // something like 5 times per slide for every slide change, so // you'd need a quicker function than lazyLoadScene. var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver, observer = new MutationObserver(function(mutations) { mutations.forEach(function() { self.slide.rgl.forEach(function(scene) { scene.lazyLoadScene.call(window); });});}); observer.observe(this.slide, { attributes: true, attributeFilter:["class"] }); } } }; rgl/inst/htmlwidgets/lib/rglClass/axes.src.js0000644000176200001440000003372614145464133020772 0ustar liggesusers /** * Methods related to axes * @name ___METHODS_FOR_AXES___ * @memberof rglwidgetClass * @kind function * @instance */ /** * Choose edges for ticks * @param { Matrix } prmv - projection-model-view matrix */ rglwidgetClass.prototype.getTickEdges = function(prmv){ var vertices = [[0,0,0,1], [0,0,1,1], [0,1,0,1], [0,1,1,1], [1,0,0,1], [1,0,1,1], [1,1,0,1], [1,1,1,1]], dim, i, j, k, edges, hull, step, result = [], proj = []; for (i = 0; i < vertices.length; i++) { proj[i] = this.multVM(vertices[i], prmv); proj[i][0] = proj[i][0]/proj[i][3]; proj[i][1] = proj[i][1]/proj[i][3]; proj[i][2] = i; } hull = this.chull(proj.slice()); for (i = 0; i < hull.length; i++) hull[i] = hull[i][2]; hull.push(hull[0]); for (dim = 0; dim < 3; dim++) { edges = []; step = Math.pow(2, 2-dim); for (i = 0; i < 4; i++) { j = (dim === 0) ? i : (dim === 1) ? i + 2*(i>1) : 2*i; for (k = 0; k < hull.length - 1; k++) { if ((hull[k] === j && hull[k+1] === j + step) || (hull[k] === j+step && hull[k+1] === j)) edges.push([j, j+step], [j+step, j]); } } // Find the edge with a vertex closest // to the bottom left corner if (edges.length) { var best, best2, val = Infinity, newval; for (i = 0; i < edges.length; i++) { j = edges[i][0]; newval = proj[j][0] + proj[j][1]; if (newval < val) { best = j; best2 = edges[i][1]; val = newval; } } if (typeof best !== "undefined") { result[dim] = vertices[best].slice(0,3); result[dim][dim] = undefined; } else result[dim] = undefined; } } return result; }; /** * Choose tick locations * @param { Object } obj - The bboxdeco */ rglwidgetClass.prototype.getTickLocations = function(obj){ var dim, i, limits, locations = [], result = [[],[],[]], value, len, delta, range, bbox = obj.bbox; obj.needsAxisCallback = false; for (dim = 0; dim < 3; dim++) { limits = bbox.slice(2*dim, 2*dim + 2); range = limits[1] - limits[0]; switch(obj.axes.mode[dim]) { case "custom": for (i=0; i < obj.vertices.length; i++) { value = (obj.vertices[i][dim] - limits[0])/range; if (typeof value !== "undefined") result[dim].push(value); } break; case "fixedstep": len = Math.floor(range/obj.axes.step[dim]); delta = obj.axes.step[dim]; for (i = 0; i < len; i++) result[dim].push(i*delta); break; case "fixednum": len = obj.axes.nticks[dim]; delta = (len > 1) ? range/(len-1) : 0; for (i = 0; i < len; i++) result[dim].push(i*delta/range); break; case "pretty": locations = this.R_pretty(limits[0], limits[1], 5, 2, // min_n 0.75, // shrink_sml [1.5, 2.75], // high_u_fact 0, // eps_correction 0); // return_bounds) for (i = locations.lo; i <= locations.up; i++) { value = (i*locations.unit - limits[0])/range; if (0 < value && value < 1) result[dim].push(value); } break; case "user": obj.needsAxisCallback = true; break; } } return result; }; /** * Set tick vertices * @param { Object } ticks - the tick object * @param { Array } edges - Which edges get the ticks? */ rglwidgetClass.prototype.getTickVertices = function(ticks) { var dim, i, j, vertices = [], locations, edges = ticks.edges, edge; for (dim = 0; dim < 3; dim++) { locations = ticks.locations[dim]; if (locations.length) for (i = 0; i < locations.length; i++) if (typeof edges[dim] !== "undefined") { edge = edges[dim].slice(); edge[dim] = locations[i]; vertices.push(edge); edge = edge.slice(); for (j = 0; j < 3; j++) if ((dim < 2 && j === 1 - dim) || (dim === 2 && j === 0)) edge[j] += 2*(edge[j] - 0.5)/ticks.axes.marklen[dim]; vertices.push(edge); } } ticks.vertices = vertices; ticks.vertexCount = vertices.length; ticks.values = new Float32Array(this.flatten(vertices)); ticks.initialized = false; }; /** * Set tick label positions * @param { Object } obj - the bbox object */ rglwidgetClass.prototype.placeTickLabels = function(obj) { var ticks = obj.ticks, labels = obj.labels, i,j,k, vertices = [], tickvertices = ticks.vertices, vertex, locations, dim, edges = obj.ticks.edges; j = 0; for (dim = 0; dim < 3; dim++) { if (typeof edges[dim] === "undefined") continue; locations = ticks.locations[dim]; if (locations.length) for (i = 0; i < locations.length; i++) { while (j < tickvertices.length && tickvertices[j][dim] !== locations[i]) j++; if (j >= tickvertices.length) break; vertex = tickvertices[j].slice(); for (k = 0; k < 3; k++) vertex[k] += 2*(tickvertices[j+1][k] - vertex[k]); vertices.push(vertex); j += 2; } } labels.vertices = vertices; labels.centers = labels.vertices; labels.initialized = false; }; /** * Set tick labels * @param { Object } obj - the bbox object */ rglwidgetClass.prototype.setTickLabels = function(obj) { var ticks = obj.ticks, mode, locations, labels = [], start = 0, nticks, dim, i, limits, range, values, max, edges = obj.ticks.edges; for (dim = 0; dim < 3; dim++) { if (typeof edges[dim] === "undefined") continue; mode = obj.axes.mode[dim]; nticks = obj.axes.nticks[dim]; // used on input only for custom! if (mode === "custom") labels = labels.concat(obj.texts.slice(start, start + nticks)); else { limits = obj.bbox.slice(2*dim, 2*(dim+1)); range = limits[1] - limits[0]; locations = ticks.locations[dim]; max = -Infinity; values = []; for (i = 0; i < locations.length; i++) { values.push(limits[0] + range*locations[i]); max = Math.max(max, Math.abs(values[i])); } for (i = 0; i < locations.length; i++) { if (Math.abs(values[i])/max < Math.pow(10, -5)) values[i] = 0; labels.push(this.signif(values[i], 4).toString()); } obj.axes.nticks[dim] = locations.length; } start += nticks; } obj.labels.texts = labels; }; /** * Set bboxdeco bbox and center vector * @param { Object } obj - the bbox object */ rglwidgetClass.prototype.setBbox = function(obj, subscene) { var i, expand, center = [], bbox; if (!obj.initialized) this.initBBox(obj); bbox = [].concat(subscene.par3d.bbox); for (i = 0; i < 3; i++) { expand = obj.axes.expand[i]; center[i] = (bbox[2*i] + bbox[2*i + 1])/2; bbox[2*i] = center[i] - expand*(bbox[2*i + 1] - center[i]); bbox[2*i+1] = center[i] + expand*(bbox[2*i + 1] - center[i]); } obj.bbox = bbox; obj.center = center; }; rglwidgetClass.prototype.setBBoxMatrices = function(obj) { var saved = {normMatrix: new CanvasMatrix4(this.normMatrix), mvMatrix: new CanvasMatrix4(this.mvMatrix)}, bboxNorm, bboxMV, bbox = obj.bbox, scale; bboxNorm = new CanvasMatrix4(); scale = [bbox[1]-bbox[0], bbox[3]-bbox[2], bbox[5]-bbox[4]]; bboxNorm.scale(1/scale[0], 1/scale[1], 1/scale[2]); bboxNorm.multRight(saved.normMatrix); this.normMatrix = bboxNorm; bboxMV = new CanvasMatrix4(); bboxMV.scale(scale[0], scale[1], scale[2]); bboxMV.translate(bbox[0], bbox[2], bbox[4]); bboxMV.multRight(saved.mvMatrix); this.mvMatrix = obj.mvMatrix = bboxMV; if (this.prmvMatrix === null) saved.prmvMatrix = null; else saved.prmvMatrix = new CanvasMatrix4(this.prmvMatrix); this.setprmvMatrix(); obj.prmvMatrix = this.prmvMatrix; return saved; }; rglwidgetClass.prototype.restoreBBoxMatrices = function(saved) { this.normMatrix = saved.normMatrix; this.mvMatrix = saved.mvMatrix; this.prmvMatrix = saved.prmvMatrix; }; rglwidgetClass.prototype.getMarginParameters = function(bboxdeco, material) { // Assume we've run this.setBbox(bboxdeco, subscene); var bbox = bboxdeco.bbox, edge = [].concat(material.edge), saved, edges, i, at = material.margin, line, level, trans, scale; if (material.floating) { saved = this.setBBoxMatrices(bboxdeco); edges = this.getTickEdges(this.prmvMatrix)[at]; this.restoreBBoxMatrices(saved); if (typeof edges !== "undefined") for (i = 0; i < 3; i++) { if (edges[i] < 1) edges[i] = -1; edge[i] = edge[i]*edges[i]; } else return undefined; } switch(at) { case 0: line = 1; level = 2; break; case 1: line = 0; level = 2; break; case 2: line = 0; level = 1; break; } scale = [edge[0]*(bbox[1]-bbox[0])/bboxdeco.axes.marklen[0], edge[1]*(bbox[3]-bbox[2])/bboxdeco.axes.marklen[1], edge[2]*(bbox[5]-bbox[4])/bboxdeco.axes.marklen[2]]; trans = [edge[0] === 1 ? bbox[1] : bbox[0], edge[1] === 1 ? bbox[3] : bbox[2], edge[2] === 1 ? bbox[5] : bbox[4]]; return {at: at, line: line, level: level, trans: trans, scale: scale}; }; rglwidgetClass.prototype.fixVertex = function(orig, parms, center, bbox) { var vertex = [0,0,0]; if (this.missing(orig[0])) vertex[parms.at] = center[parms.at]; else if (orig[0] === "-Inf") vertex[parms.at] = bbox[2*parms.at]; else if (orig[0] === "Inf") vertex[parms.at] = bbox[2*parms.at + 1]; else vertex[parms.at] = orig[0]; vertex[parms.line] = parms.scale[parms.line]*orig[1] + parms.trans[parms.line]; vertex[parms.level] = parms.scale[parms.level]*orig[2] + parms.trans[parms.level]; return vertex; }; rglwidgetClass.prototype.fixNormal = function(orig, parms) { var vertex = [0,0,0]; vertex[parms.at] = orig[0]; vertex[parms.line] = orig[1]/parms.scale[parms.line]; vertex[parms.level] = orig[2]/parms.scale[parms.level]; return vertex; }; rglwidgetClass.prototype.marginVecToDataVec = function(obj, subscene) { var bboxdeco = this.getBBoxDeco(subscene), center, bbox, parms, parmsjson, orig = obj.orig, vertices = [], normals = [], centers = [], i, vertex; if (typeof orig === "undefined") { orig = {vert: obj.vertices, norm: obj.normals, cent: obj.centers, doNormals: typeof obj.normals !== "undefined", doCenters: typeof obj.centers !== "undefined", parms: "" }; obj.orig = orig; } if (typeof bboxdeco !== "undefined") { this.setBbox(bboxdeco, subscene); center = bboxdeco.center; bbox = bboxdeco.bbox; parms = this.getMarginParameters(bboxdeco, obj.material); if (typeof parms === "undefined") return false; /* axis is not currently shown */ parmsjson = JSON.stringify(parms); if (parmsjson === orig.parms) return true; /* nothing has changed */ orig.parms = parmsjson; for (i=0; i < orig.vert.length; i++) { vertex = this.fixVertex(orig.vert[i], parms, center, bbox); vertices.push(vertex); } obj.vertices = vertices; if (orig.doNormals) { for (i=0; i < orig.norm.length; i++) { vertex = this.fixNormal(orig.norm[i], parms); normals.push(vertex); } obj.normals = normals; } if (orig.doCenters) { for (i=0; i < orig.cent.length; i++) { vertex = this.fixVertex(orig.cent[i], parms, center, bbox); centers.push(vertex); } obj.centers = centers; } obj.initialized = false; return true; } else { console.warn("bboxdeco not found"); return false; } }; rglwidgetClass.prototype.doAxisCallback = function(obj, edges) { var i, j, code, axis, fn; for (i = 0; i < 3; i++) { if (obj.axes.mode[i] === "user") { axis = ["x", "y", "z"][i]; if (typeof obj.callbacks !== "undefined" && typeof (code = obj.callbacks[axis]) !== "undefined") { if (typeof edges[i] !== "undefined") for (j = 0; j < 3; j++) if (typeof edges[i][j] !== "undefined") axis = axis + (edges[i][j] > 0 ? "+" : "-"); /* jshint evil:true */ fn = Function('"use strict";return (' + code + ')')(); /* jshint evil:false */ fn.call(this, axis); } } } }; rgl/inst/htmlwidgets/lib/rglClass/rglClass.src.js0000644000176200001440000000433414100762640021570 0ustar liggesusers//// To generate the help pages for this library, use // jsdoc --template /usr/local/lib/node_modules/foodoc/template *.src.js -R README.md -c JSDoc.json // To test, set environment variable RGL_DEBUGGING=true // before building. /* globals rglwidgetClass: true */ /** * The class of an rgl widget * @class */ rglwidgetClass = function() { this.canvas = null; this.userMatrix = new CanvasMatrix4(); this.types = []; this.prMatrix = new CanvasMatrix4(); this.mvMatrix = new CanvasMatrix4(); this.vp = null; this.prmvMatrix = null; this.origs = null; this.gl = null; this.scene = null; this.select = {state: "inactive", subscene: null, region: {p1: {x:0, y:0}, p2: {x:0, y:0}}}; this.drawing = false; }; rglwidgetClass.prototype.f_is_lit = 1; rglwidgetClass.prototype.f_is_smooth = 2; rglwidgetClass.prototype.f_has_texture = 4; rglwidgetClass.prototype.f_depth_sort = 8; rglwidgetClass.prototype.f_fixed_quads = 16; rglwidgetClass.prototype.f_is_transparent = 32; rglwidgetClass.prototype.f_is_lines = 64; rglwidgetClass.prototype.f_sprites_3d = 128; rglwidgetClass.prototype.f_is_subscene = 256; rglwidgetClass.prototype.f_is_clipplanes = 512; rglwidgetClass.prototype.f_fixed_size = 1024; rglwidgetClass.prototype.f_is_points = 2048; rglwidgetClass.prototype.f_is_twosided = 4096; rglwidgetClass.prototype.f_fat_lines = 8192; rglwidgetClass.prototype.f_is_brush = 16384; rglwidgetClass.prototype.f_has_fog = 32768; rglwidgetClass.prototype.fogNone = 0; rglwidgetClass.prototype.fogLinear = 1; rglwidgetClass.prototype.fogExp = 2; rglwidgetClass.prototype.fogExp2 = 3; /** * Methods related to obsolete approaches. * @name ___OBSOLETE_METHODS___ * @memberof rglwidgetClass * @kind function * @instance */ /** * Start the writeWebGL scene. This is only used by writeWebGL; rglwidget has no debug element. */ rglwidgetClass.prototype.start = function() { if (typeof this.prefix !== "undefined") { this.debugelement = document.getElementById(this.prefix + "debug"); this.debug(""); } this.drag = 0; this.drawScene(); }; rgl/inst/htmlwidgets/lib/rglClass/subscenes.src.js0000644000176200001440000001345014122351532022005 0ustar liggesusers /** * Methods related to subscenes * @name ___METHODS_FOR_SUBSCENES___ * @memberof rglwidgetClass * @kind function * @instance */ /** * Is a particular id in a subscene? * @returns { boolean } * @param {number} id Which id? * @param {number} subscene Which subscene id? */ rglwidgetClass.prototype.inSubscene = function(id, subscene) { return this.getObj(subscene).objects.indexOf(id) > -1; }; /** * Translate from window coordinates to viewport coordinates * @returns { Object } translated coordinates * @param { number } subsceneid - which subscene to use? * @param { Object } coords - point to translate */ rglwidgetClass.prototype.translateCoords = function(subsceneid, coords) { var viewport = this.getObj(subsceneid).par3d.viewport; return {x: coords.x - viewport.x*this.canvas.width, y: coords.y - viewport.y*this.canvas.height}; }; /** * Check whether point is in viewport of subscene * @returns {boolean} * @param { Object } coords - screen coordinates of point * @param { number } subsceneid - subscene to check */ rglwidgetClass.prototype.inViewport = function(coords, subsceneid) { var viewport = this.getObj(subsceneid).par3d.viewport, x0 = coords.x - viewport.x*this.canvas.width, y0 = coords.y - viewport.y*this.canvas.height; return 0 <= x0 && x0 <= viewport.width*this.canvas.width && 0 <= y0 && y0 <= viewport.height*this.canvas.height; }; /** * Find which subscene contains a point * @returns { number } subscene id * @param { Object } coords - coordinates of point */ rglwidgetClass.prototype.whichSubscene = function(coords) { var self = this, recurse = function(subsceneid) { var subscenes = self.getChildSubscenes(subsceneid), i, id; for (i=0; i < subscenes.length; i++) { id = recurse(subscenes[i]); if (typeof(id) !== "undefined") return(id); } if (self.inViewport(coords, subsceneid)) return(subsceneid); else return undefined; }, rootid = this.scene.rootSubscene, result = recurse(rootid); if (typeof(result) === "undefined") result = rootid; return result; }; /** * Add an id to a subscene. * @param {number} id Which id? * @param {number} subscene Which subscene id? */ rglwidgetClass.prototype.addToSubscene = function(id, subscene) { var thelist, thesub = this.getObj(subscene), ids = [id], obj = this.getObj(id), i; if (typeof obj !== "undefined" && typeof (obj.newIds) !== "undefined") { ids = ids.concat(obj.newIds); } thesub.objects = [].concat(thesub.objects); for (i = 0; i < ids.length; i++) { id = ids[i]; if (thesub.objects.indexOf(id) === -1) { thelist = this.whichList(id); thesub.objects.push(id); thesub[thelist].push(id); } } }; /** * Delete an id from a subscene * @param { number } id - the id to add * @param { number } subscene - the id of the subscene */ rglwidgetClass.prototype.delFromSubscene = function(id, subscene) { var thelist, thesub = this.getObj(subscene), obj = this.getObj(id), ids = [id], i, j; if (typeof obj !== "undefined" && typeof (obj.newIds) !== "undefined") ids = ids.concat(obj.newIds); thesub.objects = [].concat(thesub.objects); // It might be a scalar for (j=0; j -1) { thesub.objects.splice(i, 1); thelist = this.whichList(id); i = thesub[thelist].indexOf(id); thesub[thelist].splice(i, 1); } } }; /** * Set the ids in a subscene * @param { number[] } ids - the ids to set * @param { number } subsceneid - the id of the subscene */ rglwidgetClass.prototype.setSubsceneEntries = function(ids, subsceneid) { var sub = this.getObj(subsceneid); sub.objects = ids; this.initSubscene(subsceneid); }; /** * Get the ids in a subscene * @returns {number[]} * @param { number } subscene - the id of the subscene */ rglwidgetClass.prototype.getSubsceneEntries = function(subscene) { return this.getObj(subscene).objects; }; /** * Get the ids of the subscenes within a subscene * @returns { number[] } * @param { number } subscene - the id of the subscene */ rglwidgetClass.prototype.getChildSubscenes = function(subscene) { return this.getObj(subscene).subscenes; }; /** * Find a particular subscene by inheritance * @returns { number } id of subscene to use * @param { number } subsceneid - child subscene * @param { string } type - type of inheritance: "projection" or "model" */ rglwidgetClass.prototype.useid = function(subsceneid, type) { var sub = this.getObj(subsceneid); if (sub.embeddings[type] === "inherit") return(this.useid(sub.parent, type)); else return subsceneid; }; /** * Find bboxdeco for a subscene * @returns { number } id of bboxdeco, or undefined if none * @param { number } sub- subscene */ rglwidgetClass.prototype.getBBoxDeco = function(sub) { var objects = sub.objects, i, obj; for (i = 0; i < objects.length; i++) { obj = this.getObj(objects[i]); if (obj.type === "bboxdeco") return obj; } if (sub.parent) return this.getBBoxDeco(sub.parent); else return undefined; }; rgl/inst/htmlwidgets/lib/rglClass/pretty.src.js0000644000176200001440000001356614100762640021354 0ustar liggesusers/** * Pretty function from R * @name ___PRETTY_FROM_R___ * @memberof rglwidgetClass * @kind function * @instance */ /* This file is translated from pretty.c, which was taken from the R sources, r61744 of src/appl/pretty.c, with minimal changes */ /* * R : A Computer Language for Statistical Data Analysis * Copyright (C) 1995-2012 The R Core Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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, a copy is available at * http://www.r-project.org/Licenses/ */ /** * Construct pretty values to cover an interval * @param { number } lo - lower end of interval * @param { number } up - upper end of interval * @param { number } ndiv - requested number of divisions * @param { number } min_n - minimum divisions * @param { number } shrink_sml - if too many cells, amount to shrink by * @param { number } high_u_fact - bias in favour of larger units * @param { number } eps_correction - correction to bounds * @param { Boolean } return_bounds - whether to return bounds * @description * Pretty Intervals * Constructs m "pretty" values which cover the given interval *lo <= *up * m ~= *ndiv + 1 (i.e., ndiv := approximate number of INTERVALS) * * It is not quite clear what should happen for *lo = *up; * S itself behaves quite funilly, then. * * In my opinion, a proper 'pretty' should always ensure * *lo < *up, and hence *ndiv >=1 in the result. * However, in S and here, we allow *lo == *up, and *ndiv = 0. * Note however, that we are NOT COMPATIBLE to S. [Martin M.] * * NEW (0.63.2): ns, nu are double (==> no danger of integer overflow) * * We determine * if the interval (up - lo) is ``small'' [<==> i_small == TRUE, below]. * For the ``i_small'' situation, there is a parameter shrink_sml, * the factor by which the "scale" is shrunk. ~~~~~~~~~~ * It is advisable to set it to some (smaller) integer power of 2, * since this enables exact floating point division. */ rglwidgetClass.prototype.R_pretty = function( lo, up, ndiv, min_n, shrink_sml, high_u_fact, eps_correction, return_bounds) { /* From version 0.65 on, we had rounding_eps := 1e-5, before, r..eps = 0 * 1e-7 is consistent with seq.default() */ var rounding_eps = 1e-7, h = high_u_fact[0], h5 = high_u_fact[1], dx, cell, unit, base, U, ns, nu, k, i_small, DBL_EPSILON = Number.EPSILON, DBL_MIN = Number.MIN_VALUE, DBL_MAX = Number.MAX_VALUE; dx = up - lo; /* cell := "scale" here */ if (dx === 0 && up === 0) { /* up == lo == 0 */ cell = 1; i_small = true; } else { cell = Math.max(Math.abs(lo), Math.abs(up)); /* U = upper bound on cell/unit */ U = (1 + (h5 >= 1.5*h+0.5)) ? 1/(1+h) : 1.5/(1+h5); /* added times 3, as several calculations here */ i_small = dx < cell * U * Math.max(1,ndiv) * DBL_EPSILON *3; } /*OLD: cell = FLT_EPSILON+ dx / *ndiv; FLT_EPSILON = 1.192e-07 */ if(i_small) { if(cell > 10) cell = 9 + cell/10; cell *= shrink_sml; if(min_n > 1) cell /= min_n; } else { cell = dx; if(ndiv > 1) cell /= ndiv; } if(cell < 20*DBL_MIN) { /* warning(_("Internal(pretty()): very small range.. corrected")); */ cell = 20*DBL_MIN; } else if(cell * 10 > DBL_MAX) { /* warning(_("Internal(pretty()): very large range.. corrected")); */ cell = 0.1*DBL_MAX; } base = Math.pow(10, Math.floor(Math.log10(cell))); /* base <= cell < 10*base */ /* unit : from { 1,2,5,10 } * base * such that |u - cell| is small, * favoring larger (if h > 1, else smaller) u values; * favor '5' more than '2' if h5 > h (default h5 = .5 + 1.5 h) */ unit = base; if((U = 2*base)-cell < h*(cell-unit)) { unit = U; if((U = 5*base)-cell < h5*(cell-unit)) { unit = U; if((U =10*base)-cell < h*(cell-unit)) unit = U; }} /* Result: c := cell, u := unit, b := base * c in [ 1, (2+ h) /(1+h) ] b ==> u= b * c in ( (2+ h)/(1+h), (5+2h5)/(1+h5)] b ==> u= 2b * c in ( (5+2h)/(1+h), (10+5h) /(1+h) ] b ==> u= 5b * c in ((10+5h)/(1+h), 10 ) b ==> u=10b * * ===> 2/5 *(2+h)/(1+h) <= c/u <= (2+h)/(1+h) */ ns = Math.floor(lo/unit+rounding_eps); nu = Math.ceil (up/unit-rounding_eps); if(eps_correction && (eps_correction > 1 || !i_small)) { if(lo !== 0.0) lo *= (1- DBL_EPSILON); else lo = -DBL_MIN; if(up !== 0.0) up *= (1+ DBL_EPSILON); else up = +DBL_MIN; } while(ns*unit > lo + rounding_eps*unit) ns--; while(nu*unit < up - rounding_eps*unit) nu++; k = Math.floor(0.5 + nu - ns); if(k < min_n) { /* ensure that nu - ns == min_n */ k = min_n - k; if(ns >= 0) { nu += k/2; ns -= k/2 + k%2;/* ==> nu-ns = old(nu-ns) + min_n -k = min_n */ } else { ns -= k/2; nu += k/2 + k%2; } ndiv = min_n; } else { ndiv = k; } if(return_bounds) { /* if()'s to ensure that result covers original range */ if(ns * unit < lo) lo = ns * unit; if(nu * unit > up) up = nu * unit; } else { lo = ns; up = nu; } return {lo:lo, up:up, ndiv:ndiv, unit:unit}; }; rgl/inst/htmlwidgets/lib/rglClass/rglTimer.src.js0000644000176200001440000001050414100762640021577 0ustar liggesusers /* globals rgltimerClass: true */ /** * The class of an rgl timer object * @class */ /** * Construct an rgltimerClass object * @constructor * @param { function } Tick - action when timer fires * @param { number } startTime - nominal start time in seconds * @param { number } interval - seconds between updates * @param { number } stopTime - nominal stop time in seconds * @param { number } stepSize - nominal step size * @param { number } value - current nominal time * @param { number } rate - nominal units per second * @param { string } loop - "none", "cycle" or "oscillate" * @param { Object } actions - list of actions */ rgltimerClass = function(Tick, startTime, interval, stopTime, stepSize, value, rate, loop, actions) { this.enabled = false; this.timerId = 0; /** nominal start time in seconds */ this.startTime = startTime; /** current nominal time */ this.value = value; /** seconds between updates */ this.interval = interval; /** nominal stop time */ this.stopTime = stopTime; /** nominal step size */ this.stepSize = stepSize; /** nominal units per second */ this.rate = rate; /** "none", "cycle", or "oscillate" */ this.loop = loop; /** real world start time */ this.realStart = undefined; /** multiplier for fast-forward or reverse */ this.multiplier = 1; this.actions = actions; this.Tick = Tick; }; /** * Methods related to players * @name ___METHODS_FOR_PLAYERS___ * @memberof rgltimerClass * @kind function * @instance */ /** * Start playing * @memberof rgltimerClass */ rgltimerClass.prototype.play = function() { if (this.enabled) { this.enabled = false; window.clearInterval(this.timerId); this.timerId = 0; return; } var tick = function(self) { var now = new Date(); self.value = self.multiplier*self.rate*(now - self.realStart)/1000 + self.startTime; self.forceToRange(); if (typeof self.Tick !== "undefined") { self.Tick(self.value); } }; this.realStart = new Date() - 1000*(this.value - this.startTime)/this.rate/this.multiplier; this.timerId = window.setInterval(tick, 1000*this.interval, this); this.enabled = true; }; /** * Force value into legal range */ rgltimerClass.prototype.forceToRange = function() { if (this.value > this.stopTime + this.stepSize/2 || this.value < this.startTime - this.stepSize/2) { if (!this.loop) { this.reset(); } else { var cycle = this.stopTime - this.startTime + this.stepSize, newval = (this.value - this.startTime) % cycle + this.startTime; if (newval < this.startTime) { newval += cycle; } this.realStart += (this.value - newval)*1000/this.multiplier/this.rate; this.value = newval; } } }; /** * Reset to start values */ rgltimerClass.prototype.reset = function() { this.value = this.startTime; this.newmultiplier(1); if (typeof this.Tick !== "undefined") { this.Tick(this.value); } if (this.enabled) this.play(); /* really pause... */ if (typeof this.PlayButton !== "undefined") this.PlayButton.value = "Play"; }; /** * Increase the multiplier to play faster */ rgltimerClass.prototype.faster = function() { this.newmultiplier(Math.SQRT2*this.multiplier); }; /** * Decrease the multiplier to play slower */ rgltimerClass.prototype.slower = function() { this.newmultiplier(this.multiplier/Math.SQRT2); }; /** * Change sign of multiplier to reverse direction */ rgltimerClass.prototype.reverse = function() { this.newmultiplier(-this.multiplier); }; /** * Set multiplier for play speed * @param { number } newmult - new value */ rgltimerClass.prototype.newmultiplier = function(newmult) { if (newmult !== this.multiplier) { this.realStart += 1000*(this.value - this.startTime)/this.rate*(1/this.multiplier - 1/newmult); this.multiplier = newmult; } }; /** * Take one step */ rgltimerClass.prototype.step = function() { this.value += this.rate*this.multiplier; this.forceToRange(); if (typeof this.Tick !== "undefined") this.Tick(this.value); }; rgl/inst/htmlwidgets/lib/rglClass/pieces.src.js0000644000176200001440000001020114123425210021246 0ustar liggesusers/** * Methods related to drawing transparent objects * @name ___METHODS_FOR_TRANSPARENCY___ * @memberof rglwidgetClass * @kind function * @instance * These functions order the centers of displayed objects so they * can be drawn using the painters algorithm, necessary to support * transparency. * Note that objid is not obj.id when drawing spheres. */ /** * Break objects into pieces * @returns { array } Array of pieces */ rglwidgetClass.prototype.getPieces = function(context, objid, subid, obj) { var n = obj.centers.length, depth, result = new Array(n), z, w, i; context = context.slice(); for(i=0; i 0) { var i, thiscontext = pieces[0].context, thisobjid = pieces[0].objid, thissubid = pieces[0].subid, indices = []; for (i= 0; i < pieces.length; i++) { if (pieces[i].context !== thiscontext || pieces[i].objid !== thisobjid || pieces[i].subid !== thissubid) { result.push({context: thiscontext, objid: thisobjid, subid: thissubid, indices: indices}); thiscontext = pieces[i].context; thisobjid = pieces[i].objid; thissubid = pieces[i].subid; indices = []; } indices.push(pieces[i].index); } result.push({context: thiscontext, objid: thisobjid, subid: thissubid, indices: indices}); } return result; }; /** * Sort pieces by depth * @returns { array } * @param { array } pieces - array of pieces */ rglwidgetClass.prototype.sortPieces = function(pieces) { var compare = function(i,j) { var diff = j.depth - i.depth; // We want to avoid context or obj changes, // so sort on those next. if (diff === 0) { var c1 = j.context.slice(), c2 = i.context.slice(); diff = c1.length - c2.length; while (diff === 0 && c1.length > 0) { diff = c1.pop() - c2.pop(); } if (diff === 0) diff = j.objid - i.objid; if (diff === 0) diff = j.subid - i.subid; } return diff; }, result = []; if (pieces.length) result = pieces.sort(compare); return result; }; rgl/inst/htmlwidgets/lib/rglClass/mouse.src.js0000644000176200001440000005035214122351532021145 0ustar liggesusers /** * Methods related to mouse handling * @name ___METHODS_FOR_MOUSE_HANDLING___ * @memberof rglwidgetClass * @kind function * @instance */ rglwidgetClass.prototype.getCursor = function(mode) { switch(mode) { case "none": return "none"; case "trackball": case "xAxis": case "yAxis": case "zAxis": case "polar": return "grab"; case "selecting": return "crosshair"; case "fov": case "zoom": return "zoom-in"; case "user": return "default"; } return "dragging"; }; /** * Set mouse mode for a subscene * @param { string } mode - name of mode * @param { number } button - button number (0 to 4) * @param { number } subscene - subscene id number * @param { number } stayActive - if truthy, don't clear brush */ rglwidgetClass.prototype.setMouseMode = function(mode, button, subscene, stayActive) { var sub = this.getObj(subscene), which = ["none", "left", "right", "middle", "wheel"][button]; if (!stayActive && sub.par3d.mouseMode[which] === "selecting") this.clearBrush(null); sub.par3d.mouseMode[which] = mode; if (button === 1 || (button === 0 && mode !== "none")) this.canvas.style.cursor = this.getCursor(mode); if (button === 0 && mode !== "none") sub.needsBegin = mode; }; /** * Compute mouse coordinates relative to current canvas * @returns { Object } * @param { Object } event - event object from mouse click */ rglwidgetClass.prototype.relMouseCoords = function(event) { var rect = this.canvas.getBoundingClientRect(); return {x:event.clientX-rect.left, y:event.clientY-rect.top}; }; /** * Send mouse selection to Shiny */ rglwidgetClass.prototype.recordSelection = function(subid) { var result = {}; if (typeof this.select !== "undefined" && typeof this.select.state !== "undefined" && this.select.state !== "inactive") { result = { subscene: subid, state: this.select.state, region: this.select.region }; this.setmvMatrix(subid); result.model = this.mvMatrix; this.setprMatrix(subid); result.proj = this.prMatrix; this.getViewport(subid); result.view = this.vp; } else result.state = "inactive"; Shiny.setInputValue(this.scene.selectionInput + ":shinyMouse3d", result); }; /** * Set mouse handlers for the scene */ rglwidgetClass.prototype.setMouseHandlers = function() { var self = this, activeSubscene, handler, handlers = {}, drag = 0; handlers.rotBase = 0; self.screenToVector = function(x, y) { var viewport = self.getObj(activeSubscene).par3d.viewport, width = viewport.width*self.canvas.width, height = viewport.height*self.canvas.height, radius = Math.max(width, height)/2.0, cx = width/2.0, cy = height/2.0, px = (x-cx)/radius, py = (y-cy)/radius, plen = Math.sqrt(px*px+py*py); if (plen > 1.e-6) { px = px/plen; py = py/plen; } var angle = (Math.SQRT2 - plen)/Math.SQRT2*Math.PI/2, z = Math.sin(angle), zlen = Math.sqrt(1.0 - z*z); px = px * zlen; py = py * zlen; return [px, py, z]; }; handlers.trackballdown = function(x,y) { var activeSub = self.getObj(activeSubscene), activeModel = self.getObj(self.useid(activeSub.id, "model")), i, l = activeModel.par3d.listeners; handlers.rotBase = self.screenToVector(x, y); self.saveMat = []; for (i = 0; i < l.length; i++) { activeSub = self.getObj(l[i]); activeSub.saveMat = new CanvasMatrix4(activeSub.par3d.userMatrix); } self.canvas.style.cursor = "grabbing"; }; handlers.trackballmove = function(x,y) { var rotCurrent = self.screenToVector(x,y), rotBase = handlers.rotBase, dot = rotBase[0]*rotCurrent[0] + rotBase[1]*rotCurrent[1] + rotBase[2]*rotCurrent[2], angle = Math.acos( dot/self.vlen(rotBase)/self.vlen(rotCurrent) )*180.0/Math.PI, axis = self.xprod(rotBase, rotCurrent), objects = self.scene.objects, activeSub = self.getObj(activeSubscene), activeModel = self.getObj(self.useid(activeSub.id, "model")), l = activeModel.par3d.listeners, i; if (angle === 0.0) return; for (i = 0; i < l.length; i++) { activeSub = self.getObj(l[i]); activeSub.par3d.userMatrix.load(objects[l[i]].saveMat); activeSub.par3d.userMatrix.rotate(angle, axis[0], axis[1], axis[2]); } self.drawScene(); }; handlers.trackballend = 0; self.clamp = function(x, lo, hi) { return Math.max(lo, Math.min(x, hi)); }; self.screenToPolar = function(x,y) { var viewport = self.getObj(activeSubscene).par3d.viewport, width = viewport.width*self.canvas.width, height = viewport.height*self.canvas.height, r = Math.min(width, height)/2, dx = self.clamp(x - width/2, -r, r), dy = self.clamp(y - height/2, -r, r); return [Math.asin(dx/r), Math.asin(-dy/r)]; }; handlers.polardown = function(x,y) { var activeSub = self.getObj(activeSubscene), activeModel = self.getObj(self.useid(activeSub.id, "model")), i, l = activeModel.par3d.listeners; handlers.dragBase = self.screenToPolar(x, y); self.saveMat = []; for (i = 0; i < l.length; i++) { activeSub = self.getObj(l[i]); activeSub.saveMat = new CanvasMatrix4(activeSub.par3d.userMatrix); activeSub.camBase = [-Math.atan2(activeSub.saveMat.m13, activeSub.saveMat.m11), Math.atan2(activeSub.saveMat.m32, activeSub.saveMat.m22)]; } self.canvas.style.cursor = "grabbing"; }; handlers.polarmove = function(x,y) { var dragCurrent = self.screenToPolar(x,y), activeSub = self.getObj(activeSubscene), activeModel = self.getObj(self.useid(activeSub.id, "model")), objects = self.scene.objects, l = activeModel.par3d.listeners, i, j, changepos = []; for (i = 0; i < l.length; i++) { activeSub = self.getObj(l[i]); for (j=0; j<2; j++) changepos[j] = -(dragCurrent[j] - handlers.dragBase[j]); activeSub.par3d.userMatrix.makeIdentity(); activeSub.par3d.userMatrix.rotate(changepos[0]*180/Math.PI, 0,-1,0); activeSub.par3d.userMatrix.multRight(objects[l[i]].saveMat); activeSub.par3d.userMatrix.rotate(changepos[1]*180/Math.PI, -1,0,0); } self.drawScene(); }; handlers.polarend = 0; handlers.axisdown = function(x) { handlers.rotBase = self.screenToVector(x, self.canvas.height/2); var activeSub = self.getObj(activeSubscene), activeModel = self.getObj(self.useid(activeSub.id, "model")), i, l = activeModel.par3d.listeners; for (i = 0; i < l.length; i++) { activeSub = self.getObj(l[i]); activeSub.saveMat = new CanvasMatrix4(activeSub.par3d.userMatrix); } self.canvas.style.cursor = "grabbing"; }; handlers.axismove = function(x) { var rotCurrent = self.screenToVector(x, self.canvas.height/2), rotBase = handlers.rotBase, angle = (rotCurrent[0] - rotBase[0])*180/Math.PI, rotMat = new CanvasMatrix4(); rotMat.rotate(angle, handlers.axis[0], handlers.axis[1], handlers.axis[2]); var activeSub = self.getObj(activeSubscene), activeModel = self.getObj(self.useid(activeSub.id, "model")), i, l = activeModel.par3d.listeners; for (i = 0; i < l.length; i++) { activeSub = self.getObj(l[i]); activeSub.par3d.userMatrix.load(activeSub.saveMat); activeSub.par3d.userMatrix.multLeft(rotMat); } self.drawScene(); }; handlers.axisend = 0; handlers.y0zoom = 0; handlers.zoomdown = function(x, y) { var activeSub = self.getObj(activeSubscene), activeProjection = self.getObj(self.useid(activeSub.id, "projection")), i, l = activeProjection.par3d.listeners; handlers.y0zoom = y; for (i = 0; i < l.length; i++) { activeSub = self.getObj(l[i]); activeSub.zoom0 = Math.log(activeSub.par3d.zoom); } self.canvas.style.cursor = "zoom-in"; }; handlers.zoommove = function(x, y) { var activeSub = self.getObj(activeSubscene), activeProjection = self.getObj(self.useid(activeSub.id, "projection")), i, l = activeProjection.par3d.listeners; for (i = 0; i < l.length; i++) { activeSub = self.getObj(l[i]); activeSub.par3d.zoom = Math.exp(activeSub.zoom0 + (y-handlers.y0zoom)/self.canvas.height); } self.drawScene(); }; handlers.zoomend = 0; handlers.y0fov = 0; handlers.fovdown = function(x, y) { handlers.y0fov = y; var activeSub = self.getObj(activeSubscene), activeProjection = self.getObj(self.useid(activeSub.id, "projection")), i, l = activeProjection.par3d.listeners; for (i = 0; i < l.length; i++) { activeSub = self.getObj(l[i]); activeSub.fov0 = activeSub.par3d.FOV; } self.canvas.style.cursor = "zoom-in"; }; handlers.fovmove = function(x, y) { var activeSub = self.getObj(activeSubscene), activeProjection = self.getObj(self.useid(activeSub.id, "projection")), i, l = activeProjection.par3d.listeners; for (i = 0; i < l.length; i++) { activeSub = self.getObj(l[i]); activeSub.par3d.FOV = Math.max(1, Math.min(179, activeSub.fov0 + 180*(y-handlers.y0fov)/self.canvas.height)); } self.drawScene(); }; handlers.fovend = 0; handlers.selectingdown = function(x, y) { var viewport = self.getObj(activeSubscene).par3d.viewport, width = viewport.width*self.canvas.width, height = viewport.height*self.canvas.height, p = {x: 2.0*x/width - 1.0, y: 2.0*y/height - 1.0}; self.select.region = {p1: p, p2: p}; if (self.select.subscene && self.select.subscene !== activeSubscene) self.delFromSubscene(self.scene.brushId, self.select.subscene); self.select.subscene = activeSubscene; self.addToSubscene(self.scene.brushId, activeSubscene); self.select.state = "changing"; if (typeof self.scene.brushId !== "undefined") self.getObj(self.scene.brushId).initialized = false; if (typeof self.scene.selectionInput !== "undefined") self.recordSelection(activeSubscene); self.drawScene(); self.canvas.style.cursor = "crosshair"; }; handlers.selectingmove = function(x, y) { var viewport = self.getObj(activeSubscene).par3d.viewport, width = viewport.width*self.canvas.width, height = viewport.height*self.canvas.height; if (self.select.state === "inactive") return; self.select.region.p2 = {x: 2.0*x/width - 1.0, y: 2.0*y/height - 1.0}; if (typeof self.scene.brushId !== "undefined") self.getObj(self.scene.brushId).initialized = false; if (typeof self.scene.selectionInput !== "undefined") self.recordSelection(activeSubscene); self.drawScene(); }; handlers.selectingend = 0; /* jshint evil:true */ handlers.userdown = function(x, y) { var sub = self.getObj(activeSubscene), code = sub.callbacks[drag].begin; if (code) { var fn = Function('"use strict";return (' + code + ')')(); fn.call(self, x, y); } }; handlers.usermove = function(x, y) { var sub = self.getObj(activeSubscene), code = sub.callbacks[drag].update; if (code) { var fn = Function('"use strict";return (' + code + ')')(); fn.call(self, x, y); } }; handlers.userend = function() { var sub = self.getObj(activeSubscene), code = sub.callbacks[drag].end; if (code) { var fn = Function('"use strict";return (' + code + ')')(); fn.call(self); } }; self.canvas.onmousedown = function ( ev ){ if (!ev.which) // Use w3c defns in preference to MS switch (ev.button) { case 0: ev.which = 1; break; case 1: case 4: ev.which = 2; break; case 2: ev.which = 3; } drag = ["none", "left", "middle", "right", "wheel"][ev.which]; var coords = self.relMouseCoords(ev); coords.y = self.canvas.height-coords.y; activeSubscene = self.whichSubscene(coords); var sub = self.getObj(activeSubscene), f; handler = sub.par3d.mouseMode[drag]; switch (handler) { case "xAxis": handler = "axis"; handlers.axis = [1.0, 0.0, 0.0]; break; case "yAxis": handler = "axis"; handlers.axis = [0.0, 1.0, 0.0]; break; case "zAxis": handler = "axis"; handlers.axis = [0.0, 0.0, 1.0]; break; } f = handlers[handler + "down"]; if (f) { coords = self.translateCoords(activeSubscene, coords); f.call(self, coords.x, coords.y); ev.preventDefault(); } else console.warn("Mouse handler '" + handler + "' is not implemented."); }; self.canvas.onmouseup = function ( ev ){ if ( !drag ) return; var f = handlers[handler + "end"]; if (f) { f.call(self); ev.preventDefault(); } drag = 0; handlers.onmousemove( ev ); }; self.canvas.onmouseout = self.canvas.onmouseup; handlers.onmousemove = function ( ev ) { var coords = self.relMouseCoords(ev), sub, f; coords.y = self.canvas.height - coords.y; if (ev.buttons === 0) { activeSubscene = self.whichSubscene(coords); drag = "none"; sub = self.getObj(activeSubscene); handler = sub.par3d.mouseMode.none; if (handler !== "none") { if (sub.needsBegin) { f = handlers[handler + "down"]; if (f) { coords = self.translateCoords(activeSubscene, coords); f.call(self, coords.x, coords.y); } sub.needsBegin = 0; } self.canvas.style.cursor = self.getCursor(sub.par3d.mouseMode.none); } else { self.canvas.style.cursor = self.getCursor(sub.par3d.mouseMode.left); return; } } f = handlers[handler + "move"]; if (f) { coords = self.translateCoords(activeSubscene, coords); f.call(self, coords.x, coords.y); } }; self.canvas.onmouseenter = function() { self.canvas.addEventListener("mousemove", handlers.onmousemove); }; self.canvas.onmouseleave = function() { self.canvas.removeEventListener("mousemove", handlers.onmousemove); }; handlers.setZoom = function(ds) { var i; if (typeof activeSubscene === "undefined") activeSubscene = self.scene.rootSubscene; var activeSub = self.getObj(activeSubscene), activeProjection = self.getObj(self.useid(activeSub.id, "projection")), l = activeProjection.par3d.listeners; for (i = 0; i < l.length; i++) { activeSub = self.getObj(l[i]); activeSub.par3d.zoom *= ds; } self.drawScene(); }; handlers.pushwheel = function(ev) { ev.deltaY = -ev.deltaY; handlers.pullwheel(ev); }; handlers.pullwheel = function(ev) { var del = 1.05; if (ev.shiftKey) del = 1.005; var ds = ev.deltaY < 0 ? del : (1 / del); handlers.setZoom(ds); }; handlers.user2wheel = function(ev) { var sub = self.getObj(activeSubscene), code = sub.callbacks.wheel.rotate; if (code) { var fn = Function('"use strict";return (' + code + ')')(); /* jshint evil:false */ fn.call(self, ev.deltaY < 0 ? 1 : 2); } }; handlers.wheelHandler = function(ev) { var coords = self.relMouseCoords(ev); coords.y = self.canvas.height - coords.y; activeSubscene = self.whichSubscene(coords); var sub = self.getObj(activeSubscene), f, handler = sub.par3d.mouseMode.wheel, evlocal; ev.deltaY = ev.deltaY || ev.detail || ev.deltaX || ev.wheelDelta; switch(handler) { case "none": break; case "push": case "pull": case "user2": f = handlers[handler + "wheel"]; if (f) { evlocal = {}; evlocal.deltaY = ev.deltaY; evlocal.shiftKey = ev.shiftKey; evlocal.preventDefault = function() { ev.preventDefault(); }; f.call(self, evlocal); } break; default: evlocal = {}; evlocal.preventDefault = function() { ev.preventDefault(); }; evlocal.which = 4; evlocal.clientX = self.canvas.width/2; evlocal.clientY = self.canvas.height/2; self.canvas.onmousedown(evlocal); evlocal.clientX += ev.deltaX; evlocal.clientY += ev.deltaY; handlers.onmousemove(evlocal); self.canvas.onmouseup(evlocal); } ev.preventDefault(); }; handlers.get_finger_dist = function(ev) { var diffX = ev.touches[0].clientX - ev.touches[1].clientX, diffY = ev.touches[0].clientY - ev.touches[1].clientY; return Math.sqrt(diffX * diffX + diffY * diffY); }; handlers.touchstart = function(ev) { var touch = ev.touches[0], mouseEvent = new MouseEvent("mousedown", { clientX: touch.clientX, clientY: touch.clientY }); ev.preventDefault(); if (ev.touches.length === 2) { var coords = self.relMouseCoords(touch); coords.y = self.canvas.height-coords.y; activeSubscene = self.whichSubscene(coords); handlers.finger_dist0 = handlers.get_finger_dist(ev); handlers.zoomdown(coords.x, coords.y); } self.dispatchEvent(mouseEvent); }; handlers.touchend = function(ev) { var mouseEvent; ev.preventDefault(); if (ev.touches.length === 1) { mouseEvent = new MouseEvent("mouseup", {}); self.dispatchEvent(mouseEvent); } }; handlers.touchmove = function(ev) { var touch = ev.touches[0], mouseEvent; ev.preventDefault(); if (ev.touches.length > 1) { var coords = self.relMouseCoords(touch), new_dist = handlers.get_finger_dist(ev); coords.y = self.canvas.height*Math.log(handlers.finger_dist0/new_dist) + handlers.y0zoom; handlers.zoommove(coords.x, coords.y); } else { mouseEvent = new MouseEvent("mousemove", { clientX: touch.clientX, clientY: touch.clientY }); self.dispatchEvent(mouseEvent); } }; self.canvas.addEventListener("DOMMouseScroll", handlers.wheelHandler, false); self.canvas.addEventListener("mousewheel", handlers.wheelHandler, false); self.canvas.addEventListener("touchstart", handlers.touchstart, {passive: false}); self.canvas.addEventListener("touchend", handlers.touchend, {passive: false}); self.canvas.addEventListener("touchmove", handlers.touchmove, {passive: false}); }; rgl/inst/htmlwidgets/lib/rglClass/draw.src.js0000644000176200001440000011676614145464133020775 0ustar liggesusers /** * Methods related to drawing * @name ___METHODS_FOR_DRAWING___ * @memberof rglwidgetClass * @kind function * @instance */ /** * Start drawing * @returns { boolean } Previous state */ rglwidgetClass.prototype.startDrawing = function() { var value = this.drawing; this.drawing = true; return value; }; /** * Stop drawing and check for context loss * @param { boolean } saved - Previous state */ rglwidgetClass.prototype.stopDrawing = function(saved) { this.drawing = saved; if (!saved && this.gl && this.gl.isContextLost()) this.restartCanvas(); }; /** * Update the triangles used to display a plane * @param { number } id - id of the plane * @param { Object } bbox - bounding box in which to display the plane */ rglwidgetClass.prototype.planeUpdateTriangles = function(obj, bbox) { var perms = [[0,0,1], [1,2,2], [2,1,0]], x, xrow, elem, A, d, nhits, i, j, k, u, v, w, intersect, which, v0, v2, vx, reverse, face1 = [], face2 = [], normals = [], nPlanes = obj.normals.length; obj.bbox = bbox; obj.vertices = []; obj.initialized = false; for (elem = 0; elem < nPlanes; elem++) { // Vertex Av = normal.getRecycled(elem); x = []; A = obj.normals[elem]; d = obj.offsets[elem][0]; nhits = 0; for (i=0; i<3; i++) for (j=0; j<2; j++) for (k=0; k<2; k++) { u = perms[0][i]; v = perms[1][i]; w = perms[2][i]; if (A[w] !== 0.0) { intersect = -(d + A[u]*bbox[j+2*u] + A[v]*bbox[k+2*v])/A[w]; if (bbox[2*w] < intersect && intersect < bbox[1+2*w]) { xrow = []; xrow[u] = bbox[j+2*u]; xrow[v] = bbox[k+2*v]; xrow[w] = intersect; x.push(xrow); face1[nhits] = j + 2*u; face2[nhits] = k + 2*v; nhits++; } } } if (nhits > 3) { /* Re-order the intersections so the triangles work */ for (i=0; i i+1) { this.swap(x, i+1, which); this.swap(face1, i+1, which); this.swap(face2, i+1, which); } } } if (nhits >= 3) { /* Put in order so that the normal points out the FRONT of the faces */ v0 = [x[0][0] - x[1][0] , x[0][1] - x[1][1], x[0][2] - x[1][2]]; v2 = [x[2][0] - x[1][0] , x[2][1] - x[1][1], x[2][2] - x[1][2]]; /* cross-product */ vx = this.xprod(v0, v2); reverse = this.dotprod(vx, A) > 0; for (i=0; i= 0) { gl.enableVertexAttribArray( obj.normLoc ); gl.vertexAttribPointer(obj.normLoc, 3, gl.FLOAT, false, 4*obj.vOffsets.stride, 4*obj.vOffsets.nofs); return true; } else return false; }; /** * Do code for textures * @param { object } obj - Object to work with */ rglwidgetClass.prototype.doTexture = function(obj) { var gl = this.gl, is_spheres = obj.type === "spheres"; gl.enableVertexAttribArray( obj.texLoc ); if (is_spheres) gl.vertexAttribPointer(obj.texLoc, 2, gl.FLOAT, false, 4*this.sphere.vOffsets.stride, 4*this.sphere.vOffsets.tofs); else gl.vertexAttribPointer(obj.texLoc, 2, gl.FLOAT, false, 4*obj.vOffsets.stride, 4*obj.vOffsets.tofs); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, obj.texture); gl.uniform1i( obj.sampler, 0); return true; }; /** * Do code for user attributes * @param { object } obj - Object to work with */ rglwidgetClass.prototype.doUserAttributes = function(obj) { if (typeof obj.userAttributes !== "undefined") { var gl = this.gl; for (var attr in obj.userAttribSizes) { // Not all attributes may have been used gl.enableVertexAttribArray( obj.userAttribLocations[attr] ); gl.vertexAttribPointer( obj.userAttribLocations[attr], obj.userAttribSizes[attr], gl.FLOAT, false, 4*obj.vOffsets.stride, 4*obj.userAttribOffsets[attr]); } } }; /** * Do code for user uniforms * @param { object } obj - Object to work with */ rglwidgetClass.prototype.doUserUniforms = function(obj) { if (typeof obj.userUniforms !== "undefined") { var gl = this.gl; for (var attr in obj.userUniformLocations) { var loc = obj.userUniformLocations[attr]; if (loc !== null) { var uniform = obj.userUniforms[attr]; if (typeof uniform.length === "undefined") gl.uniform1f(loc, uniform); else if (typeof uniform[0].length === "undefined") { uniform = new Float32Array(uniform); switch(uniform.length) { case 2: gl.uniform2fv(loc, uniform); break; case 3: gl.uniform3fv(loc, uniform); break; case 4: gl.uniform4fv(loc, uniform); break; default: console.warn("bad uniform length"); } } else if (uniform.length === 4 && uniform[0].length === 4) gl.uniformMatrix4fv(loc, false, new Float32Array(uniform.getAsArray())); else console.warn("unsupported uniform matrix"); } } } }; /** * Load indices for complex drawing * @param { object } obj - Object to work with * @param { numeric } pass - Which pass of drawing? * @param { array } indices - Indices to draw */ rglwidgetClass.prototype.doLoadIndices = function(obj, pass, indices) { var gl = this.gl, f = obj.f[pass], type = obj.type, fat_lines = this.isSet(obj.flags, this.f_fat_lines), fnew, step; switch(type){ case "points": step = 1; break; case "abclines": case "lines": if (fat_lines) step = 6; else step = 2; break; case "linestrip": if (fat_lines) step = 6; else step = 1; break; case "sphere": case "planes": case "triangles": step = 3; break; case "text": case "sprites": case "quads": case "surface": step = 6; break; default: console.error("loadIndices for "+type); return 0; } if (obj.index_uint) fnew = new Uint32Array(step * indices.length); else fnew = new Uint16Array(step * indices.length); for (var i = 0; i < indices.length; i++) { for (var j = 0; j < step; j++) { fnew[step*i + j] = f[step*indices[i] + j]; } } gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, fnew, gl.DYNAMIC_DRAW); return fnew.length; }; /** * Do code for depth masking * @param { boolean } mask - whether to mask */ rglwidgetClass.prototype.doMasking = function(mask) { var gl = this.gl; gl.depthMask(mask); }; /** * Do code for alpha blending * @param { boolean } blend - Whether to blend. */ rglwidgetClass.prototype.doBlending = function(blend) { var gl = this.gl; if (blend) { gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE); gl.enable(gl.BLEND); } else { gl.disable(gl.BLEND); } }; /** * Set up for fog in the subscene * @param { object } obj - background object * @param { object } subscene - which subscene */ rglwidgetClass.prototype.doFog = function(obj, subscene) { var gl = this.gl, fogmode, color, observer = subscene.par3d.observer[2], sintheta = Math.sin(subscene.par3d.FOV*Math.PI/180/2), parms = [this.frustum.near - 2*observer, this.frustum.far - 2*observer, this.fogScale, (1-sintheta)/(1+sintheta)]; if (typeof this.fogType === "undefined") this.fogType = "none"; if (typeof this.fogScale === "undefined") parms[2] = 1; if (sintheta === 0) parms[3] = 1/3; switch(this.fogType){ case "none": fogmode = 0; break; case "linear": fogmode = 1; break; case "exp": fogmode = 2; break; case "exp2": fogmode = 3; break; default: console.error("Unknown fogtype "+this.fogType); } gl.uniform1i(obj.uFogMode, fogmode); color = this.fogColor; gl.uniform3f(obj.uFogColor, color[0], color[1], color[2]); gl.uniform4f(obj.uFogParms, parms[0], parms[1], parms[2], parms[3]); }; /* The draw methods are called twice. When this.opaquePass is true, they should draw opaque parts of the scene, and return the list of transparent pieces. Here context is the context array on input, modified when the matrices are changed. When this.opaquePass is false, the context argument contains a "piece", i.e. an ordered list of parts of the object to draw. */ /** * Draw simple object * @param { object } obj - Object to draw * @param { object } subscene - which subscene * @param { array } context - Which context are we in? */ rglwidgetClass.prototype.drawSimple = function(obj, subscene, context) { var flags = obj.flags, type = obj.type, is_lit = this.isSet(flags, this.f_is_lit), has_texture = this.isSet(flags, this.f_has_texture), is_transparent = this.isSet(flags, this.f_is_transparent), fixed_size = this.isSet(flags, this.f_fixed_size), fixed_quads = this.isSet(flags, this.f_fixed_quads), is_lines = this.isSet(flags, this.f_is_lines), fat_lines = this.isSet(flags, this.f_fat_lines), is_twosided = this.isSet(flags, this.f_is_twosided), has_fog = this.isSet(flags, this.f_has_fog), has_normals = (typeof obj.normals !== "undefined") || obj.type === "sphere", gl = this.gl || this.initGL(), count, pass, mode, pmode, enabled = {}; if (!obj.initialized) this.initObj(obj); count = obj.vertexCount; if (!count) return []; is_transparent = is_transparent || obj.someHidden; if (is_transparent && this.opaquePass) return this.getPieces(context, obj.id, 0, obj); this.doDepthTest(obj); this.doMasking(this.getMaterial(obj, "depth_mask")); gl.useProgram(obj.prog); this.doPolygonOffset(obj); gl.bindBuffer(gl.ARRAY_BUFFER, obj.buf); gl.uniformMatrix4fv( obj.prMatLoc, false, new Float32Array(this.prMatrix.getAsArray()) ); gl.uniformMatrix4fv( obj.mvMatLoc, false, new Float32Array(this.mvMatrix.getAsArray()) ); this.doClipping(obj, subscene); if (is_lit) this.doLighting(obj, subscene); if (has_fog) this.doFog(obj, subscene); this.doUserAttributes(obj); this.doUserUniforms(obj); gl.enableVertexAttribArray( this.posLoc ); enabled.posLoc = true; if (has_texture || obj.type === "text") enabled.texLoc = this.doTexture(obj); enabled.colLoc = this.doColors(obj); if (is_lit) enabled.normLoc = this.doNormals(obj); if (fixed_size) { gl.uniform3f( obj.textScaleLoc, 0.75/this.vp.width, 0.75/this.vp.height, 1.0); } if (fixed_quads) { gl.enableVertexAttribArray( obj.ofsLoc ); enabled.ofsLoc = true; gl.vertexAttribPointer(obj.ofsLoc, 3, gl.FLOAT, false, 4*obj.vOffsets.stride, 4*obj.vOffsets.oofs); } for (pass = 0; pass < obj.passes; pass++) { pmode = obj.pmode[pass]; if (pmode === "culled") continue; mode = fat_lines && (is_lines || pmode === "lines") ? "TRIANGLES" : this.mode4type[type]; if (is_twosided) { gl.uniform1i(obj.frontLoc, pass !== 0); if (has_normals) { gl.uniformMatrix4fv(obj.invPrMatLoc, false, new Float32Array(this.invPrMatrix.getAsArray())); } } gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, obj.ibuf[pass]); if (!this.opaquePass) { if (type === "sphere" && obj.fastTransparency) count = this.doLoadIndices(obj, pass, this.sphere.fastpieces[0].indices); else count = this.doLoadIndices(obj, pass, context.indices); } else { count = obj.f[pass].length; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, obj.f[pass], gl.STATIC_DRAW); } if (!is_lines && pmode === "lines" && !fat_lines) { mode = "LINES"; } else if (pmode === "points") { mode = "POINTS"; } if ((is_lines || pmode === "lines") && fat_lines) { gl.enableVertexAttribArray(obj.pointLoc); enabled.pointLoc = true; gl.vertexAttribPointer(obj.pointLoc, 2, gl.FLOAT, false, 4*obj.vOffsets.stride, 4*obj.vOffsets.pointofs); gl.enableVertexAttribArray(obj.nextLoc ); enabled.nextLoc = true; gl.vertexAttribPointer(obj.nextLoc, 3, gl.FLOAT, false, 4*obj.vOffsets.stride, 4*obj.vOffsets.nextofs); gl.uniform1f(obj.aspectLoc, this.vp.width/this.vp.height); gl.uniform1f(obj.lwdLoc, this.getMaterial(obj, "lwd")/this.vp.height); } gl.vertexAttribPointer(this.posLoc, 3, gl.FLOAT, false, 4*obj.vOffsets.stride, 4*obj.vOffsets.vofs); gl.drawElements(gl[mode], count, obj.index_uint ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT, 0); } this.disableArrays(obj, enabled); return []; }; /** * Draw planes object * @param { object } obj - Object to draw * @param { object } subscene - which subscene * @param { array } context - Which context are we in? */ rglwidgetClass.prototype.drawPlanes = function(obj, subscene, context) { if (obj.bbox !== subscene.par3d.bbox || !obj.initialized) { this.planeUpdateTriangles(obj, subscene.par3d.bbox); } return this.drawSimple(obj, subscene, context); }; /** * @param { object } obj - object to draw * @param { object } subscene * @param { array } context * @description * Draw spheres in a subscene
* * Drawing spheres happens in six ways:
* 1 opaquepass, not transparent: transform and draw this.sphere count times
* 2 opaquepass, transparent, not fast: transform & collect sphere pieces count times
* 3 opaquepass, transparent, fast: order the centres into separate pieces, order this.sphere once
* 4 not opaquepass, not transparent: do nothing
* 5 not opaquepass, transparent, not fast: transform for one sphere, draw one merged piece
* 6 not opaquepass, transparent, fast: transform for one sphere, draw this.sphere in fixed order.
**/ rglwidgetClass.prototype.drawSpheres = function(obj, subscene, context) { var flags = obj.flags, is_transparent = this.isSet(flags, this.f_is_transparent), sphereMV, baseofs, ofs, sscale, i, count, nc, scount, scale, indices, sphereNorm, enabled = {}, drawing, saveNorm = new CanvasMatrix4(this.normMatrix), saveMV = new CanvasMatrix4(this.mvMatrix), savePRMV = null, result = [], idx, margin = obj.material.margin; if (typeof margin !== "undefined") if (!this.marginVecToDataVec(obj, subscene)) return []; if (!obj.initialized) this.initObj(obj); count = obj.vertexCount; if (!count) return []; is_transparent = is_transparent || obj.someHidden; if (!this.opaquePass && !is_transparent) return []; if (this.prmvMatrix !== null) savePRMV = new CanvasMatrix4(this.prmvMatrix); scale = subscene.par3d.scale; sphereNorm = new CanvasMatrix4(); sphereNorm.scale(scale[0], scale[1], scale[2]); sphereNorm.multRight(saveNorm); this.normMatrix = sphereNorm; if (this.opaquePass) { context = context.slice(); context.push(obj.id); } drawing = this.opaquePass !== is_transparent; if (drawing) { nc = obj.colorCount; if (nc === 1) { this.sphere.onecolor = obj.onecolor; } } this.initShapeFromObj(this.sphere, obj); if (!this.opaquePass && obj.fastTransparency && typeof this.sphere.fastpieces === "undefined") { this.sphere.fastpieces = this.getPieces(context.context, obj.id, 0, this.sphere); this.sphere.fastpieces = this.sortPieces(this.sphere.fastpieces); this.sphere.fastpieces = this.mergePieces(this.sphere.fastpieces); } if (this.opaquePass) scount = count; else { indices = context.indices; if (obj.fastTransparency) scount = indices.length; /* Each item gives the center of a whole sphere */ else scount = 1; /* Each item is a fragment of the sphere, at location subid */ } for (i = 0; i < scount; i++) { sphereMV = new CanvasMatrix4(); if (this.opaquePass) idx = i; else if (obj.fastTransparency) idx = indices[i]; else idx = context.subid; if (typeof idx === "undefined") console.error("idx is undefined"); baseofs = idx*obj.vOffsets.stride; ofs = baseofs + obj.vOffsets.radofs; sscale = obj.values[ofs]; sphereMV.scale(sscale/scale[0], sscale/scale[1], sscale/scale[2]); sphereMV.translate(obj.values[baseofs], obj.values[baseofs+1], obj.values[baseofs+2]); sphereMV.multRight(saveMV); this.mvMatrix = sphereMV; this.setnormMatrix2(); this.setprmvMatrix(); if (drawing) { if (nc > 1) { this.sphere.onecolor = obj.values.slice(baseofs + obj.vOffsets.cofs, baseofs + obj.vOffsets.cofs + 4); } this.drawSimple(this.sphere, subscene, context); } else result = result.concat(this.getSpherePieces(context, i, obj)); } if (drawing) this.disableArrays(obj, enabled); this.normMatrix = saveNorm; this.mvMatrix = saveMV; this.prmvMatrix = savePRMV; return result; }; /** * Prepare clipplanes for drawing * @param { object } obj - clip planes object */ rglwidgetClass.prototype.drawClipplanes = function(obj) { var count = obj.offsets.length, IMVClip = []; for (var i=0; i < count; i++) { IMVClip[i] = this.multMV(this.invMatrix, obj.vClipplane.slice(4*i, 4*(i+1))); } obj.IMVClip = IMVClip; return []; }; /** * Prepare linestrip for drawing * @param { object } obj - line strip object * @param { object } subscene * @param { array } context */ rglwidgetClass.prototype.drawLinestrip = function(obj, subscene, context) { var origIndices, i, j, margin = obj.material.margin; if (typeof margin !== "undefined") if (!this.marginVecToDataVec(obj, subscene)) return []; if (this.opaquePass) return this.drawSimple(obj, subscene, context); origIndices = context.indices.slice(); for (i=0; i < origIndices.length; i++) { j = origIndices[i]; if (j < obj.centers.length - 1) { context.indices = [j, j+1]; this.drawSimple(obj, subscene, context); } } context.indices = origIndices; return []; }; /** * Draw a sprites object in a subscene * @param { object } obj - object to draw * @param { object } subscene * @param { object } context */ rglwidgetClass.prototype.drawSprites = function(obj, subscene, context) { var flags = obj.flags, is_transparent = this.isSet(flags, this.f_is_transparent), sprites3d = this.isSet(flags, this.f_sprites_3d), i,j, origMV = new CanvasMatrix4( this.mvMatrix ), origPRMV = null, pos, radius, userMatrix, result = [], margin = obj.material.margin; if (typeof margin !== "undefined") if (!this.marginVecToDataVec(obj, subscene)) return []; if (!sprites3d) return this.drawSimple(obj, subscene, context); if (!obj.initialized) this.initObj(obj); if (!obj.vertexCount) return []; is_transparent = is_transparent || obj.someHidden; var norigs = obj.vertices.length, savenorm = new CanvasMatrix4(this.normMatrix), iOrig, adj, offset; this.normMatrix = subscene.spriteNormmat; userMatrix = obj.userMatrix; if (this.opaquePass) { context = context.slice(); context.push(obj.id); } else norigs = 1; if (this.prmvMatrix !== null) origPRMV = new CanvasMatrix4( this.prmvMatrix ); offset = obj.offset; for (iOrig=0; iOrig < norigs; iOrig++) { if (this.opaquePass) j = iOrig; else j = context.subid; pos = this.multVM([].concat(obj.vertices[j]).concat(1.0), origMV); radius = obj.radii.length > 1 ? obj.radii[j][0] : obj.radii[0][0]; this.mvMatrix = new CanvasMatrix4(userMatrix); adj = this.getAdj(obj, j, offset); this.mvMatrix.translate(1 - 2*adj[0], 1 - 2*adj[1], 1 - 2*adj[2]); this.mvMatrix.scale(radius); this.mvMatrix.translate(pos[0]/pos[3], pos[1]/pos[3], pos[2]/pos[3]); this.setprmvMatrix(); for (i=0; i < obj.objects.length; i++) if (this.opaquePass) result = result.concat(this.drawObjId(obj.objects[i], subscene.id, context.concat(j))); else this.drawObjId(obj.objects[i], subscene.id, context); } this.normMatrix = savenorm; this.mvMatrix = origMV; if (origPRMV !== null) this.prmvMatrix = origPRMV; return result; }; /** * Draw object that might be in margin * @param { Object } obj - text object to draw * @param { Object } subscene - subscene holding it * @param { Object } context - context for drawing */ rglwidgetClass.prototype.drawMarginal = function(obj, subscene, context) { var margin = obj.material.margin; if (typeof margin !== "undefined") if (!this.marginVecToDataVec(obj, subscene)) return []; return this.drawSimple(obj, subscene, context); }; /** * Draw bounding box and decorations * @param { Object } obj - bboxdeco to draw * @param { Object } subscene - subscene holding it * @param { Object } context - context for drawing */ rglwidgetClass.prototype.drawBBox = function(obj, subscene, context) { var flags = obj.flags, is_transparent = this.isSet(flags, this.f_is_transparent), scale, bbox, indices, enabled = {}, drawing, result = [], idx, center, edges, saved; if (!obj.initialized) this.initBBox(obj); is_transparent = is_transparent || obj.someHidden; if (!this.opaquePass && !is_transparent) return result; this.setBbox(obj, subscene); saved = this.setBBoxMatrices(obj); bbox = obj.bbox; center = obj.center; scale = [bbox[1]-bbox[0], bbox[3]-bbox[2], bbox[5]-bbox[4]]; if (!obj.cube.initialized) { this.initObj(obj.cube); } if (this.opaquePass) { context = context.slice(); context.push(obj.id); } drawing = this.opaquePass !== is_transparent; this.cube.onecolor = obj.cube.onecolor; this.initShapeFromObj(this.cube, obj.cube); if (!this.opaquePass) indices = context.indices; if (this.opaquePass) idx = 0; else idx = context.subid; if (typeof idx === "undefined") console.error("idx is undefined"); if (drawing) { this.drawSimple(this.cube, subscene, context); } else result = result.concat(this.getCubePieces(context, obj)); if (drawing) { if (!obj.ticks.initialized) { obj.ticks.locations = this.getTickLocations(obj); obj.ticks.edges = undefined; } edges = this.getTickEdges(this.prmvMatrix); if (obj.needsAxisCallback) this.doAxisCallback(obj, edges); if (!obj.ticks.edges || edges.toString() !== obj.ticks.edges.toString()) { obj.ticks.edges = edges; this.getTickVertices(obj.ticks); this.placeTickLabels(obj); this.setTickLabels(obj); } if (!obj.ticks.initialized) { this.initObj(obj.ticks); this.initObj(obj.labels); } this.drawSimple(obj.ticks, subscene, context); this.drawSimple(obj.labels, subscene, context); } if (drawing) this.disableArrays(obj, enabled); this.restoreBBoxMatrices(saved); return result; }; /** * Use ids to choose object to draw * @param { numeric } id - object to draw * @param { numeric } subscene * @param { array } context */ rglwidgetClass.prototype.drawObjId = function(id, subsceneid, context) { if (typeof id !== "number") this.alertOnce("drawObjId id is "+typeof id); return this.drawObj(this.getObj(id), this.getObj(subsceneid), context); }; /** * Draw an object in a subscene * @param { object } obj - object to draw * @param { object } subscene * @param { array } context */ rglwidgetClass.prototype.drawObj = function(obj, subscene, context) { switch(obj.type) { case "abclines": case "surface": return this.drawSimple(obj, subscene, context); case "points": case "lines": case "triangles": case "quads": case "text": return this.drawMarginal(obj, subscene, context); case "linestrip": return this.drawLinestrip(obj, subscene, context); case "planes": return this.drawPlanes(obj, subscene, context); case "spheres": return this.drawSpheres(obj, subscene, context); case "clipplanes": return this.drawClipplanes(obj); case "sprites": return this.drawSprites(obj, subscene, context); case "light": return []; case "bboxdeco": return this.drawBBox(obj, subscene, context); } console.error("drawObj for type = "+obj.type); }; /** * Draw the background for a subscene * @param { number } id - id of background object * @param { number } subsceneid - id of subscene */ rglwidgetClass.prototype.drawBackground = function(id, subsceneid) { var gl = this.gl || this.initGL(), obj = this.getObj(id), bg, i, savepr, saveinvpr, savemv; if (!obj.initialized) this.initObj(obj); if (obj.colors.length) { bg = obj.colors[0]; gl.clearColor(bg[0], bg[1], bg[2], bg[3]); gl.depthMask(true); /* jshint bitwise: false */ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); /* jshint bitwise: true */ this.fogColor = bg; } else this.fogColor = [0,0,0,0]; this.fogType = obj.fogtype; this.fogScale = obj.fogscale; if (typeof obj.quad !== "undefined") { savepr = this.prMatrix; saveinvpr = this.invPrMatrix; savemv = this.mvMatrix; this.prMatrix = new CanvasMatrix4(); this.invPrMatrix = new CanvasMatrix4(); this.mvMatrix = new CanvasMatrix4(); gl.disable(gl.BLEND); gl.disable(gl.DEPTH_TEST); gl.depthMask(false); for (i=0; i < obj.quad.length; i++) this.drawObjId(obj.quad[i], subsceneid); this.prMatrix = savepr; this.invPrMatrix = saveinvpr; this.mvMatrix = savemv; } }; /** * Draw a subscene * @param { number } subsceneid - id of subscene * @param { array } context */ rglwidgetClass.prototype.drawSubscene = function(subsceneid, context) { var sub = this.getObj(subsceneid), objects = this.scene.objects, clipids = sub.clipplanes, subids = sub.objects, subscene_has_faces = false, subscene_needs_sorting = false, flags, i, obj, result = []; if (sub.par3d.skipRedraw) return result; if (this.opaquePass) { for (i=0; i < subids.length; i++) { obj = objects[subids[i]]; flags = obj.flags; if (typeof flags !== "undefined") { subscene_has_faces = subscene_has_faces || (this.isSet(flags, this.f_is_lit) && !this.isSet(flags, this.f_fixed_quads)); obj.is_transparent = obj.someHidden || this.isSet(flags, this.f_is_transparent); subscene_needs_sorting = subscene_needs_sorting || obj.is_transparent || this.isSet(flags, this.f_depth_sort); } } } this.setViewport(subsceneid); this.setprMatrix(subsceneid); this.setInvPrMatrix(); this.setmvMatrix(subsceneid); this.setnormMatrix2(); if (typeof sub.backgroundId !== "undefined" && this.opaquePass) this.drawBackground(sub.backgroundId, subsceneid); if (subids.length) { if (subscene_has_faces && this.isSet(sub.flags, this.f_sprites_3d) && typeof sub.spriteNormmat === "undefined") { sub.spriteNormmat = new CanvasMatrix4(this.normMatrix); } if (subscene_needs_sorting) this.setprmvMatrix(); if (clipids.length > 0) { this.invMatrix = new CanvasMatrix4(this.mvMatrix); this.invMatrix.invert(); for (i = 0; i < clipids.length; i++) this.drawObjId(clipids[i], subsceneid); } subids = sub.opaque.concat(sub.transparent); if (this.opaquePass) { context = context.slice(); context.push(subsceneid); this.doBlending(false); this.subsceneid = subsceneid; if (typeof this.sphere !== "undefined") // reset this.sphere.fastpieces; it will be recreated if needed this.sphere.fastpieces = undefined; for (i = 0; i < subids.length; i++) result = result.concat(this.drawObjId(subids[i], subsceneid, context)); subids = sub.subscenes; for (i = 0; i < subids.length; i++) result = result.concat(this.drawSubscene(subids[i], context)); } } return result; }; /** * Set the context for drawing transparently * @param { array } context */ rglwidgetClass.prototype.setContext = function(context) { var result = [], objid, obj, type; context = context.slice(); context.reverse(); while (context.length > 0) { objid = context.pop(); obj = this.getObj(objid); type = obj.type; switch (type) { case "subscene": this.drawSubscene(objid, false); break; case "sprites": result = result.concat(context.pop()); break; case "spheres": // this.initSphereFromObj(obj); // FIXME: not needed? break; case "bboxdeco": result = result.concat(context.pop()); break; default: console.error("bad type '", type, "' in setContext"); } } return result; }; /** * Draw the transparent pieces of a scene * @param {object} pieces */ rglwidgetClass.prototype.drawPieces = function(pieces) { var i, prevcontext = [], context; this.doBlending(true); for (i = 0; i < pieces.length; i++) { context = pieces[i].context.slice(); if (context !== prevcontext) { prevcontext = context.slice(); context = this.setContext(context); } this.drawObjId(pieces[i].objid, this.subsceneid, pieces[i]); } }; /** * Draw the whole scene */ rglwidgetClass.prototype.drawScene = function() { var wasDrawing = this.startDrawing(), pieces; if (!wasDrawing) { if (this.select.state !== "inactive") this.selectionChanged(); this.doStartScene(); this.opaquePass = true; pieces = this.drawSubscene(this.scene.rootSubscene, []); this.opaquePass = false; pieces = this.sortPieces(pieces); pieces = this.mergePieces(pieces); this.drawPieces(pieces); } this.stopDrawing(wasDrawing); }; rgl/inst/htmlwidgets/lib/rglClass/buffer.src.js0000644000176200001440000001200514146241661021266 0ustar liggesusers/** * Methods related to buffered data * @name ___METHODS_FOR_BUFFERS___ * @memberof rglwidgetClass * @kind function * @instance */ /** * Detect rglBuffered object * @param { Object } obj - vertices or similar */ rglwidgetClass.prototype.isBuffered = function(obj) { return typeof obj === "string"; }; /* The next two functions are taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding They were written by Mozilla Contributors and dedicated to the public domain under CC0. */ /* Array of bytes to Base64 string decoding */ rglwidgetClass.prototype.b64ToUint6 = function(nChr) { return nChr > 64 && nChr < 91 ? nChr - 65 : nChr > 96 && nChr < 123 ? nChr - 71 : nChr > 47 && nChr < 58 ? nChr + 4 : nChr === 43 ? 62 : nChr === 47 ? 63 : 0; }; /* jshint bitwise:false */ rglwidgetClass.prototype.base64DecToArr = function(sBase64, nBlocksSize) { var sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length, nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2, taBytes = new Uint8Array(nOutLen); for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) { nMod4 = nInIdx & 3; nUint24 |= this.b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 6 * (3 - nMod4); if (nMod4 === 3 || nInLen - nInIdx === 1) { for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255; } nUint24 = 0; } } return taBytes; }; /* jshint bitwise:true */ rglwidgetClass.prototype.getArrayBuffer = function(base64) { return this.base64DecToArr(base64, 4).buffer; }; rglwidgetClass.prototype.getBufferedData = function(v) { var typeSignedByte = 5120, typeUnsignedByte = 5121, typeSignedShort = 5122, typeUnsignedShort = 5123, typeSignedInt = 5124, typeUnsignedInt = 5125, typeFloat = 5126, typeDouble = 5130, buf = this.scene.buffer, accessor = buf.accessors[parseInt(v, 10)], bufferView = buf.bufferViews[accessor.bufferView], buffer = buf.buffers[bufferView.buffer], bytes, lens = { SCALAR: 1, VEC2: 2, VEC3: 3, VEC4: 4, MAT2: 4, MAT3: 9, MAT4: 16 }, rowsizes = { SCALAR: 1, VEC2: 2, VEC3: 3, VEC4: 4, MAT2: 2, MAT3: 3, MAT4: 4 }, offset = 0, len = lens[accessor.type], rowsize = rowsizes[accessor.type], count = len * accessor.count, nrows = count / rowsize, values, arr = [], row, i, j, k; if (typeof buffer.bytes === "string") buffer.bytes = this.getArrayBuffer(buffer.bytes); bytes = buffer.bytes; if (typeof accessor.byteOffset !== "undefined") offset += accessor.byteOffset; if (typeof bufferView.byteOffset !== "undefined") offset += bufferView.byteOffset; switch (accessor.componentType) { case typeSignedByte: values = new Int8Array(buffer.bytes, offset, count); break; case typeUnsignedByte: values = new Uint8Array(buffer.bytes, offset, count); break; case typeSignedShort: values = new Int16Array(buffer.bytes, offset, count); break; case typeUnsignedShort: values = new Uint16Array(buffer.bytes, offset, count); break; case typeSignedInt: values = new Int32Array(buffer.bytes, offset, count); break; case typeUnsignedInt: values = new Uint32Array(buffer.bytes, offset, count); break; case typeFloat: values = new Float32Array(buffer.bytes, offset, count); break; case typeDouble: values = new Float64Array(buffer.bytes, offset, count); break; } /* This is all very inefficient, but is convenient to work with the old code. */ k = 0; for (i = 0; i < nrows; i++) { row = []; for (j = 0; j < rowsize; j++) row.push(values[k++]); arr.push(row); } return arr; }; rglwidgetClass.prototype.expandBufferedFields = function(obj) { /* this list needs to match the one in convertScene.R */ var fields = ["vertices", "normals", "indices", "texcoords", "colors", "centers"], i, field; for (i = 0; i < fields.length; i++) { field = obj[fields[i]]; if (this.isBuffered(field)) obj[fields[i]] = this.getBufferedData(field); } }; rgl/inst/htmlwidgets/lib/rglClass/rgl.css0000644000176200001440000000044014100762640020162 0ustar liggesusers.rglPlayer { width: auto; height: auto; } .rglPlayer .rgl-button { width: auto; display: inline-block; font-size: 75%; } .rglPlayer .rgl-slider { display: inline-block; width: 30%; } .rglPlayer .rgl-label { display: inline; padding-left: 6px; padding-right: 6px; } rgl/inst/htmlwidgets/rglWebGL.js0000644000176200001440000000501614100762640016353 0ustar liggesusers/* el is the div, holding the rgl object as el.rglinstance, which holds x as el.rglinstance.scene x is the JSON encoded rglwidget. */ HTMLWidgets.widget({ name: 'rglWebGL', type: 'output', factory: function(el, width, height) { el.width = width; el.height = height; var rgl = new rglwidgetClass(), onchangeselection = function(e) { for (var i = 0; i < rgl.scene.crosstalk.sel_handle.length; i++) rgl.clearBrush(except = e.rglSubsceneId); rgl.selection(e, false); }, onchangefilter = function(e) { rgl.selection(e, true); }; return { renderValue: function(x) { var i, pel, player, groups, inShiny = (typeof Shiny !== "undefined"); x.crosstalk.group = groups = [].concat(x.crosstalk.group); x.crosstalk.id = [].concat(x.crosstalk.id); x.crosstalk.key = [].concat(x.crosstalk.key); x.crosstalk.sel_handle = new Array(groups.length); x.crosstalk.fil_handle = new Array(groups.length); x.crosstalk.selection = []; for (i = 0; i < groups.length; i++) { x.crosstalk.sel_handle[i] = new crosstalk.SelectionHandle(groups[i], {sharedId: x.crosstalk.id[i]}); x.crosstalk.sel_handle[i].on("change", onchangeselection); x.crosstalk.fil_handle[i] = new crosstalk.FilterHandle(groups[i], {sharedId: x.crosstalk.id[i]}); x.crosstalk.fil_handle[i].on("change", onchangefilter); } if (inShiny) { // Shiny calls this multiple times, so we need extra cleanup // between rgl.sphere = undefined; } rgl.initialize(el, x); rgl.initGL(); /* We might have been called after (some of) the players were rendered. We need to make sure we respond to their initial values. */ if (typeof x.players !== "undefined") { var players = [].concat(x.players); for (i = 0; i < players.length; i++) { pel = document.getElementById(players[i]); if (pel) { player = pel.rglPlayer; if (player && (!player.initialized || inShiny)) { rgl.Player(pel, player); player.initialized = true; } } } } rgl.drag = 0; rgl.drawScene(); }, resize: function(width, height) { el.width = width; el.height = height; el.rglinstance.resize(el); el.rglinstance.drawScene(); } }; } }); rgl/inst/pkgdown/0000755000176200001440000000000014100762640013464 5ustar liggesusersrgl/inst/pkgdown/templates/0000755000176200001440000000000014100762640015462 5ustar liggesusersrgl/inst/pkgdown/templates/after-head.html0000644000176200001440000000440714100762640020355 0ustar liggesusers rgl/inst/WORDLIST0000644000176200001440000000442714100762640013214 0ustar liggesusersACM AGL Albrecht Amaya Angerer ansi Asymptote Atte Baranek Baston Bengtsson Bitmapped Bolker Capitan CMD CanvasMatrix Carbonell ChangeLog Christophe Colours Csardi DEV Delaunay Demont Duursma Eddelbuettel Edelsbrunner El Elkner Esswein FC FOV FreeType Frenet FTGL GDI Gebhard Geuzaine Geuzaine's Gitbook GL GLSL GLU GLX Gabor Gebhardt Geuzaine Github Glynn Gouraud Griffiths Hadka Hammerlindl Heiberger Hirst Hornik IGLX ImageMagick Interpolator Javascript Jefferis Jens Jeroen Joue Jüttler Kajan Karline KDE Khemri Kuehnl Lafarge Laszlo Laur LibPNG Ligges Liu Luca MODELVIEW macOS MacPorts McManus Meshlab Millar MinGW ModelView Morey Mucke Mucke's NaNs Nenadic Normals OPENGL OSX Oleg Ooms OpenGL Pandoc Pateiro Pavel PGF Philipp RMarkdown RStudio Remko Rescaling Rolf Rowlingson Rtools STL Samperi Scrucca Senger Settra Soetaert StackOverflow Stříž Strzelecki SunStudio Talbert Tenenbaum Tenkanen TrueType Tuff UI Ulrich Urbanek Uwe WebGL WinBuilder XQuartz XYZ Xie Yihui Yohann Zeeman ZYX Zheng activeSubscene affine al alphashape anaglyph antialias antialiased antialiasing args atmospherical autoconf autoprinting bbox behaviour binormal bitmapped bringtotop browsable bugfix centre centred cex clipplane clipplanes colour colours config cuboctahedron customizable cvs cyclicly de de-emphasize destructor dev dinterp distro dmurdoch downlit dsave embeddings eps et fontname fontsize fpu freetype gcc github gl grayscale gz htmlwidget https ib io ip ignoreExtent interp labelled libGL libGLU libgl libglu libpng luminance lwd magrittr maxClipPlanes meshColor minification minified minify mipmap mipmapped mipmapping modelMatrix modelled modelview mouseMode multisample nd neighbouring neighbours noindent normals onclick opengl orthogonalization orthogonalizes orthogonally pgf pixmap pkgdown playwidget png polyhedra pos pre projMatrix ps rc recoded rescale rescaled rescaling resizable rglControl rwinlib saveable selectable setosa shader shaders skipRedraw specular stereogram stereolithography stylesheet subscene subscene's subscenes subtype svg tcltk tex texcoords texel texels texenvmap texmagfilter texminfilter texmipmap th tickmark tkrgl toolchain trackpad triangulations tripack unselected useFreeType userMatrix userProjection usr vectorized webgl windowRect wireframed xmax xmin xn xy ymax ymin zmax zmin rgl/cleanup0000755000176200001440000000023314146473376012430 0ustar liggesusers#! /bin/sh rm -f config.* src/Makevars src/Makedeps src/*.o src/*.so src/*.dll rm -rf autom4te.cache rm -rf R/noOpenGL.R src/useNULL/*.o inst/useNULL/*.so rgl/configure0000755000176200001440000051021314146473376012766 0ustar liggesusers#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= PACKAGE_URL= # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS LIBOBJS RGL_NO_OPENGL HIDE_IF_NO_OPENGL NULL_LIBS NULL_CPPFLAGS HAVE_FREETYPE_CONFIG HAVE_PKG_CONFIG XMKMF EGREP GREP HAVE_LIBPNG_CONFIG CPP OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_libpng enable_libpng_config enable_libpng_dynamic enable_opengl with_x with_gl_includes with_gl_libs with_gl_libname with_glu_libname enable_ftgl ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP XMKMF' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF X features: --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-libpng compile without PNG image support --disable-libpng-config disable libpng-config test and configuration --disable-libpng-dynamic disable dynamic libpng linkage, force static version linkage (only with --enable-libpng-config) --disable-opengl compile without OpenGL support --disable-ftgl compile without FTGL font support Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-x use the X Window System --with-gl-includes=DIR specify location of OpenGL headers --with-gl-libs=DIR specify location of OpenGL libs --with-gl-libname=NAME specify Library name (defaults to "GL") --with-glu-libname=NAME specify GLU Library name (defaults to "GLU") Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor XMKMF Path to xmkmf, Makefile generator for X Window System Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in src/build/autoconf "$srcdir"/src/build/autoconf; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in src/build/autoconf \"$srcdir\"/src/build/autoconf" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. ## pick up compiler as will be used by R CMD INSTALL/SHLIB if test -n "${R_HOME}"; then CC=`${R_HOME}/bin/R CMD config CC` CFLAGS=`${R_HOME}/bin/R CMD config CFLAGS` fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test `uname` = "Darwin" ; then darwin="yes" ## we want the *build* cputype and not the host one. cmd=`echo $CC $CFLAGS | grep -E 'x86_64|ppc64|-m64'` if test -n "$cmd"; then have_64bit="yes" else have_64bit="no" fi else darwin="no" fi ## --- LibPNG ---------------------------------------------------------------- # Check whether --enable-libpng was given. if test "${enable_libpng+set}" = set; then : enableval=$enable_libpng; fi # Check whether --enable-libpng-config was given. if test "${enable_libpng_config+set}" = set; then : enableval=$enable_libpng_config; fi # Check whether --enable-libpng-dynamic was given. if test "${enable_libpng_dynamic+set}" = set; then : enableval=$enable_libpng_dynamic; fi if test "x$enable_libpng" != "xno"; then if test "x$enable_libpng_config" != "xno"; then # Extract the first word of "libpng-config", so it can be a program name with args. set dummy libpng-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_HAVE_LIBPNG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$HAVE_LIBPNG_CONFIG"; then ac_cv_prog_HAVE_LIBPNG_CONFIG="$HAVE_LIBPNG_CONFIG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_HAVE_LIBPNG_CONFIG="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_HAVE_LIBPNG_CONFIG" && ac_cv_prog_HAVE_LIBPNG_CONFIG="no" fi fi HAVE_LIBPNG_CONFIG=$ac_cv_prog_HAVE_LIBPNG_CONFIG if test -n "$HAVE_LIBPNG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_LIBPNG_CONFIG" >&5 $as_echo "$HAVE_LIBPNG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test "x$HAVE_LIBPNG_CONFIG" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: using libpng-config" >&5 $as_echo "$as_me: using libpng-config" >&6;} CPPFLAGS="${CPPFLAGS} -DHAVE_PNG_H `libpng-config --I_opts`" if test "x$enable_libpng_dynamic" != "xno"; then { $as_echo "$as_me:${as_lineno-$LINENO}: using libpng dynamic linkage" >&5 $as_echo "$as_me: using libpng dynamic linkage" >&6;} LIBS="${LIBS} `libpng-config --ldflags`" else { $as_echo "$as_me:${as_lineno-$LINENO}: using libpng static linkage" >&5 $as_echo "$as_me: using libpng static linkage" >&6;} LIBS="${LIBS} `libpng-config --static --L_opts`/libpng.a" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking libpng" >&5 $as_echo_n "checking libpng... " >&6; } save_LIBS="${LIBS}" save_CPPFLAGS="${CPPFLAGS}" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in png.h do : ac_fn_c_check_header_mongrel "$LINENO" "png.h" "ac_cv_header_png_h" "$ac_includes_default" if test "x$ac_cv_header_png_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PNG_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for png_read_update_info in -lpng" >&5 $as_echo_n "checking for png_read_update_info in -lpng... " >&6; } if ${ac_cv_lib_png_png_read_update_info+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpng $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char png_read_update_info (); int main () { return png_read_update_info (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_png_png_read_update_info=yes else ac_cv_lib_png_png_read_update_info=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_png_png_read_update_info" >&5 $as_echo "$ac_cv_lib_png_png_read_update_info" >&6; } if test "x$ac_cv_lib_png_png_read_update_info" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPNG 1 _ACEOF LIBS="-lpng $LIBS" fi if test "${ac_cv_header_png_h}"; then if test "${ac_cv_lib_png_png_read_update_info}"; then CPPFLAGS="${CPPFLAGS} -DHAVE_PNG_H" LIBS="${LIBS} -lpng" { $as_echo "$as_me:${as_lineno-$LINENO}: libpng header and lib found" >&5 $as_echo "$as_me: libpng header and lib found" >&6;} if test "x$enable_libpng_dynamic" != "xno"; then { $as_echo "$as_me:${as_lineno-$LINENO}: using libpng dynamic linkage" >&5 $as_echo "$as_me: using libpng dynamic linkage" >&6;} else { $as_echo "$as_me:${as_lineno-$LINENO}: using libpng static linkage" >&5 $as_echo "$as_me: using libpng static linkage" >&6;} fi else LIBS=${save_LIBS} CPPFLAGS=${save_CPPFLAGS} { $as_echo "$as_me:${as_lineno-$LINENO}: libpng header and lib not found" >&5 $as_echo "$as_me: libpng header and lib not found" >&6;} fi fi fi fi # ---[ OpenGL enabled?]--------------------------------------------------------------- # Check whether --enable-opengl was given. if test "${enable_opengl+set}" = set; then : enableval=$enable_opengl; fi NULL_CPPFLAGS="${CPPFLAGS} -DRGL_NO_OPENGL" NULL_LIBS="${LIBS}" # ---[ X11 ]------------------------------------------------------------------ if test "x$enable_opengl" != "xno"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 $as_echo_n "checking for X... " >&6; } # Check whether --with-x was given. if test "${with_x+set}" = set; then : withval=$with_x; fi # $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then # The user explicitly disabled X. have_x=disabled else case $x_includes,$x_libraries in #( *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : $as_echo_n "(cached) " >&6 else # One or both of the vars are not set, and there is no cached value. ac_x_includes=no ac_x_libraries=no rm -f -r conftest.dir if mkdir conftest.dir; then cd conftest.dir cat >Imakefile <<'_ACEOF' incroot: @echo incroot='${INCROOT}' usrlibdir: @echo usrlibdir='${USRLIBDIR}' libdir: @echo libdir='${LIBDIR}' _ACEOF if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. for ac_var in incroot usrlibdir libdir; do eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" done # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl dylib la dll; do if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && test -f "$ac_im_libdir/libX11.$ac_extension"; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. They are # bogus both because they are the default anyway, and because # using them would break gcc on systems where it needs fixed includes. case $ac_im_incroot in /usr/include) ac_x_includes= ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; esac case $ac_im_usrlibdir in /usr/lib | /usr/lib64 | /lib | /lib64) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; esac fi cd .. rm -f -r conftest.dir fi # Standard set of common directories for X headers. # Check X11 before X11Rn because it is often a symlink to the current release. ac_x_header_dirs=' /usr/X11/include /usr/X11R7/include /usr/X11R6/include /usr/X11R5/include /usr/X11R4/include /usr/include/X11 /usr/include/X11R7 /usr/include/X11R6 /usr/include/X11R5 /usr/include/X11R4 /usr/local/X11/include /usr/local/X11R7/include /usr/local/X11R6/include /usr/local/X11R5/include /usr/local/X11R4/include /usr/local/include/X11 /usr/local/include/X11R7 /usr/local/include/X11R6 /usr/local/include/X11R5 /usr/local/include/X11R4 /usr/X386/include /usr/x386/include /usr/XFree86/include/X11 /usr/include /usr/local/include /usr/unsupported/include /usr/athena/include /usr/local/x11r5/include /usr/lpp/Xamples/include /usr/openwin/include /usr/openwin/share/include' if test "$ac_x_includes" = no; then # Guess where to find include files, by looking for Xlib.h. # First, try using that file with no special directory specified. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # We can compile using X headers with no special include directory. ac_x_includes= else for ac_dir in $ac_x_header_dirs; do if test -r "$ac_dir/X11/Xlib.h"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest.err conftest.i conftest.$ac_ext fi # $ac_x_includes = no if test "$ac_x_libraries" = no; then # Check for the libraries. # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS=$LIBS LIBS="-lX11 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { XrmInitialize () ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : LIBS=$ac_save_LIBS # We can link X programs with no special library path. ac_x_libraries= else LIBS=$ac_save_LIBS for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` do # Don't even attempt the hair of trying to link an X program! for ac_extension in a so sl dylib la dll; do if test -r "$ac_dir/libX11.$ac_extension"; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi # $ac_x_libraries = no case $ac_x_includes,$ac_x_libraries in #( no,* | *,no | *\'*) # Didn't find X, or a directory has "'" in its name. ac_cv_have_x="have_x=no";; #( *) # Record where we found X for the cache. ac_cv_have_x="have_x=yes\ ac_x_includes='$ac_x_includes'\ ac_x_libraries='$ac_x_libraries'" esac fi ;; #( *) have_x=yes;; esac eval "$ac_cv_have_x" fi # $with_x != no if test "$have_x" != yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 $as_echo "$have_x" >&6; } no_x=yes else # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries # Update the cache value to reflect the command line values. ac_cv_have_x="have_x=yes\ ac_x_includes='$x_includes'\ ac_x_libraries='$x_libraries'" { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 $as_echo "libraries $x_libraries, headers $x_includes" >&6; } fi if test x$no_x = xyes ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: X11 not found, continuing without OpenGL support." >&5 $as_echo "$as_me: WARNING: X11 not found, continuing without OpenGL support." >&2;} enable_opengl=no else if test -n "${x_includes}"; then CPPFLAGS="${CPPFLAGS} -I${x_includes}" fi if test -n "${x_libraries}"; then LIBS="${LIBS} -L${x_libraries} -lX11" else LIBS="${LIBS} -lX11" fi if test $darwin = yes; then CPPFLAGS="${CPPFLAGS} -DDarwin" if test -e /System/Library/Frameworks/GLKit.framework ; then LIBS="-framework GLKit ${LIBS}" fi # X11 must come *after* the OpenGL stuff CPPFLAGS="${CPPFLAGS} -I/opt/X11/include" fi ac_fn_c_check_func "$LINENO" "XAllocClassHint" "ac_cv_func_XAllocClassHint" if test "x$ac_cv_func_XAllocClassHint" = xyes; then : else enable_opengl=no fi fi fi if test "x$enable_opengl" != "xno"; then ## --- OpenGL ---------------------------------------------------------------- # Check whether --with-gl-includes was given. if test "${with_gl_includes+set}" = set; then : withval=$with_gl_includes; CPPFLAGS="${CPPFLAGS} -I${withval}" fi if test $darwin != yes; then for ac_header in GL/gl.h GL/glu.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test "x$ac_cv_header_GL_gl_h" = xno; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing required header GL/gl.h" >&5 $as_echo "$as_me: WARNING: missing required header GL/gl.h" >&2;} enable_opengl=no fi if test "x$ac_cv_header_GL_glu_h" = xno; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing required header GL/glu.h" >&5 $as_echo "$as_me: WARNING: missing required header GL/glu.h" >&2;} enable_opengl=no fi fi fi if test "x$enable_opengl" != "xno"; then # Check whether --with-gl-libs was given. if test "${with_gl_libs+set}" = set; then : withval=$with_gl_libs; LDFLAGS="${LDFLAGS} -L${withval}" L_LIB="-L${withval}" fi # Check whether --with-gl-libname was given. if test "${with_gl_libname+set}" = set; then : withval=$with_gl_libname; lGL=${withval} else lGL=GL fi as_ac_Lib=`$as_echo "ac_cv_lib_$lGL''_glEnd" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glEnd in -l$lGL" >&5 $as_echo_n "checking for glEnd in -l$lGL... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-l$lGL $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char glEnd (); int main () { return glEnd (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_LIB$lGL" | $as_tr_cpp` 1 _ACEOF LIBS="-l$lGL $LIBS" fi this=`eval echo '${'$as_ac_Lib'}'` if test "x$this" != xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing required library ${lGL}" >&5 $as_echo "$as_me: WARNING: missing required library ${lGL}" >&2;} enable_opengl=no else ac_fn_c_check_func "$LINENO" "glEnd" "ac_cv_func_glEnd" if test "x$ac_cv_func_glEnd" = xyes; then : else enable_opengl=no fi fi fi if test "x$enable_opengl" != "xno"; then # Check whether --with-glu-libname was given. if test "${with_glu_libname+set}" = set; then : withval=$with_glu_libname; lGLU=${withval} else lGLU=GLU fi as_ac_Lib=`$as_echo "ac_cv_lib_$lGLU''_gluErrorString" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gluErrorString in -l$lGLU" >&5 $as_echo_n "checking for gluErrorString in -l$lGLU... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-l$lGLU $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gluErrorString (); int main () { return gluErrorString (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_LIB$lGLU" | $as_tr_cpp` 1 _ACEOF LIBS="-l$lGLU $LIBS" fi this=`eval echo '${'$as_ac_Lib'}'` if test "x$this" != xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing required library ${lGLU}" >&5 $as_echo "$as_me: WARNING: missing required library ${lGLU}" >&2;} enable_opengl=no else ac_fn_c_check_func "$LINENO" "gluErrorString" "ac_cv_func_gluErrorString" if test "x$ac_cv_func_gluErrorString" = xyes; then : else enable_opengl=no fi fi fi if test "x$enable_opengl" != "xno"; then if test x$L_LIB != x; then LIBS="${L_LIB} ${LIBS}" fi ## --- FTGL ------------------------------------------------------------------ # Check whether --enable-ftgl was given. if test "${enable_ftgl+set}" = set; then : enableval=$enable_ftgl; fi if test "x$enable_ftgl" != "xno"; then if test "x$darwin" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: Darwin, so ensuring /opt/X11/bin is at the head of the PATH..." >&5 $as_echo "$as_me: Darwin, so ensuring /opt/X11/bin is at the head of the PATH..." >&6;} PATH=/opt/X11/bin:${PATH} fi ## new pkg-config bit # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_HAVE_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$HAVE_PKG_CONFIG"; then ac_cv_prog_HAVE_PKG_CONFIG="$HAVE_PKG_CONFIG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_HAVE_PKG_CONFIG="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_HAVE_PKG_CONFIG" && ac_cv_prog_HAVE_PKG_CONFIG="no" fi fi HAVE_PKG_CONFIG=$ac_cv_prog_HAVE_PKG_CONFIG if test -n "$HAVE_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_PKG_CONFIG" >&5 $as_echo "$HAVE_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$HAVE_PKG_CONFIG" = "xyes" -a "x`pkg-config freetype2 --cflags`" != "x"; then CPPFLAGS="${CPPFLAGS} -DHAVE_FREETYPE -Iext/ftgl `pkg-config freetype2 --cflags`" LIBS="${LIBS} `pkg-config freetype2 --static --libs`" { $as_echo "$as_me:${as_lineno-$LINENO}: using Freetype and FTGL" >&5 $as_echo "$as_me: using Freetype and FTGL" >&6;} else # Extract the first word of "freetype-config", so it can be a program name with args. set dummy freetype-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_HAVE_FREETYPE_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$HAVE_FREETYPE_CONFIG"; then ac_cv_prog_HAVE_FREETYPE_CONFIG="$HAVE_FREETYPE_CONFIG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_HAVE_FREETYPE_CONFIG="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_HAVE_FREETYPE_CONFIG" && ac_cv_prog_HAVE_FREETYPE_CONFIG="no" fi fi HAVE_FREETYPE_CONFIG=$ac_cv_prog_HAVE_FREETYPE_CONFIG if test -n "$HAVE_FREETYPE_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_FREETYPE_CONFIG" >&5 $as_echo "$HAVE_FREETYPE_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$HAVE_FREETYPE_CONFIG" = "xyes"; then CPPFLAGS="${CPPFLAGS} -DHAVE_FREETYPE -Iext/ftgl `freetype-config --cflags`" LIBS="${LIBS} `freetype-config --static --libs`" { $as_echo "$as_me:${as_lineno-$LINENO}: using Freetype and FTGL" >&5 $as_echo "$as_me: using Freetype and FTGL" >&6;} else { $as_echo "$as_me:${as_lineno-$LINENO}: compiling without FTGL support" >&5 $as_echo "$as_me: compiling without FTGL support" >&6;} fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: compiling without FTGL support" >&5 $as_echo "$as_me: compiling without FTGL support" >&6;} fi fi if test "x$enable_opengl" = "xno"; then { $as_echo "$as_me:${as_lineno-$LINENO}: compiling without OpenGL support" >&5 $as_echo "$as_me: compiling without OpenGL support" >&6;} HIDE_IF_NO_OPENGL="#" RGL_NO_OPENGL=TRUE else HIDE_IF_NO_OPENGL="" RGL_NO_OPENGL=FALSE fi ## --- Output ---------------------------------------------------------------- ac_config_files="$ac_config_files R/noOpenGL.R src/useNULL/Makevars" ac_config_files="$ac_config_files src/Makevars" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "R/noOpenGL.R") CONFIG_FILES="$CONFIG_FILES R/noOpenGL.R" ;; "src/useNULL/Makevars") CONFIG_FILES="$CONFIG_FILES src/useNULL/Makevars" ;; "src/Makevars") CONFIG_FILES="$CONFIG_FILES src/Makevars" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi