Repository: BurntSushi/xgbutil Branch: master Commit: ad855c713046 Files: 78 Total size: 695.2 KB Directory structure: gitextract_k216nv23/ ├── .gitignore ├── COPYING ├── Makefile ├── README ├── STYLE ├── _examples/ │ ├── change-cursor/ │ │ └── main.go │ ├── compress-events/ │ │ └── main.go │ ├── doc.go │ ├── draw-text/ │ │ └── main.go │ ├── fullscreen/ │ │ └── main.go │ ├── graceful-window-close/ │ │ └── main.go │ ├── image-speed/ │ │ └── main.go │ ├── keypress-english/ │ │ └── main.go │ ├── multiple-source-event-loop/ │ │ └── main.go │ ├── pointer-painting/ │ │ └── main.go │ ├── screenshot/ │ │ └── main.go │ ├── show-image/ │ │ └── main.go │ ├── show-window-icons/ │ │ └── main.go │ ├── simple-keybinding/ │ │ └── main.go │ ├── simple-mousebinding/ │ │ └── main.go │ ├── window-gradient/ │ │ └── main.go │ ├── window-name-sizes/ │ │ └── main.go │ ├── workarea-struts/ │ │ └── main.go │ ├── xgraphics-compat/ │ │ └── main.go │ └── xmodmap/ │ └── main.go ├── doc.go ├── ewmh/ │ ├── doc.go │ ├── ewmh.go │ └── winman.go ├── gopher/ │ ├── doc.go │ └── gopher.go ├── icccm/ │ ├── doc.go │ ├── icccm.go │ └── protocols.go ├── keybind/ │ ├── callback.go │ ├── doc.go │ ├── encoding.go │ ├── keybind.go │ ├── keysymdef.go │ └── xutil.go ├── motif/ │ └── motif.go ├── mousebind/ │ ├── callback.go │ ├── doc.go │ ├── drag.go │ ├── mousebind.go │ └── xutil.go ├── scripts/ │ ├── README │ └── write-events ├── session.vim ├── types.go ├── xcursor/ │ ├── cursordef.go │ ├── doc.go │ └── xcursor.go ├── xevent/ │ ├── callback.go │ ├── doc.go │ ├── eventloop.go │ ├── types_auto.go │ ├── types_manual.go │ └── xevent.go ├── xgbutil.go ├── xgraphics/ │ ├── convert.go │ ├── doc.go │ ├── image.go │ ├── new.go │ ├── text.go │ ├── util.go │ └── xsurface.go ├── xinerama/ │ ├── doc.go │ └── xinerama.go ├── xprop/ │ ├── atom.go │ ├── doc.go │ └── xprop.go ├── xrect/ │ ├── doc.go │ └── xrect.go └── xwindow/ ├── doc.go ├── ewmh.go ├── icccm.go └── xwindow.go ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.swp *.png tst_first tst_graphics TAGS ================================================ FILE: COPYING ================================================ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 Copyright (C) 2004 Sam Hocevar Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. You just DO WHAT THE FUCK YOU WANT TO. ================================================ FILE: Makefile ================================================ all: callback.go types_auto.go gofmt install: go install -p 6 . ./ewmh ./gopher ./icccm ./keybind ./motif ./mousebind \ ./xcursor ./xevent ./xgraphics ./xinerama ./xprop ./xrect ./xwindow push: git push origin master git push github master build-ex: find ./_examples/ -type d -wholename './_examples/[a-z]*' -print0 \ | xargs -0 go build -p 6 gofmt: gofmt -w *.go */*.go _examples/*/*.go colcheck *.go */*.go _examples/*/*.go callback.go: scripts/write-events callbacks > xevent/callback.go types_auto.go: scripts/write-events evtypes > xevent/types_auto.go tags: find ./ \( -name '*.go' -and -not -wholename './tests/*' -and -not -wholename './_examples/*' \) -print0 | xargs -0 gotags > TAGS loc: find ./ -name '*.go' -and -not -wholename './tests*' -and -not -name '*keysymdef.go' -and -not -name '*gopher.go' -print | sort | xargs wc -l ex-%: go run _examples/$*/main.go gopherimg: go-bindata -f GopherPng -p gopher -i gopher/gophercolor-small.png -o gopher/gopher.go ================================================ FILE: README ================================================ xgbutil is a utility library designed to work with the X Go Binding. This project's main goal is to make various X related tasks easier. For example, binding keys, using the EWMH or ICCCM specs with the window manager, moving/resizing windows, assigning function callbacks to particular events, drawing images to a window, etc. xgbutil attempts to be thread safe, but it has not been completely tested in this regard. In general, the X event loop implemented in the xevent package is sequential. The idea is to be sequential by default, and let the user spawn concurrent code at their discretion. (i.e., the complexity of making the main event loop generally concurrent is vast.) You may sleep safely at night by assuming that XGB is thread safe, though. To start using xgbutil, you should have at least a passing familiarity with X. Your first stop should be the examples directory. Installation ============ go get github.com/BurntSushi/xgbutil Dependencies ============ XGB is the main dependency. Use of the xgraphics packages requires graphics-go and freetype-go. XGB project URL: https://github.com/BurntSushi/xgb Quick Example ============= go get github.com/BurntSushi/xgbutil/_examples/window-name-sizes "$GOPATH"/bin/window-name-sizes The output will be a list of names of all top-level windows and their geometry including window manager decorations. (Assuming your window manager supports some basic EWMH properties.) Documentation ============= https://godoc.org/github.com/BurntSushi/xgbutil Examples ======== There are several examples in the examples directory covering common use cases. They are heavily documented and should run out of the box. Python ====== An older project of mine, xpybutil, served as inspiration for xgbutil. If you want to use Python, xpybutil should help quite a bit. Please note though, that at this point, xgbutil provides a lot more functionality and is much better documented. xpybutil project URL: https://github.com/BurntSushi/xpybutil ================================================ FILE: STYLE ================================================ I like to keep all my code to 80 columns or less. I have plenty of screen real estate, but enjoy 80 columns so that I can have multiple code windows open side to side and not be plagued by the ugly auto-wrapping of a text editor. If you don't oblige me, I will fix any patch you submit to abide 80 columns. Note that this style restriction does not preclude gofmt, but introduces a few peculiarities. The first is that gofmt will occasionally add spacing (typically to comments) that ends up going over 80 columns. Either shorten the comment or put it on its own line. The second and more common hiccup is when a function definition extends beyond 80 columns. If one adds line breaks to keep it below 80 columns, gofmt will indent all subsequent lines in a function definition to the same indentation level of the function body. This results in a less-than-ideal separation between function definition and function body. To remedy this, simply add a line break like so: func RestackWindowExtra(xu *xgbutil.XUtil, win xproto.Window, stackMode int, sibling xproto.Window, source int) error { return ClientEvent(xu, win, "_NET_RESTACK_WINDOW", source, int(sibling), stackMode) } Something similar should also be applied to long 'if' or 'for' conditionals, although it would probably be preferrable to break up the conditional to smaller chunks with a few helper variables. ================================================ FILE: _examples/change-cursor/main.go ================================================ // Example change-cursor shows how to use the cursor package to change the // X cursor in a particular window. To see the new cursor, move your cursor // into the window created by this program. // Note that this only shows how to use one of the pre-defined cursors built // into X using the "cursor" font. Creating your own cursor with your own // image is a bit more complex, and probably not an instructive example. // // While this example shows how to set a cursor in an entire window, the cursor // value returned from xcursor.CreateCursor[Extra] can be used in pointer // grab requests too. (So that the cursor changes during the grab.) package main import ( "log" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/xcursor" "github.com/BurntSushi/xgbutil/xwindow" ) func main() { X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Create the cursor. You can find a list of available cursors in // xcursor/cursordef.go. // We'll make an umbrella here, with an orange foreground and a blue // background. (The background it typically the outline of the cursor.) // Note that each component of the RGB color is a 16 bit color. I think // using the most significant byte to specify each component is good // enough. cursor, err := xcursor.CreateCursorExtra(X, xcursor.Umbrella, 0xff00, 0x5500, 0x0000, 0x3300, 0x6600, 0xff00) if err != nil { log.Fatal(err) } // Create a new window. In the create window request, we'll set the // background color and set the cursor we created above. // This results in changing the cursor only when it moves into this window. win, err := xwindow.Generate(X) if err != nil { log.Fatal(err) } win.Create(X.RootWin(), 0, 0, 500, 500, xproto.CwBackPixel|xproto.CwCursor, 0xffffffff, uint32(cursor)) win.Map() // We can free the cursor now that we've set it. // If you plan on using this cursor again, then it shouldn't be freed. // (i.e., if you try to free this before setting it as the cursor in a // window, you'll get a BadCursor error when trying to use it.) xproto.FreeCursor(X.Conn(), cursor) // Block. No need to process any events. select {} } ================================================ FILE: _examples/compress-events/main.go ================================================ /* Example compress-events shows how to manipulate the xevent package's event queue to compress events that arrive more often than you'd like to process them. This example in particular shows how to compress MotionNotify events, but the same approach could be used to compress ConfigureNotify events. Note that we show the difference between compressed and uncompressed MotionNotify events by displaying two windows that listen for MotionNotify events. The green window compresses them while the red window does not. Hovering over each window will print the x and y positions in each MotionNotify event received. You should notice that the red window lags behind the pointer (particularly if you moved the pointer quickly in and out of the window) while the green window always keeps up, regardless of the speed of the pointer. In each case, we simulate work by sleeping for some amount of time. (The whole point of compressing events is that there is too much work to be done for each event.) Note that when compressing events, you should always make sure that the event you're compressing *ought* to be compressed. For example, with MotionNotify events, if the Event field changes, then it applies to a different window and probably shouldn't be compressed with MotionNotify events for other windows. Finally, compressing events implicitly assumes that the event handler doing the compression is the *only* event handler for a particular (event, window) tuple. If there is more than one event handler for a single (event, window) tuple and one of them does compression, the other will be left out in the cold. (Since the main event loop is subverted and won't process the compressed events in the usual way.) N.B. This functionality isn't included in xgbutil because event compression isn't something that is always desirable, and the conditions under which compression happens can vary. In particular, compressing ConfigureRequest events from the perspective of the window manager can be faulty, since changes to other properties (like WM_NORMAL_HINTS) can change the semantics of a ConfigureRequest event. (i.e., your compression would need to specifically look for events that could change future ConfigureRequest events.) */ package main import ( "fmt" "log" "time" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/xevent" "github.com/BurntSushi/xgbutil/xwindow" ) // workTime is the amount of time to sleep to simulate "work" in response to // MotionNotify events. Increasing this will exacerbate the difference // between the green and red windows. But if you increase it too much, // the red window starts to *really* lag, and you'll probably have to kill // the program. var workTime = 50 * time.Millisecond // newWindow creates a new window that listens to MotionNotify events with // the given backgroundcolor. func newWindow(X *xgbutil.XUtil, color uint32) *xwindow.Window { win, err := xwindow.Generate(X) if err != nil { log.Fatal(err) } err = win.CreateChecked(X.RootWin(), 0, 0, 400, 400, xproto.CwBackPixel|xproto.CwEventMask, color, xproto.EventMaskPointerMotion) if err != nil { log.Fatal(err) } win.Map() return win } // compressMotionNotify takes a MotionNotify event, and inspects the event // queue for any future MotionNotify events that can be received without // blocking. The most recent MotionNotify event is then returned. // Note that we need to make sure that the Event, Child, Detail, State, Root // and SameScreen fields are the same to ensure the same window/action is // generating events. That is, we are only compressing the RootX, RootY, // EventX and EventY fields. // This function is not thread safe, since Peek returns a *copy* of the // event queue---which could be out of date by the time we dequeue events. func compressMotionNotify(X *xgbutil.XUtil, ev xevent.MotionNotifyEvent) xevent.MotionNotifyEvent { // We force a round trip request so that we make sure to read all // available events. X.Sync() xevent.Read(X, false) // The most recent MotionNotify event that we'll end up returning. laste := ev // Look through each event in the queue. If it's an event and it matches // all the fields in 'ev' that are detailed above, then set it to 'laste'. // In which case, we'll also dequeue the event, otherwise it will be // processed twice! // N.B. If our only goal was to find the most recent relevant MotionNotify // event, we could traverse the event queue backwards and simply use // the first MotionNotify we see. However, this could potentially leave // other MotionNotify events in the queue, which we *don't* want to be // processed. So we stride along and just pick off MotionNotify events // until we don't see any more. for i, ee := range xevent.Peek(X) { if ee.Err != nil { // This is an error, skip it. continue } // Use type assertion to make sure this is a MotionNotify event. if mn, ok := ee.Event.(xproto.MotionNotifyEvent); ok { // Now make sure all appropriate fields are equivalent. if ev.Event == mn.Event && ev.Child == mn.Child && ev.Detail == mn.Detail && ev.State == mn.State && ev.Root == mn.Root && ev.SameScreen == mn.SameScreen { // Set the most recent/valid motion notify event. laste = xevent.MotionNotifyEvent{&mn} // We cheat and use the stack semantics of defer to dequeue // most recent motion notify events first, so that the indices // don't become invalid. (If we dequeued oldest first, we'd // have to account for all future events shifting to the left // by one.) defer func(i int) { xevent.DequeueAt(X, i) }(i) } } } // This isn't strictly necessary, but is correct. We should update // xgbutil's sense of time with the most recent event processed. // This is typically done in the main event loop, but since we are // subverting the main event loop, we should take care of it. X.TimeSet(laste.Time) return laste } func main() { X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Create window for receiving compressed MotionNotify events. cwin := newWindow(X, 0x00ff00) // Attach event handler for MotionNotify that compresses events. xevent.MotionNotifyFun( func(X *xgbutil.XUtil, ev xevent.MotionNotifyEvent) { ev = compressMotionNotify(X, ev) fmt.Printf("COMPRESSED: (EventX %d, EventY %d)\n", ev.EventX, ev.EventY) time.Sleep(workTime) }).Connect(X, cwin.Id) // Create window for receiving uncompressed MotionNotify events. uwin := newWindow(X, 0xff0000) // Attach event handler for MotionNotify that does not compress events. xevent.MotionNotifyFun( func(X *xgbutil.XUtil, ev xevent.MotionNotifyEvent) { fmt.Printf("UNCOMPRESSED: (EventX %d, EventY %d)\n", ev.EventX, ev.EventY) time.Sleep(workTime) }).Connect(X, uwin.Id) xevent.Main(X) } ================================================ FILE: _examples/doc.go ================================================ /* Package examples contains several complete examples depicting some common use cases of xgbutil. The examples included are designed to either demonstrate how a particular facility of xgbutil works, or how to accomplish some common goal when using X. For example, example simple-keybinding demonstrates how to use xgbutil to respond to particular key presses while example graceful-window-close shows how to close windows without killing your connection to X. My goal is that each example demonstrates one thing, although the nature of X typically requires some amount of boilerplate so that some examples are a bit more bloated than I would like. If you have any suggestions for other examples to include, I'd be happy to hear them. You may post them at the main project page: https://github.com/BurntSushi/xgbutil. */ package documentation ================================================ FILE: _examples/draw-text/main.go ================================================ // Example draw-text shows how to draw text to an xgraphics.Image type. package main import ( "image" "log" "os" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/xevent" "github.com/BurntSushi/xgbutil/xgraphics" ) var ( // The geometry of the canvas to draw text on. canvasWidth, canvasHeight = 600, 100 // The background color of the canvas. bg = xgraphics.BGRA{B: 0xff, G: 0x66, R: 0x33, A: 0xff} // The path to the font used to draw text. fontPath = "/usr/share/fonts/TTF/FreeMonoBold.ttf" // The color of the text. fg = xgraphics.BGRA{B: 0xff, G: 0xff, R: 0xff, A: 0xff} // The size of the text. size = 20.0 // The text to draw. msg = "This is some text drawn by xgraphics!" ) func main() { X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Load some font. You may need to change the path depending upon your // system configuration. fontReader, err := os.Open(fontPath) if err != nil { log.Fatal(err) } // Now parse the font. font, err := xgraphics.ParseFont(fontReader) if err != nil { log.Fatal(err) } // Create some canvas. ximg := xgraphics.New(X, image.Rect(0, 0, canvasWidth, canvasHeight)) ximg.For(func(x, y int) xgraphics.BGRA { return bg }) // Now write the text. _, _, err = ximg.Text(10, 10, fg, size, font, msg) if err != nil { log.Fatal(err) } // Compute extents of first line of text. _, firsth := xgraphics.Extents(font, size, msg) // Now show the image in its own window. win := ximg.XShowExtra("Drawing text using xgraphics", true) // Now draw some more text below the above and demonstrate how to update // only the region we've updated. _, _, err = ximg.Text(10, 10+firsth, fg, size, font, "Some more text.") if err != nil { log.Fatal(err) } // Now compute extents of the second line of text, so we know which region // to update. secw, sech := xgraphics.Extents(font, size, "Some more text.") // Now repaint on the region that we drew text on. Then update the screen. bounds := image.Rect(10, 10+firsth, 10+secw, 10+firsth+sech) ximg.SubImage(bounds).(*xgraphics.Image).XDraw() ximg.XPaint(win.Id) // All we really need to do is block, which could be achieved using // 'select{}'. Invoking the main event loop however, will emit error // message if anything went seriously wrong above. xevent.Main(X) } ================================================ FILE: _examples/fullscreen/main.go ================================================ // Example fullscreen shows how to make a window showing the Go Gopher go // fullscreen and back using keybindings and EWMH. package main import ( "bytes" "image" _ "image/png" "log" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/ewmh" "github.com/BurntSushi/xgbutil/gopher" "github.com/BurntSushi/xgbutil/icccm" "github.com/BurntSushi/xgbutil/keybind" "github.com/BurntSushi/xgbutil/mousebind" "github.com/BurntSushi/xgbutil/xevent" "github.com/BurntSushi/xgbutil/xgraphics" "github.com/BurntSushi/xgbutil/xwindow" ) func main() { X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } keybind.Initialize(X) // call once before using keybind package // Read an example gopher image into a regular png image. img, _, err := image.Decode(bytes.NewBuffer(gopher.GopherPng())) if err != nil { log.Fatal(err) } // Now convert it into an X image. ximg := xgraphics.NewConvert(X, img) // Now show it in a new window. // We set the window title and tell the program to quit gracefully when // the window is closed. // There is also a convenience method, XShow, that requires no parameters. win := showImage(ximg, "The Go Gopher!", true) // Listen for key press events. win.Listen(xproto.EventMaskKeyPress) err = keybind.KeyPressFun( func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) { println("fullscreen!") err := ewmh.WmStateReq(X, win.Id, ewmh.StateToggle, "_NET_WM_STATE_FULLSCREEN") if err != nil { log.Fatal(err) } }).Connect(X, win.Id, "f", false) if err != nil { log.Fatal(err) } err = keybind.KeyPressFun( func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) { println("quit fullscreen!") err := ewmh.WmStateReq(X, win.Id, ewmh.StateToggle, "_NET_WM_STATE_FULLSCREEN") if err != nil { log.Fatal(err) } }).Connect(X, win.Id, "Escape", false) if err != nil { log.Fatal(err) } // If we don't block, the program will end and the window will disappear. // We could use a 'select{}' here, but xevent.Main will emit errors if // something went wrong, so use that instead. xevent.Main(X) } // This is a slightly modified version of xgraphics.XShowExtra that does // not set any resize constraints on the window (so that it can go // fullscreen). func showImage(im *xgraphics.Image, name string, quit bool) *xwindow.Window { if len(name) == 0 { name = "xgbutil Image Window" } w, h := im.Rect.Dx(), im.Rect.Dy() win, err := xwindow.Generate(im.X) if err != nil { xgbutil.Logger.Printf("Could not generate new window id: %s", err) return nil } // Create a very simple window with dimensions equal to the image. win.Create(im.X.RootWin(), 0, 0, w, h, 0) // Make this window close gracefully. win.WMGracefulClose(func(w *xwindow.Window) { xevent.Detach(w.X, w.Id) keybind.Detach(w.X, w.Id) mousebind.Detach(w.X, w.Id) w.Destroy() if quit { xevent.Quit(w.X) } }) // Set WM_STATE so it is interpreted as a top-level window. err = icccm.WmStateSet(im.X, win.Id, &icccm.WmState{ State: icccm.StateNormal, }) if err != nil { // not a fatal error xgbutil.Logger.Printf("Could not set WM_STATE: %s", err) } // Set _NET_WM_NAME so it looks nice. err = ewmh.WmNameSet(im.X, win.Id, name) if err != nil { // not a fatal error xgbutil.Logger.Printf("Could not set _NET_WM_NAME: %s", err) } // Paint our image before mapping. im.XSurfaceSet(win.Id) im.XDraw() im.XPaint(win.Id) // Now we can map, since we've set all our properties. // (The initial map is when the window manager starts managing.) win.Map() return win } ================================================ FILE: _examples/graceful-window-close/main.go ================================================ // Example graceful-window-close shows how to create windows that can be closed // without killing your X connection (and thereby destroying any other windows // you may have open). This is actually achieved through an ICCCM standard. // We add the WM_DELETE_WINDOW to the WM_PROTOCOLS property on our window. // This indicates to well-behaving window managers that a certain kind of // client message should be sent to our client when the window should be closed. // If we *don't* add the WM_DELETE_WINDOW to the WM_PROTOCOLS property, the // window manager will typically call KillClient---which will destroy the // window and your X connection. // // If you click inside one of the windows created, a new window will be // automatically created. // // The program will stop when all windows have been closed. // // For more information on the convention used please see // http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.2.7 and // http://tronche.com/gui/x/icccm/sec-4.html#s-4.2.8 package main import ( "log" "math/rand" "os" "time" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/mousebind" "github.com/BurntSushi/xgbutil/xevent" "github.com/BurntSushi/xgbutil/xwindow" ) // When counter reaches 0, exit. var counter int32 // Just iniaitlize the RNG seed for generating random background colors. func init() { rand.Seed(time.Now().UnixNano()) } // newWindow creates a new window with a random background color. It sets the // WM_PROTOCOLS property to contain the WM_DELETE_WINDOW atom. It also sets // up a ClientMessage event handler so that we know when to destroy the window. // We also set up a mouse binding so that clicking inside a window will // create another one. func newWindow(X *xgbutil.XUtil) { counter++ win, err := xwindow.Generate(X) if err != nil { log.Fatal(err) } // Get a random background color, create the window (ask to receive button // release events while we're at it) and map the window. bgColor := rand.Intn(0xffffff + 1) win.Create(X.RootWin(), 0, 0, 200, 200, xproto.CwBackPixel|xproto.CwEventMask, uint32(bgColor), xproto.EventMaskButtonRelease) // WMGracefulClose does all of the work for us. It sets the appropriate // values for WM_PROTOCOLS, and listens for ClientMessages that implement // the WM_DELETE_WINDOW protocol. When one is found, the provided callback // is executed. win.WMGracefulClose( func(w *xwindow.Window) { // Detach all event handlers. // This should always be done when a window can no longer // receive events. xevent.Detach(w.X, w.Id) mousebind.Detach(w.X, w.Id) w.Destroy() // Exit if there are no more windows left. counter-- if counter == 0 { os.Exit(0) } }) // It's important that the map comes after setting WMGracefulClose, since // the WM isn't obliged to watch updates to the WM_PROTOCOLS property. win.Map() // A mouse binding so that a left click will spawn a new window. // Note that we don't issue a grab here. Typically, window managers will // grab a button press on the client window (which usually activates the // window), so that we'd end up competing with the window manager if we // tried to grab it. // Instead, we set a ButtonRelease mask when creating the window and attach // a mouse binding *without* a grab. err = mousebind.ButtonReleaseFun( func(X *xgbutil.XUtil, ev xevent.ButtonReleaseEvent) { newWindow(X) }).Connect(X, win.Id, "1", false, false) if err != nil { log.Fatal(err) } } func main() { X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Anytime the mousebind (keybind) package is used, mousebind.Initialize // *should* be called once. In the case of the mousebind package, this // isn't strictly necessary (currently!), but the 'Drag' features of // the mousebind package won't work without it. mousebind.Initialize(X) // Create two windows to prove we can close one while keeping the // other alive. newWindow(X) newWindow(X) xevent.Main(X) } ================================================ FILE: _examples/image-speed/main.go ================================================ //This demonstration shows drawing entire generated images to an x window //and calculating the speed of the generation and the drawing operations //It should be noted that redrawing the entire image is inefficient, this demo //was made to show me how fast I could draw to the windows with this method. package main import ( "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/keybind" "github.com/BurntSushi/xgbutil/xevent" "github.com/BurntSushi/xgbutil/xgraphics" "github.com/BurntSushi/xgbutil/xwindow" "image" "log" "time" ) func main() { X, err := xgbutil.NewConn() if err != nil { log.Println(err) return } //Initialize the keybind package keybind.Initialize(X) //Create a window win, err := xwindow.Generate(X) if err != nil { log.Fatalf("Could not generate a new window X id: %s", err) } win.Create(X.RootWin(), 0, 0, 1024, 768, xproto.CwBackPixel, 0x606060ff) // Listen for Key{Press,Release} events. win.Listen(xproto.EventMaskKeyPress, xproto.EventMaskKeyRelease) // Map the window. This is what makes it on the screen win.Map() //Make a ...callback... for the events and connect xevent.KeyPressFun( func(X *xgbutil.XUtil, e xevent.KeyPressEvent) { modStr := keybind.ModifierString(e.State) keyStr := keybind.LookupString(X, e.State, e.Detail) if len(modStr) > 0 { log.Printf("Key: %s-%s\n", modStr, keyStr) } else { log.Println("Key:", keyStr) } if keybind.KeyMatch(X, "Escape", e.State, e.Detail) { if e.State&xproto.ModMaskControl > 0 { log.Println("Control-Escape detected. Quitting...") xevent.Quit(X) } } }).Connect(X, win.Id) //So here i'm going to try to make a image..' img := xgraphics.New(X, image.Rect(0, 0, 1024, 768)) err = img.XSurfaceSet(win.Id) if err != nil { log.Printf("Error while setting window surface to image %d: %s\n", win, err) } else { log.Printf("Window %d surface set to image OK\n", win) } // I /think/ XDraw actually sends data to server? img.XDraw() // I /think/ XPaint tells the server to paint image to window img.XPaint(win.Id) //Start the routine that updates the window go updater(img, win) //This seems to start a main loop for listening to xevents xevent.Main(X) } func updater(img *xgraphics.Image, win *xwindow.Window) { //We keep track of times based on 1024 frames frame := 0 start := time.Now() var genStart, drawStart time.Time var genTotal, drawTotal time.Duration for { frame = frame + 1 if frame > 1024 { frame = 0 log.Printf("Time elapsed: %s\n", time.Now().Sub(start)) log.Printf("Time generate: %s\n", genTotal) log.Printf("Time drawing: %s\n", drawTotal) start = time.Now() drawTotal, genTotal = 0, 0 } genStart = time.Now() var x, y, i int for y = 0; y < 768; y++ { //set last pixel back to black img.SetBGRA(frame-1, y, xgraphics.BGRA{0, 0, 0, 255}) for i = 0; i < 10; i++ { x = i + frame if x > 1024 { x = 1024 } img.SetBGRA(x, y, xgraphics.BGRA{0, 0, 255, 255}) } } genTotal += time.Now().Sub(genStart) drawStart = time.Now() //hopefully using checked will block us from drawing again before x //draws although XDraw might block anyway, we can check for an error //here err := img.XDrawChecked() if err != nil { log.Println(err) return } //img.XDraw() img.XPaint(win.Id) drawTotal += time.Now().Sub(drawStart) } } ================================================ FILE: _examples/keypress-english/main.go ================================================ // Example keypress-english shows how to convert the State (modifiers) and // Detail (keycode) members of Key{Press,Release} events to an english // string representation. package main import ( "flag" "log" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/keybind" "github.com/BurntSushi/xgbutil/xevent" "github.com/BurntSushi/xgbutil/xwindow" ) var flagRoot = false func init() { log.SetFlags(0) flag.BoolVar(&flagRoot, "root", flagRoot, "When set, the keyboard will be grabbed on the root window. "+ "Make sure you have a way to kill the window created with "+ "the mouse.") flag.Parse() } func main() { // Connect to the X server using the DISPLAY environment variable. X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Anytime the keybind (mousebind) package is used, keybind.Initialize // *should* be called once. It isn't strictly necessary, but allows your // keybindings to persist even if the keyboard mapping is changed during // run-time. (Assuming you're using the xevent package's event loop.) // It also handles the case when your modifier map is changed. keybind.Initialize(X) // Create a new window. We will listen for key presses and translate them // only when this window is in focus. (Similar to how `xev` works.) win, err := xwindow.Generate(X) if err != nil { log.Fatalf("Could not generate a new window X id: %s", err) } win.Create(X.RootWin(), 0, 0, 500, 500, xproto.CwBackPixel, 0xffffffff) // Listen for Key{Press,Release} events. win.Listen(xproto.EventMaskKeyPress, xproto.EventMaskKeyRelease) // Map the window. win.Map() // Notice that we use xevent.KeyPressFun instead of keybind.KeyPressFun, // because we aren't trying to make a grab *and* because we want to listen // to *all* key press events, rather than just a particular key sequence // that has been pressed. wid := win.Id if flagRoot { wid = X.RootWin() } xevent.KeyPressFun( func(X *xgbutil.XUtil, e xevent.KeyPressEvent) { // keybind.LookupString does the magic of implementing parts of // the X Keyboard Encoding to determine an english representation // of the modifiers/keycode tuple. // N.B. It's working for me, but probably isn't 100% correct in // all environments yet. modStr := keybind.ModifierString(e.State) keyStr := keybind.LookupString(X, e.State, e.Detail) if len(modStr) > 0 { log.Printf("Key: %s-%s\n", modStr, keyStr) } else { log.Println("Key:", keyStr) } if keybind.KeyMatch(X, "Escape", e.State, e.Detail) { if e.State&xproto.ModMaskControl > 0 { log.Println("Control-Escape detected. Quitting...") xevent.Quit(X) } } }).Connect(X, wid) // If we want root, then we take over the entire keyboard. if flagRoot { if err := keybind.GrabKeyboard(X, X.RootWin()); err != nil { log.Fatalf("Could not grab keyboard: %s", err) } log.Println("WARNING: We are taking *complete* control of the root " + "window. The only way out is to press 'Control + Escape' or to " + "close the window with the mouse.") } // Finally, start the main event loop. This will route any appropriate // KeyPressEvents to your callback function. log.Println("Program initialized. Start pressing keys!") xevent.Main(X) } ================================================ FILE: _examples/multiple-source-event-loop/main.go ================================================ // Example multiple-source-event-loop shows how to use the xevent package to // combine multiple sources in your main event loop. This is particularly // useful if your application can respond to user input from other sources. package main import ( "fmt" "log" "time" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/ewmh" "github.com/BurntSushi/xgbutil/xevent" "github.com/BurntSushi/xgbutil/xprop" "github.com/BurntSushi/xgbutil/xwindow" ) // otherSource serves as a placeholder from some other source of user input. func otherSource() chan int { c := make(chan int, 0) go func() { defer close(c) i := 1 for { c <- i i++ time.Sleep(time.Second) } }() return c } // sendClientMessages is a goroutine that sends client messages to the root // window. We then listen to them later as a demonstration of responding to // X events. (They are sent with SubstructureNotify and SubstructureRedirect // masks set. So in order to receive them, we'll have to explicitly listen // to events of that type on the root window.) func xSource(X *xgbutil.XUtil) { i := 1 for { ewmh.ClientEvent(X, X.RootWin(), "NOOP", i) i++ time.Sleep(200 * time.Millisecond) } } func main() { X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Start generating other source events. otherChan := otherSource() // Start generating X events (by sending client messages to root window). go xSource(X) // Listen to those X events. xwindow.New(X, X.RootWin()).Listen(xproto.EventMaskSubstructureNotify) // Respond to those X events. xevent.ClientMessageFun( func(X *xgbutil.XUtil, ev xevent.ClientMessageEvent) { atmName, err := xprop.AtomName(X, ev.Type) if err != nil { log.Fatal(err) } fmt.Printf("ClientMessage: %d. %s\n", ev.Data.Data32[0], atmName) }).Connect(X, X.RootWin()) // Instead of using the usual xevent.Main, we use xevent.MainPing. // It runs the main event loop inside a goroutine and returns ping // channels, which are sent benign values right before an event is // dequeued and right after that event has finished running all callbacks // associated with it, respectively. pingBefore, pingAfter, pingQuit := xevent.MainPing(X) for { select { case <-pingBefore: // Wait for the event to finish processing. <-pingAfter case otherVal := <-otherChan: fmt.Printf("Processing other event: %d\n", otherVal) case <-pingQuit: fmt.Printf("xevent loop has quit") return } } } ================================================ FILE: _examples/pointer-painting/main.go ================================================ // Example pointer-painting shows how to draw on a window, MS Paint style. // This is an extremely involved example, but it showcases a lot of xgbutil // and how pieces of it can be tied together. // // If you're just starting with xgbutil, I highly recommend checking out the // other examples before attempting to digest this one. package main import ( "bytes" "fmt" "image" _ "image/png" "log" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/gopher" "github.com/BurntSushi/xgbutil/keybind" "github.com/BurntSushi/xgbutil/mousebind" "github.com/BurntSushi/xgbutil/xevent" "github.com/BurntSushi/xgbutil/xgraphics" "github.com/BurntSushi/xgbutil/xwindow" ) var ( // The color to use for the background. bg = xgraphics.BGRA{0x0, 0x0, 0x0, 0xff} // Different colors for drawing. // The keys represent the key sequences that must be pressed to // switch to the color value. pencils = map[string]xgraphics.BGRA{ "1": xgraphics.BGRA{0xff, 0xff, 0xff, 0xff}, // white "2": xgraphics.BGRA{0xff, 0x0, 0x0, 0xff}, // blue "3": xgraphics.BGRA{0x0, 0xff, 0x0, 0xff}, // green "4": xgraphics.BGRA{0x0, 0x0, 0xff, 0xff}, // red "5": xgraphics.BGRA{0x0, 0x7f, 0xff, 0xff}, // orange "6": xgraphics.BGRA{0xaa, 0x0, 0xff, 0x55}, // transparent pink } // The current pencil color. pencil = xgraphics.BGRA{0xff, 0xff, 0xff, 0xff} // The size of the tip of the pencil, in pixels. pencilTip = 30 // The width and height of the canvas. width, height = 1000, 1000 // The key sequence to use to clear the canvas. clearKey = "c" // Easter egg! Right click to draw a gopher with the following dimensions. gopherWidth, gopherHeight = 100, 100 ) // drawPencil takes an (x, y) position (from a MotionNotify event) and draws // a rectangle of size pencilTip on to canvas. func drawPencil(canvas *xgraphics.Image, win *xwindow.Window, x, y int) { // Create a subimage at (x, y) with pencilTip width and height from canvas. // Creating subimages is very cheap---no pixels are copied. // Moreover, when subimages are drawn to the screen, only the pixels in // the sub-image are sent to X. tipRect := midRect(x, y, pencilTip, pencilTip, width, height) // If the rectangle contains no pixels, don't draw anything. if tipRect.Empty() { return } // Output a little message. log.Printf("Drawing pencil point at (%d, %d)", x, y) // Create the subimage of the canvas to draw to. tip := canvas.SubImage(tipRect).(*xgraphics.Image) fmt.Println(tip.Rect) // Now color each pixel in tip with the pencil color. tip.For(func(x, y int) xgraphics.BGRA { return xgraphics.BlendBGRA(tip.At(x, y).(xgraphics.BGRA), pencil) }) // Now draw the changes to the pixmap. tip.XDraw() // And paint them to the window. tip.XPaint(win.Id) } // drawGopher draws the gopher image to the canvas. func drawGopher(canvas *xgraphics.Image, gopher image.Image, win *xwindow.Window, x, y int) { // Find the rectangle of the canvas where we're going to draw the gopher. gopherRect := midRect(x, y, gopherWidth, gopherHeight, width, height) // If the rectangle contains no pixels, don't draw anything. if gopherRect.Empty() { return } // Output a little message. log.Printf("Drawing gopher at (%d, %d)", x, y) // Get a subimage of the gopher that's in sync with gopherRect. gopherPt := image.Pt(gopher.Bounds().Min.X, gopher.Bounds().Min.Y) if gopherRect.Min.X == 0 { gopherPt.X = gopherWidth - gopherRect.Dx() } if gopherRect.Min.Y == 0 { gopherPt.Y = gopherHeight - gopherRect.Dy() } // Create the canvas subimage. subCanvas := canvas.SubImage(gopherRect).(*xgraphics.Image) // Blend the gopher image into the sub-canvas. // This does alpha blending. xgraphics.Blend(subCanvas, gopher, gopherPt) // Now draw the changes to the pixmap. subCanvas.XDraw() // And paint them to the window. subCanvas.XPaint(win.Id) } // clearCanvas erases all your pencil marks. func clearCanvas(canvas *xgraphics.Image, win *xwindow.Window) { log.Println("Clearing canvas...") canvas.For(func(x, y int) xgraphics.BGRA { return bg }) canvas.XDraw() canvas.XPaint(win.Id) } func fatal(err error) { if err != nil { log.Panic(err) } } func main() { X, err := xgbutil.NewConn() fatal(err) // Whenever the mousebind package is used, you must call Initialize. // Similarly for the keybind package. keybind.Initialize(X) mousebind.Initialize(X) // Easter egg! Use a right click to draw a gopher. gopherPng, _, err := image.Decode(bytes.NewBuffer(gopher.GopherPng())) fatal(err) // Now scale it to a reasonable size. gopher := xgraphics.Scale(gopherPng, gopherWidth, gopherHeight) // Create a new xgraphics.Image. It automatically creates an X pixmap for // you, and handles drawing to windows in the XDraw, XPaint and // XSurfaceSet functions. // N.B. An error is possible since X pixmap allocation can fail. canvas := xgraphics.New(X, image.Rect(0, 0, width, height)) // Color in the background color. canvas.For(func(x, y int) xgraphics.BGRA { return bg }) // Use the convenience function XShowExtra to create and map the // canvas window. // XShowExtra will also set the surface window of canvas for us. // We also use XShowExtra to set the name of the window and to quit the // main event loop when the window is closed. win := canvas.XShowExtra("Pointer painting", true) // Listen for pointer motion events and key press events. win.Listen(xproto.EventMaskButtonPress | xproto.EventMaskButtonRelease | xproto.EventMaskKeyPress) // The mousebind drag function runs three callbacks: one when the drag is // first started, another at each "step" in the drag, and a final one when // the drag is done. // The button sequence (in this case '1') is pressed, the first callback // is executed. If the first return value is true, the drag continues // and a pointer grab is initiated with the cursor id specified in the // second return value (use 0 to keep the cursor unchanged). // If it's false, the drag stops. // Note that Drag will automatically compress MotionNotify events. mousebind.Drag(X, win.Id, win.Id, "1", false, func(X *xgbutil.XUtil, rx, ry, ex, ey int) (bool, xproto.Cursor) { drawPencil(canvas, win, ex, ey) return true, 0 }, func(X *xgbutil.XUtil, rx, ry, ex, ey int) { drawPencil(canvas, win, ex, ey) }, func(X *xgbutil.XUtil, rx, ry, ex, ey int) {}) mousebind.Drag(X, win.Id, win.Id, "3", false, func(X *xgbutil.XUtil, rx, ry, ex, ey int) (bool, xproto.Cursor) { drawGopher(canvas, gopher, win, ex, ey) return true, 0 }, func(X *xgbutil.XUtil, rx, ry, ex, ey int) { drawGopher(canvas, gopher, win, ex, ey) }, func(X *xgbutil.XUtil, rx, ry, ex, ey int) {}) // Bind to the clear key specified, and just redraw the bg color. keybind.KeyPressFun( func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) { clearCanvas(canvas, win) }).Connect(X, win.Id, clearKey, false) // Bind a callback to each key specified in the 'pencils' color map. // The response is to simply switch the pencil color. for key, clr := range pencils { c := clr keybind.KeyPressFun( func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) { log.Printf("Changing pencil color to: %#v", c) pencil = c }).Connect(X, win.Id, key, false) } // Output some basic directions. fmt.Println("Use the left or right buttons on your mouse to paint " + "squares and gophers.") fmt.Println("Pressing numbers 1, 2, 3, 4, 5 or 6 will switch your pencil " + "color.") fmt.Println("Pressing 'c' will clear the canvas.") xevent.Main(X) } // midRect takes an (x, y) position where the pointer was clicked, along with // the width and height of the thing being drawn and the width and height of // the canvas, and returns a Rectangle whose midpoint (roughly) is (x, y) and // whose width and height match the parameters when the rectangle doesn't // extend past the border of the canvas. Make sure to check if the rectange is // empty or not before using it! func midRect(x, y, width, height, canWidth, canHeight int) image.Rectangle { return image.Rect( max(0, min(canWidth, x-width/2)), // top left x max(0, min(canHeight, y-height/2)), // top left y max(0, min(canWidth, x+width/2)), // bottom right x max(0, min(canHeight, y+height/2)), // bottom right y ) } func max(a, b int) int { if a > b { return a } return b } func min(a, b int) int { if a < b { return a } return b } ================================================ FILE: _examples/screenshot/main.go ================================================ // Example screenshot shows how to take a screenshot of the current desktop // and show it in a window. In a comment, it also shows how to save it as // a png. // // It works by getting the image of the root window, which automatically // includes all child windows. package main import ( "log" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/xevent" "github.com/BurntSushi/xgbutil/xgraphics" ) func main() { X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Use the "NewDrawable" constructor to create an xgraphics.Image value // from a drawable. (Usually this is done with pixmaps, but drawables // can also be windows.) ximg, err := xgraphics.NewDrawable(X, xproto.Drawable(X.RootWin())) if err != nil { log.Fatal(err) } // Shows the screenshot in a window. ximg.XShowExtra("Screenshot", true) // If you'd like to save it as a png, use: // err = ximg.SavePng("screenshot.png") // if err != nil { // log.Fatal(err) // } xevent.Main(X) } ================================================ FILE: _examples/show-image/main.go ================================================ // Example show-image is a very simple example to show how to use the // xgraphics package to show an image in a window. package main import ( "bytes" "image" _ "image/png" "log" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/gopher" "github.com/BurntSushi/xgbutil/xevent" "github.com/BurntSushi/xgbutil/xgraphics" ) func main() { X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Read an example gopher image into a regular png image. img, _, err := image.Decode(bytes.NewBuffer(gopher.GopherPng())) if err != nil { log.Fatal(err) } // Now convert it into an X image. ximg := xgraphics.NewConvert(X, img) // Now show it in a new window. // We set the window title and tell the program to quit gracefully when // the window is closed. // There is also a convenience method, XShow, that requires no parameters. ximg.XShowExtra("The Go Gopher!", true) // If we don't block, the program will end and the window will disappear. // We could use a 'select{}' here, but xevent.Main will emit errors if // something went wrong, so use that instead. xevent.Main(X) } ================================================ FILE: _examples/show-window-icons/main.go ================================================ // Example show-window-icons shows how to get a list of all top-level client // windows managed by the currently running window manager, and show the icon // for each window. (Each icon is shown by opening its own window.) package main import ( "image/color" "log" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/ewmh" "github.com/BurntSushi/xgbutil/xevent" "github.com/BurntSushi/xgbutil/xgraphics" ) var ( // The icon width and height to use. // _NET_WM_ICON will be searched for an icon closest to these values. // The icon closest in size to what's specified here will be used. // The resulting icon will be scaled to this size. // (Set both to 0 to avoid scaling and use the biggest possible icon.) iconWidth, iconHeight = 300, 300 ) func main() { X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Get the list of window ids managed by the window manager. clients, err := ewmh.ClientListGet(X) if err != nil { log.Fatal(err) } // For each client, try to find its icon. If we find one, blend it with // a nice background color and show it in its own window. // Otherwise, skip it. for _, wid := range clients { // FindIcon will find an icon closest to the size specified. // If one can't be found, the resulting image will be scaled // automatically. // To avoid scaling the icon, specify '0' for both the width and height. // In this case, the largest icon found will be returned. xicon, err := xgraphics.FindIcon(X, wid, iconWidth, iconHeight) if err != nil { log.Printf("Could not find icon for window %d.", wid) continue } // Get the name of this client. (It will be set as the icon window's // name.) name, err := ewmh.WmNameGet(X, wid) if err != nil { // not a fatal error log.Println(err) name = "" } // Blend a pink background color so its easy to see that alpha blending // works. xgraphics.BlendBgColor(xicon, color.RGBA{0xff, 0x0, 0xff, 0xff}) xicon.XShowExtra(name, false) } // All we really need to do is block, so a 'select{}' would be sufficient. // But running the event loop will emit errors if anything went wrong. xevent.Main(X) } ================================================ FILE: _examples/simple-keybinding/main.go ================================================ // Example simple-keybinding shows how to grab keys on the root window and // respond to them via callback functions. It also shows how to remove such // callbacks so that they no longer respond to the key events. // Note that more documentation can be found in the keybind package. package main import ( "log" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/keybind" "github.com/BurntSushi/xgbutil/xevent" ) func main() { // Connect to the X server using the DISPLAY environment variable. X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Anytime the keybind (mousebind) package is used, keybind.Initialize // *should* be called once. It isn't strictly necessary, but allows your // keybindings to persist even if the keyboard mapping is changed during // run-time. (Assuming you're using the xevent package's event loop.) keybind.Initialize(X) // Before attaching callbacks, wrap them in a callback function type. // The keybind package exposes two such callback types: keybind.KeyPressFun // and keybind.KeyReleaseFun. cb1 := keybind.KeyPressFun( func(X *xgbutil.XUtil, e xevent.KeyPressEvent) { log.Println("Key press!") }) // We can now attach the callback to a particular window and key // combination. This particular example grabs a key on the root window, // which makes it a global keybinding. // Also, "Mod4-j" typically corresponds to pressing down the "Super" or // "Windows" key on your keyboard, and then pressing the letter "j". // N.B. This approach works by issuing a passive grab on the window // specified. To respond to Key{Press,Release} events without a grab, use // the xevent.Key{Press,Release}Fun callback function types instead. err = cb1.Connect(X, X.RootWin(), "Mod4-j", true) // A keybinding can fail if the key string could not be parsed, or if you're // trying to bind a key that has already been grabbed by another client. if err != nil { log.Fatal(err) } // We can even attach multiple callbacks to the same key. err = keybind.KeyPressFun( func(X *xgbutil.XUtil, e xevent.KeyPressEvent) { log.Println("A second handler always happens after the first.") }).Connect(X, X.RootWin(), "Mod4-j", true) if err != nil { log.Fatal(err) } // Finally, if we want this client to stop responding to key events, we // can attach another handler that, when run, detaches all previous // handlers. // This time, we'll show an example of a KeyRelease binding. err = keybind.KeyReleaseFun( func(X *xgbutil.XUtil, e xevent.KeyReleaseEvent) { // Use keybind.Detach to detach the root window // from all KeyPress *and* KeyRelease handlers. keybind.Detach(X, X.RootWin()) log.Printf("Detached all Key{Press,Release}Events from the "+ "root window (%d).", X.RootWin()) }).Connect(X, X.RootWin(), "Mod4-Shift-q", true) if err != nil { log.Fatal(err) } // Finally, start the main event loop. This will route any appropriate // KeyPressEvents to your callback function. log.Println("Program initialized. Start pressing keys!") xevent.Main(X) } ================================================ FILE: _examples/simple-mousebinding/main.go ================================================ // Example simple-mousebinding shows how to grab buttons on the root window and // respond to them via callback functions. It also shows how to remove such // callbacks so that they no longer respond to the button events. // Note that more documentation can be found in the mousebind package. package main import ( "log" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/mousebind" "github.com/BurntSushi/xgbutil/xevent" ) func main() { // Connect to the X server using the DISPLAY environment variable. X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Anytime the mousebind (keybind) package is used, mousebind.Initialize // *should* be called once. In the case of the mousebind package, this // isn't strictly necessary, but the 'Drag' features of the mousebind // package won't work without it. mousebind.Initialize(X) // Before attaching callbacks, wrap them in a callback function type. // The mouse package exposes two such callback types: // mousebind.ButtonPressFun and mousebind.ButtonReleaseFun. cb1 := mousebind.ButtonPressFun( func(X *xgbutil.XUtil, e xevent.ButtonPressEvent) { log.Println("Button press!") }) // We can now attach the callback to a particular window and button // combination. This particular example grabs a button on the root window, // which makes it a global mouse binding. // Also, "Mod4-1" typically corresponds to pressing down the "Super" or // "Windows" key on your keyboard, and then pressing the left mouse button. // The last two parameters are whether to make a synchronous grab and // whether to actually issue a grab, respectively. // (The parameters used here are the common case.) // See the documentation for the Connect method for more details. err = cb1.Connect(X, X.RootWin(), "Mod4-1", false, true) // A mouse binding can fail if the mouse string could not be parsed, or if // you're trying to bind a button that has already been grabbed by another // client. if err != nil { log.Fatal(err) } // We can even attach multiple callbacks to the same button. err = mousebind.ButtonPressFun( func(X *xgbutil.XUtil, e xevent.ButtonPressEvent) { log.Println("A second handler always happens after the first.") }).Connect(X, X.RootWin(), "Mod4-1", false, true) if err != nil { log.Fatal(err) } // Finally, if we want this client to stop responding to mouse events, we // can attach another handler that, when run, detaches all previous // handlers. // This time, we'll show an example of a ButtonRelease binding. err = mousebind.ButtonReleaseFun( func(X *xgbutil.XUtil, e xevent.ButtonReleaseEvent) { // Use mousebind.Detach to detach the root window // from all ButtonPress *and* ButtonRelease handlers. mousebind.Detach(X, X.RootWin()) mousebind.Detach(X, X.RootWin()) log.Printf("Detached all Button{Press,Release}Events from the "+ "root window (%d).", X.RootWin()) }).Connect(X, X.RootWin(), "Mod4-Shift-1", false, true) if err != nil { log.Fatal(err) } // Finally, start the main event loop. This will route any appropriate // ButtonPressEvents to your callback function. log.Println("Program initialized. Start pressing mouse buttons!") xevent.Main(X) } ================================================ FILE: _examples/window-gradient/main.go ================================================ // Example window-gradient demonstrates how to create several windows and draw // gradients as their background. Namely, it shows how to use the // xgraphics.Image type as a canvas that can change size. This example also // demonstrates how to compress ConfigureNotify events so that the gradient // drawing does not lag behind the rate of incoming ConfigureNotify events. package main import ( "image" "image/color" "log" "math/rand" "time" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/xevent" "github.com/BurntSushi/xgbutil/xgraphics" "github.com/BurntSushi/xgbutil/xwindow" ) func main() { rand.Seed(time.Now().UnixNano()) X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Create three gradient windows of varying size with random colors. // Waiting a little bit inbetween seems to increase the diversity of the // random colors. newGradientWindow(X, 200, 200, newRandomColor(), newRandomColor()) time.Sleep(500 * time.Millisecond) newGradientWindow(X, 400, 400, newRandomColor(), newRandomColor()) time.Sleep(500 * time.Millisecond) newGradientWindow(X, 600, 600, newRandomColor(), newRandomColor()) xevent.Main(X) } // newGradientWindow creates a new X window, paints the initial gradient // image, and listens for ConfigureNotify events. (A new gradient image must // be painted in response to each ConfigureNotify event, since a // ConfigureNotify event corresponds to a change in the window's geometry.) func newGradientWindow(X *xgbutil.XUtil, width, height int, start, end color.RGBA) { // Generate a new window id. win, err := xwindow.Generate(X) if err != nil { log.Fatal(err) } // Create the window and die if it fails. err = win.CreateChecked(X.RootWin(), 0, 0, width, height, 0) if err != nil { log.Fatal(err) } // In order to get ConfigureNotify events, we must listen to the window // using the 'StructureNotify' mask. win.Listen(xproto.EventMaskStructureNotify) // Paint the initial gradient to the window and then map the window. paintGradient(X, win.Id, width, height, start, end) win.Map() xevent.ConfigureNotifyFun( func(X *xgbutil.XUtil, ev xevent.ConfigureNotifyEvent) { // If the width and height have not changed, skip this one. if int(ev.Width) == width && int(ev.Height) == height { return } // Compress ConfigureNotify events so that we don't lag when // drawing gradients in response. ev = compressConfigureNotify(X, ev) // Update the width and height and paint the gradient image. width, height = int(ev.Width), int(ev.Height) paintGradient(X, win.Id, width, height, start, end) }).Connect(X, win.Id) } // paintGradient creates a new xgraphics.Image value and draws a gradient // starting at color 'start' and ending at color 'end'. // // Since xgraphics.Image values use pixmaps and pixmaps cannot be resized, // a new pixmap must be allocated for each resize event. func paintGradient(X *xgbutil.XUtil, wid xproto.Window, width, height int, start, end color.RGBA) { ximg := xgraphics.New(X, image.Rect(0, 0, width, height)) // Now calculate the increment step between each RGB channel in // the start and end colors. rinc := (0xff * (int(end.R) - int(start.R))) / width ginc := (0xff * (int(end.G) - int(start.G))) / width binc := (0xff * (int(end.B) - int(start.B))) / width // Now apply the increment to each "column" in the image. // Using 'ForExp' allows us to bypass the creation of a color.BGRA value // for each pixel in the image. ximg.ForExp(func(x, y int) (uint8, uint8, uint8, uint8) { return uint8(int(start.B) + (binc*x)/0xff), uint8(int(start.G) + (ginc*x)/0xff), uint8(int(start.R) + (rinc*x)/0xff), 0xff }) // Set the surface to paint on for ximg. // (This simply sets the background pixmap of the window to the pixmap // used by ximg.) ximg.XSurfaceSet(wid) // XDraw will draw the contents of ximg to its corresponding pixmap. ximg.XDraw() // XPaint will "clear" the window provided so that it shows the updated // pixmap. ximg.XPaint(wid) // Since we will not reuse ximg, we must destroy its pixmap. ximg.Destroy() } // compressConfigureNotify "compresses" incoming ConfigureNotify events so that // event processing never lags behind gradient drawing. // This is necessary because drawing a gradient cannot keep up with the rate // at which ConfigureNotify events are sent to us, thereby creating a "lag". // Compression works by examining the "future" of the event queue, and skipping // ahead to the most recent ConfigureNotify event and throwing away the rest. // // A more detailed treatment of event compression can be found in // xgbutil/examples/compress-events. func compressConfigureNotify(X *xgbutil.XUtil, ev xevent.ConfigureNotifyEvent) xevent.ConfigureNotifyEvent { // Catch up with all X events as much as we can. X.Sync() xevent.Read(X, false) // non-blocking laste := ev for i, ee := range xevent.Peek(X) { if ee.Err != nil { continue } if cn, ok := ee.Event.(xproto.ConfigureNotifyEvent); ok { // Only compress this ConfigureNotify if it matches the window // of the original event. if ev.Event == cn.Event && ev.Window == cn.Window { laste = xevent.ConfigureNotifyEvent{&cn} defer func(i int) { xevent.DequeueAt(X, i) }(i) } } } return laste } // newRandomColor creates a new RGBA color where each channel (except alpha) // is randomly generated. func newRandomColor() color.RGBA { return color.RGBA{ R: uint8(rand.Intn(256)), G: uint8(rand.Intn(256)), B: uint8(rand.Intn(256)), A: 0xff, } } ================================================ FILE: _examples/window-name-sizes/main.go ================================================ // Example window-names fetches a list of all top-level client windows managed // by the currently running window manager, and prints the name and size // of each window. // // This example demonstrates how to use some aspects of the ewmh and icccm // packages. It also shows how to use the xwindow package to find the // geometry of a client window. In particular, finding the geometry is // intelligent, as it includes the geometry of the decorations if they exist. package main import ( "fmt" "log" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/ewmh" "github.com/BurntSushi/xgbutil/icccm" "github.com/BurntSushi/xgbutil/xwindow" ) func main() { // Connect to the X server using the DISPLAY environment variable. X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Get a list of all client ids. clientids, err := ewmh.ClientListGet(X) if err != nil { log.Fatal(err) } // Iterate through each client, find its name and find its size. for _, clientid := range clientids { name, err := ewmh.WmNameGet(X, clientid) // If there was a problem getting _NET_WM_NAME or if its empty, // try the old-school version. if err != nil || len(name) == 0 { name, err = icccm.WmNameGet(X, clientid) // If we still can't find anything, give up. if err != nil || len(name) == 0 { name = "N/A" } } // Now find the geometry, including decorations, of the client window. // Note that DecorGeometry actually traverses the window tree by // issuing QueryTree requests until a top-level window (i.e., its // parent is the root window) is found. The geometry of *that* window // is then returned. dgeom, err := xwindow.New(X, clientid).DecorGeometry() if err != nil { log.Printf("Could not get geometry for %s (0x%X) because: %s", name, clientid, err) continue } fmt.Printf("%s (0x%x)\n", name, clientid) fmt.Printf("\tGeometry: %s\n", dgeom) } } ================================================ FILE: _examples/workarea-struts/main.go ================================================ // Example workarea-struts shows how to find the all of the struts set by // top-level clients and apply them to each active monitor to get the true // workarea for each monitor. // // For example, consider a monitor with a 1920x1080 resolution and a panel // on the bottom of the desktop 50 pixels tall. The actual workarea for the // desktop then, is (0, 0) 1920x1030. (When there is more than one monitor, // the x and y coordinates will be adjusted too.) package main import ( "fmt" "log" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/ewmh" "github.com/BurntSushi/xgbutil/xinerama" "github.com/BurntSushi/xgbutil/xrect" "github.com/BurntSushi/xgbutil/xwindow" ) func main() { // Connect to the X server using the DISPLAY environment variable. X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Wrap the root window in a nice Window type. root := xwindow.New(X, X.RootWin()) // Get the geometry of the root window. rgeom, err := root.Geometry() if err != nil { log.Fatal(err) } // Get the rectangles for each of the active physical heads. // These are returned sorted in order from left to right and then top // to bottom. // But first check if Xinerama is enabled. If not, use root geometry. var heads xinerama.Heads if X.ExtInitialized("XINERAMA") { heads, err = xinerama.PhysicalHeads(X) if err != nil { log.Fatal(err) } } else { heads = xinerama.Heads{rgeom} } // Fetch the list of top-level client window ids currently managed // by the running window manager. clients, err := ewmh.ClientListGet(X) if err != nil { log.Fatal(err) } // Output the head geometry before modifying them. fmt.Println("Workarea for each head:") for i, head := range heads { fmt.Printf("\tHead #%d: %s\n", i+1, head) } // For each client, check to see if it has struts, and if so, apply // them to our list of head rectangles. for _, clientid := range clients { strut, err := ewmh.WmStrutPartialGet(X, clientid) if err != nil { // no struts for this client continue } // Apply the struts to our heads. // This modifies 'heads' in place. xrect.ApplyStrut(heads, uint(rgeom.Width()), uint(rgeom.Height()), strut.Left, strut.Right, strut.Top, strut.Bottom, strut.LeftStartY, strut.LeftEndY, strut.RightStartY, strut.RightEndY, strut.TopStartX, strut.TopEndX, strut.BottomStartX, strut.BottomEndX) } // Now output the head geometry again after modification. fmt.Println("Workarea for each head after applying struts:") for i, head := range heads { fmt.Printf("\tHead #%d: %s\n", i+1, head) } } ================================================ FILE: _examples/xgraphics-compat/main.go ================================================ package main import ( "log" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/xgraphics" ) func main() { log.SetFlags(0) X, err := xgbutil.NewConn() if err != nil { log.Fatalln(err) } checkCompatibility(X) } // checkCompatibility reads info in the X setup info struct and emits // messages to stderr if they don't correspond to values that xgraphics // supports. // The idea is that in the future, we'll support more values. // The real reason for checkCompatibility is to make debugging easier. Without // it, if the values weren't what we'd expect, we'd see garbled images in the // best case, and probably BadLength errors in the worst case. func checkCompatibility(X *xgbutil.XUtil) { s := X.Setup() scrn := X.Screen() failed := false if s.ImageByteOrder != xproto.ImageOrderLSBFirst { log.Printf("Your X server uses MSB image byte order. Unfortunately, " + "xgraphics currently requires LSB image byte order. You may see " + "weird things. Please report this.") failed = true } if s.BitmapFormatBitOrder != xproto.ImageOrderLSBFirst { log.Printf("Your X server uses MSB bitmap bit order. Unfortunately, " + "xgraphics currently requires LSB bitmap bit order. If you " + "aren't using X bitmaps, you should be able to proceed normally. " + "Please report this.") failed = true } if s.BitmapFormatScanlineUnit != 32 { log.Printf("xgraphics expects that the scanline unit is set to 32, "+ "but your X server has it set to '%d'. "+ "Namely, xgraphics hasn't been tested on other values. Things "+ "may still work. Particularly, if you aren't using X bitmaps, "+ "you should be completely unaffected. Please report this.", s.BitmapFormatScanlineUnit) failed = true } if scrn.RootDepth != 24 { log.Printf("xgraphics expects that the root window has a depth of 24, "+ "but yours has depth '%d'. Its possible things will still work "+ "if your value is 32, but will be unlikely to work with values "+ "less than 24. Please report this.", scrn.RootDepth) failed = true } // Look for the default format for pixmaps and make sure bits per pixel // is 32. format := xgraphics.GetFormat(X, scrn.RootDepth) if format.BitsPerPixel != 32 { log.Printf("xgraphics expects that the bits per pixel for the root "+ "window depth is 32. On your system, the root depth is %d and "+ "the bits per pixel is %d. Things will most certainly not work. "+ "Please report this.", scrn.RootDepth, format.BitsPerPixel) failed = true } // Give instructions on reporting the issue. if failed { log.Printf("Please report the aforementioned error message(s) at " + "https://github.com/BurntSushi/xgbutil. Please also include the " + "entire output of the `xdpyinfo` command in your report. Thanks!") } else { log.Printf("No compatibility issues detected.") } } ================================================ FILE: _examples/xmodmap/main.go ================================================ // Example xmodmap shows how one might implement a rudimentary version // of xmodmap's modifier listing. // (xmodmap is a program that shows all modifier keys, and which // keysyms activate each modifier. xmodmap can also modify the modifier // mapping, which this doesn't do.) package main import ( "fmt" "log" "strings" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/keybind" ) func main() { // Connect to the X server using the DISPLAY environment variable. X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Nice names for the modifier keys (same ones used by xmodmap). // This slice corresponds to the keybind.Modifiers slice (except for // the last 'Any' modifier element). nice := []string{ "shift", "lock", "control", "mod1", "mod2", "mod3", "mod4", "mod5", } // Whenever one uses the keybind package, Initialize should always be // called first. In this case, it initializes the key and modifier maps. keybind.Initialize(X) // Get the current modifier map. // The map is actually a table, where rows correspond to modifiers, and // columns correspond to the keys that activate that modifier. modMap := keybind.ModMapGet(X) // The number of keycodes allowed per modifier (i.e., the number of // columns in the modifier map). kPerMod := int(modMap.KeycodesPerModifier) // Get the number of allowable keysyms per keycode. // This is used to search for a valid keysym for a particular keycode. symsPerKc := int(keybind.KeyMapGet(X).KeysymsPerKeycode) // Imitate everything... fmt.Printf("xmodmap: up to %d keys per modifier, "+ "(keycodes in parentheses):\n\n", kPerMod) // Iterate through all keyboard modifiers defined in xgb/xproto // except the 'Any' modifier (which is last). for mmi := range keybind.Modifiers[:len(keybind.Modifiers)-1] { niceName := nice[mmi] keys := make([]string, 0, kPerMod) // row is the row for the 'mmi' modifier in the modifier mapping table. row := mmi * kPerMod // Iterate over each keycode in the modifier map for this modifier. for _, kc := range modMap.Keycodes[row : row+kPerMod] { // If this entry doesn't have a keycode (i.e., it's zero), we // have to skip it. if kc == 0 { continue } // Look for the first valid keysym in the keyboard map corresponding // to this keycode. If one can't be found, output "BadKey." var ksym xproto.Keysym = 0 for column := 0; column < symsPerKc; column++ { ksym = keybind.KeysymGet(X, kc, byte(column)) if ksym != 0 { break } } if ksym == 0 { keys = append(keys, fmt.Sprintf("BadKey (0x%x)", kc)) } else { keys = append(keys, fmt.Sprintf("%s (0x%x)", keybind.KeysymToStr(ksym), kc)) } } fmt.Printf("%-12s%s\n", niceName, strings.Join(keys, ", ")) } fmt.Println("") } ================================================ FILE: doc.go ================================================ /* Package xgbutil is a utility library designed to make common tasks with the X server easier. The central design choice that has driven development is to hide the complexity of X wherever possible but expose it when necessary. For example, the xevent package provides an implementation of an X event loop that acts as a dispatcher to event handlers set up with the xevent, keybind and mousebind packages. At the same time, the event queue is exposed and can be modified using xevent.Peek and xevent.DequeueAt. Sub-packages The xgbutil package is considerably small, and only contains some type definitions and the initial setup for an X connection. Much of the functionality of xgbutil comes from its sub-packages. Each sub-package is appropriately documented. Installation xgbutil is go-gettable: go get github.com/BurntSushi/xgbutil Dependencies XGB is the main dependency, and is required for all packages inside xgbutil. graphics-go and freetype-go are also required if using the xgraphics package. Quick Example A quick example to demonstrate that xgbutil is working correctly: go get github.com/BurntSushi/xgbutil/examples/window-name-sizes GO/PATH/bin/window-name-sizes The output will be a list of names of all top-level windows and their geometry including window manager decorations. (Assuming your window manager supports some basic EWMH properties.) Examples The examples directory contains a sizable number of examples demonstrating common tasks with X. They are intended to demonstrate a single thing each, although a few that require setup are necessarily long. Each example is heavily documented. The examples directory should be your first stop when learning how to use xgbutil. xgbutil is also used heavily throughout my window manager, Wingo. It may be useful reference material. Wingo project page: https://github.com/BurntSushi/wingo Thread Safety While I am fairly confident that XGB is thread safe, I am only somewhat confident that xgbutil is thread safe. It simply has not been tested enough for my confidence to be higher. Note that the xevent package's X event loop is not concurrent. Namely, designing a generally concurrent X event loop is extremely complex. Instead, the onus is on you, the user, to design concurrent callback functions if concurrency is desired. */ package xgbutil ================================================ FILE: ewmh/doc.go ================================================ /* Package ewmh provides a comprehensive API to get and set properties specified by the EWMH spec, as well as perform actions specified by the EWMH spec. Since there are so many functions and they adhere to an existing spec, this package file does not contain much documentation. Indeed, each method has only a single comment associated with it: the EWMH property name. The idea is to provide a consistent interface to use all facilities described in the EWMH spec: http://standards.freedesktop.org/wm-spec/wm-spec-latest.html. Naming scheme Using "_NET_ACTIVE_WINDOW" as an example, functions "ActiveWindowGet" and "ActiveWindowSet" get and set the property, respectively. Both of these functions exist for most EWMH properties. Additionally, some EWMH properties support sending a client message event to request the window manager to perform some action. In the case of "_NET_ACTIVE_WINDOW", this request is used to set the active window. These sorts of functions end in "Req". So for "_NET_ACTIVE_WINDOW", the method name is "ActiveWindowReq". Moreover, most requests include various parameters that don't need to be changed often (like the source indication). Thus, by default, functions ending in "Req" force these to sensible defaults. If you need access to all of the parameters, use the corresponding "ReqExtra" method. So for "_NET_ACTIVE_WINDOW", that would be "ActiveWindowReqExtra". (If no "ReqExtra" method exists, then the "Req" method covers all available parameters.) This naming scheme has one exception: if a property's only use is through sending an event (like "_NET_CLOSE_WINDOW"), then the name will be "CloseWindow" for the short-hand version and "CloseWindowExtra" for access to all of the parameters. (Since there is no "_NET_CLOSE_WINDOW" property, there is no need for "CloseWindowGet" and "CloseWindowSet" functions.) For properties that store more than just a simple integer, name or list of integers, structs have been created and exposed to organize the information returned in a sensible manner. For example, the "_NET_DESKTOP_GEOMETRY" property would typically return a slice of integers of length 2, where the first integer is the width and the second is the height. Xgbutil will wrap this in a struct with the obvious members. These structs are documented. Finally, functions ending in "*Set" are typically only used when setting properties on clients *you've* created or when the window manager sets properties. Thus, it's unlikely that you should use them unless you're creating a top-level client or building a window manager. Functions ending in "Get" or "Req[Extra]" are commonly used. N.B. Not all properties have "*Req" functions. */ package ewmh ================================================ FILE: ewmh/ewmh.go ================================================ package ewmh import ( "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/xevent" "github.com/BurntSushi/xgbutil/xprop" ) // ClientEvent is a convenience function that sends ClientMessage events // to the root window as specified by the EWMH spec. func ClientEvent(xu *xgbutil.XUtil, window xproto.Window, messageType string, data ...interface{}) error { mstype, err := xprop.Atm(xu, messageType) if err != nil { return err } evMask := (xproto.EventMaskSubstructureNotify | xproto.EventMaskSubstructureRedirect) cm, err := xevent.NewClientMessage(32, window, mstype, data...) if err != nil { return err } return xevent.SendRootEvent(xu, cm, uint32(evMask)) } // _NET_ACTIVE_WINDOW get func ActiveWindowGet(xu *xgbutil.XUtil) (xproto.Window, error) { return xprop.PropValWindow(xprop.GetProperty(xu, xu.RootWin(), "_NET_ACTIVE_WINDOW")) } // _NET_ACTIVE_WINDOW set func ActiveWindowSet(xu *xgbutil.XUtil, win xproto.Window) error { return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_ACTIVE_WINDOW", "WINDOW", uint(win)) } // _NET_ACTIVE_WINDOW req func ActiveWindowReq(xu *xgbutil.XUtil, win xproto.Window) error { return ActiveWindowReqExtra(xu, win, 2, 0, 0) } // _NET_ACTIVE_WINDOW req extra func ActiveWindowReqExtra(xu *xgbutil.XUtil, win xproto.Window, source int, time xproto.Timestamp, currentActive xproto.Window) error { return ClientEvent(xu, win, "_NET_ACTIVE_WINDOW", source, int(time), int(currentActive)) } // _NET_CLIENT_LIST get func ClientListGet(xu *xgbutil.XUtil) ([]xproto.Window, error) { return xprop.PropValWindows(xprop.GetProperty(xu, xu.RootWin(), "_NET_CLIENT_LIST")) } // _NET_CLIENT_LIST set func ClientListSet(xu *xgbutil.XUtil, wins []xproto.Window) error { return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_CLIENT_LIST", "WINDOW", xprop.WindowToInt(wins)...) } // _NET_CLIENT_LIST_STACKING get func ClientListStackingGet(xu *xgbutil.XUtil) ([]xproto.Window, error) { return xprop.PropValWindows(xprop.GetProperty(xu, xu.RootWin(), "_NET_CLIENT_LIST_STACKING")) } // _NET_CLIENT_LIST_STACKING set func ClientListStackingSet(xu *xgbutil.XUtil, wins []xproto.Window) error { return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_CLIENT_LIST_STACKING", "WINDOW", xprop.WindowToInt(wins)...) } // _NET_CLOSE_WINDOW req func CloseWindow(xu *xgbutil.XUtil, win xproto.Window) error { return CloseWindowExtra(xu, win, 0, 2) } // _NET_CLOSE_WINDOW req extra func CloseWindowExtra(xu *xgbutil.XUtil, win xproto.Window, time xproto.Timestamp, source int) error { return ClientEvent(xu, win, "_NET_CLOSE_WINDOW", int(time), source) } // _NET_CURRENT_DESKTOP get func CurrentDesktopGet(xu *xgbutil.XUtil) (uint, error) { return xprop.PropValNum(xprop.GetProperty(xu, xu.RootWin(), "_NET_CURRENT_DESKTOP")) } // _NET_CURRENT_DESKTOP set func CurrentDesktopSet(xu *xgbutil.XUtil, desk uint) error { return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_CURRENT_DESKTOP", "CARDINAL", desk) } // _NET_CURRENT_DESKTOP req func CurrentDesktopReq(xu *xgbutil.XUtil, desk int) error { return CurrentDesktopReqExtra(xu, desk, 0) } // _NET_CURRENT_DESKTOP req extra func CurrentDesktopReqExtra(xu *xgbutil.XUtil, desk int, time xproto.Timestamp) error { return ClientEvent(xu, xu.RootWin(), "_NET_CURRENT_DESKTOP", desk, int(time)) } // _NET_DESKTOP_NAMES get func DesktopNamesGet(xu *xgbutil.XUtil) ([]string, error) { return xprop.PropValStrs(xprop.GetProperty(xu, xu.RootWin(), "_NET_DESKTOP_NAMES")) } // _NET_DESKTOP_NAMES set func DesktopNamesSet(xu *xgbutil.XUtil, names []string) error { nullterm := make([]byte, 0) for _, name := range names { nullterm = append(nullterm, name...) nullterm = append(nullterm, 0) } return xprop.ChangeProp(xu, xu.RootWin(), 8, "_NET_DESKTOP_NAMES", "UTF8_STRING", nullterm) } // DesktopGeometry is a struct that houses the width and height of a // _NET_DESKTOP_GEOMETRY property reply. type DesktopGeometry struct { Width int Height int } // _NET_DESKTOP_GEOMETRY get func DesktopGeometryGet(xu *xgbutil.XUtil) (*DesktopGeometry, error) { geom, err := xprop.PropValNums(xprop.GetProperty(xu, xu.RootWin(), "_NET_DESKTOP_GEOMETRY")) if err != nil { return nil, err } return &DesktopGeometry{Width: int(geom[0]), Height: int(geom[1])}, nil } // _NET_DESKTOP_GEOMETRY set func DesktopGeometrySet(xu *xgbutil.XUtil, dg *DesktopGeometry) error { return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_DESKTOP_GEOMETRY", "CARDINAL", uint(dg.Width), uint(dg.Height)) } // _NET_DESKTOP_GEOMETRY req func DesktopGeometryReq(xu *xgbutil.XUtil, dg *DesktopGeometry) error { return ClientEvent(xu, xu.RootWin(), "_NET_DESKTOP_GEOMETRY", dg.Width, dg.Height) } // DesktopLayout is a struct that organizes information pertaining to // the _NET_DESKTOP_LAYOUT property. Namely, the orientation, the number // of columns, the number of rows, and the starting corner. type DesktopLayout struct { Orientation int Columns int Rows int StartingCorner int } // _NET_DESKTOP_LAYOUT constants for orientation const ( OrientHorz = iota OrientVert ) // _NET_DESKTOP_LAYOUT constants for starting corner const ( TopLeft = iota TopRight BottomRight BottomLeft ) // _NET_DESKTOP_LAYOUT get func DesktopLayoutGet(xu *xgbutil.XUtil) (dl *DesktopLayout, err error) { dlraw, err := xprop.PropValNums(xprop.GetProperty(xu, xu.RootWin(), "_NET_DESKTOP_LAYOUT")) if err != nil { return nil, err } dl = &DesktopLayout{} dl.Orientation = int(dlraw[0]) dl.Columns = int(dlraw[1]) dl.Rows = int(dlraw[2]) if len(dlraw) > 3 { dl.StartingCorner = int(dlraw[3]) } else { dl.StartingCorner = TopLeft } return dl, nil } // _NET_DESKTOP_LAYOUT set func DesktopLayoutSet(xu *xgbutil.XUtil, orientation, columns, rows, startingCorner uint) error { return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_DESKTOP_LAYOUT", "CARDINAL", orientation, columns, rows, startingCorner) } // DesktopViewport is a struct that contains a pairing of x,y coordinates // representing the top-left corner of each desktop. (There will typically // be one struct here for each desktop in existence.) type DesktopViewport struct { X int Y int } // _NET_DESKTOP_VIEWPORT get func DesktopViewportGet(xu *xgbutil.XUtil) ([]DesktopViewport, error) { coords, err := xprop.PropValNums(xprop.GetProperty(xu, xu.RootWin(), "_NET_DESKTOP_VIEWPORT")) if err != nil { return nil, err } viewports := make([]DesktopViewport, len(coords)/2) for i, _ := range viewports { viewports[i] = DesktopViewport{ X: int(coords[i*2]), Y: int(coords[i*2+1]), } } return viewports, nil } // _NET_DESKTOP_VIEWPORT set func DesktopViewportSet(xu *xgbutil.XUtil, viewports []DesktopViewport) error { coords := make([]uint, len(viewports)*2) for i, viewport := range viewports { coords[i*2] = uint(viewport.X) coords[i*2+1] = uint(viewport.Y) } return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_DESKTOP_VIEWPORT", "CARDINAL", coords...) } // _NET_DESKTOP_VIEWPORT req func DesktopViewportReq(xu *xgbutil.XUtil, x, y int) error { return ClientEvent(xu, xu.RootWin(), "_NET_DESKTOP_VIEWPORT", x, y) } // FrameExtents is a struct that organizes information associated with // the _NET_FRAME_EXTENTS property. Namely, the left, right, top and bottom // decoration sizes. type FrameExtents struct { Left int Right int Top int Bottom int } // _NET_FRAME_EXTENTS get func FrameExtentsGet(xu *xgbutil.XUtil, win xproto.Window) (*FrameExtents, error) { raw, err := xprop.PropValNums(xprop.GetProperty(xu, win, "_NET_FRAME_EXTENTS")) if err != nil { return nil, err } return &FrameExtents{ Left: int(raw[0]), Right: int(raw[1]), Top: int(raw[2]), Bottom: int(raw[3]), }, nil } // _NET_FRAME_EXTENTS set func FrameExtentsSet(xu *xgbutil.XUtil, win xproto.Window, extents *FrameExtents) error { raw := make([]uint, 4) raw[0] = uint(extents.Left) raw[1] = uint(extents.Right) raw[2] = uint(extents.Top) raw[3] = uint(extents.Bottom) return xprop.ChangeProp32(xu, win, "_NET_FRAME_EXTENTS", "CARDINAL", raw...) } // _NET_MOVERESIZE_WINDOW req // If 'w' or 'h' are 0, then they are not sent. // If you need to resize a window without moving it, use the ReqExtra variant, // or Resize. func MoveresizeWindow(xu *xgbutil.XUtil, win xproto.Window, x, y, w, h int) error { return MoveresizeWindowExtra(xu, win, x, y, w, h, xproto.GravityBitForget, 2, true, true) } // _NET_MOVERESIZE_WINDOW req resize only func ResizeWindow(xu *xgbutil.XUtil, win xproto.Window, w, h int) error { return MoveresizeWindowExtra(xu, win, 0, 0, w, h, xproto.GravityBitForget, 2, false, false) } // _NET_MOVERESIZE_WINDOW req move only func MoveWindow(xu *xgbutil.XUtil, win xproto.Window, x, y int) error { return MoveresizeWindowExtra(xu, win, x, y, 0, 0, xproto.GravityBitForget, 2, true, true) } // _NET_MOVERESIZE_WINDOW req extra // If 'w' or 'h' are 0, then they are not sent. // To not set 'x' or 'y', 'usex' or 'usey' need to be set to false. func MoveresizeWindowExtra(xu *xgbutil.XUtil, win xproto.Window, x, y, w, h, gravity, source int, usex, usey bool) error { flags := gravity flags |= source << 12 if usex { flags |= 1 << 8 } if usey { flags |= 1 << 9 } if w > 0 { flags |= 1 << 10 } if h > 0 { flags |= 1 << 11 } return ClientEvent(xu, win, "_NET_MOVERESIZE_WINDOW", flags, x, y, w, h) } // _NET_NUMBER_OF_DESKTOPS get func NumberOfDesktopsGet(xu *xgbutil.XUtil) (uint, error) { return xprop.PropValNum(xprop.GetProperty(xu, xu.RootWin(), "_NET_NUMBER_OF_DESKTOPS")) } // _NET_NUMBER_OF_DESKTOPS set func NumberOfDesktopsSet(xu *xgbutil.XUtil, numDesks uint) error { return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_NUMBER_OF_DESKTOPS", "CARDINAL", numDesks) } // _NET_NUMBER_OF_DESKTOPS req func NumberOfDesktopsReq(xu *xgbutil.XUtil, numDesks int) error { return ClientEvent(xu, xu.RootWin(), "_NET_NUMBER_OF_DESKTOPS", numDesks) } // _NET_REQUEST_FRAME_EXTENTS req func RequestFrameExtents(xu *xgbutil.XUtil, win xproto.Window) error { return ClientEvent(xu, win, "_NET_REQUEST_FRAME_EXTENTS") } // _NET_RESTACK_WINDOW req // The shortcut here is to just raise the window to the top of the window stack. func RestackWindow(xu *xgbutil.XUtil, win xproto.Window) error { return RestackWindowExtra(xu, win, xproto.StackModeAbove, 0, 2) } // _NET_RESTACK_WINDOW req extra func RestackWindowExtra(xu *xgbutil.XUtil, win xproto.Window, stackMode int, sibling xproto.Window, source int) error { return ClientEvent(xu, win, "_NET_RESTACK_WINDOW", source, int(sibling), stackMode) } // _NET_SHOWING_DESKTOP get func ShowingDesktopGet(xu *xgbutil.XUtil) (bool, error) { reply, err := xprop.GetProperty(xu, xu.RootWin(), "_NET_SHOWING_DESKTOP") if err != nil { return false, err } val, err := xprop.PropValNum(reply, nil) if err != nil { return false, err } return val == 1, nil } // _NET_SHOWING_DESKTOP set func ShowingDesktopSet(xu *xgbutil.XUtil, show bool) error { var showInt uint if show { showInt = 1 } else { showInt = 0 } return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_SHOWING_DESKTOP", "CARDINAL", showInt) } // _NET_SHOWING_DESKTOP req func ShowingDesktopReq(xu *xgbutil.XUtil, show bool) error { var showInt uint if show { showInt = 1 } else { showInt = 0 } return ClientEvent(xu, xu.RootWin(), "_NET_SHOWING_DESKTOP", showInt) } // _NET_SUPPORTED get func SupportedGet(xu *xgbutil.XUtil) ([]string, error) { reply, err := xprop.GetProperty(xu, xu.RootWin(), "_NET_SUPPORTED") return xprop.PropValAtoms(xu, reply, err) } // _NET_SUPPORTED set // This will create any atoms in the argument if they don't already exist. func SupportedSet(xu *xgbutil.XUtil, atomNames []string) error { atoms, err := xprop.StrToAtoms(xu, atomNames) if err != nil { return err } return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_SUPPORTED", "ATOM", atoms...) } // _NET_SUPPORTING_WM_CHECK get func SupportingWmCheckGet(xu *xgbutil.XUtil, win xproto.Window) (xproto.Window, error) { return xprop.PropValWindow(xprop.GetProperty(xu, win, "_NET_SUPPORTING_WM_CHECK")) } // _NET_SUPPORTING_WM_CHECK set func SupportingWmCheckSet(xu *xgbutil.XUtil, win xproto.Window, wmWin xproto.Window) error { return xprop.ChangeProp32(xu, win, "_NET_SUPPORTING_WM_CHECK", "WINDOW", uint(wmWin)) } // _NET_VIRTUAL_ROOTS get func VirtualRootsGet(xu *xgbutil.XUtil) ([]xproto.Window, error) { return xprop.PropValWindows(xprop.GetProperty(xu, xu.RootWin(), "_NET_VIRTUAL_ROOTS")) } // _NET_VIRTUAL_ROOTS set func VirtualRootsSet(xu *xgbutil.XUtil, wins []xproto.Window) error { return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_VIRTUAL_ROOTS", "WINDOW", xprop.WindowToInt(wins)...) } // _NET_VISIBLE_DESKTOPS get // This is not part of the EWMH spec, but is a property of my own creation. // It allows the window manager to report that it has multiple desktops // viewable at the same time. (This conflicts with other EWMH properties, // so I don't think this will ever be added to the official spec.) func VisibleDesktopsGet(xu *xgbutil.XUtil) ([]uint, error) { return xprop.PropValNums(xprop.GetProperty(xu, xu.RootWin(), "_NET_VISIBLE_DESKTOPS")) } // _NET_VISIBLE_DESKTOPS set func VisibleDesktopsSet(xu *xgbutil.XUtil, desktops []uint) error { return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_VISIBLE_DESKTOPS", "CARDINAL", desktops...) } // _NET_WM_ALLOWED_ACTIONS get func WmAllowedActionsGet(xu *xgbutil.XUtil, win xproto.Window) ([]string, error) { raw, err := xprop.GetProperty(xu, win, "_NET_WM_ALLOWED_ACTIONS") return xprop.PropValAtoms(xu, raw, err) } // _NET_WM_ALLOWED_ACTIONS set func WmAllowedActionsSet(xu *xgbutil.XUtil, win xproto.Window, atomNames []string) error { atoms, err := xprop.StrToAtoms(xu, atomNames) if err != nil { return err } return xprop.ChangeProp32(xu, win, "_NET_WM_ALLOWED_ACTIONS", "ATOM", atoms...) } // _NET_WM_DESKTOP get func WmDesktopGet(xu *xgbutil.XUtil, win xproto.Window) (uint, error) { return xprop.PropValNum(xprop.GetProperty(xu, win, "_NET_WM_DESKTOP")) } // _NET_WM_DESKTOP set func WmDesktopSet(xu *xgbutil.XUtil, win xproto.Window, desk uint) error { return xprop.ChangeProp32(xu, win, "_NET_WM_DESKTOP", "CARDINAL", uint(desk)) } // _NET_WM_DESKTOP req func WmDesktopReq(xu *xgbutil.XUtil, win xproto.Window, desk uint) error { return WmDesktopReqExtra(xu, win, desk, 2) } // _NET_WM_DESKTOP req extra func WmDesktopReqExtra(xu *xgbutil.XUtil, win xproto.Window, desk uint, source int) error { return ClientEvent(xu, win, "_NET_WM_DESKTOP", desk, source) } // WmFullscreenMonitors is a struct that organizes information related to the // _NET_WM_FULLSCREEN_MONITORS property. Namely, the top, bottom, left and // right monitor edges for a particular window. type WmFullscreenMonitors struct { Top uint Bottom uint Left uint Right uint } // _NET_WM_FULLSCREEN_MONITORS get func WmFullscreenMonitorsGet(xu *xgbutil.XUtil, win xproto.Window) (*WmFullscreenMonitors, error) { raw, err := xprop.PropValNums( xprop.GetProperty(xu, win, "_NET_WM_FULLSCREEN_MONITORS")) if err != nil { return nil, err } return &WmFullscreenMonitors{ Top: raw[0], Bottom: raw[1], Left: raw[2], Right: raw[3], }, nil } // _NET_WM_FULLSCREEN_MONITORS set func WmFullscreenMonitorsSet(xu *xgbutil.XUtil, win xproto.Window, edges *WmFullscreenMonitors) error { raw := make([]uint, 4) raw[0] = edges.Top raw[1] = edges.Bottom raw[2] = edges.Left raw[3] = edges.Right return xprop.ChangeProp32(xu, win, "_NET_WM_FULLSCREEN_MONITORS", "CARDINAL", raw...) } // _NET_WM_FULLSCREEN_MONITORS req func WmFullscreenMonitorsReq(xu *xgbutil.XUtil, win xproto.Window, edges *WmFullscreenMonitors) error { return WmFullscreenMonitorsReqExtra(xu, win, edges, 2) } // _NET_WM_FULLSCREEN_MONITORS req extra func WmFullscreenMonitorsReqExtra(xu *xgbutil.XUtil, win xproto.Window, edges *WmFullscreenMonitors, source int) error { return ClientEvent(xu, win, "_NET_WM_FULLSCREEN_MONITORS", edges.Top, edges.Bottom, edges.Left, edges.Right, source) } // _NET_WM_HANDLED_ICONS get func WmHandledIconsGet(xu *xgbutil.XUtil, win xproto.Window) (bool, error) { reply, err := xprop.GetProperty(xu, win, "_NET_WM_HANDLED_ICONS") if err != nil { return false, err } val, err := xprop.PropValNum(reply, nil) if err != nil { return false, err } return val == 1, nil } // _NET_WM_HANDLED_ICONS set func WmHandledIconsSet(xu *xgbutil.XUtil, handle bool) error { var handled uint if handle { handled = 1 } else { handled = 0 } return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_WM_HANDLED_ICONS", "CARDINAL", handled) } // WmIcon is a struct that contains data for a single icon. // The WmIcon method will return a list of these, since a single // client can specify multiple icons of varying sizes. type WmIcon struct { Width uint Height uint Data []uint } // _NET_WM_ICON get func WmIconGet(xu *xgbutil.XUtil, win xproto.Window) ([]WmIcon, error) { icon, err := xprop.PropValNums(xprop.GetProperty(xu, win, "_NET_WM_ICON")) if err != nil { return nil, err } wmicons := make([]WmIcon, 0) start := uint(0) for int(start) < len(icon) { w, h := icon[start], icon[start+1] upto := w * h wmicon := WmIcon{ Width: w, Height: h, Data: icon[(start + 2):(start + upto + 2)], } wmicons = append(wmicons, wmicon) start += upto + 2 } return wmicons, nil } // _NET_WM_ICON set func WmIconSet(xu *xgbutil.XUtil, win xproto.Window, icons []WmIcon) error { raw := make([]uint, 0, 10000) // start big for _, icon := range icons { raw = append(raw, icon.Width, icon.Height) raw = append(raw, icon.Data...) } return xprop.ChangeProp32(xu, win, "_NET_WM_ICON", "CARDINAL", raw...) } // WmIconGeometry struct organizes the information pertaining to the // _NET_WM_ICON_GEOMETRY property. Namely, x, y, width and height. type WmIconGeometry struct { X int Y int Width uint Height uint } // _NET_WM_ICON_GEOMETRY get func WmIconGeometryGet(xu *xgbutil.XUtil, win xproto.Window) (*WmIconGeometry, error) { geom, err := xprop.PropValNums(xprop.GetProperty(xu, win, "_NET_WM_ICON_GEOMETRY")) if err != nil { return nil, err } return &WmIconGeometry{ X: int(geom[0]), Y: int(geom[1]), Width: geom[2], Height: geom[3], }, nil } // _NET_WM_ICON_GEOMETRY set func WmIconGeometrySet(xu *xgbutil.XUtil, win xproto.Window, geom *WmIconGeometry) error { rawGeom := make([]uint, 4) rawGeom[0] = uint(geom.X) rawGeom[1] = uint(geom.Y) rawGeom[2] = geom.Width rawGeom[3] = geom.Height return xprop.ChangeProp32(xu, win, "_NET_WM_ICON_GEOMETRY", "CARDINAL", rawGeom...) } // _NET_WM_ICON_NAME get func WmIconNameGet(xu *xgbutil.XUtil, win xproto.Window) (string, error) { return xprop.PropValStr(xprop.GetProperty(xu, win, "_NET_WM_ICON_NAME")) } // _NET_WM_ICON_NAME set func WmIconNameSet(xu *xgbutil.XUtil, win xproto.Window, name string) error { return xprop.ChangeProp(xu, win, 8, "_NET_WM_ICON_NAME", "UTF8_STRING", []byte(name)) } // _NET_WM_MOVERESIZE constants const ( SizeTopLeft = iota SizeTop SizeTopRight SizeRight SizeBottomRight SizeBottom SizeBottomLeft SizeLeft Move SizeKeyboard MoveKeyboard Cancel Infer // special for Wingo. DO NOT USE. ) // _NET_WM_MOVERESIZE req func WmMoveresize(xu *xgbutil.XUtil, win xproto.Window, direction int) error { return WmMoveresizeExtra(xu, win, direction, 0, 0, 0, 2) } // _NET_WM_MOVERESIZE req extra func WmMoveresizeExtra(xu *xgbutil.XUtil, win xproto.Window, direction, xRoot, yRoot, button, source int) error { return ClientEvent(xu, win, "_NET_WM_MOVERESIZE", xRoot, yRoot, direction, button, source) } // _NET_WM_NAME get func WmNameGet(xu *xgbutil.XUtil, win xproto.Window) (string, error) { return xprop.PropValStr(xprop.GetProperty(xu, win, "_NET_WM_NAME")) } // _NET_WM_NAME set func WmNameSet(xu *xgbutil.XUtil, win xproto.Window, name string) error { return xprop.ChangeProp(xu, win, 8, "_NET_WM_NAME", "UTF8_STRING", []byte(name)) } // WmOpaqueRegion organizes information related to the _NET_WM_OPAQUE_REGION // property. Namely, the x, y, width and height of an opaque rectangle // relative to the client window. type WmOpaqueRegion struct { X int Y int Width uint Height uint } // _NET_WM_OPAQUE_REGION get func WmOpaqueRegionGet(xu *xgbutil.XUtil, win xproto.Window) ([]WmOpaqueRegion, error) { raw, err := xprop.PropValNums(xprop.GetProperty(xu, win, "_NET_WM_OPAQUE_REGION")) if err != nil { return nil, err } regions := make([]WmOpaqueRegion, len(raw)/4) for i, _ := range regions { regions[i] = WmOpaqueRegion{ X: int(raw[i*4+0]), Y: int(raw[i*4+1]), Width: raw[i*4+2], Height: raw[i*4+3], } } return regions, nil } // _NET_WM_OPAQUE_REGION set func WmOpaqueRegionSet(xu *xgbutil.XUtil, win xproto.Window, regions []WmOpaqueRegion) error { raw := make([]uint, len(regions)*4) for i, region := range regions { raw[i*4+0] = uint(region.X) raw[i*4+1] = uint(region.Y) raw[i*4+2] = region.Width raw[i*4+3] = region.Height } return xprop.ChangeProp32(xu, win, "_NET_WM_OPAQUE_REGION", "CARDINAL", raw...) } // _NET_WM_PID get func WmPidGet(xu *xgbutil.XUtil, win xproto.Window) (uint, error) { return xprop.PropValNum(xprop.GetProperty(xu, win, "_NET_WM_PID")) } // _NET_WM_PID set func WmPidSet(xu *xgbutil.XUtil, win xproto.Window, pid uint) error { return xprop.ChangeProp32(xu, win, "_NET_WM_PID", "CARDINAL", pid) } // _NET_WM_PING req func WmPing(xu *xgbutil.XUtil, win xproto.Window, response bool) error { return WmPingExtra(xu, win, response, 0) } // _NET_WM_PING req extra func WmPingExtra(xu *xgbutil.XUtil, win xproto.Window, response bool, time xproto.Timestamp) error { pingAtom, err := xprop.Atm(xu, "_NET_WM_PING") if err != nil { return err } var evWindow xproto.Window if response { evWindow = xu.RootWin() } else { evWindow = win } return ClientEvent(xu, evWindow, "WM_PROTOCOLS", int(pingAtom), int(time), int(win)) } // _NET_WM_STATE constants for state toggling // These correspond to the "action" parameter. const ( StateRemove = iota StateAdd StateToggle ) // _NET_WM_STATE get func WmStateGet(xu *xgbutil.XUtil, win xproto.Window) ([]string, error) { raw, err := xprop.GetProperty(xu, win, "_NET_WM_STATE") return xprop.PropValAtoms(xu, raw, err) } // _NET_WM_STATE set func WmStateSet(xu *xgbutil.XUtil, win xproto.Window, atomNames []string) error { atoms, err := xprop.StrToAtoms(xu, atomNames) if err != nil { return err } return xprop.ChangeProp32(xu, win, "_NET_WM_STATE", "ATOM", atoms...) } // _NET_WM_STATE req func WmStateReq(xu *xgbutil.XUtil, win xproto.Window, action int, atomName string) error { return WmStateReqExtra(xu, win, action, atomName, "", 2) } // _NET_WM_STATE req extra func WmStateReqExtra(xu *xgbutil.XUtil, win xproto.Window, action int, first string, second string, source int) (err error) { var atom1, atom2 xproto.Atom atom1, err = xprop.Atom(xu, first, false) if err != nil { return err } if len(second) > 0 { atom2, err = xprop.Atom(xu, second, false) if err != nil { return err } } else { atom2 = 0 } return ClientEvent(xu, win, "_NET_WM_STATE", action, int(atom1), int(atom2), source) } // WmStrut struct organizes information for the _NET_WM_STRUT property. // Namely, it encapsulates its four values: left, right, top and bottom. type WmStrut struct { Left uint Right uint Top uint Bottom uint } // _NET_WM_STRUT get func WmStrutGet(xu *xgbutil.XUtil, win xproto.Window) (*WmStrut, error) { struts, err := xprop.PropValNums(xprop.GetProperty(xu, win, "_NET_WM_STRUT")) if err != nil { return nil, err } return &WmStrut{ Left: struts[0], Right: struts[1], Top: struts[2], Bottom: struts[3], }, nil } // _NET_WM_STRUT set func WmStrutSet(xu *xgbutil.XUtil, win xproto.Window, struts *WmStrut) error { rawStruts := make([]uint, 4) rawStruts[0] = struts.Left rawStruts[1] = struts.Right rawStruts[2] = struts.Top rawStruts[3] = struts.Bottom return xprop.ChangeProp32(xu, win, "_NET_WM_STRUT", "CARDINAL", rawStruts...) } // WmStrutPartial struct organizes information for the _NET_WM_STRUT_PARTIAL // property. Namely, it encapsulates its twelve values: left, right, top, // bottom, left_start_y, left_end_y, right_start_y, right_end_y, // top_start_x, top_end_x, bottom_start_x, and bottom_end_x. type WmStrutPartial struct { Left, Right, Top, Bottom uint LeftStartY, LeftEndY, RightStartY, RightEndY uint TopStartX, TopEndX, BottomStartX, BottomEndX uint } // _NET_WM_STRUT_PARTIAL get func WmStrutPartialGet(xu *xgbutil.XUtil, win xproto.Window) (*WmStrutPartial, error) { struts, err := xprop.PropValNums(xprop.GetProperty(xu, win, "_NET_WM_STRUT_PARTIAL")) if err != nil { return nil, err } return &WmStrutPartial{ Left: struts[0], Right: struts[1], Top: struts[2], Bottom: struts[3], LeftStartY: struts[4], LeftEndY: struts[5], RightStartY: struts[6], RightEndY: struts[7], TopStartX: struts[8], TopEndX: struts[9], BottomStartX: struts[10], BottomEndX: struts[11], }, nil } // _NET_WM_STRUT_PARTIAL set func WmStrutPartialSet(xu *xgbutil.XUtil, win xproto.Window, struts *WmStrutPartial) error { rawStruts := make([]uint, 12) rawStruts[0] = struts.Left rawStruts[1] = struts.Right rawStruts[2] = struts.Top rawStruts[3] = struts.Bottom rawStruts[4] = struts.LeftStartY rawStruts[5] = struts.LeftEndY rawStruts[6] = struts.RightStartY rawStruts[7] = struts.RightEndY rawStruts[8] = struts.TopStartX rawStruts[9] = struts.TopEndX rawStruts[10] = struts.BottomStartX rawStruts[11] = struts.BottomEndX return xprop.ChangeProp32(xu, win, "_NET_WM_STRUT_PARTIAL", "CARDINAL", rawStruts...) } // _NET_WM_SYNC_REQUEST req func WmSyncRequest(xu *xgbutil.XUtil, win xproto.Window, req_num uint64) error { return WmSyncRequestExtra(xu, win, req_num, 0) } // _NET_WM_SYNC_REQUEST req extra func WmSyncRequestExtra(xu *xgbutil.XUtil, win xproto.Window, reqNum uint64, time xproto.Timestamp) error { syncReq, err := xprop.Atm(xu, "_NET_WM_SYNC_REQUEST") if err != nil { return err } high := int(reqNum >> 32) low := int(reqNum<<32 ^ reqNum) return ClientEvent(xu, win, "WM_PROTOCOLS", int(syncReq), int(time), low, high) } // _NET_WM_SYNC_REQUEST_COUNTER get // I'm pretty sure this needs 64 bit integers, but I'm not quite sure // how to go about that yet. Any ideas? func WmSyncRequestCounter(xu *xgbutil.XUtil, win xproto.Window) (uint, error) { return xprop.PropValNum(xprop.GetProperty(xu, win, "_NET_WM_SYNC_REQUEST_COUNTER")) } // _NET_WM_SYNC_REQUEST_COUNTER set // I'm pretty sure this needs 64 bit integers, but I'm not quite sure // how to go about that yet. Any ideas? func WmSyncRequestCounterSet(xu *xgbutil.XUtil, win xproto.Window, counter uint) error { return xprop.ChangeProp32(xu, win, "_NET_WM_SYNC_REQUEST_COUNTER", "CARDINAL", counter) } // _NET_WM_USER_TIME get func WmUserTimeGet(xu *xgbutil.XUtil, win xproto.Window) (uint, error) { return xprop.PropValNum(xprop.GetProperty(xu, win, "_NET_WM_USER_TIME")) } // _NET_WM_USER_TIME set func WmUserTimeSet(xu *xgbutil.XUtil, win xproto.Window, userTime uint) error { return xprop.ChangeProp32(xu, win, "_NET_WM_USER_TIME", "CARDINAL", userTime) } // _NET_WM_USER_TIME_WINDOW get func WmUserTimeWindowGet(xu *xgbutil.XUtil, win xproto.Window) (xproto.Window, error) { return xprop.PropValWindow(xprop.GetProperty(xu, win, "_NET_WM_USER_TIME_WINDOW")) } // _NET_WM_USER_TIME set func WmUserTimeWindowSet(xu *xgbutil.XUtil, win xproto.Window, timeWin xproto.Window) error { return xprop.ChangeProp32(xu, win, "_NET_WM_USER_TIME_WINDOW", "CARDINAL", uint(timeWin)) } // _NET_WM_VISIBLE_ICON_NAME get func WmVisibleIconNameGet(xu *xgbutil.XUtil, win xproto.Window) (string, error) { return xprop.PropValStr(xprop.GetProperty(xu, win, "_NET_WM_VISIBLE_ICON_NAME")) } // _NET_WM_VISIBLE_ICON_NAME set func WmVisibleIconNameSet(xu *xgbutil.XUtil, win xproto.Window, name string) error { return xprop.ChangeProp(xu, win, 8, "_NET_WM_VISIBLE_ICON_NAME", "UTF8_STRING", []byte(name)) } // _NET_WM_VISIBLE_NAME get func WmVisibleNameGet(xu *xgbutil.XUtil, win xproto.Window) (string, error) { return xprop.PropValStr(xprop.GetProperty(xu, win, "_NET_WM_VISIBLE_NAME")) } // _NET_WM_VISIBLE_NAME set func WmVisibleNameSet(xu *xgbutil.XUtil, win xproto.Window, name string) error { return xprop.ChangeProp(xu, win, 8, "_NET_WM_VISIBLE_NAME", "UTF8_STRING", []byte(name)) } // _NET_WM_WINDOW_OPACITY get // This isn't part of the EWMH spec, but is widely used by drop in // compositing managers (i.e., xcompmgr, cairo-compmgr, etc.). // This property is typically set not on a client window, but the *parent* // of a client window in reparenting window managers. // The float returned will be in the range [0.0, 1.0] where 0.0 is completely // transparent and 1.0 is completely opaque. func WmWindowOpacityGet(xu *xgbutil.XUtil, win xproto.Window) (float64, error) { intOpacity, err := xprop.PropValNum( xprop.GetProperty(xu, win, "_NET_WM_WINDOW_OPACITY")) if err != nil { return 0, err } return float64(uint(intOpacity)) / float64(0xffffffff), nil } // _NET_WM_WINDOW_OPACITY set func WmWindowOpacitySet(xu *xgbutil.XUtil, win xproto.Window, opacity float64) error { return xprop.ChangeProp32(xu, win, "_NET_WM_WINDOW_OPACITY", "CARDINAL", uint(opacity*0xffffffff)) } // _NET_WM_WINDOW_TYPE get func WmWindowTypeGet(xu *xgbutil.XUtil, win xproto.Window) ([]string, error) { raw, err := xprop.GetProperty(xu, win, "_NET_WM_WINDOW_TYPE") return xprop.PropValAtoms(xu, raw, err) } // _NET_WM_WINDOW_TYPE set // This will create any atoms used in 'atomNames' if they don't already exist. func WmWindowTypeSet(xu *xgbutil.XUtil, win xproto.Window, atomNames []string) error { atoms, err := xprop.StrToAtoms(xu, atomNames) if err != nil { return err } return xprop.ChangeProp32(xu, win, "_NET_WM_WINDOW_TYPE", "ATOM", atoms...) } // Workarea is a struct that represents a rectangle as a bounding box of // a single desktop. So there should be as many Workarea structs as there // are desktops. type Workarea struct { X int Y int Width uint Height uint } // _NET_WORKAREA get func WorkareaGet(xu *xgbutil.XUtil) ([]Workarea, error) { rects, err := xprop.PropValNums(xprop.GetProperty(xu, xu.RootWin(), "_NET_WORKAREA")) if err != nil { return nil, err } workareas := make([]Workarea, len(rects)/4) for i, _ := range workareas { workareas[i] = Workarea{ X: int(rects[i*4]), Y: int(rects[i*4+1]), Width: rects[i*4+2], Height: rects[i*4+3], } } return workareas, nil } // _NET_WORKAREA set func WorkareaSet(xu *xgbutil.XUtil, workareas []Workarea) error { rects := make([]uint, len(workareas)*4) for i, workarea := range workareas { rects[i*4+0] = uint(workarea.X) rects[i*4+1] = uint(workarea.Y) rects[i*4+2] = workarea.Width rects[i*4+3] = workarea.Height } return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_WORKAREA", "CARDINAL", rects...) } ================================================ FILE: ewmh/winman.go ================================================ package ewmh import ( "fmt" "github.com/BurntSushi/xgbutil" ) // GetEwmhWM uses the EWMH spec to find if a conforming window manager // is currently running or not. If it is, then its name will be returned. // Otherwise, an error will be returned explaining why one couldn't be found. func GetEwmhWM(xu *xgbutil.XUtil) (string, error) { childCheck, err := SupportingWmCheckGet(xu, xu.RootWin()) if err != nil { return "", fmt.Errorf("GetEwmhWM: Failed because: %s", err) } childCheck2, err := SupportingWmCheckGet(xu, childCheck) if err != nil { return "", fmt.Errorf("GetEwmhWM: Failed because: %s", err) } if childCheck != childCheck2 { return "", fmt.Errorf( "GetEwmhWM: _NET_SUPPORTING_WM_CHECK value on the root window "+ "(%x) does not match _NET_SUPPORTING_WM_CHECK value "+ "on the child window (%x).", childCheck, childCheck2) } return WmNameGet(xu, childCheck) } ================================================ FILE: gopher/doc.go ================================================ /* Package gopher contains a single image of the Go gopher. It is included to guarantee that at least one image is always available for some examples to run successfully. This file was automatically generated by go-bindata. */ package gopher ================================================ FILE: gopher/gopher.go ================================================ package gopher import ( "bytes" "compress/gzip" "io" ) // GopherPng returns the raw, uncompressed file data data. func GopherPng() []byte { gz, err := gzip.NewReader(bytes.NewBuffer([]byte{ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x00, 0xff, 0x34, 0x9b, 0x05, 0x50, 0x5d, 0x4d, 0xd3, 0xad, 0x0f, 0xee, 0x12, 0xf4, 0x20, 0x81, 0xe0, 0x04, 0x77, 0xf7, 0x60, 0xc1, 0xdd, 0x9d, 0xe0, 0xee, 0xee, 0xee, 0x21, 0xb8, 0x3b, 0x04, 0x87, 0xe0, 0xee, 0xf0, 0x62, 0xc1, 0x35, 0xb8, 0xbb, 0xbb, 0xde, 0x4d, 0x7d, 0xf7, 0x4f, 0x55, 0x8a, 0x02, 0x4e, 0xd5, 0xee, 0xdd, 0xd3, 0xbd, 0xfa, 0x59, 0x33, 0x43, 0x84, 0x82, 0x9c, 0x04, 0x0a, 0x22, 0x3e, 0x22, 0x08, 0x04, 0x42, 0xf9, 0x2e, 0x29, 0xaa, 0x04, 0x02, 0x41, 0xdc, 0x7c, 0xfc, 0x87, 0x87, 0x05, 0x7e, 0x32, 0x3a, 0xbf, 0x1e, 0x09, 0x7c, 0x81, 0x76, 0x12, 0xf9, 0xae, 0x02, 0x0f, 0xfc, 0xf3, 0x86, 0xff, 0x11, 0x0e, 0x02, 0x7d, 0x01, 0x7d, 0x17, 0x15, 0x56, 0x71, 0xcf, 0x3c, 0xc9, 0x72, 0x53, 0x51, 0x19, 0xc2, 0x1d, 0xea, 0xb2, 0xa3, 0x6d, 0xbb, 0x61, 0x90, 0x52, 0x45, 0xff, 0x1a, 0x08, 0x53, 0x43, 0x8a, 0xe8, 0xda, 0xaf, 0x67, 0x6c, 0xf7, 0x5d, 0x26, 0xba, 0x76, 0x00, 0x1c, 0x33, 0xb8, 0x83, 0xcb, 0xde, 0x88, 0x15, 0x13, 0x31, 0x08, 0x96, 0xa5, 0xfb, 0x1e, 0x1d, 0xc1, 0x7f, 0x87, 0x31, 0xb0, 0xa6, 0x88, 0x8e, 0x04, 0x09, 0x39, 0xcd, 0x6b, 0xbd, 0x7e, 0xef, 0xeb, 0x97, 0x8b, 0x24, 0x8d, 0x99, 0xac, 0xeb, 0x1a, 0xf0, 0x98, 0x99, 0xe0, 0x94, 0xf9, 0xbc, 0x37, 0xae, 0x83, 0x72, 0xb2, 0xda, 0xe2, 0x84, 0x24, 0xf4, 0x05, 0x1d, 0x1e, 0x1a, 0x32, 0xaf, 0xa7, 0x6f, 0xbe, 0x09, 0x12, 0x1a, 0x52, 0xb8, 0xed, 0xe1, 0xf1, 0xb4, 0xf0, 0x4f, 0x5d, 0x4e, 0xda, 0xd3, 0x53, 0x55, 0x92, 0x34, 0x39, 0x5d, 0x80, 0x4c, 0xf2, 0x39, 0x0a, 0xfc, 0xc9, 0x92, 0x75, 0x14, 0x07, 0x72, 0x90, 0x2b, 0xa8, 0x0b, 0xc5, 0x60, 0x36, 0x74, 0xc8, 0xe9, 0x20, 0x5f, 0xe5, 0x0a, 0x2f, 0xa0, 0x5b, 0x5f, 0x58, 0x71, 0x9e, 0x50, 0x7f, 0xbd, 0xfa, 0xc7, 0xe1, 0x21, 0xdc, 0x6d, 0xa5, 0x40, 0x80, 0xd0, 0x24, 0xba, 0xd4, 0x3a, 0x22, 0x3a, 0x7c, 0x70, 0x3a, 0x19, 0x96, 0xeb, 0x16, 0x2d, 0x96, 0x07, 0x89, 0x94, 0x49, 0x80, 0x42, 0x29, 0x1d, 0x4e, 0x9d, 0x06, 0xa1, 0x76, 0x68, 0x7c, 0x1b, 0x6b, 0xb4, 0x0c, 0xa8, 0x06, 0x1a, 0x6b, 0xa0, 0x1e, 0x6e, 0x63, 0x90, 0xe9, 0x0a, 0x07, 0x44, 0x8b, 0x9b, 0xfb, 0xe8, 0xaf, 0xa4, 0xf1, 0x5a, 0x56, 0xa1, 0xfe, 0x5e, 0xab, 0xaf, 0x80, 0xc5, 0xf8, 0xcb, 0x50, 0x83, 0xaa, 0x59, 0xe7, 0xf9, 0x19, 0xcb, 0x04, 0x83, 0x2c, 0x61, 0x55, 0x71, 0xb6, 0x4f, 0x3f, 0xea, 0x23, 0xbe, 0xe0, 0xc1, 0xa8, 0xa4, 0x39, 0x78, 0xb2, 0xee, 0xa9, 0xa0, 0xf1, 0xc6, 0xd7, 0x9f, 0xf9, 0xd0, 0x12, 0xa0, 0x33, 0x3f, 0x10, 0x27, 0x1c, 0x48, 0x59, 0xf0, 0xfd, 0x12, 0x0b, 0x24, 0x08, 0x81, 0x4e, 0x68, 0x50, 0x6b, 0x6d, 0x5a, 0xa7, 0x61, 0x4b, 0xe4, 0xeb, 0xcb, 0xab, 0x79, 0x7b, 0x95, 0x52, 0x2d, 0x51, 0x51, 0x41, 0xa9, 0x79, 0xa8, 0x0d, 0x07, 0x29, 0x4c, 0xf0, 0x13, 0x93, 0x27, 0xc0, 0x00, 0x54, 0xa3, 0x61, 0x8b, 0x43, 0x18, 0xeb, 0xf8, 0x53, 0x26, 0x79, 0x2a, 0x33, 0x7f, 0x91, 0x01, 0xb4, 0x3d, 0xc1, 0x74, 0x85, 0xea, 0xaf, 0xa3, 0x30, 0xc3, 0x3e, 0x26, 0x13, 0x6c, 0xef, 0x5c, 0x03, 0x13, 0x36, 0x1e, 0x18, 0x96, 0x41, 0xe6, 0x09, 0xdd, 0x10, 0xe2, 0x3f, 0x11, 0x94, 0x14, 0xf2, 0x15, 0x5a, 0xdc, 0x7b, 0x07, 0x17, 0x87, 0x6c, 0x6f, 0x09, 0x29, 0xbc, 0x1f, 0x23, 0x15, 0x3f, 0x85, 0x6e, 0x74, 0xff, 0xda, 0xc0, 0xd8, 0x10, 0x36, 0x5e, 0x34, 0x12, 0xf3, 0x7d, 0xb5, 0xb7, 0x12, 0x4e, 0xfe, 0x67, 0x52, 0x82, 0xfe, 0x38, 0xc3, 0x0a, 0x61, 0xe4, 0xd6, 0x2a, 0xb4, 0xc6, 0xbb, 0x03, 0xd7, 0xb8, 0xdc, 0xe8, 0xee, 0xd5, 0x3f, 0x21, 0x48, 0xe5, 0x85, 0x2e, 0x3f, 0x9f, 0x3e, 0xa3, 0x86, 0x3d, 0x65, 0x95, 0x29, 0x95, 0xf4, 0xbf, 0x39, 0xe3, 0x4c, 0x18, 0x8c, 0xfe, 0x59, 0xa2, 0x8a, 0x2f, 0xd6, 0xa1, 0x86, 0xaf, 0x23, 0xbb, 0x1c, 0xbc, 0x3d, 0x46, 0xdc, 0x7f, 0x02, 0xa0, 0xa9, 0xec, 0xce, 0x6d, 0x4a, 0xce, 0xd6, 0x50, 0xe6, 0x9a, 0x5a, 0xa1, 0x45, 0x62, 0xbe, 0xc0, 0x66, 0x09, 0x4d, 0x42, 0x29, 0x97, 0x48, 0xfd, 0xe6, 0xf7, 0x82, 0xd4, 0xc1, 0x8a, 0x3c, 0x59, 0xf3, 0x37, 0xc7, 0x90, 0xc5, 0x75, 0x81, 0x4c, 0x6c, 0x1f, 0xd9, 0xe3, 0xe1, 0x5e, 0xec, 0x5d, 0x6f, 0xc3, 0x1e, 0x93, 0x8d, 0x21, 0x61, 0xdb, 0xea, 0x9b, 0x5e, 0x81, 0xa6, 0xc3, 0x81, 0x81, 0xe3, 0xb5, 0xba, 0x68, 0x26, 0x5c, 0xd4, 0xd2, 0xf6, 0x9f, 0xd8, 0xee, 0xed, 0xf9, 0x8b, 0x48, 0xe8, 0xba, 0xda, 0x6b, 0x64, 0x9e, 0x2e, 0xee, 0xa9, 0xc6, 0x10, 0x39, 0xa0, 0xb4, 0x83, 0x8b, 0x55, 0x20, 0x49, 0x0e, 0x0b, 0xc2, 0x8a, 0xe8, 0x0f, 0x6f, 0xc7, 0x8b, 0xa9, 0x4b, 0x39, 0x17, 0xa2, 0x64, 0x3c, 0x0e, 0xd9, 0x2f, 0x52, 0xc0, 0x3a, 0x27, 0x14, 0xbb, 0xb4, 0x45, 0x82, 0xfe, 0x4b, 0x15, 0x19, 0x75, 0xce, 0x5f, 0x95, 0x00, 0xc9, 0xd3, 0xbb, 0xc8, 0xb5, 0x28, 0x45, 0xfa, 0xdd, 0x41, 0x99, 0xa6, 0x4e, 0x67, 0xc9, 0x5a, 0xad, 0x59, 0x49, 0x93, 0x0d, 0x5e, 0x61, 0x51, 0x4d, 0xa0, 0xed, 0xc6, 0x38, 0x3e, 0x9f, 0xee, 0xad, 0x90, 0xfa, 0x8d, 0x43, 0xa0, 0x6b, 0x57, 0xac, 0xf6, 0x21, 0xb2, 0x3d, 0x7b, 0x96, 0x02, 0x9d, 0x2d, 0x10, 0xec, 0x0c, 0x99, 0x97, 0xcd, 0xc4, 0x62, 0x69, 0x47, 0x9e, 0x52, 0x72, 0x5f, 0x70, 0x98, 0xff, 0xe6, 0xdf, 0xce, 0xda, 0x27, 0xb9, 0x9c, 0xe4, 0xde, 0x44, 0xbb, 0x65, 0x60, 0x16, 0xb3, 0xf9, 0xda, 0x96, 0x27, 0x7f, 0x8f, 0x6a, 0x6f, 0x61, 0x88, 0x16, 0xc9, 0x12, 0xad, 0x3f, 0x67, 0x86, 0xc0, 0x58, 0x6b, 0x3a, 0x9a, 0xd3, 0x7c, 0xbb, 0x81, 0x00, 0x2e, 0x6e, 0x3f, 0xa3, 0x83, 0xdd, 0x58, 0x83, 0xd4, 0x88, 0xa7, 0x4b, 0x1e, 0xf6, 0xc1, 0x4c, 0xb0, 0x35, 0x43, 0x44, 0x44, 0x2d, 0x3e, 0x10, 0x53, 0x04, 0xe9, 0x54, 0x85, 0x61, 0xca, 0xee, 0xfb, 0xe4, 0xaa, 0xe0, 0xdc, 0xc0, 0x62, 0xd9, 0x40, 0x50, 0x94, 0xa0, 0x96, 0x47, 0x7c, 0x8d, 0x24, 0x80, 0xb1, 0x67, 0x54, 0x4e, 0x7c, 0x44, 0xe0, 0x6d, 0x8b, 0x48, 0x99, 0x9e, 0x56, 0x93, 0xaa, 0x2f, 0xa1, 0x0f, 0x50, 0x70, 0x43, 0xde, 0x56, 0x0e, 0x14, 0x32, 0x2f, 0xbc, 0x70, 0x7f, 0x33, 0x65, 0xcb, 0x62, 0x56, 0x29, 0xa5, 0xc3, 0x1f, 0x64, 0xda, 0x62, 0x12, 0x32, 0xd4, 0xf2, 0x8d, 0xfd, 0x94, 0x13, 0x85, 0x73, 0xc7, 0x71, 0xb0, 0xd8, 0xc8, 0xde, 0xea, 0x7a, 0x13, 0xea, 0xe4, 0xc4, 0x5b, 0xef, 0xec, 0x3a, 0x19, 0xd6, 0xca, 0x4e, 0xc9, 0x4d, 0x8f, 0xf4, 0x9e, 0xdd, 0x15, 0xf0, 0x50, 0xa8, 0xb2, 0xe2, 0x7b, 0x81, 0x85, 0xb7, 0xe4, 0x91, 0x34, 0x66, 0x34, 0x0c, 0x71, 0x46, 0x81, 0x3a, 0xb4, 0xf5, 0x45, 0x8c, 0xfb, 0x8d, 0x3e, 0x65, 0xdd, 0x57, 0x93, 0xb8, 0xd5, 0xa1, 0x25, 0xfb, 0x2f, 0xa2, 0xd8, 0x91, 0x51, 0xe8, 0x27, 0x59, 0x28, 0x2c, 0x6f, 0xdd, 0x93, 0x1e, 0xa3, 0x34, 0x72, 0xe0, 0xf9, 0x52, 0xbc, 0x6d, 0x35, 0x39, 0xca, 0xca, 0x7e, 0x64, 0x01, 0x41, 0xd0, 0x41, 0xfe, 0xc0, 0xfb, 0x0b, 0x5b, 0x35, 0x07, 0x0e, 0xb1, 0xde, 0x29, 0x52, 0x2b, 0x79, 0xcd, 0xd4, 0xff, 0xc6, 0xec, 0x7e, 0x80, 0x92, 0xe2, 0x14, 0x52, 0xdc, 0x24, 0x6a, 0x97, 0xa5, 0xa5, 0x42, 0x3e, 0xc0, 0x0b, 0xde, 0xbb, 0x9b, 0x3f, 0x58, 0x59, 0x93, 0x76, 0x29, 0xa9, 0x44, 0xfa, 0xe3, 0x84, 0x74, 0xb1, 0x65, 0x02, 0xdb, 0x4c, 0x88, 0xfa, 0xe0, 0xcd, 0x80, 0x18, 0x35, 0x40, 0x4d, 0x4d, 0xa7, 0xc6, 0xbf, 0x7f, 0xdd, 0x6c, 0xef, 0x62, 0x0d, 0x4b, 0x20, 0xcd, 0x6a, 0xdf, 0xd2, 0x20, 0xd8, 0x4f, 0x63, 0x81, 0xaf, 0x18, 0x97, 0x4d, 0x76, 0xa5, 0xc6, 0x86, 0xf1, 0x6b, 0x06, 0xfd, 0x95, 0xfc, 0x93, 0x45, 0x1a, 0xf7, 0xae, 0x69, 0xad, 0x79, 0xe4, 0x1f, 0x2e, 0x4b, 0x13, 0x6c, 0x1e, 0x76, 0x5e, 0x2f, 0xbf, 0xc7, 0x30, 0xad, 0x80, 0x51, 0x9b, 0xdd, 0x4a, 0x15, 0x53, 0x3f, 0xa9, 0x99, 0x90, 0x3e, 0x50, 0x91, 0xe2, 0xe3, 0x3e, 0x96, 0x58, 0x4f, 0x4b, 0xcb, 0x67, 0x3e, 0x6d, 0x9e, 0xfc, 0x96, 0x8e, 0xdb, 0x72, 0x37, 0xae, 0x9a, 0xba, 0x46, 0x7f, 0xa5, 0xef, 0xdb, 0xc3, 0xd7, 0x3f, 0xda, 0xc7, 0xfe, 0x0b, 0xfd, 0x55, 0x6c, 0x48, 0x83, 0xb5, 0xb1, 0xbc, 0x2a, 0x81, 0xfe, 0xbd, 0x70, 0xee, 0xec, 0xbb, 0x62, 0xf1, 0x3e, 0x9e, 0x38, 0x17, 0x84, 0x64, 0x75, 0x0a, 0x23, 0x2d, 0xb4, 0x88, 0x0b, 0x7a, 0x90, 0xdc, 0x17, 0xf3, 0xf0, 0xba, 0x6b, 0x29, 0x5f, 0xa9, 0x91, 0x64, 0x50, 0x68, 0x7c, 0x13, 0x6c, 0xff, 0xb6, 0x85, 0xd6, 0x0a, 0xea, 0x4f, 0x6d, 0xf5, 0x5d, 0x71, 0x3b, 0x43, 0xbb, 0xa0, 0x1a, 0xdb, 0xd3, 0x29, 0xaa, 0x66, 0x28, 0x6f, 0xad, 0xb6, 0xc0, 0x22, 0x13, 0x4e, 0x4f, 0xe1, 0x78, 0x78, 0x6e, 0x0f, 0x18, 0xc9, 0x89, 0x91, 0x81, 0x99, 0x87, 0x94, 0x66, 0xef, 0x67, 0x12, 0x96, 0xba, 0xeb, 0x4f, 0x39, 0x99, 0xb0, 0x45, 0xbf, 0x7c, 0xb7, 0x9f, 0x8b, 0x07, 0x45, 0x90, 0x11, 0x8f, 0x83, 0xf1, 0x8c, 0xe1, 0xba, 0x97, 0x7b, 0x65, 0x8c, 0xf9, 0x13, 0xa5, 0xf0, 0x39, 0xcf, 0x86, 0xb6, 0x9a, 0xfc, 0xe4, 0xb6, 0x97, 0x57, 0x17, 0x1d, 0xab, 0x3c, 0x6c, 0x09, 0x33, 0x6c, 0x3a, 0xa6, 0xfa, 0x0b, 0x87, 0xfe, 0xbe, 0xbc, 0xf8, 0xc0, 0xe0, 0xdb, 0x29, 0xc1, 0xd2, 0x96, 0x0b, 0xdc, 0x3d, 0x3e, 0x36, 0x09, 0xaa, 0xd3, 0x20, 0x15, 0x43, 0x21, 0xa2, 0x02, 0x0d, 0x8a, 0xe5, 0xe9, 0x7a, 0x17, 0x96, 0xd5, 0x00, 0x73, 0x52, 0x41, 0xbf, 0x31, 0xb3, 0x8c, 0x5d, 0x15, 0x7b, 0x57, 0xd3, 0x54, 0x5b, 0x71, 0xd9, 0xba, 0xe4, 0x11, 0xd2, 0xec, 0xbc, 0x0d, 0x71, 0x47, 0xc4, 0x13, 0x46, 0x75, 0x39, 0x3c, 0x37, 0xb6, 0x33, 0x50, 0xab, 0x81, 0x7a, 0x9e, 0x9e, 0xe1, 0xe7, 0xcc, 0xc1, 0xe9, 0xe6, 0x1a, 0x84, 0x84, 0x4e, 0xce, 0x46, 0x14, 0x2e, 0x4c, 0x85, 0x6e, 0x19, 0x42, 0xfb, 0xe0, 0xed, 0xaa, 0xdf, 0xc2, 0xe7, 0xf7, 0xa5, 0x0f, 0x2b, 0xce, 0x0c, 0x5c, 0x2b, 0x6b, 0x52, 0xb7, 0x48, 0x87, 0xc3, 0xf3, 0xd0, 0xda, 0x57, 0xd2, 0x40, 0x2b, 0x13, 0x13, 0x72, 0x61, 0x7b, 0x1a, 0xe8, 0xdf, 0x48, 0xb4, 0xe1, 0x78, 0x64, 0x1f, 0xf3, 0x8c, 0x18, 0x6a, 0xa8, 0x40, 0x97, 0x4c, 0xca, 0xc0, 0x0c, 0x23, 0x46, 0x8a, 0x60, 0x94, 0x4d, 0x4e, 0xca, 0x4a, 0x45, 0x0c, 0x27, 0xaf, 0x1f, 0x20, 0xa3, 0x76, 0xdf, 0x4c, 0x4f, 0x26, 0x80, 0xa6, 0x77, 0xf6, 0xb7, 0xa6, 0x81, 0x45, 0x22, 0x43, 0x4d, 0xee, 0xa3, 0x98, 0xbc, 0xf9, 0x75, 0x7b, 0x4c, 0xe7, 0x04, 0x8c, 0x4f, 0xf5, 0x64, 0x08, 0xe5, 0x24, 0xd6, 0x84, 0x75, 0xb6, 0xa4, 0x57, 0xa2, 0x3d, 0x75, 0xf6, 0xa2, 0x60, 0x38, 0xe3, 0x46, 0x5d, 0x5e, 0x94, 0x18, 0xcc, 0x3a, 0xa1, 0x30, 0xd8, 0x9c, 0x35, 0xdb, 0x94, 0xf8, 0x88, 0x1a, 0x44, 0x29, 0xa5, 0xd3, 0xd0, 0xfe, 0x53, 0x29, 0x35, 0x43, 0x75, 0x55, 0x7b, 0x58, 0x7f, 0xf9, 0x0a, 0x7f, 0x61, 0x55, 0xb9, 0xf4, 0x67, 0xf7, 0xa7, 0xa4, 0xc9, 0xc3, 0xf1, 0x7a, 0x14, 0x97, 0xeb, 0x19, 0x2c, 0x91, 0xa0, 0x7c, 0x19, 0xb9, 0x6b, 0x2e, 0x34, 0xc3, 0xc2, 0xa1, 0x79, 0x9d, 0x69, 0x9f, 0x38, 0x05, 0x85, 0x0d, 0xb9, 0xdb, 0x31, 0x74, 0x87, 0x10, 0x32, 0x4f, 0x80, 0x02, 0x54, 0x70, 0x2f, 0xd1, 0x9d, 0x91, 0xc3, 0xac, 0xb9, 0x90, 0x40, 0x90, 0x61, 0xe4, 0x6b, 0x59, 0xba, 0x99, 0xb1, 0x49, 0x6c, 0x78, 0xcd, 0x5f, 0xb0, 0x20, 0x1b, 0x16, 0x47, 0xf2, 0x9e, 0xd6, 0x9c, 0x30, 0x65, 0xc2, 0xf6, 0x74, 0x65, 0x18, 0x97, 0xf7, 0x1e, 0x0d, 0xc3, 0x7a, 0x74, 0xa8, 0x48, 0xe9, 0xec, 0xd1, 0xd3, 0xdc, 0xe6, 0x81, 0x41, 0x14, 0x73, 0x90, 0x08, 0x3a, 0xd1, 0x32, 0x82, 0xda, 0x1e, 0x76, 0x2f, 0x68, 0x0d, 0xbe, 0x8f, 0x49, 0xf2, 0xfb, 0xc4, 0x60, 0x00, 0x66, 0xfc, 0xc3, 0x73, 0x3f, 0xc5, 0x0e, 0x76, 0xbb, 0xeb, 0x23, 0x01, 0x3f, 0xd4, 0xc3, 0x31, 0x17, 0x61, 0x58, 0xb9, 0x80, 0xc0, 0x73, 0xc1, 0xf9, 0xfa, 0xbd, 0x4f, 0x1d, 0x2d, 0x04, 0x28, 0x6a, 0x6e, 0x3a, 0xb2, 0x78, 0xa6, 0x09, 0x6a, 0xe0, 0xdb, 0xe8, 0x08, 0x59, 0x2f, 0xcf, 0x76, 0x81, 0x9b, 0x78, 0xdf, 0xd8, 0x0e, 0x4a, 0x83, 0x33, 0x9b, 0xbf, 0x21, 0x98, 0x4f, 0x5e, 0xaa, 0xaf, 0x38, 0x0b, 0xce, 0x61, 0x73, 0xf9, 0x95, 0xc6, 0x14, 0xc1, 0x16, 0x21, 0xc4, 0x46, 0x00, 0x3d, 0xe2, 0x4c, 0x6f, 0xa6, 0x15, 0x12, 0xba, 0x97, 0xe0, 0x43, 0xb3, 0x7e, 0x43, 0x2a, 0xcf, 0x30, 0xc4, 0x92, 0x2a, 0xae, 0xa8, 0xa4, 0x33, 0x1c, 0x0d, 0x32, 0x4d, 0x9f, 0xf9, 0x4f, 0x37, 0x9f, 0x38, 0x45, 0xe6, 0xa3, 0x1f, 0x9c, 0x23, 0xc8, 0x73, 0x4a, 0xa4, 0x66, 0xe0, 0x17, 0x48, 0x50, 0x09, 0xd6, 0x3b, 0xba, 0x82, 0x32, 0x2a, 0x57, 0x97, 0x69, 0x91, 0xfb, 0x36, 0xba, 0x87, 0x47, 0x1f, 0x1c, 0xee, 0x3f, 0xfd, 0x50, 0xcb, 0x20, 0xd3, 0xe3, 0xd6, 0x61, 0xc0, 0xe5, 0x23, 0x42, 0x43, 0xee, 0x13, 0x22, 0xc7, 0x98, 0xfb, 0x8e, 0x9b, 0xf7, 0x89, 0xd8, 0x18, 0xee, 0xbe, 0xb7, 0x7e, 0xea, 0xd5, 0x80, 0x74, 0xf6, 0x64, 0xad, 0x4b, 0x83, 0xae, 0xe7, 0x50, 0xda, 0xad, 0xc6, 0x61, 0x1f, 0x62, 0x67, 0x07, 0xbb, 0x6c, 0x87, 0x2e, 0x79, 0xc9, 0x04, 0x67, 0xd4, 0xb7, 0xb1, 0xb4, 0xf4, 0xb8, 0x63, 0x65, 0x65, 0x46, 0xb5, 0xf3, 0xfc, 0xfc, 0x1d, 0x1d, 0x8d, 0x08, 0x3a, 0xa7, 0xf8, 0x70, 0x65, 0xad, 0xda, 0x04, 0xc7, 0x94, 0x32, 0x55, 0xd0, 0x18, 0x9a, 0xb4, 0x97, 0xe7, 0x98, 0x8f, 0x0c, 0x88, 0x1d, 0x58, 0xa0, 0xc0, 0x4a, 0xaf, 0xb8, 0xad, 0xbf, 0x7d, 0x66, 0x49, 0x99, 0x8b, 0x5f, 0x61, 0xc2, 0xb6, 0x9b, 0xf5, 0xf3, 0x0c, 0xe4, 0x41, 0x18, 0x47, 0xe7, 0xda, 0xb8, 0x79, 0xc3, 0xdf, 0x3e, 0x72, 0x8d, 0xca, 0xd1, 0x66, 0x82, 0x94, 0xfe, 0xf7, 0x19, 0x44, 0xed, 0x19, 0x67, 0xf8, 0x03, 0x3b, 0xb6, 0x00, 0x58, 0xb2, 0x83, 0x05, 0x32, 0x90, 0x4f, 0x10, 0xd4, 0xc6, 0xe9, 0x66, 0x85, 0xb2, 0xae, 0xe3, 0x75, 0xd4, 0xc5, 0xa3, 0x5b, 0x5b, 0x19, 0xf7, 0xa7, 0x32, 0xe3, 0x1f, 0x3f, 0x82, 0x3f, 0x91, 0x89, 0x77, 0xcf, 0xcd, 0x61, 0xf3, 0x7b, 0xde, 0xf8, 0xc7, 0xc4, 0xa0, 0xf0, 0xf1, 0xf3, 0x1b, 0x5a, 0x5b, 0x23, 0x17, 0x29, 0x45, 0x94, 0xc8, 0xe7, 0xe4, 0xe7, 0xe6, 0x82, 0xd2, 0xd2, 0xd2, 0x9a, 0x3d, 0xae, 0x29, 0xe5, 0x72, 0x04, 0x62, 0x9a, 0x9b, 0xb9, 0x7e, 0x98, 0x9a, 0x06, 0x16, 0x5b, 0x39, 0x73, 0xc1, 0x82, 0x34, 0xd2, 0x32, 0x8c, 0x64, 0x44, 0xe5, 0xa3, 0x09, 0x56, 0xa4, 0xb7, 0x67, 0xec, 0x2d, 0xc5, 0x51, 0x05, 0xd6, 0x9b, 0x91, 0x16, 0xce, 0xf8, 0x68, 0xc8, 0x8a, 0xba, 0x8d, 0xd2, 0xd6, 0xa0, 0x64, 0xd6, 0xf3, 0x0e, 0x13, 0x09, 0x92, 0x3a, 0x86, 0xb6, 0x1f, 0x91, 0x4c, 0xfe, 0xa4, 0x1a, 0xe5, 0xee, 0x78, 0x1a, 0x8a, 0xbe, 0x1b, 0x78, 0x33, 0x99, 0x50, 0xd3, 0x8d, 0x45, 0xd3, 0x66, 0x54, 0x29, 0x13, 0xf1, 0xc5, 0x0e, 0x99, 0xad, 0xbf, 0x84, 0xee, 0x33, 0x2a, 0xd1, 0xf2, 0x19, 0xd7, 0x8e, 0xc9, 0x39, 0xb4, 0xd8, 0x94, 0x7c, 0x2f, 0x4a, 0xb9, 0x4d, 0x6e, 0x95, 0x30, 0xd7, 0xfa, 0x68, 0x66, 0x10, 0x48, 0xa7, 0x67, 0x17, 0xf1, 0x25, 0x69, 0xe4, 0xa6, 0x85, 0x4d, 0x97, 0x0b, 0xe2, 0x67, 0xb9, 0xae, 0x2b, 0x52, 0xcc, 0xc3, 0xc1, 0xf4, 0x14, 0x01, 0x3f, 0xef, 0x73, 0x81, 0x7e, 0x1c, 0xe8, 0x82, 0x2d, 0x1c, 0xb6, 0xfa, 0xab, 0x63, 0x0b, 0xa4, 0x5b, 0x7e, 0xce, 0xe6, 0x41, 0xcb, 0x31, 0x97, 0xdb, 0x2e, 0x43, 0xa4, 0x98, 0xaa, 0xfe, 0x70, 0xa3, 0xcd, 0x3f, 0x1c, 0x9f, 0xe7, 0xbb, 0x10, 0xa1, 0x2f, 0xfe, 0x21, 0x21, 0x21, 0x23, 0xa9, 0x0b, 0x38, 0x11, 0xa2, 0x81, 0xbf, 0x7f, 0x53, 0x93, 0x93, 0x93, 0x7f, 0xa1, 0xa1, 0x41, 0x54, 0xaf, 0xd2, 0xe9, 0x89, 0x21, 0xe0, 0x54, 0xd0, 0xd1, 0xd1, 0x39, 0xf5, 0x4a, 0x06, 0x92, 0xcc, 0x96, 0x8f, 0x06, 0x7b, 0x7f, 0x06, 0x69, 0x25, 0x3d, 0x0e, 0x79, 0x88, 0x9a, 0xd5, 0x19, 0x18, 0xc3, 0x8b, 0x46, 0xca, 0xdb, 0x64, 0x1d, 0x4d, 0xa8, 0xdd, 0xb3, 0xb9, 0xe8, 0x53, 0xa9, 0x70, 0xa1, 0x0e, 0x42, 0xd8, 0x5a, 0x50, 0xca, 0xab, 0xc9, 0x48, 0x90, 0x74, 0x36, 0x43, 0xfa, 0x42, 0xf4, 0xdf, 0xae, 0x7d, 0xcd, 0x8f, 0x3b, 0x6d, 0xf0, 0x7c, 0x53, 0xb9, 0xf8, 0xb3, 0x25, 0x52, 0x9a, 0x4e, 0x80, 0xf1, 0x7e, 0xf5, 0x76, 0x9b, 0x3e, 0xea, 0x97, 0xea, 0x5c, 0xc9, 0x53, 0xbc, 0x0c, 0x9b, 0xb7, 0xe9, 0xc5, 0xc5, 0x6a, 0x75, 0xe1, 0x9e, 0x22, 0x2a, 0x4f, 0xa5, 0xb8, 0xc9, 0x60, 0xa0, 0xb0, 0x26, 0x77, 0x0c, 0xeb, 0xb2, 0xf8, 0x03, 0x7a, 0x93, 0xa4, 0x4c, 0xde, 0x98, 0xfc, 0xd5, 0xae, 0x53, 0x32, 0x32, 0xf0, 0xc9, 0xf2, 0xdd, 0x70, 0x65, 0x88, 0x57, 0xd1, 0x92, 0xf1, 0x57, 0x3e, 0x2f, 0x84, 0x06, 0x92, 0x7e, 0xf2, 0x7d, 0x7a, 0xd5, 0x27, 0xe4, 0x76, 0xc2, 0x7e, 0x0c, 0x99, 0x23, 0x50, 0x32, 0x33, 0x33, 0xb3, 0x5e, 0xef, 0xfc, 0x6c, 0x68, 0x68, 0xc8, 0xe3, 0xc4, 0x4c, 0x8b, 0x85, 0x28, 0x2a, 0x21, 0x61, 0x3c, 0x91, 0xcd, 0xff, 0xb0, 0x1d, 0x27, 0xf8, 0x33, 0x31, 0x51, 0x65, 0x57, 0x07, 0x35, 0x23, 0x26, 0xd7, 0x35, 0x3b, 0x95, 0xd3, 0x06, 0x9a, 0x6f, 0x45, 0x6b, 0xd6, 0x93, 0x31, 0x4d, 0x27, 0x76, 0x26, 0xde, 0xad, 0xd6, 0x62, 0xbf, 0xc7, 0xf1, 0xab, 0xdd, 0x8a, 0x8c, 0xbf, 0x13, 0x58, 0x88, 0x2e, 0x8a, 0xc2, 0xbe, 0xf8, 0x30, 0xd0, 0xc1, 0xbf, 0x17, 0x16, 0xa4, 0xe6, 0xc7, 0x07, 0x05, 0x25, 0x02, 0x69, 0xd9, 0x91, 0x52, 0xf5, 0xa1, 0x7a, 0xb8, 0x04, 0x6e, 0xdb, 0x57, 0x95, 0x07, 0x8e, 0xf2, 0x5c, 0x4b, 0xe2, 0xe2, 0xd9, 0x51, 0xe4, 0xbf, 0x0e, 0xf4, 0x6f, 0xf2, 0xc1, 0x79, 0xc3, 0x40, 0xcb, 0xe6, 0x0d, 0x1b, 0x59, 0xe2, 0x6f, 0x28, 0xeb, 0x10, 0xde, 0x63, 0xcb, 0xee, 0xdf, 0xc3, 0x99, 0x37, 0x90, 0xb9, 0x79, 0x11, 0xbb, 0x21, 0x1f, 0x2f, 0xa0, 0x18, 0xae, 0x2e, 0xf7, 0x69, 0x28, 0x90, 0x14, 0x69, 0x1e, 0xf7, 0x53, 0x74, 0xf6, 0xb7, 0x33, 0x36, 0x6d, 0x88, 0x49, 0x89, 0x37, 0x5c, 0x6b, 0xd0, 0xe1, 0x0c, 0xc6, 0x11, 0xc7, 0xb9, 0x1c, 0xcf, 0xf7, 0xac, 0xad, 0xe9, 0xed, 0x7b, 0x76, 0x84, 0x16, 0x5b, 0xe8, 0xb4, 0xbb, 0x7f, 0x3a, 0x5e, 0xa8, 0x1e, 0xf2, 0x7b, 0x7f, 0x0d, 0xcb, 0xcf, 0xcf, 0x97, 0xda, 0xc7, 0xbb, 0xf4, 0x78, 0x30, 0xb8, 0x52, 0x68, 0x67, 0x2f, 0x4c, 0x11, 0xd7, 0x67, 0xfb, 0xe3, 0x78, 0x55, 0xbb, 0xf5, 0x4f, 0x37, 0xbc, 0xfd, 0xb6, 0x66, 0xd9, 0x83, 0x24, 0xeb, 0xf5, 0xe2, 0xf4, 0x8f, 0x26, 0xac, 0xb2, 0xf0, 0x39, 0x3b, 0x9b, 0xec, 0x76, 0x6f, 0x03, 0xf5, 0x09, 0x8f, 0x3d, 0xac, 0x5b, 0x41, 0x4e, 0x92, 0x47, 0x6f, 0x71, 0x8b, 0xce, 0x7e, 0x9c, 0x8f, 0x4f, 0x53, 0x35, 0x55, 0xc3, 0x26, 0x42, 0x6b, 0x6f, 0x8d, 0x2f, 0x01, 0x7c, 0xb0, 0x67, 0xf7, 0x92, 0x47, 0x99, 0x85, 0xe3, 0xd5, 0x14, 0x05, 0x72, 0x42, 0x93, 0xbf, 0xe1, 0xce, 0xca, 0x82, 0x23, 0xa2, 0x7f, 0x75, 0x09, 0x81, 0xa9, 0x6c, 0xb4, 0x50, 0xca, 0x9d, 0xde, 0xad, 0x11, 0x1d, 0x38, 0xb4, 0x67, 0xca, 0x89, 0xb3, 0xe6, 0x29, 0xac, 0x03, 0x3d, 0xa2, 0x9c, 0xc1, 0xa8, 0xd7, 0xa8, 0x76, 0xb2, 0xcd, 0xcd, 0xae, 0x42, 0xaf, 0x03, 0xff, 0x33, 0x8f, 0xf3, 0x64, 0x8b, 0xde, 0x1c, 0x49, 0xbc, 0xa4, 0xfd, 0xf1, 0x3c, 0xfd, 0xcb, 0xcd, 0x8c, 0xfc, 0x62, 0x93, 0x1d, 0x71, 0xe1, 0x74, 0xa4, 0x27, 0x1a, 0xe2, 0x69, 0x70, 0xda, 0x76, 0xef, 0xe6, 0x74, 0x6f, 0xd5, 0xfc, 0x31, 0x2b, 0x72, 0xd0, 0x07, 0x16, 0xa5, 0xac, 0x9f, 0x97, 0x5e, 0xb5, 0x6e, 0x6e, 0xc8, 0xd3, 0x6e, 0x1c, 0x2d, 0x56, 0xcc, 0x5b, 0x2d, 0xe0, 0x22, 0x52, 0xc4, 0xa0, 0x08, 0x9e, 0x0f, 0x9d, 0x87, 0xfd, 0x4d, 0x8a, 0x57, 0xda, 0xb8, 0xee, 0xd8, 0x93, 0x2e, 0x62, 0x5e, 0x3f, 0x90, 0x65, 0x16, 0x29, 0x08, 0x05, 0x3b, 0x8b, 0x24, 0x08, 0x7f, 0x39, 0x20, 0x4f, 0x1c, 0xc6, 0x10, 0x54, 0xa1, 0x71, 0xda, 0x03, 0xb1, 0xb0, 0x5b, 0xa1, 0x4f, 0x36, 0xb2, 0xe3, 0x74, 0xf0, 0xe2, 0x13, 0x55, 0xd1, 0x1f, 0x9d, 0xce, 0x96, 0x14, 0x5a, 0xbc, 0x5c, 0xfc, 0x33, 0x7c, 0xb9, 0x5a, 0x40, 0x50, 0x89, 0x5f, 0x46, 0x06, 0xc1, 0xa3, 0xa2, 0x0e, 0xc6, 0x09, 0xbe, 0xc1, 0x13, 0x13, 0xe7, 0x78, 0x4e, 0x95, 0x73, 0xfc, 0x30, 0x31, 0x31, 0x9c, 0xaf, 0xd0, 0x5c, 0xec, 0xf2, 0xf3, 0x0b, 0x31, 0xa3, 0xc3, 0x09, 0x41, 0x91, 0x5e, 0x17, 0xae, 0x66, 0x38, 0x65, 0xd3, 0xe2, 0xfd, 0xca, 0x8e, 0xc9, 0x7b, 0x9f, 0xd3, 0xbb, 0xc9, 0xaa, 0x4e, 0x92, 0x52, 0x5e, 0x52, 0x16, 0x47, 0xb8, 0x08, 0x25, 0xbd, 0x4e, 0x6c, 0x66, 0x4f, 0x75, 0xf3, 0x87, 0x09, 0x39, 0x28, 0x69, 0xfd, 0x7c, 0xe0, 0x6d, 0x3b, 0x65, 0x44, 0xf2, 0x91, 0xdb, 0x5f, 0x0c, 0xf7, 0x4b, 0xd6, 0x4a, 0x29, 0x66, 0xbd, 0xdc, 0xaa, 0x16, 0xeb, 0x27, 0x78, 0x14, 0x90, 0xdf, 0x7b, 0xd8, 0x7f, 0x23, 0xad, 0x8b, 0x8a, 0x0c, 0x7e, 0xae, 0x81, 0xc5, 0x4e, 0x83, 0x90, 0x52, 0x98, 0xa0, 0x9a, 0x46, 0xb6, 0xbe, 0x1a, 0xdf, 0xd5, 0x8b, 0x61, 0x2f, 0x63, 0x66, 0x1b, 0x67, 0xbf, 0x45, 0x8d, 0xf4, 0x85, 0x8c, 0x80, 0x9f, 0xb4, 0x89, 0x1a, 0x97, 0xab, 0xb6, 0x2f, 0x1e, 0x3b, 0x22, 0x45, 0x13, 0x30, 0x90, 0x10, 0x83, 0x31, 0x04, 0x61, 0xb2, 0x19, 0x1c, 0x86, 0x8f, 0x57, 0xbb, 0xb7, 0x47, 0x7a, 0xd5, 0x28, 0x22, 0x79, 0xe8, 0x7d, 0xa1, 0x28, 0xdf, 0xb4, 0xb4, 0xf0, 0xcf, 0x56, 0xdb, 0x4a, 0x92, 0x7b, 0x07, 0x98, 0xba, 0x1f, 0xcb, 0xef, 0x7f, 0xa6, 0xa7, 0x05, 0x71, 0x54, 0x66, 0x5a, 0x66, 0xed, 0x99, 0xda, 0x5a, 0x46, 0xff, 0x94, 0xf3, 0x05, 0x66, 0x43, 0x4c, 0x9d, 0xfa, 0x59, 0x99, 0x8b, 0x47, 0x94, 0x47, 0x3a, 0x7c, 0xba, 0x21, 0xfa, 0xc1, 0xc2, 0xb2, 0x41, 0x0c, 0x8f, 0x98, 0xe2, 0x01, 0x90, 0x88, 0xaa, 0x95, 0x58, 0x61, 0xb5, 0xb3, 0x63, 0xe7, 0x6f, 0x45, 0xfe, 0xf9, 0x93, 0xeb, 0xcb, 0x9e, 0x7b, 0x68, 0x46, 0x97, 0xb2, 0x4a, 0xaa, 0xb1, 0xb9, 0xaa, 0xc8, 0xd7, 0x9c, 0x00, 0x6d, 0x63, 0x8c, 0xa7, 0xcb, 0x62, 0x98, 0x9a, 0xe5, 0xac, 0xd2, 0xa6, 0x94, 0xa0, 0x42, 0x98, 0x03, 0x3c, 0xe8, 0x6c, 0xb9, 0x1f, 0x72, 0x16, 0xd0, 0x19, 0x0e, 0x7f, 0x8c, 0x9c, 0x27, 0x44, 0xd5, 0xc1, 0x5b, 0x46, 0xd1, 0x55, 0x03, 0x8e, 0x52, 0xb3, 0xeb, 0xbb, 0xf5, 0xaa, 0xc5, 0xce, 0x06, 0xe4, 0xc9, 0xf0, 0x70, 0xba, 0x28, 0x95, 0xc3, 0x06, 0xdf, 0xda, 0x9a, 0x86, 0x5e, 0xc4, 0xac, 0xa6, 0xdd, 0xfd, 0x12, 0x52, 0xbb, 0xc9, 0x76, 0xa0, 0x4a, 0xb7, 0x8d, 0x06, 0x7a, 0x32, 0x2d, 0x0d, 0xbe, 0x76, 0x73, 0xc6, 0xed, 0xd3, 0x6f, 0xc3, 0xdb, 0xc6, 0xe7, 0xb8, 0x2d, 0x66, 0xaf, 0x47, 0x71, 0x2c, 0x9c, 0xa8, 0xb9, 0x1d, 0x40, 0x40, 0xb6, 0x47, 0x43, 0x94, 0x0d, 0x49, 0x2b, 0x34, 0x33, 0x83, 0x7e, 0x15, 0x2b, 0x6a, 0x90, 0x8b, 0x68, 0x99, 0x32, 0xd8, 0xf2, 0xbb, 0x07, 0xbe, 0x04, 0x92, 0xb2, 0xd5, 0xd5, 0x89, 0x3b, 0xf1, 0x5a, 0xd5, 0xdb, 0x6c, 0x97, 0x39, 0xd8, 0xfa, 0xb8, 0x00, 0x4a, 0x6d, 0x74, 0x15, 0xd8, 0x20, 0x29, 0x35, 0xae, 0x32, 0xbc, 0x68, 0x9d, 0x02, 0x21, 0x65, 0xb2, 0x85, 0x50, 0x69, 0x27, 0x6e, 0x3e, 0x0d, 0x68, 0x94, 0x79, 0xbd, 0x7d, 0xcb, 0x5a, 0xd6, 0xee, 0x55, 0xbf, 0xac, 0x90, 0x83, 0x7f, 0x44, 0x2d, 0x28, 0x41, 0xe2, 0xa6, 0xe7, 0x77, 0x00, 0xbf, 0x81, 0xa1, 0x69, 0x3e, 0x67, 0x16, 0x86, 0xf2, 0x34, 0xf3, 0x7d, 0x14, 0xf1, 0xa7, 0x9c, 0x44, 0xb5, 0x4d, 0xcd, 0xf5, 0x4e, 0x9f, 0x5a, 0xe3, 0x21, 0x54, 0x36, 0xbb, 0x35, 0x1d, 0xb4, 0x74, 0x0b, 0xb4, 0x5a, 0x8d, 0xe8, 0x34, 0x56, 0x33, 0x23, 0xa0, 0x9d, 0x2d, 0x1d, 0x03, 0x3e, 0x11, 0x77, 0x55, 0xe8, 0x82, 0x18, 0xdd, 0xc6, 0x1d, 0xef, 0x89, 0x07, 0x28, 0x0c, 0xff, 0x46, 0x8e, 0xff, 0x47, 0xb7, 0xb0, 0x34, 0x5e, 0x2d, 0x2b, 0x6d, 0xad, 0xf9, 0x68, 0x98, 0xa4, 0xff, 0xf7, 0x87, 0x23, 0xcc, 0x5f, 0xd1, 0xb5, 0x1e, 0xe0, 0x95, 0xb9, 0xdc, 0x6e, 0x89, 0x22, 0x23, 0x07, 0x92, 0x92, 0xed, 0x76, 0x1d, 0xb9, 0x2f, 0x5c, 0xdd, 0x7a, 0xfa, 0x0d, 0x0d, 0x0f, 0x56, 0x75, 0xdb, 0x1c, 0x10, 0x3f, 0x58, 0x90, 0xe2, 0x58, 0x2a, 0x68, 0x65, 0xc9, 0x7a, 0x74, 0x55, 0xca, 0xe4, 0x4c, 0xb4, 0xd2, 0x56, 0xc4, 0xfc, 0xea, 0x23, 0xc6, 0x1f, 0xcd, 0x8e, 0x0f, 0xde, 0x77, 0xff, 0x94, 0x2c, 0x46, 0xd8, 0x84, 0x96, 0x89, 0x0c, 0x34, 0x82, 0xbc, 0xdc, 0x7a, 0xc2, 0x94, 0xc3, 0x2c, 0x32, 0xa9, 0x2a, 0xe9, 0x19, 0x56, 0xbd, 0xc3, 0x29, 0xac, 0x9a, 0xd4, 0xb9, 0x4c, 0x1a, 0x2d, 0xe7, 0x10, 0x09, 0x38, 0xac, 0xbb, 0x37, 0x7a, 0x82, 0x50, 0xe6, 0x7d, 0x74, 0xb4, 0xc1, 0xa1, 0xc2, 0x2a, 0x2a, 0x58, 0xbd, 0x7d, 0x7d, 0xf1, 0xbf, 0x94, 0xb4, 0xd4, 0x07, 0x56, 0x1b, 0xb8, 0x5d, 0xfd, 0xea, 0xc0, 0xe2, 0xde, 0xd9, 0xe2, 0xc7, 0x02, 0xd2, 0xde, 0x11, 0x87, 0x51, 0x1c, 0x2a, 0x92, 0xc7, 0xc7, 0x38, 0x1b, 0x51, 0xd5, 0x82, 0x3e, 0xb8, 0xde, 0xd9, 0x9e, 0x3e, 0xfe, 0xbf, 0x17, 0xf7, 0x35, 0xee, 0x6e, 0xab, 0x25, 0x65, 0xe4, 0xaa, 0xe7, 0x04, 0xfa, 0x9e, 0xdd, 0x86, 0x86, 0xce, 0x63, 0x21, 0x72, 0x86, 0x7c, 0xae, 0x77, 0xf0, 0xbf, 0xfc, 0x92, 0x9c, 0x72, 0xdb, 0x32, 0xc2, 0x2a, 0x7d, 0x5b, 0x77, 0x3a, 0x87, 0x72, 0x1c, 0x0f, 0x44, 0x82, 0x0f, 0xa6, 0xf9, 0xe2, 0x76, 0x10, 0x2c, 0x1e, 0x10, 0xf1, 0x1d, 0x8d, 0x43, 0x96, 0xd6, 0x74, 0xc6, 0x79, 0xb0, 0x5a, 0xca, 0x64, 0x8f, 0x5c, 0x68, 0x6a, 0x65, 0x70, 0x24, 0xf3, 0xc9, 0xe8, 0x0d, 0x4b, 0x86, 0x60, 0x15, 0xad, 0xd7, 0x53, 0x92, 0xbf, 0x1c, 0x31, 0x14, 0x22, 0x36, 0xb3, 0x23, 0xb2, 0xe8, 0xd8, 0x4d, 0x88, 0x2e, 0xbe, 0x74, 0x87, 0x0e, 0x07, 0x09, 0x93, 0x52, 0xa6, 0xbb, 0x27, 0x08, 0x6e, 0xf3, 0xfc, 0x7c, 0xdd, 0x3c, 0x9a, 0x5b, 0xc1, 0xd1, 0x6f, 0xa5, 0x42, 0x93, 0x95, 0x1a, 0x0b, 0x31, 0x93, 0xdb, 0x49, 0x9c, 0x62, 0x62, 0x98, 0x56, 0x34, 0x5e, 0x32, 0xd0, 0x16, 0x42, 0x00, 0xff, 0xd5, 0xa7, 0x92, 0x4e, 0xe6, 0xd3, 0xc1, 0x3a, 0x2c, 0x6e, 0xd5, 0xaa, 0xfa, 0x73, 0x93, 0x8c, 0x67, 0x5a, 0x40, 0x73, 0xbf, 0xca, 0xcd, 0xc9, 0x16, 0x1a, 0x6a, 0x06, 0x4a, 0xad, 0x68, 0x68, 0x5f, 0x49, 0xb5, 0xc1, 0x65, 0xfa, 0xe9, 0x2e, 0xe2, 0x7c, 0x22, 0x06, 0x06, 0x46, 0x60, 0x6e, 0xee, 0x97, 0x1f, 0x66, 0x66, 0xea, 0xd4, 0xb9, 0xd7, 0x07, 0x4b, 0x48, 0x3a, 0x6d, 0xcf, 0xf0, 0x3e, 0x81, 0xbc, 0x96, 0x03, 0xbf, 0x9d, 0xb8, 0x09, 0xc9, 0x8b, 0x4c, 0x49, 0x39, 0xce, 0x6e, 0x55, 0xa1, 0x79, 0x3f, 0xe7, 0x36, 0xcd, 0x7a, 0x18, 0x42, 0xe6, 0x21, 0xc7, 0xec, 0x63, 0x06, 0x4f, 0xfe, 0xd8, 0xbc, 0xe4, 0x69, 0x4c, 0x1e, 0x26, 0x3a, 0x85, 0x15, 0x0d, 0x10, 0xfa, 0xce, 0x70, 0xb3, 0x18, 0x9e, 0x9d, 0xca, 0x6c, 0x0a, 0x92, 0x71, 0x5e, 0x34, 0x6b, 0x2f, 0xce, 0x6c, 0x73, 0x44, 0x43, 0x52, 0xb7, 0x81, 0x91, 0x4d, 0x69, 0xf5, 0xe8, 0xeb, 0xed, 0xad, 0xf1, 0x79, 0x76, 0x6d, 0x6e, 0x6e, 0x3e, 0x50, 0x64, 0x5d, 0x2d, 0x50, 0xa1, 0x61, 0xb6, 0x59, 0x66, 0x7b, 0xb9, 0xfb, 0x67, 0x47, 0x83, 0x07, 0x63, 0x30, 0xd0, 0x3e, 0x0c, 0x9e, 0x2e, 0x89, 0x1a, 0x3c, 0xa6, 0x2c, 0xfe, 0x61, 0xb0, 0xb7, 0x65, 0xf7, 0x33, 0x3e, 0xab, 0x9c, 0xd2, 0xce, 0xd6, 0x0e, 0x85, 0x80, 0xd6, 0x89, 0x4f, 0x5a, 0xb2, 0x94, 0x03, 0x05, 0x1d, 0x24, 0xf0, 0x74, 0x40, 0x56, 0xa1, 0xdb, 0x86, 0x03, 0xa8, 0xe3, 0xce, 0x70, 0x02, 0x98, 0xd5, 0x14, 0x19, 0x11, 0x09, 0x69, 0x6e, 0x0f, 0xd0, 0xe4, 0xcf, 0xa3, 0xfb, 0xd1, 0x0b, 0x23, 0x29, 0x95, 0x8b, 0xcd, 0xe4, 0xd1, 0xcf, 0x06, 0x14, 0x60, 0x10, 0x16, 0xc5, 0xd8, 0xc5, 0xfd, 0xfb, 0xca, 0xe5, 0x5a, 0x47, 0xdc, 0xd1, 0x1a, 0x51, 0x9c, 0x90, 0x3b, 0x0c, 0x77, 0x1e, 0x26, 0x3e, 0x9d, 0xb8, 0xf8, 0x9b, 0x1a, 0x9b, 0x2c, 0xbd, 0x1a, 0x35, 0x46, 0x13, 0xd4, 0xaf, 0xe4, 0x41, 0x48, 0x32, 0x19, 0xbc, 0x39, 0x5c, 0x5a, 0x5c, 0x39, 0x31, 0x8d, 0x85, 0xbb, 0x0d, 0x8b, 0x61, 0x5d, 0x2d, 0x5c, 0x00, 0xe2, 0x7a, 0xf3, 0xe7, 0xfe, 0xcd, 0xca, 0x25, 0x70, 0x70, 0x70, 0x34, 0x3b, 0xee, 0x46, 0xf6, 0x88, 0x57, 0x59, 0x61, 0xe2, 0x44, 0x85, 0x5c, 0x5c, 0xd8, 0xaf, 0x34, 0x3b, 0x40, 0x39, 0x38, 0x38, 0xd0, 0x78, 0xec, 0x8c, 0x87, 0x99, 0xaf, 0x4e, 0x23, 0x54, 0xc5, 0xa6, 0xbf, 0x12, 0x68, 0xa4, 0xe2, 0x15, 0x74, 0xc4, 0xf1, 0x02, 0xab, 0x53, 0x76, 0x27, 0x56, 0x5a, 0xa3, 0x11, 0x7d, 0x53, 0xa1, 0xf3, 0x1f, 0xb6, 0xea, 0xbd, 0xe8, 0xe1, 0x42, 0x35, 0x71, 0xbf, 0x11, 0x33, 0x83, 0x5e, 0x3b, 0x7c, 0x7a, 0xb1, 0xa1, 0xb1, 0x71, 0x90, 0xed, 0x6a, 0x6b, 0x40, 0x3e, 0x75, 0x26, 0xbf, 0x97, 0x9a, 0x8d, 0xad, 0xf5, 0x0a, 0x52, 0xcd, 0x92, 0xb5, 0xb3, 0xf5, 0x71, 0x5e, 0x7c, 0xb6, 0x49, 0x2d, 0x20, 0x45, 0xc3, 0xd2, 0x4d, 0xfa, 0x49, 0x61, 0x49, 0x04, 0x66, 0x26, 0xfc, 0xef, 0x51, 0xc5, 0x4e, 0xe5, 0xd5, 0xe4, 0xa2, 0x5f, 0x66, 0x21, 0x4f, 0x1b, 0x43, 0x48, 0xd1, 0x8f, 0x10, 0x88, 0x26, 0x1a, 0x52, 0x54, 0x9e, 0xe8, 0x00, 0xa2, 0x4b, 0x86, 0x62, 0x71, 0xf2, 0xab, 0x56, 0x5b, 0x7c, 0xdf, 0x76, 0x6c, 0x17, 0x74, 0x60, 0xb2, 0xae, 0xac, 0xff, 0xd7, 0xa8, 0xa2, 0xcc, 0xa0, 0xd3, 0x16, 0x77, 0x48, 0xec, 0x17, 0xb3, 0xf2, 0x32, 0x5d, 0x66, 0x49, 0x88, 0x0a, 0xf7, 0xaf, 0xd1, 0x26, 0x28, 0x2d, 0xcd, 0xf7, 0xfc, 0xfa, 0x18, 0x93, 0x28, 0x2e, 0x2c, 0x08, 0x0e, 0x2d, 0x5f, 0x3e, 0x47, 0x80, 0x26, 0x4d, 0xa4, 0xb4, 0xff, 0xaa, 0xda, 0x8d, 0x54, 0x3a, 0xe8, 0xcc, 0xa1, 0xfa, 0xf2, 0xd6, 0x79, 0xa0, 0x7b, 0x52, 0xae, 0xc1, 0xd7, 0x6e, 0x20, 0x12, 0x9b, 0xcb, 0xfb, 0x81, 0x89, 0x1c, 0x03, 0x21, 0x99, 0x51, 0x3f, 0xd6, 0xf5, 0x74, 0xd9, 0x70, 0x2c, 0x95, 0x59, 0x52, 0x4e, 0xae, 0xca, 0xf9, 0x6d, 0xbe, 0x43, 0x22, 0x5e, 0x91, 0x01, 0x5d, 0x1e, 0x93, 0x3a, 0x52, 0xe4, 0xa7, 0x1f, 0xc1, 0x5c, 0xaa, 0x61, 0x64, 0xc3, 0x4c, 0x4d, 0x16, 0x90, 0x4d, 0xe6, 0x83, 0x60, 0xd8, 0x90, 0xa6, 0x7b, 0x16, 0x08, 0x83, 0x4e, 0x29, 0x4a, 0x2f, 0x87, 0x48, 0xc3, 0x48, 0x6d, 0x05, 0xac, 0x90, 0x78, 0xa8, 0xc0, 0x5a, 0x93, 0x5d, 0x42, 0xae, 0x45, 0xc0, 0xa5, 0xf3, 0x83, 0x28, 0x20, 0x0c, 0xfd, 0x88, 0x3a, 0xc2, 0x1f, 0xf5, 0x6d, 0xe9, 0x31, 0xa1, 0x55, 0x1d, 0xb5, 0x5e, 0x81, 0xa1, 0xcd, 0xe4, 0x7c, 0x30, 0x69, 0xb9, 0x66, 0x9b, 0x09, 0x0f, 0x0d, 0x69, 0xbd, 0xda, 0xaa, 0x7a, 0x1a, 0x25, 0x03, 0x58, 0x90, 0xa8, 0xce, 0x27, 0x3c, 0xa5, 0xb4, 0x3d, 0xbd, 0xfd, 0xcd, 0xd7, 0xd6, 0x85, 0xa7, 0xac, 0x16, 0xa7, 0xfd, 0xfc, 0xdf, 0xbf, 0xe1, 0xdf, 0xdf, 0x9e, 0x19, 0x4f, 0x4e, 0x4f, 0xf3, 0x54, 0x68, 0x6a, 0xed, 0xd6, 0x05, 0xac, 0xd7, 0xda, 0x5b, 0xa6, 0x1f, 0xa5, 0x28, 0x62, 0xde, 0xab, 0x24, 0x2c, 0x2a, 0x8c, 0x35, 0xb5, 0xd8, 0xea, 0xd4, 0x5e, 0xd3, 0x0c, 0x77, 0x0c, 0xb5, 0x34, 0x13, 0xff, 0x7f, 0x3c, 0x50, 0x61, 0x33, 0xcb, 0x82, 0x94, 0xa6, 0x7d, 0x36, 0x5f, 0xde, 0x31, 0xfd, 0xf7, 0xc0, 0x97, 0x1e, 0x1a, 0x2d, 0xf6, 0x34, 0x02, 0xaf, 0x06, 0x7c, 0xd0, 0xe2, 0xb7, 0x39, 0xf2, 0x7a, 0xd8, 0x1f, 0xc1, 0x54, 0xfb, 0xbe, 0x74, 0x88, 0xf0, 0x4e, 0x03, 0x8b, 0x19, 0x0d, 0x66, 0x16, 0x91, 0xd7, 0x3a, 0x24, 0xe6, 0xe4, 0xe4, 0x04, 0x5a, 0x06, 0x76, 0x7e, 0xbe, 0x48, 0xfc, 0xf4, 0x6f, 0x5f, 0xc9, 0x62, 0xf3, 0x75, 0xee, 0xa0, 0xd5, 0x53, 0x83, 0xc3, 0xb7, 0xf7, 0xec, 0x80, 0x06, 0xcf, 0xfd, 0xa7, 0xdb, 0x63, 0x78, 0x24, 0xa4, 0x20, 0x0d, 0xba, 0xc1, 0x0e, 0xaf, 0xfb, 0x8d, 0x93, 0x97, 0x3d, 0xb6, 0x56, 0x3b, 0xbf, 0x47, 0xb8, 0x96, 0xc7, 0x10, 0xbb, 0xcc, 0x7b, 0xca, 0xf4, 0x7f, 0x49, 0x6f, 0xab, 0x16, 0x5a, 0xb3, 0xe5, 0x7f, 0x91, 0x30, 0xe0, 0x4d, 0x00, 0xc2, 0x31, 0x98, 0x6c, 0x6e, 0xdd, 0xfb, 0x46, 0x7d, 0xc2, 0x14, 0x9d, 0x1f, 0x5c, 0x82, 0x1d, 0x69, 0xd6, 0x04, 0x8a, 0xc7, 0x05, 0x01, 0x7e, 0x7e, 0x23, 0xa5, 0x01, 0x89, 0xa9, 0x46, 0xfd, 0x67, 0xa7, 0xaa, 0xca, 0xb6, 0xf3, 0xce, 0xe7, 0x8a, 0xa5, 0x2b, 0x89, 0x10, 0x3e, 0x33, 0x34, 0x34, 0xb4, 0x97, 0x97, 0xeb, 0x09, 0xcf, 0xe9, 0x11, 0x7b, 0x78, 0x64, 0xe4, 0xfe, 0xcb, 0xed, 0xa1, 0x9e, 0xfd, 0x14, 0x5f, 0x88, 0xe7, 0xd7, 0x8b, 0x16, 0x29, 0x9e, 0xc4, 0x39, 0xe4, 0xc8, 0xfc, 0x8b, 0xdd, 0xc0, 0xaf, 0x60, 0x6c, 0x22, 0xa5, 0xf2, 0xfb, 0x44, 0x29, 0x8a, 0x50, 0x34, 0xe2, 0xd8, 0x38, 0x81, 0xa7, 0xdf, 0xe2, 0xd7, 0x51, 0x62, 0x18, 0xfd, 0x7c, 0x5e, 0x79, 0x11, 0x91, 0x96, 0x1a, 0x9a, 0x89, 0xa7, 0x8b, 0x54, 0x54, 0xcc, 0x32, 0xd0, 0x95, 0x22, 0xc8, 0x3c, 0x3d, 0x06, 0x9b, 0xf6, 0xed, 0xc1, 0xdf, 0xbf, 0x13, 0x79, 0x89, 0xe5, 0x7b, 0xbd, 0x33, 0x45, 0xff, 0xbe, 0x3f, 0x8e, 0x35, 0x17, 0x20, 0x62, 0x78, 0x30, 0x39, 0x85, 0x74, 0xf7, 0x02, 0xab, 0x05, 0xbb, 0x2b, 0xd6, 0x82, 0xcb, 0x39, 0xce, 0x2b, 0xeb, 0xcd, 0x87, 0xd3, 0xd9, 0xad, 0x0c, 0xcc, 0xd4, 0x9f, 0xc5, 0x29, 0x62, 0xe2, 0xbb, 0xbb, 0x85, 0xa2, 0x09, 0xb9, 0x95, 0xd8, 0x8b, 0x2d, 0x60, 0xad, 0x1a, 0x5f, 0x4a, 0x6b, 0x8f, 0xb3, 0xfa, 0x4c, 0x8d, 0x2f, 0x2b, 0x98, 0x0f, 0x4a, 0x84, 0x69, 0xe7, 0x56, 0xdb, 0xdc, 0xb6, 0x07, 0xa2, 0xd2, 0xf1, 0x8e, 0xa2, 0x38, 0x89, 0x66, 0x3d, 0x5f, 0xaf, 0xc2, 0x47, 0xa0, 0x25, 0x20, 0xed, 0x59, 0xd9, 0x4f, 0xcb, 0xbb, 0x68, 0x24, 0x82, 0xc5, 0xe1, 0x98, 0x0f, 0xa0, 0x83, 0xfa, 0xff, 0xfb, 0xed, 0xa4, 0x1d, 0x42, 0xfa, 0x56, 0xac, 0x94, 0xc6, 0x8c, 0x4a, 0xed, 0xa0, 0x9b, 0x81, 0x8f, 0x74, 0xd1, 0x93, 0x98, 0xb7, 0xd8, 0xb2, 0x49, 0xc6, 0xc5, 0xbd, 0x78, 0xa4, 0xd9, 0x17, 0x99, 0xd9, 0xee, 0x2e, 0x4d, 0x0f, 0x3a, 0x63, 0xef, 0xf0, 0xbc, 0x15, 0x11, 0x15, 0x0d, 0x26, 0x62, 0x63, 0xd1, 0x19, 0xc1, 0x77, 0x06, 0xb9, 0x5f, 0xb2, 0x40, 0x49, 0xfc, 0xd5, 0x9b, 0x71, 0xe7, 0xe7, 0x88, 0x0a, 0x79, 0x1f, 0xcf, 0xc8, 0x77, 0x20, 0x4b, 0x4d, 0xb7, 0xbf, 0x39, 0x61, 0xc7, 0x8a, 0xe8, 0xb7, 0xcb, 0xd6, 0x40, 0x69, 0xf1, 0xb0, 0xe4, 0xbe, 0x4c, 0x6c, 0x69, 0x69, 0xaa, 0x28, 0x6b, 0x81, 0x16, 0xb1, 0x21, 0x01, 0x32, 0xac, 0x20, 0x93, 0xae, 0x02, 0xcf, 0xb0, 0xe0, 0x52, 0x23, 0x83, 0xe3, 0x82, 0xf0, 0xd3, 0xbd, 0x2b, 0x19, 0xed, 0x00, 0x2f, 0xfc, 0xdb, 0xbf, 0xce, 0xee, 0x9b, 0xa9, 0xd7, 0x9e, 0x5d, 0xfb, 0x32, 0x6d, 0x11, 0xc6, 0xf0, 0x7e, 0xa5, 0x97, 0xa7, 0xfb, 0x43, 0x44, 0x47, 0x4c, 0x4c, 0xcc, 0x97, 0xc7, 0xfd, 0x9c, 0x0d, 0x70, 0xee, 0xdf, 0xe5, 0x60, 0xc3, 0x54, 0x44, 0x66, 0xa8, 0xb9, 0x4f, 0x38, 0x38, 0xb0, 0x44, 0xf2, 0x1d, 0x5a, 0x2b, 0x67, 0x50, 0x66, 0x56, 0x0d, 0xe2, 0x1e, 0xee, 0x7c, 0xa8, 0xf3, 0x0c, 0xd9, 0x01, 0x9f, 0xa0, 0x02, 0xf3, 0xa2, 0xf0, 0xf9, 0xd9, 0xc6, 0xfd, 0xc7, 0xa7, 0x8f, 0x24, 0x28, 0x13, 0x32, 0x5f, 0xe8, 0x81, 0x17, 0xab, 0x9c, 0x6a, 0x16, 0x34, 0x81, 0x47, 0x41, 0x0c, 0xc8, 0xad, 0xbe, 0xad, 0xd2, 0x95, 0xd3, 0x06, 0x53, 0xfa, 0x91, 0x2b, 0x6c, 0x35, 0x36, 0x36, 0xd5, 0xf6, 0xe3, 0x5e, 0x53, 0x91, 0xfd, 0xb7, 0x3e, 0x93, 0x4b, 0x5b, 0xfa, 0xea, 0x70, 0x03, 0xa9, 0xd7, 0x5e, 0x91, 0xaa, 0xf4, 0x72, 0x58, 0x92, 0xd3, 0x3b, 0x3f, 0x7f, 0xd1, 0x8e, 0xb0, 0x2c, 0x52, 0xaa, 0xb2, 0x35, 0x99, 0xf7, 0x4d, 0xa3, 0xc5, 0x91, 0x82, 0x48, 0xd0, 0x37, 0xda, 0xf7, 0xf5, 0x09, 0x80, 0x42, 0x22, 0x40, 0x52, 0x98, 0xd8, 0xd9, 0x43, 0x6a, 0x6b, 0x99, 0xc5, 0xe3, 0x88, 0x74, 0xf3, 0xa6, 0xa2, 0x4b, 0x4b, 0xbf, 0x7a, 0xde, 0x1c, 0xe4, 0xa9, 0x89, 0x31, 0x90, 0x70, 0xa3, 0xe0, 0x56, 0x49, 0x90, 0xd4, 0xa3, 0x96, 0x58, 0x33, 0xa4, 0x04, 0xc9, 0x9b, 0xc5, 0x85, 0x75, 0xa9, 0xd3, 0x7a, 0xd7, 0x3a, 0xe0, 0x62, 0xcd, 0xed, 0x14, 0x2c, 0x24, 0x33, 0x7c, 0x6e, 0xaf, 0x27, 0xf4, 0x1e, 0xae, 0xe1, 0x22, 0xb4, 0x53, 0x0e, 0x21, 0x2d, 0x3e, 0x9b, 0x72, 0x85, 0x86, 0x04, 0xec, 0x31, 0x18, 0xba, 0x8a, 0x89, 0xc5, 0xa8, 0x83, 0x0a, 0x47, 0xff, 0x01, 0xf9, 0x67, 0x29, 0x43, 0x3a, 0xbf, 0x36, 0xf7, 0xe6, 0x3f, 0x93, 0x3a, 0x64, 0xca, 0xcf, 0x95, 0x34, 0x8e, 0x57, 0x88, 0xb5, 0xcf, 0xdd, 0x69, 0x88, 0x8e, 0x12, 0x12, 0x12, 0x74, 0x3a, 0xcd, 0x0a, 0x68, 0xf8, 0x87, 0x44, 0xf1, 0x92, 0xc1, 0xf4, 0xda, 0x8d, 0x06, 0xd7, 0x7b, 0xe3, 0xee, 0x6f, 0x2f, 0x2d, 0x52, 0x6f, 0x13, 0x82, 0xef, 0x2a, 0xa9, 0xbc, 0x7e, 0x6f, 0xde, 0xc1, 0xa1, 0xa1, 0x5b, 0xd7, 0x13, 0x82, 0x12, 0x43, 0xb1, 0x9f, 0x7b, 0x3c, 0x5d, 0x46, 0xb2, 0x38, 0xed, 0xb2, 0xd3, 0x85, 0xe1, 0xfc, 0x6f, 0xb5, 0xdf, 0x45, 0x4a, 0x5c, 0x6d, 0x0c, 0x74, 0xc2, 0x94, 0x3a, 0xb0, 0x60, 0x90, 0xcf, 0x56, 0xf1, 0xf6, 0x8a, 0x45, 0xbc, 0xff, 0xdc, 0xe1, 0x86, 0xf7, 0x63, 0xc4, 0x2c, 0xd0, 0x48, 0x2f, 0xc1, 0xbb, 0x9c, 0x0a, 0x29, 0xd3, 0xe1, 0xac, 0x13, 0x82, 0x3e, 0xb2, 0x25, 0xa4, 0x73, 0x06, 0xcd, 0xbf, 0x6d, 0x29, 0xa7, 0xd8, 0x02, 0x47, 0xf1, 0x6b, 0x3f, 0x43, 0x9f, 0xc0, 0x89, 0x28, 0x25, 0x68, 0x29, 0x21, 0x6c, 0x63, 0xe1, 0x96, 0x18, 0xaf, 0x9d, 0x19, 0xce, 0x3f, 0xcb, 0x2f, 0x47, 0x44, 0x2e, 0xfb, 0xc9, 0xec, 0x4f, 0x47, 0x07, 0x3f, 0x87, 0xf5, 0x22, 0x88, 0xa3, 0xcd, 0x01, 0x86, 0x05, 0xa0, 0x4c, 0xe5, 0x12, 0xb9, 0x9e, 0x99, 0x19, 0x4c, 0x24, 0x1c, 0x3a, 0x05, 0xd6, 0x3d, 0x55, 0x92, 0x24, 0x29, 0x87, 0x97, 0x07, 0x07, 0x68, 0x18, 0x18, 0x12, 0x6a, 0x6a, 0xf8, 0xf8, 0xf8, 0x78, 0x90, 0x3f, 0x04, 0x14, 0xac, 0xd0, 0x17, 0x05, 0xc6, 0xf1, 0x67, 0x16, 0x32, 0x02, 0x60, 0xca, 0xe7, 0x61, 0xeb, 0x7e, 0xe3, 0x79, 0x34, 0xdc, 0x6f, 0x0d, 0x81, 0x3f, 0x5d, 0x46, 0xa5, 0x53, 0x5b, 0x6d, 0xe7, 0x5d, 0x85, 0xf4, 0xbe, 0x78, 0x2b, 0x24, 0x71, 0x99, 0x1f, 0x6e, 0x95, 0x99, 0x22, 0x8b, 0x64, 0x91, 0x4b, 0x18, 0x3e, 0x53, 0xd3, 0x1b, 0x0f, 0x15, 0x9a, 0x04, 0x19, 0x4d, 0x22, 0x78, 0xf6, 0xcd, 0xbb, 0x26, 0x92, 0x85, 0x29, 0x3b, 0x47, 0x19, 0x5e, 0xa9, 0xe6, 0x24, 0xf6, 0x04, 0x74, 0x3e, 0x98, 0xac, 0x8a, 0x8c, 0x81, 0x59, 0x85, 0xb6, 0x63, 0x75, 0x6e, 0x23, 0x44, 0xf2, 0xfa, 0x4b, 0xa3, 0x9a, 0x68, 0xff, 0x73, 0x3b, 0x5d, 0x0e, 0x99, 0x2a, 0x90, 0x38, 0x16, 0x26, 0x5b, 0x8d, 0xff, 0xf9, 0xd3, 0xbf, 0x69, 0xdd, 0x97, 0xe0, 0xf5, 0xe9, 0xb6, 0xfc, 0x4f, 0xd9, 0x72, 0x46, 0xb3, 0xcf, 0x33, 0x87, 0xc8, 0xb7, 0x6f, 0x1f, 0x00, 0x03, 0x28, 0x5d, 0x77, 0x77, 0x24, 0xf7, 0x4e, 0xd7, 0x99, 0xa0, 0xae, 0xcd, 0xe1, 0xfc, 0xf2, 0x64, 0x6b, 0x11, 0x59, 0xe7, 0xdb, 0x8d, 0xae, 0x37, 0xb3, 0x9f, 0x54, 0x56, 0x74, 0x6b, 0x98, 0x15, 0x12, 0x7c, 0xf4, 0xd1, 0xdb, 0xb5, 0x06, 0x07, 0x54, 0xe0, 0x78, 0x63, 0x45, 0xfb, 0x2f, 0x94, 0x80, 0x5c, 0x92, 0xfe, 0x5d, 0xb9, 0x49, 0x24, 0xc8, 0x00, 0xf5, 0xfb, 0x8a, 0x0a, 0x3f, 0x37, 0x26, 0x99, 0x5a, 0x5e, 0x85, 0x69, 0x15, 0xe3, 0x9e, 0xb1, 0x78, 0xf8, 0xd3, 0xe9, 0xbf, 0xb9, 0xe7, 0x23, 0xa3, 0x4e, 0x57, 0x5b, 0xf4, 0x85, 0x26, 0x7b, 0xbf, 0x87, 0x97, 0xeb, 0x2d, 0x82, 0xd6, 0x3a, 0xbc, 0x8e, 0xbf, 0x93, 0x9d, 0xf6, 0x31, 0x21, 0xbb, 0x9e, 0xad, 0x44, 0x2c, 0xd5, 0x99, 0x7d, 0x23, 0xc7, 0xb0, 0x68, 0x8f, 0x6d, 0x69, 0xe1, 0x0e, 0x0c, 0x0a, 0x72, 0xb8, 0x39, 0x50, 0x94, 0xc9, 0xe0, 0x40, 0xc1, 0xc3, 0xc3, 0x03, 0x33, 0x1b, 0x41, 0x03, 0xf3, 0xe5, 0x37, 0x07, 0x23, 0x37, 0x3d, 0xe6, 0xbb, 0x6e, 0x9c, 0xc8, 0xb9, 0xed, 0xe9, 0x71, 0x59, 0x6b, 0xa4, 0x70, 0x5e, 0x96, 0x02, 0xdd, 0xaf, 0x8d, 0x72, 0x62, 0xda, 0x79, 0x78, 0x77, 0xcc, 0xe2, 0x41, 0xc8, 0x4a, 0xb1, 0x09, 0x41, 0x35, 0x17, 0xed, 0x02, 0xc0, 0x97, 0x9e, 0x2e, 0x8c, 0xe4, 0x43, 0xf7, 0xd2, 0xfe, 0x87, 0x90, 0xa5, 0x50, 0x0d, 0x1f, 0x22, 0xcc, 0x17, 0xf9, 0x47, 0x93, 0x0a, 0x67, 0x48, 0xcf, 0x20, 0xd5, 0xc8, 0x0d, 0x68, 0xc1, 0x43, 0x63, 0x58, 0x83, 0xf7, 0xb8, 0xd1, 0x4f, 0xf3, 0x0d, 0x3e, 0x41, 0x2c, 0x7b, 0x20, 0xfb, 0xbd, 0xab, 0x2c, 0xc4, 0x3f, 0xdc, 0x4e, 0x7b, 0x6c, 0xcd, 0x5d, 0x12, 0xaa, 0x93, 0x6c, 0x31, 0x80, 0x36, 0x1b, 0x01, 0x11, 0xba, 0x00, 0xbf, 0xfb, 0x92, 0x30, 0x5c, 0x63, 0x39, 0x47, 0x73, 0x73, 0xa4, 0xaa, 0xf4, 0xe5, 0xb4, 0x6e, 0x42, 0xe0, 0x9b, 0xa8, 0x28, 0xb4, 0x56, 0x83, 0xa5, 0xaa, 0xe1, 0xd9, 0x79, 0xd8, 0xc4, 0xc2, 0xf2, 0x45, 0x67, 0xc4, 0xd4, 0x26, 0xc9, 0x83, 0xeb, 0x23, 0xdd, 0x43, 0xbd, 0x6b, 0xe5, 0x25, 0xaf, 0x08, 0x04, 0xb1, 0xb6, 0xda, 0x78, 0x50, 0x97, 0xba, 0x74, 0xe5, 0xc1, 0xc5, 0x85, 0x43, 0x6f, 0xb9, 0xa0, 0x83, 0xfe, 0xc3, 0x83, 0xb5, 0x67, 0x7e, 0x92, 0x18, 0x42, 0xb0, 0x3a, 0xc0, 0x68, 0xbf, 0x39, 0x83, 0x7b, 0x51, 0x3b, 0x44, 0xf3, 0x0f, 0x08, 0x90, 0x13, 0x1a, 0xd0, 0x0d, 0x16, 0x01, 0xb3, 0x70, 0x71, 0xbc, 0x10, 0x75, 0xd1, 0xb3, 0x43, 0x82, 0x8e, 0xaf, 0x70, 0x38, 0x9f, 0x2e, 0x32, 0xc3, 0x46, 0xf4, 0x5b, 0x20, 0x57, 0x7a, 0xb1, 0xd6, 0x18, 0xce, 0x74, 0x3c, 0xbd, 0x88, 0x38, 0xc4, 0xb9, 0x1b, 0x40, 0xdc, 0x1a, 0x87, 0x6d, 0xf1, 0xca, 0x0a, 0x0a, 0x9c, 0xa8, 0x29, 0xc0, 0xdc, 0xa8, 0x26, 0xe0, 0x94, 0xaa, 0x44, 0x32, 0x76, 0xbd, 0x60, 0x48, 0x27, 0xd3, 0x95, 0x32, 0xdd, 0xdb, 0xde, 0xcc, 0xf0, 0xcc, 0xb9, 0x57, 0x23, 0x47, 0xd2, 0xb4, 0xa8, 0xaf, 0x5f, 0x9f, 0x1a, 0x55, 0xbc, 0x98, 0xe3, 0xd3, 0x8d, 0xad, 0xe9, 0xcc, 0x98, 0x4c, 0x5f, 0x08, 0x5c, 0x5c, 0xba, 0x3b, 0x59, 0x2c, 0xa6, 0x0b, 0xcd, 0x20, 0x67, 0x53, 0x16, 0xb6, 0x4f, 0x87, 0xe0, 0x3a, 0xdd, 0xdb, 0xfe, 0x76, 0xed, 0xaa, 0x45, 0x4f, 0xe7, 0x8b, 0xd9, 0x06, 0x0b, 0x33, 0x99, 0xa7, 0xb3, 0x13, 0xd8, 0x26, 0x65, 0xfb, 0xba, 0xe2, 0xf5, 0x61, 0xfd, 0x85, 0x30, 0x4f, 0x2e, 0x8d, 0x40, 0x3f, 0x6f, 0xc7, 0x8e, 0x05, 0x5e, 0x6b, 0xc3, 0x81, 0xe0, 0xac, 0x72, 0x62, 0x7b, 0x7f, 0x18, 0xcc, 0xfa, 0x2c, 0x3d, 0xb7, 0xb8, 0xb4, 0x84, 0x87, 0x80, 0x80, 0x10, 0xb3, 0xe7, 0xcc, 0x90, 0x32, 0x3a, 0xd5, 0xea, 0x62, 0x05, 0x78, 0xec, 0x03, 0x6b, 0x34, 0x60, 0xf4, 0xce, 0xce, 0xaa, 0xdc, 0x9c, 0xfe, 0xc3, 0x6d, 0xb2, 0x2b, 0x1f, 0x22, 0xb5, 0x7e, 0x5b, 0x87, 0x3b, 0x98, 0x9f, 0x92, 0x30, 0xf3, 0x32, 0xfb, 0xb1, 0x6f, 0x78, 0x99, 0x9e, 0xe3, 0xb0, 0xbf, 0x59, 0x27, 0x95, 0x43, 0x70, 0xe9, 0xc1, 0xd5, 0x66, 0x46, 0x1f, 0x1d, 0x92, 0x2e, 0xb1, 0x92, 0xb2, 0x0b, 0xb8, 0xbe, 0xb1, 0xd7, 0x2d, 0x38, 0x10, 0x48, 0x2c, 0xad, 0xca, 0x30, 0xb5, 0x77, 0x40, 0x4b, 0x33, 0xf5, 0x7f, 0xec, 0xe2, 0x1c, 0x2a, 0x84, 0xfe, 0xdf, 0x96, 0xa3, 0xf6, 0x98, 0xac, 0x34, 0xef, 0x55, 0xb8, 0xe1, 0xd5, 0x3e, 0x24, 0x5b, 0x79, 0x50, 0x35, 0xdc, 0x9d, 0xef, 0x3d, 0x02, 0x25, 0x32, 0x8a, 0xd5, 0xe4, 0x20, 0x21, 0x88, 0x61, 0x4d, 0xe1, 0xbc, 0x9b, 0xdd, 0xfb, 0xe1, 0x42, 0xdc, 0x78, 0x2c, 0xe0, 0xd7, 0x4c, 0x0b, 0x43, 0x0c, 0xb7, 0xc2, 0x56, 0xe8, 0x7a, 0xbb, 0x87, 0x53, 0x51, 0xc9, 0xcd, 0x98, 0xf5, 0xb8, 0x76, 0xf9, 0x3c, 0x34, 0xaf, 0x15, 0x92, 0xb5, 0x2e, 0x3b, 0xee, 0x8c, 0xf8, 0x7d, 0x35, 0x9b, 0x41, 0xec, 0xc4, 0x76, 0x99, 0xd2, 0xc9, 0x11, 0x62, 0x1f, 0xd3, 0xa2, 0x4f, 0x0d, 0x9b, 0x58, 0xdc, 0x78, 0x63, 0x6b, 0x45, 0x52, 0x08, 0x42, 0x30, 0x0b, 0xb0, 0x1a, 0x93, 0x08, 0x58, 0xbb, 0x07, 0x5f, 0xe3, 0xfb, 0x75, 0x7f, 0x8e, 0x2a, 0x77, 0x42, 0xec, 0xb8, 0x42, 0x92, 0x09, 0x08, 0x78, 0x9a, 0xb1, 0x35, 0x56, 0x66, 0x5b, 0xfd, 0x34, 0xd1, 0x66, 0xdf, 0x1c, 0x7c, 0x1d, 0xb2, 0xdc, 0x7e, 0x7b, 0x7d, 0x3e, 0xfe, 0x8e, 0xb9, 0x5a, 0x63, 0xf3, 0xaf, 0xd1, 0x73, 0x69, 0xbf, 0x24, 0xc7, 0xb7, 0xb7, 0x3b, 0x00, 0x6a, 0x73, 0x6f, 0x4f, 0x8d, 0xf1, 0x39, 0x29, 0x64, 0x74, 0xd3, 0xe0, 0x6f, 0x62, 0xde, 0x83, 0xe9, 0x52, 0x05, 0xa2, 0x26, 0x60, 0xe6, 0x07, 0xc0, 0xdc, 0xc7, 0x48, 0xfd, 0x7c, 0xb2, 0x15, 0xd7, 0x02, 0x29, 0x76, 0x43, 0x1b, 0x6a, 0x2a, 0xc3, 0x49, 0xdc, 0x62, 0x08, 0x09, 0x36, 0xd6, 0x83, 0x59, 0x15, 0xd7, 0xf9, 0xd0, 0x22, 0xdc, 0x80, 0x9c, 0x99, 0x63, 0x13, 0x4d, 0x90, 0xfd, 0xcc, 0x97, 0x41, 0x63, 0x96, 0x39, 0xfa, 0x16, 0x3a, 0x8c, 0x00, 0x0b, 0xf2, 0xab, 0x4e, 0x7e, 0x38, 0x0e, 0x33, 0x01, 0x0b, 0x92, 0xd7, 0x4f, 0xed, 0x98, 0xd0, 0x62, 0x49, 0xf1, 0xd1, 0xcc, 0xf8, 0x8c, 0x2e, 0x2e, 0x82, 0xf9, 0xbd, 0xee, 0x66, 0x73, 0x44, 0xb4, 0x28, 0xbf, 0x7e, 0x45, 0x68, 0xb2, 0x5d, 0x2d, 0x4b, 0xe9, 0xf8, 0x95, 0x90, 0xa0, 0xa8, 0xa1, 0x11, 0xee, 0xb0, 0x3d, 0x58, 0x3a, 0x8c, 0x14, 0x19, 0x79, 0x6c, 0xe2, 0x97, 0xbb, 0x63, 0xeb, 0xb3, 0x2b, 0xa1, 0xdc, 0x63, 0x5a, 0xee, 0x47, 0x5e, 0x5c, 0x68, 0xb6, 0xb9, 0x5a, 0xb4, 0xbe, 0x79, 0x65, 0x33, 0xde, 0xda, 0xd3, 0xb1, 0x77, 0x71, 0x48, 0x5b, 0x26, 0xc8, 0x1a, 0x4d, 0xca, 0x42, 0x7f, 0x4a, 0xab, 0x74, 0x95, 0x94, 0xeb, 0xf2, 0xf1, 0x70, 0x04, 0x75, 0x7b, 0x2e, 0x5b, 0xa7, 0x1f, 0x7f, 0xf6, 0x71, 0xf1, 0x8a, 0xed, 0x99, 0x72, 0x77, 0xec, 0x17, 0xad, 0x65, 0x88, 0x57, 0x89, 0x05, 0xab, 0x35, 0x41, 0x43, 0xa6, 0x1c, 0x76, 0x7a, 0xf9, 0x10, 0x24, 0x49, 0xa3, 0x8a, 0x74, 0x34, 0x95, 0x42, 0x38, 0x60, 0xf0, 0xef, 0x79, 0x8c, 0xfa, 0x3c, 0xa7, 0xbd, 0x31, 0x3c, 0x00, 0xb9, 0x2b, 0xab, 0x86, 0x4d, 0xeb, 0xa6, 0x8a, 0x65, 0x33, 0xa4, 0x56, 0x17, 0x35, 0x35, 0x35, 0xe1, 0xd1, 0xd0, 0xd4, 0x17, 0x36, 0xaf, 0x74, 0x2b, 0x25, 0x5a, 0xd5, 0x25, 0x00, 0xb0, 0x5c, 0xac, 0xdf, 0xf2, 0x49, 0xcd, 0xc0, 0x2f, 0x07, 0xc2, 0x12, 0x4d, 0x7d, 0xef, 0xa2, 0xe7, 0xba, 0x5c, 0x97, 0x8d, 0xb9, 0x31, 0x04, 0x6f, 0x78, 0x28, 0x69, 0xe1, 0x21, 0x3c, 0x2e, 0x52, 0x1c, 0xc0, 0x5e, 0x25, 0x88, 0xfd, 0xc6, 0xf4, 0xf5, 0xe5, 0xed, 0xd9, 0x77, 0x43, 0x2e, 0xfc, 0x7d, 0xe2, 0x83, 0x28, 0xd6, 0xeb, 0xe6, 0x3f, 0x0d, 0x0f, 0x5a, 0xf6, 0x68, 0xa2, 0x89, 0x30, 0xc8, 0x61, 0xc1, 0xd2, 0x91, 0xdb, 0xe6, 0x4a, 0x4a, 0xa1, 0x60, 0x27, 0x93, 0x38, 0xed, 0xeb, 0x90, 0x88, 0x23, 0xf2, 0x9c, 0x15, 0x7f, 0x36, 0x3f, 0x3e, 0x03, 0x83, 0x06, 0x63, 0x3f, 0x47, 0xd1, 0xaa, 0x57, 0x7d, 0x01, 0xf2, 0x10, 0x47, 0xc4, 0xdf, 0x7b, 0x77, 0xfa, 0x8f, 0x76, 0xcc, 0xe3, 0x62, 0x03, 0x42, 0x47, 0x57, 0x77, 0xce, 0xa4, 0xf6, 0x52, 0x72, 0x74, 0x6c, 0x2e, 0x9d, 0x88, 0x3d, 0xcf, 0x4a, 0x22, 0x07, 0xe3, 0xde, 0xab, 0x85, 0x94, 0x45, 0x29, 0x8d, 0x30, 0xa7, 0xe2, 0x15, 0x46, 0xf0, 0xdd, 0xa3, 0x7d, 0x5e, 0x9c, 0x9f, 0xb7, 0x1a, 0xc4, 0xa8, 0x34, 0xad, 0x6a, 0xcc, 0xb0, 0xb0, 0x55, 0xa5, 0x96, 0x48, 0x81, 0x3e, 0x22, 0x8c, 0xcc, 0x93, 0x87, 0xda, 0x8c, 0x2f, 0xe8, 0xdd, 0x6c, 0xd0, 0xa4, 0xe2, 0xb9, 0x0f, 0xdb, 0x87, 0x15, 0xeb, 0xb9, 0xaa, 0x60, 0xb2, 0x75, 0x21, 0xf0, 0x81, 0x10, 0x0f, 0x60, 0x8d, 0x2e, 0x47, 0x9b, 0x2b, 0x16, 0x7e, 0x6d, 0x1b, 0x9d, 0xce, 0x47, 0xc9, 0x6f, 0xfb, 0xbb, 0xa3, 0x29, 0x5a, 0x9a, 0x43, 0x13, 0x13, 0x68, 0x5e, 0xf7, 0x67, 0x62, 0x29, 0x0c, 0xba, 0x1b, 0x1b, 0x1b, 0x20, 0x50, 0x2a, 0x8b, 0x09, 0xa2, 0xb7, 0x8f, 0xcf, 0xdc, 0x5e, 0xed, 0x92, 0x35, 0x9b, 0xd5, 0x3c, 0xb2, 0x9e, 0x9e, 0x1e, 0x0d, 0x5e, 0x1f, 0x53, 0x33, 0x81, 0xae, 0x07, 0x74, 0x2b, 0xc3, 0xe1, 0xc6, 0x71, 0x6c, 0x4c, 0x4e, 0x87, 0x7e, 0x5e, 0x36, 0x1f, 0x50, 0x77, 0x2f, 0xff, 0x0c, 0xf9, 0x94, 0xb0, 0xc3, 0x4a, 0xf1, 0xd4, 0xed, 0x24, 0xbe, 0x51, 0xfa, 0x9d, 0x9e, 0x32, 0x49, 0x6d, 0x5d, 0xf3, 0xfb, 0x4e, 0xff, 0x2a, 0x83, 0x0e, 0xc4, 0xef, 0xcf, 0xc5, 0xb4, 0x8c, 0x51, 0x58, 0x6c, 0xc0, 0x0b, 0xdb, 0xae, 0x0f, 0xcf, 0x67, 0x31, 0xb2, 0xe0, 0xf1, 0x7a, 0xb1, 0xfa, 0x86, 0x0a, 0x52, 0x96, 0x40, 0xeb, 0x7e, 0x39, 0xec, 0x6b, 0xf0, 0xec, 0x65, 0x15, 0x1d, 0x29, 0xe1, 0xe1, 0xe6, 0xe1, 0x39, 0x02, 0xaa, 0x70, 0x12, 0x28, 0xf4, 0xca, 0x0a, 0x63, 0x5b, 0x5b, 0x3d, 0x92, 0x2b, 0x7d, 0x9a, 0x24, 0x52, 0x01, 0x01, 0x3d, 0xd9, 0xbd, 0xfd, 0x7d, 0x38, 0x80, 0xdd, 0x6f, 0x8f, 0x17, 0xca, 0x87, 0xeb, 0xe6, 0x9e, 0xc3, 0x16, 0x08, 0x84, 0xdf, 0xb2, 0x1f, 0x0e, 0xcb, 0x3d, 0x98, 0x58, 0x3f, 0xa9, 0xb9, 0xdf, 0xdd, 0x51, 0xad, 0xcf, 0x1e, 0x45, 0x89, 0x2f, 0x6d, 0x7c, 0x47, 0x2d, 0x59, 0x7a, 0xca, 0xcf, 0x97, 0xf6, 0xd0, 0x52, 0xfc, 0x25, 0x44, 0x2d, 0xb1, 0xfd, 0x36, 0x4b, 0x61, 0x8e, 0x4d, 0x56, 0x70, 0x67, 0x4a, 0xa7, 0x16, 0x15, 0xd7, 0xbf, 0xc5, 0x2b, 0x8f, 0x1d, 0x59, 0xc8, 0x8e, 0x4c, 0xa6, 0x54, 0x67, 0x74, 0x1e, 0x4b, 0x1c, 0xcc, 0x9d, 0x00, 0xc7, 0x59, 0x36, 0x5b, 0x39, 0x62, 0x00, 0x86, 0x0d, 0x93, 0x4b, 0x31, 0xfd, 0x5c, 0xab, 0x41, 0x57, 0x6f, 0x55, 0x92, 0x35, 0x9d, 0x1b, 0x13, 0x33, 0xb2, 0x32, 0x43, 0x1a, 0x0f, 0x3f, 0x30, 0x50, 0x04, 0x61, 0x57, 0xa9, 0xd5, 0x10, 0xd8, 0xd6, 0xc6, 0x0b, 0xca, 0x75, 0xda, 0xff, 0x6b, 0xe9, 0x34, 0xea, 0x25, 0x72, 0x84, 0x49, 0x8c, 0x86, 0xeb, 0x5d, 0xf7, 0xd2, 0x81, 0x78, 0x76, 0x9f, 0x6f, 0xc4, 0xec, 0xbb, 0xe4, 0xf6, 0x47, 0xbc, 0xca, 0x2d, 0xbd, 0x78, 0x14, 0xec, 0xec, 0x9b, 0x2d, 0x42, 0x52, 0x9d, 0x33, 0x0b, 0x21, 0x92, 0x10, 0x0c, 0x76, 0x16, 0x89, 0xd9, 0xb8, 0xf6, 0x79, 0xfe, 0xef, 0x47, 0x5c, 0xce, 0x94, 0xf3, 0x88, 0x56, 0x68, 0xfc, 0xef, 0xa4, 0x45, 0xa3, 0x3a, 0xcd, 0x54, 0xae, 0x76, 0xce, 0x35, 0x22, 0xce, 0x9a, 0x29, 0x02, 0x27, 0x10, 0xba, 0x74, 0x21, 0x35, 0x0d, 0x26, 0xba, 0x99, 0x85, 0x45, 0x69, 0x4a, 0x62, 0x79, 0xa8, 0x90, 0xb5, 0x35, 0xdd, 0xd9, 0x6a, 0x5b, 0x58, 0x89, 0x7c, 0xce, 0xd6, 0xd1, 0x5c, 0x39, 0x97, 0xcb, 0x11, 0xd6, 0x7c, 0x85, 0x66, 0x01, 0xc7, 0xd0, 0x4c, 0x5d, 0xfd, 0x02, 0x7f, 0xca, 0x28, 0x4c, 0xca, 0xa8, 0x2a, 0x7f, 0x94, 0xb4, 0x4c, 0xa5, 0xba, 0xcf, 0xe8, 0xcc, 0xd4, 0xc2, 0xe7, 0x72, 0x1c, 0xb9, 0x72, 0x74, 0x38, 0xc7, 0xc3, 0x3d, 0x28, 0xef, 0xb7, 0x55, 0x06, 0x2c, 0x1c, 0x75, 0x7d, 0xd4, 0xfb, 0x83, 0x96, 0x63, 0xc9, 0x09, 0x9a, 0x08, 0x28, 0x83, 0xba, 0x90, 0x78, 0xa1, 0x48, 0x0d, 0xb3, 0x11, 0x8c, 0x74, 0x3e, 0x94, 0xb6, 0x3f, 0x70, 0x79, 0x44, 0xf6, 0x9b, 0xb5, 0x4b, 0xf9, 0x13, 0x45, 0xd3, 0xa9, 0x8f, 0x20, 0xdd, 0xbc, 0xd5, 0x44, 0x85, 0xee, 0xa1, 0x32, 0xb1, 0x99, 0xa9, 0xba, 0x84, 0x1c, 0x81, 0xc4, 0x19, 0x24, 0x8c, 0x34, 0x42, 0x44, 0x0f, 0x0b, 0x68, 0x77, 0xe3, 0x17, 0x0c, 0x63, 0x20, 0x9a, 0x24, 0x97, 0x3f, 0x7f, 0xfe, 0x4c, 0x76, 0xfa, 0xdc, 0xca, 0xaa, 0x21, 0x22, 0x4a, 0xad, 0x1e, 0x15, 0x17, 0x17, 0x33, 0x71, 0x70, 0x88, 0xeb, 0xe9, 0x45, 0xa8, 0x3f, 0xf5, 0x6c, 0xbb, 0x4b, 0x9a, 0x38, 0x5e, 0x78, 0xac, 0x94, 0xe9, 0x2d, 0x70, 0xe7, 0xe9, 0xfe, 0xdb, 0xcc, 0xa1, 0xa7, 0xad, 0xb9, 0x3e, 0x57, 0xe6, 0xb2, 0x27, 0xc5, 0xb8, 0x29, 0x4f, 0x78, 0xec, 0x51, 0x56, 0x47, 0xbf, 0xbe, 0x81, 0x69, 0xac, 0x4a, 0x47, 0x92, 0xbe, 0x1e, 0x19, 0xfd, 0xaf, 0x53, 0x72, 0x58, 0xe1, 0x35, 0xad, 0x98, 0x7b, 0xc7, 0x59, 0x6e, 0xf2, 0xeb, 0x4e, 0xb0, 0xdc, 0x6f, 0x0c, 0xa2, 0x89, 0x36, 0x46, 0x31, 0x13, 0x01, 0x15, 0x1a, 0x56, 0x5c, 0x75, 0xd3, 0xb1, 0x36, 0xe7, 0x8b, 0xc1, 0x80, 0x4a, 0xda, 0xf4, 0x44, 0x80, 0x2b, 0x56, 0xda, 0x45, 0x12, 0x5d, 0x1a, 0xd5, 0xe6, 0x75, 0x0a, 0xf3, 0x58, 0x0d, 0xba, 0x41, 0x0f, 0xcf, 0xcf, 0x0b, 0xa3, 0x7a, 0xc6, 0x83, 0xd1, 0x8a, 0x04, 0x4e, 0x5c, 0x45, 0xfb, 0xc8, 0x11, 0x2a, 0xb0, 0x11, 0x2a, 0xef, 0x5f, 0xff, 0xc9, 0x8d, 0xdb, 0xd4, 0x9e, 0x04, 0x5d, 0x3e, 0xac, 0xf7, 0x96, 0x5a, 0xaa, 0xee, 0x66, 0xf7, 0x53, 0x19, 0xdf, 0xc6, 0xf9, 0xa9, 0x3c, 0xae, 0xf5, 0x51, 0x21, 0x54, 0xbf, 0xf5, 0x0f, 0x6f, 0x3b, 0x66, 0xc4, 0x1b, 0xb1, 0x40, 0x67, 0x89, 0xc8, 0x1d, 0x04, 0x23, 0x72, 0x71, 0x8f, 0xb3, 0xcb, 0xca, 0xbe, 0x1e, 0xe3, 0xa6, 0x9d, 0x5c, 0xda, 0x0b, 0x69, 0x6e, 0x4a, 0xe7, 0x84, 0xa4, 0x31, 0x9b, 0x46, 0xe3, 0x85, 0x33, 0x7f, 0xe2, 0x27, 0x30, 0x91, 0x02, 0x80, 0xe0, 0xfd, 0xa0, 0x65, 0x79, 0x71, 0x49, 0x93, 0x77, 0x9c, 0x17, 0x19, 0x81, 0x21, 0x25, 0xea, 0x6f, 0x16, 0xef, 0x87, 0x20, 0xf2, 0xac, 0x8f, 0x0e, 0x0f, 0x97, 0xf6, 0x72, 0xd1, 0xd2, 0x1e, 0xcf, 0x85, 0x07, 0xe8, 0x54, 0xad, 0x7a, 0x3f, 0xb4, 0xa2, 0xaf, 0xd1, 0xc2, 0xab, 0xed, 0x51, 0xba, 0x63, 0xe4, 0x04, 0xbe, 0x0e, 0x31, 0x92, 0x1e, 0x9a, 0x50, 0xca, 0xe9, 0xb6, 0x87, 0x08, 0x09, 0xca, 0x47, 0x13, 0x4e, 0xea, 0x8e, 0x6b, 0x7f, 0x9b, 0x61, 0xcb, 0xe6, 0xf3, 0x5b, 0xe5, 0xcc, 0xbe, 0x16, 0xa5, 0xf4, 0xfa, 0x32, 0x17, 0x37, 0x1f, 0x5c, 0x0c, 0x09, 0x48, 0xfe, 0xc8, 0x66, 0xef, 0x77, 0xd9, 0xd7, 0xeb, 0x1a, 0x91, 0x78, 0x96, 0x3f, 0x2c, 0xc6, 0x6b, 0x45, 0x41, 0x9c, 0x77, 0x36, 0x7a, 0xa1, 0x08, 0x7d, 0xbd, 0xe9, 0x85, 0xcc, 0x70, 0x52, 0x52, 0x81, 0xc9, 0x62, 0xa5, 0x2a, 0x1f, 0x85, 0xcf, 0x62, 0xbd, 0xc8, 0x94, 0x85, 0x3b, 0x6a, 0x58, 0xab, 0x31, 0xd7, 0xba, 0x83, 0x07, 0x8b, 0x4e, 0xd0, 0x8d, 0xd0, 0x41, 0xa7, 0xcb, 0xe3, 0x6e, 0x7c, 0x15, 0x2e, 0xb0, 0xf8, 0x36, 0x07, 0x59, 0xef, 0xc8, 0x30, 0x0c, 0xab, 0xd1, 0xe0, 0xc1, 0xd8, 0x78, 0xc6, 0x0f, 0x9b, 0x5e, 0xac, 0x7a, 0x8d, 0xf1, 0x6b, 0x26, 0x3e, 0x43, 0x1f, 0x1e, 0x64, 0x50, 0x1b, 0x4c, 0x7e, 0x9f, 0x99, 0xeb, 0x04, 0x88, 0x1f, 0x08, 0x94, 0xce, 0xb9, 0xde, 0xb3, 0xe9, 0xa8, 0xdd, 0x01, 0x55, 0xa8, 0xaf, 0x40, 0xad, 0xe4, 0xa5, 0xc6, 0x61, 0x36, 0x96, 0x8b, 0xfe, 0x72, 0xd1, 0x85, 0x66, 0x60, 0x66, 0xa3, 0x38, 0xb1, 0x8c, 0x87, 0x53, 0x9a, 0xc6, 0x6d, 0xb9, 0x0d, 0x48, 0xcf, 0x21, 0xf0, 0xc8, 0xe9, 0x6a, 0x7d, 0x41, 0xeb, 0xa5, 0x3f, 0x62, 0x25, 0x5e, 0x32, 0xd9, 0x7c, 0x2d, 0x81, 0x61, 0x05, 0x27, 0x5f, 0x53, 0xf2, 0x7f, 0x4b, 0x29, 0x0f, 0x21, 0x43, 0xf0, 0x12, 0x20, 0x79, 0x37, 0xb8, 0xf3, 0x68, 0xd0, 0xe1, 0x80, 0x43, 0x7b, 0x92, 0xf9, 0x25, 0x98, 0x1d, 0xde, 0xb4, 0x56, 0xa2, 0x22, 0xbe, 0x79, 0x2b, 0xe1, 0xe3, 0x54, 0xbf, 0xee, 0xce, 0xcd, 0x21, 0x0f, 0xd4, 0x2c, 0xc5, 0xee, 0xbc, 0x7d, 0x3c, 0x77, 0x34, 0x0b, 0xd4, 0x9d, 0x94, 0x95, 0xdd, 0xe9, 0x5c, 0xa2, 0xf4, 0xe8, 0xe8, 0x6d, 0x22, 0xff, 0x35, 0xb2, 0x77, 0x31, 0x3c, 0x5b, 0x83, 0xc9, 0xf8, 0x47, 0x01, 0x32, 0xa8, 0x9c, 0x5e, 0x6d, 0xaf, 0xd8, 0x72, 0x3b, 0x3a, 0x3a, 0x9a, 0xc6, 0x94, 0xc3, 0x9b, 0x94, 0x94, 0xd4, 0xc0, 0xc8, 0x28, 0x30, 0x3f, 0x9f, 0xb4, 0xb2, 0x7a, 0xb5, 0x54, 0xb9, 0x04, 0xd1, 0x63, 0x1f, 0xb4, 0xb1, 0xb5, 0x15, 0xc8, 0xeb, 0x76, 0x06, 0xa2, 0x7e, 0x5c, 0x62, 0xdd, 0xc9, 0xe1, 0x76, 0x4b, 0xd9, 0x03, 0x4f, 0xb2, 0xa2, 0x0f, 0xfd, 0xd5, 0x85, 0x03, 0x89, 0x0a, 0x7e, 0xef, 0x4e, 0x0c, 0x39, 0x1e, 0x19, 0xdf, 0xea, 0x60, 0x62, 0xbd, 0x6e, 0xcd, 0xc8, 0xfa, 0xac, 0xea, 0x00, 0x01, 0x29, 0x1c, 0xf5, 0x13, 0xd3, 0x33, 0x61, 0x30, 0x62, 0x60, 0x9b, 0xdb, 0x0f, 0xa1, 0x90, 0x42, 0xdd, 0x64, 0x4c, 0xf7, 0xf3, 0x69, 0xad, 0xcb, 0x9c, 0x8e, 0xf7, 0xcb, 0x19, 0xd8, 0x3e, 0xfd, 0x77, 0x54, 0x07, 0x5f, 0x47, 0x9b, 0x1b, 0xa8, 0x3c, 0x3a, 0x3e, 0x7e, 0x74, 0x57, 0xab, 0xda, 0xcb, 0x96, 0x5a, 0x43, 0x5b, 0x7b, 0xfb, 0xb8, 0xba, 0x6b, 0xfe, 0xa9, 0x95, 0xd5, 0x74, 0xac, 0x3b, 0x04, 0x09, 0xd7, 0xc0, 0xc4, 0x44, 0x75, 0x53, 0x53, 0x13, 0xca, 0x96, 0x94, 0x8d, 0x65, 0x11, 0x93, 0x47, 0x21, 0xff, 0xf8, 0x8a, 0x1b, 0x73, 0xb2, 0xc4, 0x6b, 0xa8, 0xcc, 0x94, 0x49, 0xa7, 0x6a, 0xbb, 0xf7, 0xe4, 0x44, 0xf0, 0x90, 0x86, 0x12, 0x1d, 0x5e, 0x2b, 0x28, 0x73, 0x32, 0x83, 0x09, 0x4b, 0xb5, 0x46, 0x8e, 0x72, 0x34, 0x47, 0x7f, 0x89, 0x95, 0x80, 0xd6, 0x29, 0x1a, 0x15, 0xad, 0xa7, 0x70, 0xb3, 0x83, 0xb6, 0x3e, 0xc9, 0xfa, 0xa8, 0xb9, 0x8d, 0xcd, 0xd4, 0xc5, 0x28, 0xfa, 0xff, 0xee, 0x02, 0x84, 0x09, 0x75, 0xab, 0xb3, 0x9b, 0x7d, 0xa5, 0xa6, 0x16, 0xd2, 0xd1, 0x21, 0xe4, 0xe3, 0xe7, 0xbf, 0xad, 0x48, 0xb3, 0x4d, 0x65, 0x36, 0x86, 0xe5, 0x22, 0x44, 0xdd, 0x1b, 0xcf, 0x08, 0x7b, 0x79, 0x69, 0xbd, 0xa5, 0x6e, 0xaa, 0xad, 0xed, 0xc9, 0xe6, 0xf7, 0x9a, 0x6c, 0xb2, 0xd3, 0xa7, 0xb7, 0x28, 0xf1, 0x7b, 0xe0, 0x63, 0x98, 0xa7, 0xcb, 0x46, 0xdd, 0xd7, 0x6d, 0x5c, 0x7c, 0xdb, 0x47, 0x68, 0x30, 0xc3, 0xa2, 0x88, 0xfe, 0x35, 0xba, 0x7d, 0x77, 0xfc, 0x9d, 0x5d, 0x04, 0xf3, 0xe3, 0xd9, 0xd4, 0x90, 0x01, 0xef, 0x3f, 0x42, 0xbf, 0xbe, 0xd4, 0xfc, 0x31, 0x0b, 0x7a, 0x76, 0x1e, 0xe8, 0xc9, 0x11, 0x18, 0xfa, 0xb7, 0x0d, 0x3b, 0xbf, 0x94, 0x0a, 0xe0, 0x76, 0x20, 0xe9, 0xa7, 0x48, 0xd1, 0xa3, 0x5b, 0x36, 0x51, 0x23, 0x04, 0x22, 0x41, 0x79, 0x96, 0xf0, 0x44, 0x72, 0x59, 0xa6, 0x4f, 0x88, 0xb3, 0x83, 0x5f, 0xbf, 0x7e, 0xf5, 0x9c, 0x16, 0xbd, 0x07, 0xf8, 0x16, 0xc8, 0xf0, 0xd6, 0xe3, 0xf5, 0xbe, 0x46, 0x9d, 0x29, 0x8a, 0xb5, 0x0d, 0xfb, 0xb1, 0xd9, 0xf9, 0xce, 0x4e, 0x70, 0x14, 0x2e, 0x63, 0xe7, 0x54, 0x6a, 0xca, 0x6b, 0x53, 0x22, 0x6d, 0xe2, 0xcf, 0xe1, 0x5d, 0xfc, 0x53, 0xf5, 0x9c, 0x1a, 0x0d, 0xba, 0xb1, 0x6c, 0x36, 0x68, 0x81, 0x4a, 0xdd, 0xb9, 0x1d, 0x64, 0xb2, 0xbb, 0x6d, 0x47, 0x1f, 0xbe, 0x9b, 0x02, 0xec, 0xbc, 0x52, 0x61, 0xb9, 0x03, 0x59, 0xf4, 0x48, 0x47, 0x47, 0xcc, 0x28, 0x63, 0x5f, 0x68, 0x73, 0x76, 0xe2, 0xd6, 0x90, 0x34, 0x04, 0x81, 0x1c, 0x4e, 0x04, 0x12, 0xfc, 0x9d, 0xa4, 0x7d, 0x5c, 0x9c, 0x6d, 0x5b, 0x67, 0x42, 0x22, 0xbe, 0x58, 0x09, 0x23, 0x29, 0xcf, 0xef, 0x9c, 0x2c, 0xe9, 0xe2, 0xa6, 0xb6, 0x10, 0x7f, 0x9c, 0xae, 0x7a, 0x8c, 0x6a, 0x0d, 0x5e, 0x46, 0x7c, 0x8e, 0x36, 0xf7, 0xc2, 0xff, 0xa1, 0x65, 0x7f, 0xe9, 0xaa, 0x01, 0x03, 0xd0, 0xb1, 0x42, 0x78, 0x3a, 0x35, 0xd2, 0x00, 0x93, 0x49, 0x68, 0xbd, 0x79, 0xb6, 0x4c, 0x08, 0x61, 0xa3, 0x4d, 0x50, 0x9f, 0x81, 0x0d, 0x0a, 0x0c, 0x5a, 0x36, 0x7a, 0xef, 0xc2, 0x55, 0xdd, 0xfe, 0xef, 0x3f, 0x49, 0xc0, 0xba, 0x1c, 0x29, 0x92, 0xad, 0x1a, 0x9b, 0x98, 0x84, 0x88, 0x45, 0xe1, 0x6c, 0x66, 0xb9, 0xad, 0xf5, 0x00, 0x39, 0x73, 0xd8, 0xe8, 0x86, 0xe8, 0xef, 0xef, 0x17, 0xa2, 0xc3, 0x51, 0xd7, 0x86, 0x6d, 0x70, 0x39, 0x9e, 0x07, 0xf3, 0xba, 0xd2, 0x99, 0x4e, 0x64, 0xeb, 0x16, 0x30, 0x42, 0x15, 0x7d, 0xb5, 0xa2, 0x60, 0x9f, 0x23, 0x90, 0xd2, 0x07, 0x45, 0xe6, 0x33, 0x79, 0x5d, 0xa1, 0x7b, 0xd7, 0xbc, 0x78, 0x51, 0xab, 0xa4, 0xa1, 0xb1, 0x0d, 0x30, 0x69, 0xe6, 0x34, 0x58, 0xd4, 0x39, 0x28, 0x59, 0x9f, 0x10, 0x6e, 0xb9, 0x52, 0x1d, 0x60, 0xf5, 0xc5, 0x70, 0x90, 0x98, 0x7f, 0x66, 0xac, 0x3e, 0xd7, 0x94, 0xcf, 0xae, 0x88, 0xca, 0x3d, 0xbc, 0x41, 0x41, 0x26, 0x53, 0x2c, 0x0f, 0xc5, 0x38, 0x38, 0x8f, 0xd8, 0x75, 0xa2, 0xec, 0x1e, 0xce, 0x33, 0x2d, 0x61, 0x4c, 0xd3, 0x09, 0xb8, 0x19, 0xd3, 0x21, 0x2f, 0x32, 0xdd, 0xba, 0x48, 0xa3, 0xe5, 0xf2, 0xda, 0xcd, 0x9e, 0xbf, 0x0a, 0xf1, 0xe0, 0x63, 0xf0, 0xd6, 0x6e, 0x23, 0xe5, 0x9a, 0xc4, 0x85, 0xf2, 0x84, 0xcd, 0x4b, 0xab, 0x74, 0x2d, 0x4b, 0xb6, 0x48, 0xe0, 0x9d, 0x9a, 0x60, 0x3a, 0x2d, 0x98, 0xf6, 0xaf, 0xba, 0xb8, 0xb0, 0x27, 0xe4, 0xf7, 0x54, 0x89, 0xc3, 0x3f, 0x84, 0x0b, 0x35, 0xbc, 0x78, 0x79, 0x74, 0xd2, 0x69, 0x71, 0x84, 0x71, 0x3b, 0x5b, 0x11, 0x36, 0x32, 0xca, 0x3f, 0x3a, 0x22, 0xa1, 0xa2, 0x82, 0xf3, 0x79, 0xbe, 0x1b, 0xf8, 0x49, 0xf2, 0x6d, 0x36, 0x72, 0x40, 0x45, 0x42, 0x4f, 0x8f, 0xa8, 0xa2, 0xb2, 0x52, 0xf5, 0x50, 0xbf, 0xad, 0x53, 0x33, 0xba, 0x31, 0xbb, 0xaa, 0x55, 0x49, 0x9f, 0x6a, 0xa5, 0xf9, 0x1d, 0x5c, 0xee, 0xf7, 0xf0, 0xf9, 0xd2, 0xc4, 0x33, 0xd7, 0xa9, 0x85, 0xde, 0x95, 0x06, 0x2b, 0x79, 0x06, 0x6f, 0x8f, 0x84, 0xf9, 0x08, 0x3a, 0x4b, 0x18, 0xd9, 0x13, 0x53, 0xf8, 0xcb, 0xc1, 0x39, 0x5d, 0xbc, 0xce, 0xea, 0x20, 0xd3, 0xa3, 0xe5, 0x9b, 0x1c, 0x43, 0x58, 0x4c, 0xcb, 0x8c, 0xc4, 0x46, 0x65, 0x4f, 0x87, 0x25, 0x96, 0xec, 0x0b, 0x0b, 0x19, 0x9c, 0xf6, 0x3d, 0xe1, 0x40, 0xda, 0xa8, 0x9b, 0x8a, 0xdb, 0x7f, 0xad, 0xc1, 0xa3, 0x9b, 0xb9, 0x4e, 0xcf, 0x1c, 0x07, 0xb8, 0x18, 0xe1, 0x6f, 0x24, 0x10, 0x1b, 0x35, 0x28, 0x64, 0x4c, 0xf2, 0xa5, 0x85, 0x53, 0x6e, 0xd3, 0x46, 0x3f, 0xf6, 0x93, 0x13, 0xe9, 0x1b, 0x9a, 0x9a, 0x24, 0xb4, 0xb4, 0x96, 0x09, 0xd6, 0x48, 0xdb, 0x23, 0x32, 0x38, 0xed, 0x48, 0xa9, 0xa9, 0x25, 0xd9, 0xcf, 0x16, 0xc8, 0x40, 0x56, 0x38, 0x13, 0x93, 0x05, 0xe2, 0xe9, 0xf1, 0xfa, 0x0a, 0xd1, 0xf1, 0xe7, 0x3e, 0x01, 0x63, 0x99, 0xd3, 0xa9, 0x50, 0x38, 0xa3, 0x9b, 0x68, 0x7e, 0xef, 0xfc, 0xdb, 0xe7, 0x6b, 0x28, 0x14, 0xe2, 0x59, 0xb9, 0x98, 0xc8, 0xdb, 0x33, 0xf1, 0xb9, 0xca, 0xc1, 0xbd, 0xae, 0xac, 0xe4, 0xbf, 0x08, 0xde, 0x59, 0xa2, 0x25, 0xe9, 0x2d, 0xcb, 0x8b, 0xea, 0xa0, 0x3a, 0x35, 0x39, 0x90, 0x7c, 0x5a, 0xdd, 0xdc, 0x0b, 0x98, 0xd5, 0xa9, 0x93, 0xb8, 0x9c, 0x9f, 0x68, 0x04, 0xde, 0x2c, 0x09, 0xce, 0x06, 0xfa, 0xe7, 0xb4, 0x6f, 0x19, 0xd2, 0x8b, 0x2f, 0xb7, 0x4c, 0x60, 0xff, 0xea, 0xb6, 0x84, 0x29, 0xa7, 0xd8, 0x06, 0x8d, 0x9b, 0x16, 0x24, 0xd5, 0x05, 0xad, 0x91, 0x9d, 0x69, 0xd2, 0x21, 0xd6, 0x3a, 0x30, 0x5e, 0xd0, 0xe5, 0x15, 0xda, 0xb9, 0x3b, 0x38, 0x30, 0x0f, 0xc6, 0x11, 0xa3, 0x59, 0x59, 0x59, 0x75, 0x1c, 0xcd, 0x4d, 0x2e, 0x75, 0x78, 0x71, 0xfe, 0xcd, 0xe4, 0x2e, 0xc0, 0xbf, 0x3f, 0xfe, 0xe4, 0x1f, 0x6b, 0x43, 0xb0, 0x86, 0x5d, 0xff, 0x29, 0x07, 0x8e, 0x62, 0x7c, 0xe3, 0x69, 0x75, 0x1a, 0x1f, 0x06, 0x59, 0x79, 0x27, 0x23, 0xc1, 0x49, 0x31, 0x5f, 0x65, 0x4f, 0xec, 0x48, 0x91, 0x5d, 0x84, 0x2c, 0x74, 0x25, 0x8f, 0xd3, 0x68, 0x65, 0x35, 0x65, 0x63, 0x20, 0xca, 0x47, 0x5a, 0x34, 0xff, 0xf7, 0x3b, 0x44, 0xfd, 0x11, 0xe9, 0xf4, 0xac, 0x68, 0x78, 0x9a, 0x31, 0x9c, 0xc1, 0x58, 0x6e, 0xb6, 0x9d, 0xb5, 0xa7, 0x30, 0x2b, 0x32, 0xc3, 0xaa, 0xbb, 0x7f, 0xa5, 0x57, 0x1c, 0xc9, 0x9e, 0x85, 0x51, 0x83, 0x93, 0xae, 0x8e, 0x0e, 0x3a, 0x0e, 0x0e, 0xac, 0xbc, 0xbc, 0x7c, 0xbd, 0xf9, 0x14, 0xa4, 0x63, 0x0b, 0x61, 0x69, 0x69, 0x29, 0x3c, 0x3c, 0x3c, 0x28, 0x6a, 0x40, 0x44, 0x4e, 0xce, 0x42, 0x18, 0x27, 0x4d, 0xa6, 0x18, 0xd1, 0xf7, 0x97, 0x54, 0x91, 0xfb, 0xdd, 0x09, 0xde, 0xf4, 0xcc, 0x4c, 0x7c, 0x5a, 0x5a, 0xc4, 0xe2, 0xa2, 0x86, 0x24, 0x39, 0x46, 0x43, 0x99, 0xb6, 0xd0, 0xf7, 0xdd, 0xca, 0x8f, 0x43, 0x09, 0x3b, 0xbf, 0x9c, 0xc1, 0x5f, 0x4b, 0x76, 0x79, 0x4e, 0xbc, 0x8c, 0x07, 0xac, 0x62, 0x4b, 0x0b, 0x33, 0x28, 0x43, 0x8c, 0x2b, 0x2a, 0x31, 0xd5, 0x3a, 0x2d, 0x90, 0x68, 0x71, 0xa1, 0x66, 0xde, 0xc8, 0x11, 0xc1, 0xc1, 0xd0, 0x0d, 0xb5, 0x71, 0x12, 0x7d, 0xf4, 0xe5, 0xbc, 0x0c, 0xf9, 0x54, 0x55, 0x6b, 0xb1, 0x3d, 0x31, 0xcf, 0xb5, 0x34, 0x69, 0x32, 0x77, 0x5b, 0x98, 0x0c, 0x0b, 0xfb, 0xc4, 0x2d, 0x7c, 0x4f, 0x11, 0x44, 0xaa, 0x64, 0x6c, 0x4a, 0xe1, 0xa3, 0x1d, 0xf1, 0x5b, 0x5b, 0x57, 0x09, 0x97, 0x51, 0xb8, 0x39, 0xde, 0x7d, 0x4c, 0xdc, 0xac, 0x8a, 0xc5, 0x49, 0xff, 0xfd, 0xec, 0xd4, 0x65, 0xb6, 0x5b, 0xb6, 0xd7, 0x48, 0x55, 0x5d, 0xfb, 0x7c, 0xc4, 0x1e, 0x22, 0x46, 0xfa, 0x72, 0x7b, 0x4e, 0x41, 0xc8, 0xe7, 0x82, 0xc7, 0xa8, 0xa7, 0xa6, 0xcb, 0x35, 0x30, 0x3d, 0x8d, 0x01, 0xd8, 0xea, 0xee, 0x60, 0x04, 0x4c, 0x40, 0x2e, 0xf3, 0xd9, 0x5f, 0x9d, 0x9c, 0x9c, 0x1c, 0x4e, 0x16, 0x99, 0x09, 0x79, 0x9c, 0xe1, 0x87, 0xe2, 0x88, 0xd5, 0x8f, 0x73, 0x50, 0x12, 0xa1, 0xbf, 0x84, 0xdc, 0x1f, 0x05, 0xa3, 0x15, 0x23, 0x87, 0x74, 0xc4, 0xf8, 0xd2, 0x2c, 0xf0, 0x4b, 0x7b, 0x47, 0xc4, 0xd7, 0x75, 0x2a, 0xc4, 0xc0, 0xa1, 0xe0, 0x07, 0x93, 0x49, 0xc4, 0x1e, 0x88, 0xa5, 0x0c, 0xfa, 0x2b, 0x95, 0x06, 0x37, 0x35, 0x71, 0x66, 0xf3, 0x7d, 0x6d, 0x70, 0x19, 0xf2, 0x7d, 0xc4, 0xa0, 0x4f, 0x5f, 0x3a, 0x50, 0x2c, 0x6f, 0x25, 0x49, 0x1a, 0xfe, 0xd8, 0xde, 0x77, 0xb8, 0x95, 0x8b, 0x96, 0x12, 0x57, 0x1c, 0x74, 0xc3, 0x1b, 0xe4, 0x00, 0x49, 0x7e, 0xa9, 0x72, 0x0b, 0x54, 0x23, 0x81, 0xed, 0xf8, 0xb4, 0x75, 0xda, 0x11, 0xf6, 0xfa, 0x70, 0xb9, 0x22, 0x98, 0x38, 0x32, 0x16, 0x5f, 0x6d, 0xc2, 0xa1, 0xb6, 0xf7, 0x70, 0xd2, 0x17, 0x71, 0x40, 0xb4, 0xa1, 0x5c, 0xe9, 0xa5, 0x4b, 0x17, 0x6f, 0x74, 0x1f, 0x50, 0xb7, 0xe8, 0x73, 0x61, 0x1d, 0x92, 0xbe, 0x2b, 0x34, 0xfc, 0xb5, 0x5d, 0xb9, 0x44, 0xee, 0xe2, 0xee, 0x4e, 0x5c, 0x41, 0x01, 0xbd, 0xd5, 0xed, 0x1c, 0x55, 0x59, 0x79, 0x46, 0x4a, 0x6d, 0x9a, 0x08, 0x80, 0x29, 0x2a, 0xf9, 0xec, 0xfe, 0x1c, 0xbf, 0xb7, 0x08, 0x28, 0x38, 0x54, 0x21, 0x4a, 0x5a, 0x59, 0x17, 0x4c, 0xc4, 0x07, 0x30, 0x7b, 0x0d, 0x5c, 0x71, 0xf4, 0x89, 0xba, 0x09, 0x92, 0xb4, 0xae, 0xf0, 0x0c, 0x9b, 0xc8, 0xba, 0x56, 0x70, 0x7b, 0xe0, 0x2f, 0x1a, 0x4b, 0x2c, 0xb1, 0xcd, 0x81, 0x28, 0x5c, 0x7b, 0x67, 0xe7, 0x0a, 0x75, 0x7e, 0x7c, 0x24, 0x80, 0x47, 0x45, 0x00, 0x26, 0x56, 0x31, 0x06, 0xb4, 0x37, 0x73, 0xed, 0x36, 0x49, 0x58, 0x3d, 0xb2, 0x1c, 0xe1, 0xeb, 0xa1, 0x26, 0x98, 0x65, 0xbb, 0x8e, 0x25, 0xfe, 0x1c, 0x94, 0x72, 0x7c, 0x95, 0xa6, 0x93, 0xfd, 0x20, 0xc6, 0x5e, 0xfd, 0x09, 0xbe, 0xe1, 0xa3, 0x36, 0x58, 0x5e, 0x5e, 0x5c, 0x49, 0x39, 0x5c, 0x87, 0x61, 0x8b, 0x58, 0x6c, 0x9e, 0xac, 0xd2, 0xaa, 0x4b, 0x08, 0x7c, 0xb5, 0xf8, 0x71, 0xd7, 0xce, 0xfe, 0xce, 0xf9, 0x72, 0xe9, 0xb5, 0x7c, 0x8e, 0x41, 0x13, 0x7c, 0x87, 0x30, 0x63, 0x58, 0x0f, 0x51, 0x29, 0xce, 0x7e, 0x1e, 0xdd, 0x75, 0xac, 0xb5, 0x5e, 0x62, 0x39, 0x59, 0x6d, 0xc3, 0xb5, 0xeb, 0xb8, 0xc5, 0xf1, 0xbc, 0x3b, 0x41, 0x40, 0x43, 0x43, 0xcb, 0xe2, 0x3c, 0x77, 0xef, 0x68, 0x4a, 0x49, 0xc1, 0x15, 0x8f, 0x25, 0x8c, 0xc0, 0x63, 0x35, 0xcd, 0xad, 0xa9, 0x41, 0x57, 0x54, 0x54, 0xcc, 0xb5, 0xc0, 0x77, 0x0c, 0xc1, 0xb8, 0x27, 0xe6, 0x1f, 0x1a, 0x8e, 0x6a, 0xda, 0xf8, 0x37, 0x88, 0x3d, 0x6e, 0x4d, 0xab, 0x46, 0x34, 0x83, 0x0d, 0xc4, 0x3b, 0x1f, 0x44, 0x65, 0x49, 0x14, 0xed, 0xef, 0x0f, 0xaa, 0x07, 0x4c, 0xd4, 0x9a, 0xb3, 0xb9, 0xcc, 0xc9, 0x4a, 0x0b, 0x26, 0x2e, 0x83, 0x8e, 0x42, 0x8c, 0x76, 0x1b, 0xb7, 0x91, 0x46, 0x97, 0xed, 0x93, 0xb2, 0xa4, 0x74, 0x6a, 0x1a, 0x7c, 0x7c, 0x5a, 0x42, 0xb5, 0xab, 0x89, 0xd8, 0x8c, 0x18, 0x3f, 0x00, 0xee, 0x08, 0x52, 0x26, 0x8d, 0x67, 0xff, 0x96, 0x3e, 0xa5, 0x23, 0xf7, 0xe7, 0x72, 0x92, 0xbe, 0xbc, 0xca, 0xd7, 0x18, 0x1b, 0xed, 0x55, 0xa9, 0x53, 0x2b, 0xa9, 0xcc, 0xad, 0x8b, 0xa3, 0xc2, 0x0f, 0xa6, 0x0f, 0xb0, 0x1a, 0xd8, 0x5a, 0xea, 0xec, 0x7a, 0xb5, 0x3c, 0x8a, 0x2d, 0xde, 0x1c, 0x0b, 0x57, 0xac, 0xb6, 0x56, 0x4f, 0x2b, 0x7b, 0xd8, 0xdb, 0x33, 0x7d, 0xec, 0x27, 0x0c, 0x27, 0x50, 0x05, 0x8d, 0x56, 0xbe, 0xfd, 0xd5, 0x5d, 0x48, 0x4d, 0x4f, 0x07, 0xe6, 0x2a, 0xe4, 0xf6, 0x60, 0xcc, 0x37, 0x60, 0xee, 0x64, 0x0b, 0xf8, 0x20, 0x82, 0xa8, 0x31, 0x22, 0x1c, 0x6e, 0x4e, 0xd8, 0xed, 0x9b, 0x09, 0x1f, 0xbc, 0x1a, 0x2a, 0x9a, 0x94, 0x75, 0xe5, 0x7c, 0x49, 0xaa, 0x56, 0x18, 0x5c, 0x4a, 0xb4, 0xb4, 0xb4, 0x8c, 0x2e, 0x36, 0x7a, 0x6e, 0xff, 0xb8, 0x19, 0x6f, 0x01, 0xa8, 0x93, 0x2a, 0xe0, 0xd3, 0x5a, 0x16, 0x5c, 0x15, 0x51, 0x0b, 0x2a, 0xc7, 0x95, 0xb5, 0x62, 0x8b, 0xf1, 0x5f, 0x7e, 0xae, 0xef, 0x05, 0x44, 0x45, 0x41, 0x81, 0xda, 0x93, 0xc2, 0x90, 0x3a, 0x1d, 0xc7, 0x05, 0x4a, 0xeb, 0x05, 0x7a, 0x27, 0xa1, 0xb1, 0x0c, 0xba, 0x72, 0xb2, 0xc6, 0x47, 0x33, 0x98, 0xa5, 0xb9, 0xe6, 0xd1, 0x7b, 0x9e, 0xa1, 0x94, 0xcd, 0x77, 0xc5, 0x6a, 0x78, 0xb1, 0xa7, 0xa3, 0xe6, 0x20, 0x6b, 0xca, 0xd2, 0x65, 0x68, 0xb4, 0x97, 0x09, 0xf9, 0xaf, 0x4e, 0x67, 0xd4, 0xbb, 0xcd, 0x72, 0x50, 0xa0, 0x14, 0x72, 0x4b, 0x50, 0x10, 0x14, 0x2a, 0x11, 0xdf, 0xef, 0x64, 0xf1, 0x1f, 0x92, 0x4c, 0xc8, 0x41, 0x40, 0xf5, 0x19, 0xac, 0xb5, 0x7b, 0xb8, 0xbf, 0xb5, 0xd7, 0x4b, 0xb4, 0x14, 0xb5, 0x20, 0x54, 0xd0, 0x8d, 0x31, 0x19, 0x6a, 0x80, 0x43, 0x6f, 0xe7, 0x4e, 0x11, 0x18, 0x29, 0xe8, 0x09, 0x82, 0x8a, 0xfd, 0xca, 0x68, 0x2a, 0xb6, 0x4e, 0x4e, 0xa2, 0x1f, 0x1e, 0x1e, 0x60, 0x95, 0x91, 0x07, 0x14, 0x16, 0xff, 0x98, 0x20, 0x7d, 0x6c, 0x0e, 0xe0, 0xcb, 0x13, 0xae, 0x11, 0x20, 0x99, 0x46, 0x57, 0xec, 0xc5, 0x84, 0x4a, 0x8c, 0xcd, 0x88, 0xca, 0x68, 0x36, 0xa3, 0xfe, 0x61, 0xc1, 0x23, 0x25, 0x8c, 0xf5, 0x21, 0x17, 0xf3, 0x08, 0x1e, 0xd9, 0x8d, 0x0f, 0xd5, 0x47, 0x8d, 0x33, 0xb8, 0x00, 0x80, 0x80, 0xcc, 0x7f, 0xc0, 0xd1, 0x15, 0x16, 0x11, 0x8d, 0x16, 0xab, 0x74, 0x93, 0xc2, 0x18, 0x47, 0xc0, 0xc3, 0x8e, 0xf0, 0x03, 0xb4, 0xa5, 0x8c, 0xe5, 0x58, 0x91, 0x1b, 0xdf, 0x3d, 0x20, 0xcb, 0x39, 0xde, 0x51, 0x2d, 0x28, 0x76, 0xd5, 0x83, 0x82, 0x82, 0x1c, 0x00, 0xc3, 0x17, 0x54, 0x25, 0x2f, 0xa7, 0x88, 0x05, 0x0c, 0x69, 0x66, 0x9f, 0x27, 0x67, 0x60, 0x54, 0x12, 0x70, 0xda, 0x0a, 0x95, 0xaa, 0x88, 0x90, 0x26, 0x91, 0x70, 0x76, 0xa1, 0xe3, 0x56, 0x0b, 0x0a, 0x49, 0x9b, 0xc1, 0xd5, 0x3b, 0x5a, 0x54, 0xb1, 0x7e, 0x1e, 0x93, 0x09, 0x6e, 0x76, 0xde, 0x0e, 0xa0, 0x59, 0xe7, 0x12, 0x14, 0x24, 0xd6, 0x6d, 0x73, 0x0d, 0x69, 0x6b, 0x6b, 0xfb, 0x7b, 0x67, 0x1d, 0xed, 0x7d, 0x39, 0x80, 0x5b, 0x66, 0xc0, 0x85, 0x23, 0xb6, 0x79, 0xed, 0x91, 0xb0, 0x0e, 0x6e, 0x5e, 0x9a, 0xac, 0x69, 0x68, 0x04, 0x0d, 0xe4, 0xdb, 0x6f, 0xbf, 0x19, 0x27, 0x45, 0x17, 0x47, 0x65, 0x7d, 0x95, 0x8a, 0xef, 0x61, 0x0a, 0xe1, 0xbc, 0xf9, 0x8d, 0x9f, 0x17, 0x2f, 0x14, 0xfb, 0x09, 0x85, 0x90, 0x8c, 0xec, 0x1d, 0x82, 0x2d, 0xcb, 0x33, 0xc3, 0xd0, 0x31, 0x28, 0xe0, 0xd7, 0x97, 0xda, 0x24, 0xa4, 0x12, 0x23, 0x67, 0xf7, 0x38, 0x9a, 0xd5, 0xbf, 0x03, 0x46, 0x08, 0x02, 0xcf, 0x7b, 0xea, 0xd6, 0x6f, 0xa7, 0x0a, 0x21, 0xbf, 0xb2, 0x00, 0xdc, 0xfe, 0x78, 0xff, 0xbf, 0x39, 0x82, 0x71, 0x40, 0x0e, 0x0e, 0xdf, 0x18, 0x73, 0x61, 0x64, 0x64, 0x64, 0x6a, 0x1c, 0x77, 0xa5, 0x56, 0x3a, 0x7d, 0x08, 0x20, 0x20, 0x20, 0x68, 0xb8, 0xfb, 0x98, 0x34, 0xde, 0x6e, 0xab, 0x9b, 0xed, 0x75, 0x9b, 0x6c, 0x68, 0xbd, 0x12, 0x69, 0x93, 0x9e, 0x4f, 0x9b, 0xd6, 0x8f, 0x9c, 0xbb, 0x06, 0xc5, 0x1d, 0x1d, 0x59, 0x62, 0x89, 0x05, 0xab, 0xf0, 0x9b, 0x6c, 0xb6, 0x61, 0xd5, 0x25, 0xbc, 0xf8, 0x2d, 0x0b, 0x79, 0x29, 0xe3, 0x0e, 0x82, 0x5c, 0xd7, 0x2c, 0xc5, 0xf0, 0x85, 0x67, 0x5a, 0xa4, 0x63, 0xa2, 0x21, 0xd9, 0x69, 0x7f, 0xca, 0x7f, 0x49, 0x0c, 0x00, 0xdf, 0xc0, 0x46, 0xd1, 0x72, 0x11, 0x96, 0x38, 0x28, 0x1d, 0x16, 0x7c, 0xf3, 0x5f, 0x81, 0x05, 0x45, 0xc3, 0x88, 0x2f, 0xde, 0xcd, 0x79, 0x23, 0x1f, 0xe0, 0x69, 0xec, 0x6a, 0x7b, 0xc0, 0x0c, 0xb8, 0xbb, 0x0d, 0xbb, 0x71, 0x39, 0xee, 0x69, 0x85, 0x98, 0x01, 0x8f, 0x74, 0xbf, 0x39, 0xf8, 0xb4, 0xe6, 0xb1, 0xff, 0xb9, 0x06, 0xa5, 0x90, 0x54, 0xdb, 0xe6, 0xe2, 0xf2, 0xb2, 0x07, 0x30, 0x8d, 0x97, 0xb7, 0x0b, 0xfa, 0x7d, 0x8b, 0xcd, 0xe4, 0xa6, 0x42, 0xa4, 0x49, 0x9b, 0xdb, 0xd5, 0x8d, 0x9b, 0x97, 0xd7, 0x3f, 0xb2, 0x4e, 0x79, 0xbf, 0x90, 0xa3, 0x9f, 0xb0, 0x30, 0xdc, 0xd5, 0x99, 0x4d, 0x90, 0xf2, 0xf2, 0x6a, 0x9b, 0x3d, 0xb3, 0x73, 0xb8, 0x9e, 0xaf, 0x55, 0xce, 0xfb, 0xba, 0xca, 0x88, 0xca, 0xbf, 0x7e, 0x2d, 0x30, 0x6e, 0x26, 0x44, 0x55, 0x63, 0x4c, 0x47, 0xb5, 0x42, 0x62, 0x4d, 0x8a, 0x36, 0xec, 0x1f, 0x2f, 0x9c, 0xa6, 0x12, 0x3c, 0x56, 0xa4, 0x17, 0x21, 0xfb, 0x08, 0x09, 0x3e, 0x67, 0x3d, 0x1b, 0xe9, 0xc7, 0xb9, 0x02, 0xf5, 0xaf, 0x7b, 0xa6, 0xe8, 0x68, 0x24, 0xd0, 0x9e, 0x29, 0xe5, 0xc3, 0xe6, 0x28, 0xf7, 0xc5, 0xe5, 0x6f, 0x1e, 0x5c, 0xbe, 0xea, 0x1a, 0x70, 0x5d, 0xb2, 0x4d, 0x7f, 0xd0, 0xd0, 0x25, 0x76, 0xf6, 0xed, 0xc9, 0x12, 0x26, 0xe0, 0x94, 0xc4, 0xa3, 0x70, 0xe8, 0x9d, 0x4b, 0xdc, 0xf9, 0xbb, 0xb7, 0x2f, 0x99, 0xec, 0xd6, 0xf8, 0x56, 0xda, 0x3d, 0x30, 0xdf, 0xde, 0xde, 0x40, 0xa0, 0x52, 0x95, 0xd8, 0xfb, 0x14, 0x9b, 0xde, 0x51, 0xe7, 0x55, 0xb0, 0xe6, 0x3e, 0x8e, 0x2b, 0xfc, 0xf1, 0xbc, 0x1e, 0x7b, 0xf2, 0xe8, 0x2e, 0x97, 0xcf, 0x53, 0xbd, 0xdc, 0x9d, 0xa5, 0xf5, 0x24, 0x5b, 0xcc, 0xb7, 0x30, 0xd4, 0xd2, 0xc1, 0xbd, 0xe2, 0xc1, 0x83, 0x99, 0xca, 0x20, 0x22, 0xf6, 0x69, 0x7e, 0x54, 0x57, 0xb5, 0xc5, 0x9a, 0x93, 0xcf, 0x0d, 0xf9, 0x72, 0xc8, 0x09, 0xc4, 0x3d, 0xfb, 0x4d, 0x9e, 0xda, 0x71, 0x96, 0x9f, 0xf0, 0x21, 0x80, 0xd6, 0x64, 0x6a, 0xef, 0x50, 0xa6, 0x4e, 0xa3, 0xf3, 0xc0, 0x53, 0xe0, 0x82, 0x31, 0xa0, 0xce, 0x2d, 0x94, 0x5e, 0x4e, 0x66, 0x14, 0x0c, 0xee, 0x52, 0x1f, 0xa5, 0x59, 0xa7, 0xa5, 0xc6, 0xd8, 0xec, 0x90, 0xe7, 0xdc, 0x52, 0xa4, 0x98, 0x5b, 0x0b, 0x45, 0xc6, 0x0b, 0xdc, 0x1e, 0x8a, 0xeb, 0xeb, 0xcd, 0x77, 0x10, 0xc5, 0x82, 0xf2, 0x07, 0xe4, 0x83, 0x94, 0x8c, 0xec, 0x13, 0x06, 0x06, 0x24, 0xe8, 0xbf, 0x91, 0xf1, 0xa1, 0xe9, 0x5b, 0xde, 0x59, 0xc8, 0x5f, 0xf5, 0xc3, 0x63, 0x0e, 0x50, 0x3d, 0xa6, 0x29, 0x6f, 0x3c, 0x59, 0x7c, 0x1e, 0x4a, 0x54, 0xcf, 0x6c, 0x1c, 0xbe, 0xef, 0xaf, 0x6e, 0x3a, 0x6d, 0x6a, 0x47, 0xf4, 0x47, 0xcb, 0x53, 0x70, 0x3a, 0xb6, 0xdb, 0x8c, 0x06, 0x4b, 0x7f, 0xcb, 0xb1, 0xd7, 0x72, 0x0a, 0x93, 0x51, 0x84, 0x87, 0x7f, 0x1c, 0xd2, 0xca, 0xca, 0xf4, 0x12, 0x4c, 0x30, 0x92, 0xe4, 0xad, 0x59, 0xb8, 0xfb, 0xce, 0x51, 0xca, 0xe9, 0xad, 0x05, 0x3c, 0x4a, 0xed, 0x8e, 0x26, 0x55, 0x0f, 0xfd, 0xff, 0x9d, 0x38, 0x37, 0x76, 0x0a, 0x16, 0x6c, 0x44, 0x0a, 0x81, 0x97, 0x17, 0x38, 0x80, 0xcf, 0xcb, 0x2f, 0x2a, 0xcc, 0x26, 0xb2, 0xb9, 0xdc, 0x2f, 0xbe, 0x00, 0xc0, 0xed, 0x5c, 0x50, 0x43, 0xb4, 0x79, 0xe9, 0xfe, 0xb1, 0xbd, 0xf8, 0xf6, 0x7c, 0x2e, 0x48, 0x4e, 0x41, 0x41, 0x42, 0xcf, 0x0a, 0x77, 0xb8, 0xe4, 0x01, 0x7f, 0x78, 0x52, 0x72, 0x5b, 0xcf, 0x01, 0x2c, 0x40, 0xa1, 0xe9, 0xce, 0x17, 0x0e, 0x06, 0x04, 0xd0, 0x07, 0xbe, 0xc8, 0x64, 0xf1, 0x60, 0x53, 0x52, 0xc6, 0xd0, 0xd6, 0x48, 0x67, 0x84, 0x0f, 0x18, 0x45, 0x83, 0x99, 0x21, 0x3d, 0x3c, 0x3c, 0x40, 0x52, 0x81, 0x84, 0x29, 0x7e, 0x5c, 0x10, 0x77, 0x1c, 0xa1, 0x0b, 0xba, 0xf2, 0xb8, 0x0f, 0x8d, 0xae, 0x7d, 0x59, 0x07, 0x25, 0x26, 0x7c, 0x12, 0x2c, 0x79, 0x4a, 0x69, 0x54, 0x06, 0xe0, 0x29, 0x84, 0x0e, 0x1a, 0x71, 0xf3, 0x1a, 0xa0, 0xff, 0xa0, 0x02, 0x07, 0x1c, 0xeb, 0xd4, 0x69, 0x94, 0xdf, 0xef, 0x5b, 0x13, 0x69, 0x73, 0x86, 0x06, 0x42, 0xe5, 0xd7, 0x7d, 0x8c, 0x3b, 0x8e, 0x4f, 0x9f, 0xe5, 0x7e, 0x8b, 0xcd, 0x77, 0x16, 0x03, 0xf6, 0x99, 0xcb, 0x7e, 0x43, 0xa8, 0x80, 0x6d, 0xaf, 0x9a, 0x99, 0x9d, 0x7d, 0x40, 0xf0, 0xfd, 0x05, 0x8a, 0x97, 0x97, 0x17, 0xd4, 0xbd, 0x39, 0xa3, 0x5e, 0xb3, 0xcd, 0xb8, 0x9a, 0x99, 0x5d, 0x12, 0x4d, 0x67, 0xf3, 0x43, 0x5d, 0x41, 0xc1, 0x1f, 0x10, 0x5c, 0x21, 0xcd, 0x62, 0x1e, 0xb0, 0x70, 0x96, 0xbe, 0xdf, 0xab, 0x6a, 0xa5, 0xeb, 0x73, 0x8d, 0xef, 0xea, 0xe4, 0xfc, 0x8c, 0xac, 0x1f, 0xe2, 0x1c, 0xab, 0x35, 0x07, 0x12, 0x2d, 0xae, 0x9c, 0xea, 0x33, 0x64, 0x81, 0xca, 0x5e, 0x4c, 0x09, 0xb5, 0xfa, 0x6a, 0xb2, 0x1e, 0x39, 0x9b, 0xd6, 0x7f, 0x08, 0x1d, 0x01, 0x93, 0x15, 0x4b, 0x9e, 0x64, 0xf1, 0x07, 0x27, 0xc2, 0xe9, 0x0c, 0x37, 0x20, 0x29, 0xa5, 0x99, 0x79, 0x6f, 0x3e, 0x28, 0xfe, 0xc0, 0xb2, 0x6a, 0xa9, 0x3b, 0x80, 0x45, 0x04, 0x74, 0xbb, 0xa0, 0x10, 0x43, 0x5a, 0x0d, 0x2d, 0x16, 0xaa, 0x3e, 0xcb, 0x65, 0xf1, 0xc0, 0x48, 0x8f, 0x0e, 0xfa, 0xe1, 0xb3, 0x30, 0x33, 0x0b, 0x1b, 0x18, 0x7c, 0xf1, 0x7d, 0xbd, 0x55, 0x07, 0x75, 0x9f, 0xc2, 0xc9, 0x4f, 0x56, 0x16, 0xa0, 0x9d, 0xd4, 0xeb, 0x40, 0xad, 0xad, 0xcc, 0x82, 0x35, 0x5b, 0x60, 0xdc, 0x5f, 0xf8, 0xf0, 0x90, 0xfb, 0x36, 0x0e, 0x67, 0x4a, 0x14, 0x68, 0x92, 0xe0, 0x51, 0x50, 0xe6, 0x8e, 0x04, 0x62, 0x02, 0x1e, 0x1e, 0xdc, 0x3f, 0x4e, 0x9c, 0x54, 0x07, 0x53, 0xf2, 0xfd, 0x07, 0xea, 0x06, 0xf3, 0xd3, 0x6c, 0xb6, 0xdf, 0x3d, 0xe8, 0xa2, 0x22, 0x14, 0x40, 0xeb, 0xf3, 0x55, 0x5c, 0x8e, 0x77, 0x34, 0x52, 0x18, 0x72, 0xe6, 0x24, 0x61, 0x7d, 0x25, 0xe6, 0xad, 0x0f, 0x15, 0x9d, 0x2e, 0x64, 0x6c, 0x7c, 0xe1, 0xc2, 0x76, 0x20, 0x2e, 0xae, 0x0a, 0xdc, 0xc2, 0x22, 0x9f, 0xc6, 0x2c, 0xc3, 0x2b, 0x32, 0x7f, 0x0c, 0xe3, 0x4e, 0xeb, 0xbf, 0xd0, 0xc8, 0x27, 0xaa, 0x3e, 0x3d, 0x29, 0xf5, 0x63, 0x3a, 0x63, 0x5a, 0x8d, 0xdf, 0xe7, 0xea, 0x9e, 0xd9, 0x03, 0x02, 0x02, 0xb8, 0x3c, 0xae, 0x7e, 0x24, 0x58, 0xde, 0x1e, 0x1e, 0x1d, 0x45, 0x02, 0x40, 0xdc, 0x3f, 0x34, 0x14, 0x64, 0x08, 0x5e, 0x89, 0xf3, 0xf9, 0xb8, 0x5f, 0xa6, 0xd5, 0x51, 0x5d, 0x44, 0x8d, 0x48, 0x92, 0xf5, 0xd2, 0xbd, 0xeb, 0x68, 0xff, 0xaa, 0xf7, 0x3d, 0xac, 0x12, 0xf8, 0xc4, 0xe2, 0xf2, 0x32, 0x29, 0x53, 0xcd, 0xd1, 0x58, 0x50, 0x31, 0x6c, 0x1f, 0xd3, 0xc7, 0xc5, 0x81, 0xfc, 0x7c, 0xa9, 0x69, 0x84, 0x47, 0x3e, 0x86, 0xe4, 0xf6, 0x77, 0x1c, 0x4f, 0x97, 0xcb, 0x85, 0x3a, 0xd3, 0xa7, 0x9e, 0x9e, 0xbf, 0x88, 0x9c, 0x67, 0x82, 0xc2, 0x96, 0xe2, 0x11, 0xc7, 0x59, 0xc5, 0x45, 0x6f, 0x74, 0xc9, 0xd7, 0x72, 0xa1, 0xc3, 0xb4, 0xd3, 0x75, 0x96, 0xc1, 0xb0, 0xb0, 0xcc, 0x07, 0xb0, 0x71, 0xb4, 0xfd, 0x5b, 0x48, 0xcf, 0x78, 0x94, 0x76, 0xb3, 0x56, 0xc3, 0x15, 0x08, 0x9f, 0x52, 0x99, 0xea, 0x9f, 0x94, 0xf5, 0xd5, 0x6c, 0x21, 0x4c, 0xbd, 0x5f, 0x5c, 0x42, 0xe4, 0x2c, 0x88, 0x88, 0x88, 0xb8, 0xfc, 0xde, 0xf8, 0xac, 0xad, 0xf1, 0x6d, 0xe1, 0x68, 0x65, 0x2f, 0x2f, 0x2e, 0xba, 0xef, 0x4e, 0xff, 0x41, 0x80, 0x5a, 0x1e, 0x43, 0xdc, 0xb1, 0x52, 0x82, 0x05, 0x56, 0x79, 0xcd, 0xf9, 0xc5, 0x26, 0x46, 0x57, 0xf1, 0xcc, 0xaa, 0x57, 0x54, 0xd9, 0x6d, 0xb8, 0x7d, 0x5f, 0xb8, 0x76, 0x1c, 0xb9, 0x3d, 0x6f, 0x8f, 0xe6, 0x36, 0x08, 0x62, 0xcc, 0x83, 0xec, 0x3a, 0x1f, 0x61, 0x01, 0x5d, 0x55, 0x89, 0xe9, 0xd2, 0x61, 0xc2, 0x0e, 0xf2, 0x72, 0x9b, 0x2a, 0x10, 0x7f, 0x0a, 0x1b, 0x37, 0xdd, 0x5c, 0x49, 0xf2, 0xaa, 0x16, 0x67, 0xcb, 0x19, 0xdf, 0xf3, 0x98, 0x76, 0xbe, 0x3c, 0xf7, 0x54, 0x8d, 0x9c, 0xdc, 0xf8, 0x02, 0xbb, 0xda, 0xbd, 0x69, 0x1f, 0xbd, 0x47, 0x9b, 0x74, 0xe8, 0xa4, 0x17, 0xd7, 0xd7, 0xda, 0x30, 0xb4, 0xa5, 0x69, 0x5c, 0xce, 0x8e, 0x8c, 0x18, 0x82, 0x71, 0x4e, 0xff, 0x2f, 0x98, 0xea, 0xf2, 0xa8, 0x65, 0x81, 0x83, 0x83, 0x03, 0xe8, 0x5f, 0xb6, 0xcc, 0x2c, 0x02, 0xdb, 0xb8, 0xc3, 0xd6, 0x8d, 0xff, 0x79, 0x99, 0xb2, 0x33, 0x9b, 0x04, 0x25, 0xd6, 0x4b, 0x72, 0x01, 0x98, 0x8e, 0xb6, 0x06, 0xf5, 0x28, 0x85, 0x6a, 0x5a, 0x42, 0x54, 0x82, 0xcf, 0xff, 0x3c, 0x37, 0x66, 0x07, 0xfe, 0x95, 0x51, 0x72, 0x7e, 0xd0, 0x83, 0xa5, 0x25, 0x0d, 0x2c, 0x0a, 0xfe, 0xec, 0x8f, 0x18, 0x9e, 0x3e, 0xa6, 0x07, 0xa0, 0x13, 0x6a, 0x0d, 0x7a, 0x20, 0x55, 0x85, 0x0b, 0xe2, 0xa1, 0xbc, 0x0c, 0x96, 0x7f, 0xbf, 0x79, 0x9e, 0x5a, 0xd9, 0xc1, 0x37, 0xd7, 0xd7, 0x0c, 0x05, 0x60, 0xa6, 0x90, 0x24, 0x27, 0x26, 0xba, 0x94, 0x58, 0xc4, 0xb7, 0xc5, 0x2b, 0x2e, 0x08, 0x62, 0x45, 0x92, 0x2b, 0x4d, 0xfa, 0x2b, 0x18, 0x87, 0x0b, 0x73, 0x1a, 0x68, 0xd0, 0x51, 0x49, 0x14, 0xb1, 0x5c, 0xdb, 0xf9, 0xef, 0x41, 0xf8, 0x3b, 0x39, 0xf1, 0x5a, 0x3f, 0x79, 0x73, 0x44, 0xbb, 0xcf, 0x71, 0x4a, 0x2e, 0xf9, 0xbd, 0x60, 0xdc, 0x11, 0x77, 0x15, 0x52, 0x5e, 0x5f, 0x5d, 0xf5, 0x76, 0xbd, 0xbf, 0x21, 0xd9, 0xd9, 0xd9, 0xad, 0x7e, 0xd5, 0x89, 0x23, 0xa7, 0xa4, 0xdc, 0x9a, 0x91, 0x17, 0x1c, 0x78, 0x79, 0xbc, 0xbe, 0xbc, 0xd8, 0xfc, 0xc6, 0xe7, 0xfb, 0x02, 0x9e, 0x9a, 0x9a, 0x92, 0x94, 0x91, 0xe9, 0x07, 0x54, 0x71, 0x63, 0x63, 0x43, 0xc1, 0x82, 0xaa, 0x39, 0x37, 0xf7, 0xcb, 0x87, 0xf9, 0x36, 0x51, 0xc0, 0x50, 0x9e, 0x36, 0x34, 0x36, 0x81, 0x05, 0x2a, 0x48, 0x6b, 0x6e, 0x62, 0xb9, 0x17, 0x19, 0xf0, 0x61, 0x97, 0xe7, 0x21, 0x04, 0x65, 0x1d, 0xb6, 0xeb, 0x9d, 0x28, 0xa8, 0x61, 0x05, 0xf3, 0xa4, 0xf5, 0xa5, 0x3f, 0x33, 0x32, 0xa2, 0x14, 0x0b, 0xc4, 0x0d, 0x81, 0x21, 0x5f, 0xe6, 0x17, 0xb7, 0xf9, 0x1a, 0x54, 0xbb, 0xd3, 0xe1, 0x60, 0x50, 0x9b, 0xde, 0xcc, 0x0e, 0xd7, 0x6d, 0x58, 0x07, 0x00, 0x9c, 0x03, 0xab, 0x14, 0x76, 0xbb, 0x14, 0x73, 0x34, 0x5d, 0x90, 0x61, 0x24, 0xe3, 0x91, 0x32, 0xa3, 0x48, 0x5f, 0xe0, 0x0b, 0x25, 0x1e, 0xb5, 0x8e, 0x2d, 0x67, 0x9e, 0x12, 0xde, 0xe7, 0xef, 0x33, 0x1e, 0xa7, 0x10, 0x42, 0xdd, 0xfb, 0x86, 0xfb, 0xa1, 0x71, 0x1b, 0x4b, 0xd3, 0xa5, 0xcb, 0xf7, 0x58, 0x52, 0x14, 0xe2, 0x7f, 0x9f, 0x20, 0x11, 0x86, 0x0f, 0x69, 0xd2, 0x32, 0x32, 0x08, 0x6c, 0x57, 0x5b, 0x61, 0x68, 0xcb, 0x9f, 0xac, 0xe8, 0xcb, 0x90, 0x00, 0xc3, 0x3f, 0x9e, 0xc1, 0x59, 0x6b, 0xd8, 0x07, 0xfb, 0x41, 0x97, 0x4a, 0x16, 0x73, 0xb2, 0x65, 0x74, 0xf4, 0xf4, 0x53, 0x80, 0x61, 0xa5, 0xd3, 0xef, 0x24, 0xd4, 0xd3, 0xd3, 0xb3, 0x2c, 0xd9, 0x72, 0xd8, 0x1e, 0xdc, 0x8c, 0x13, 0x7c, 0x53, 0x88, 0x01, 0x9c, 0xb7, 0x83, 0xc1, 0x31, 0x62, 0x56, 0x66, 0x66, 0xd7, 0xeb, 0x2e, 0xf1, 0xc9, 0x8a, 0x9f, 0x14, 0x7b, 0x31, 0x35, 0x62, 0x18, 0xea, 0xe7, 0x8f, 0xe3, 0xc1, 0xf9, 0x7b, 0x16, 0x95, 0xab, 0xeb, 0xeb, 0x4f, 0xf8, 0xf8, 0x91, 0x80, 0xc1, 0xff, 0xfd, 0xe3, 0xe3, 0xba, 0x46, 0x64, 0x0b, 0xe6, 0x77, 0xcc, 0x0c, 0x96, 0xf0, 0x7e, 0x25, 0xe4, 0xb4, 0x16, 0x9d, 0x39, 0x5c, 0xd0, 0x06, 0x4e, 0x7a, 0xfa, 0xdd, 0xcd, 0x57, 0x3a, 0xbe, 0xac, 0x42, 0xf5, 0x01, 0x78, 0x14, 0xd8, 0xab, 0x7f, 0x3f, 0x72, 0xa9, 0x93, 0xe2, 0x38, 0x3b, 0x39, 0xf6, 0xac, 0x71, 0x90, 0xac, 0x04, 0xd2, 0x1e, 0xc5, 0x8d, 0x51, 0x41, 0x25, 0x0c, 0x6b, 0x6a, 0xac, 0x7b, 0x38, 0x38, 0x38, 0x1f, 0x22, 0x12, 0xc4, 0xb9, 0xf7, 0x71, 0x6c, 0x22, 0xe0, 0xcd, 0xc5, 0xe3, 0x72, 0x14, 0x0c, 0xb8, 0x2c, 0x55, 0xab, 0xb1, 0x80, 0x5f, 0x98, 0x9b, 0x00, 0x5f, 0x22, 0x10, 0x13, 0x13, 0xdf, 0x00, 0xa3, 0x41, 0xbd, 0x5a, 0x4f, 0x95, 0x5f, 0xbb, 0xdd, 0xbd, 0x76, 0x79, 0x25, 0x78, 0xe7, 0x86, 0xe5, 0x3e, 0x65, 0xd9, 0x64, 0xaf, 0x39, 0xc0, 0xde, 0x91, 0x9a, 0x7e, 0x66, 0x9c, 0x09, 0xd9, 0xf4, 0x6f, 0x66, 0x04, 0x20, 0x90, 0x96, 0x6b, 0x96, 0x7c, 0xd4, 0x58, 0x88, 0x32, 0x69, 0x2c, 0x62, 0xe3, 0xa9, 0x19, 0x69, 0x88, 0x97, 0x9b, 0xb3, 0x86, 0xfd, 0xa9, 0x29, 0xdf, 0xa8, 0x37, 0xb6, 0xb7, 0x35, 0x8d, 0x47, 0x24, 0x77, 0x8a, 0x07, 0x06, 0x9a, 0xd6, 0xe6, 0x32, 0x44, 0x82, 0x61, 0xe1, 0x1e, 0x63, 0x58, 0x84, 0x9a, 0x75, 0x9a, 0xf2, 0xd8, 0xb2, 0x58, 0x6f, 0x6f, 0xdd, 0xe7, 0xfb, 0xc3, 0x39, 0x8b, 0x4b, 0x20, 0xfc, 0x65, 0xaa, 0x7e, 0xff, 0x34, 0x7e, 0x7d, 0xbd, 0x5f, 0x2f, 0x97, 0xca, 0xe5, 0x10, 0x05, 0x6a, 0xdf, 0xf7, 0xf9, 0x94, 0xf3, 0xe1, 0xf1, 0x71, 0x73, 0xa3, 0x27, 0x08, 0xbf, 0xd2, 0xe1, 0x72, 0x4b, 0x0c, 0x1a, 0x0e, 0xce, 0xf8, 0x78, 0xbe, 0xd2, 0x00, 0x0c, 0xeb, 0xeb, 0xeb, 0x7b, 0x30, 0x5b, 0x9a, 0xb0, 0x9c, 0x79, 0xfb, 0xef, 0x2d, 0xb0, 0xf0, 0x57, 0x95, 0x93, 0xcb, 0x80, 0x86, 0x41, 0x30, 0xf6, 0x35, 0x65, 0x29, 0x5e, 0xf5, 0xcd, 0x8d, 0x33, 0x60, 0x80, 0x49, 0xd9, 0xd9, 0x55, 0x8f, 0x9f, 0xf1, 0xf0, 0x01, 0xd2, 0xff, 0x7d, 0xf1, 0x6e, 0xd3, 0x13, 0x1d, 0x5f, 0xd3, 0xc8, 0x56, 0xbe, 0x15, 0x53, 0x2c, 0xab, 0xb1, 0x70, 0x67, 0xd9, 0x70, 0x62, 0xa1, 0xc5, 0x06, 0x61, 0x4f, 0x91, 0x33, 0x13, 0x8c, 0x2f, 0xec, 0xab, 0x80, 0x8c, 0xcc, 0x5a, 0x27, 0xf0, 0xd7, 0xd1, 0x63, 0x04, 0xc7, 0xdf, 0x14, 0x42, 0xc8, 0xdd, 0xdc, 0x4c, 0xe6, 0xf3, 0x5c, 0xb5, 0xf8, 0xf9, 0x9b, 0xef, 0x03, 0x5f, 0x36, 0x65, 0xe1, 0xef, 0x41, 0xe9, 0x14, 0x86, 0x01, 0x6d, 0xbb, 0x8e, 0x22, 0x02, 0xb1, 0xe3, 0x00, 0xc0, 0xcc, 0x40, 0xc3, 0xc0, 0x18, 0x5e, 0xed, 0x0c, 0x4b, 0xca, 0xcb, 0xfb, 0x5d, 0x23, 0xa9, 0x4e, 0x16, 0x49, 0xe3, 0x52, 0x27, 0x49, 0x8d, 0xa5, 0xb3, 0x23, 0x01, 0x05, 0x09, 0x2b, 0x3b, 0x93, 0xca, 0x6c, 0x1c, 0xba, 0x9c, 0x39, 0x1b, 0x4d, 0xf8, 0xf2, 0x32, 0x74, 0x49, 0xa3, 0xf6, 0x9b, 0xe0, 0xb3, 0x0f, 0x7f, 0x8d, 0xc5, 0xc0, 0xb3, 0xfd, 0xd7, 0x19, 0x61, 0x3a, 0x1e, 0x1e, 0x7c, 0x4c, 0x2a, 0x39, 0x15, 0x2b, 0xa9, 0xe9, 0x45, 0x2e, 0xd7, 0x13, 0x30, 0x87, 0xcd, 0x72, 0x21, 0x25, 0xc1, 0x5a, 0x97, 0x57, 0x42, 0x9c, 0x79, 0x35, 0x2a, 0x60, 0xbe, 0xad, 0x5e, 0xbe, 0x5c, 0xa8, 0x38, 0xb0, 0x28, 0x99, 0x71, 0x64, 0x90, 0x86, 0x20, 0xc3, 0xb3, 0x07, 0x42, 0x0f, 0xe0, 0x61, 0x9d, 0xe9, 0x94, 0xde, 0x4c, 0x39, 0x08, 0x6d, 0x21, 0x80, 0x6c, 0xf8, 0x75, 0x2f, 0xc7, 0xaf, 0x34, 0x37, 0x66, 0xbf, 0x54, 0x4a, 0x95, 0x16, 0xd6, 0x3a, 0xbf, 0xa2, 0x62, 0xe1, 0x44, 0x41, 0x80, 0x36, 0x37, 0x37, 0x17, 0x5b, 0x5d, 0xac, 0x82, 0x5c, 0xac, 0x88, 0x04, 0x7d, 0x09, 0x81, 0xef, 0x2c, 0x93, 0xfa, 0xd9, 0x76, 0xef, 0xd7, 0xfd, 0xc2, 0x34, 0xe8, 0x06, 0xfb, 0xc2, 0xd0, 0x1c, 0xae, 0xf7, 0x64, 0x53, 0x53, 0x53, 0x37, 0x00, 0xb4, 0x19, 0xdc, 0x1b, 0xcf, 0x20, 0x89, 0x97, 0x54, 0xb9, 0x26, 0x12, 0xf8, 0xde, 0xed, 0x9f, 0x2d, 0xcc, 0xc4, 0x8a, 0x3d, 0xef, 0x31, 0x71, 0xc5, 0xc5, 0xd9, 0xd4, 0x37, 0x29, 0xa0, 0x1b, 0xff, 0x33, 0x33, 0xe0, 0xa1, 0xf0, 0x57, 0x82, 0x87, 0xb7, 0x37, 0xdf, 0xd9, 0x7a, 0x57, 0x5c, 0x78, 0x38, 0xfc, 0x85, 0x3b, 0x5f, 0xe5, 0x79, 0xa9, 0x7c, 0xec, 0x67, 0xde, 0xd0, 0xa9, 0x02, 0x89, 0x6f, 0x0c, 0x29, 0xe5, 0x3f, 0x0a, 0x7a, 0xbf, 0xd5, 0x38, 0xdf, 0x69, 0x1b, 0xb0, 0xdf, 0xfe, 0xbc, 0xe3, 0x34, 0xe8, 0xdf, 0x27, 0xe1, 0x6d, 0x42, 0x47, 0xcb, 0x21, 0x6f, 0xff, 0x35, 0x49, 0x27, 0xe4, 0x29, 0x94, 0xc3, 0xf3, 0x09, 0x1f, 0x16, 0xe5, 0x7a, 0xa6, 0x33, 0xbe, 0xd7, 0x54, 0x5a, 0x1d, 0x62, 0x20, 0x0b, 0xe4, 0x3f, 0xb4, 0xbb, 0xb1, 0xed, 0x36, 0x14, 0x38, 0x5a, 0xba, 0xe4, 0x56, 0x35, 0x13, 0xdf, 0xa4, 0xca, 0x9e, 0xd7, 0xa2, 0xc3, 0xc0, 0x61, 0xbb, 0xb2, 0xf8, 0x45, 0x3b, 0x17, 0x92, 0xc2, 0x65, 0x32, 0x0c, 0x85, 0x20, 0x74, 0x65, 0x45, 0xa7, 0xb2, 0x82, 0xf3, 0xc7, 0x7f, 0xe8, 0xd1, 0xf8, 0x45, 0x52, 0xdb, 0x43, 0x4d, 0xeb, 0xbe, 0x48, 0x0c, 0x29, 0x51, 0x97, 0xdb, 0x43, 0xe5, 0xe3, 0x09, 0xc3, 0xd8, 0x8b, 0x4e, 0x92, 0x6e, 0x30, 0xad, 0xd0, 0xe2, 0xde, 0x15, 0xba, 0x7c, 0x50, 0x09, 0xe2, 0x37, 0x8a, 0x45, 0xc3, 0x9f, 0x05, 0xbc, 0xc1, 0x40, 0x2e, 0xad, 0xd9, 0x28, 0x8c, 0x06, 0x8c, 0x98, 0x3f, 0x76, 0x85, 0x80, 0x68, 0xc3, 0x45, 0x49, 0x93, 0x56, 0xa6, 0x7a, 0x70, 0xae, 0x8b, 0xd1, 0xa8, 0x06, 0xdb, 0x43, 0x65, 0x18, 0xae, 0x59, 0x7b, 0x99, 0xa6, 0x37, 0xf9, 0xf4, 0xd4, 0x79, 0xf9, 0xcb, 0x45, 0xcd, 0x41, 0xe8, 0x41, 0xb6, 0x5f, 0x6a, 0x96, 0xf4, 0xa0, 0x12, 0x47, 0x12, 0x3d, 0xaa, 0x87, 0xce, 0x63, 0x89, 0xa1, 0xf5, 0xe5, 0x17, 0xf0, 0x3b, 0xa4, 0x67, 0x90, 0x7d, 0x9f, 0xf7, 0xa3, 0x2d, 0xf9, 0x6c, 0x57, 0xb8, 0xea, 0xad, 0x35, 0x5d, 0xf6, 0xd9, 0xbf, 0x99, 0x3d, 0x5e, 0xed, 0xda, 0x21, 0x7b, 0x96, 0xa3, 0x70, 0x73, 0x73, 0x03, 0x73, 0x3f, 0xd8, 0xf2, 0xe5, 0x6a, 0x57, 0x7a, 0xa5, 0xc3, 0x0b, 0xf7, 0xbc, 0xe3, 0x5e, 0x0f, 0x06, 0x6d, 0x70, 0x8e, 0x37, 0xae, 0xbe, 0xd1, 0xce, 0xa4, 0x66, 0x89, 0x6e, 0x2c, 0x47, 0x00, 0x52, 0x9f, 0x41, 0x21, 0x44, 0x72, 0x03, 0x28, 0x55, 0xe0, 0xa3, 0xa2, 0x59, 0x55, 0xd8, 0xc8, 0x01, 0xe5, 0xea, 0xd5, 0xbd, 0x13, 0x13, 0x68, 0xeb, 0xbe, 0xcf, 0x95, 0x34, 0xec, 0x31, 0xa3, 0x86, 0x64, 0x15, 0xda, 0x5e, 0x1f, 0x27, 0x4d, 0x22, 0x05, 0x91, 0x16, 0xc1, 0xc1, 0x23, 0x16, 0xa6, 0x56, 0x11, 0xb1, 0x36, 0xda, 0x5d, 0xf8, 0xdf, 0x43, 0xa4, 0x4c, 0x4e, 0xaa, 0xd4, 0x2a, 0xd5, 0x38, 0xd7, 0x8a, 0x91, 0xa0, 0x2b, 0x85, 0x90, 0x5b, 0x21, 0x36, 0x4e, 0xf8, 0xfa, 0x32, 0x8b, 0x31, 0x9b, 0x20, 0xd9, 0x08, 0xa8, 0x4b, 0xd9, 0x38, 0x1c, 0xdc, 0xcf, 0xf1, 0xbb, 0xfc, 0x9e, 0x37, 0x95, 0xfb, 0x13, 0x2d, 0xa2, 0x9e, 0x36, 0xc3, 0x88, 0x2d, 0xf5, 0x87, 0x3d, 0x49, 0x19, 0x18, 0x50, 0x9f, 0xef, 0x4e, 0x67, 0x1e, 0x05, 0xba, 0x5e, 0xae, 0x90, 0xda, 0xdb, 0xdb, 0x27, 0x4b, 0xe4, 0x89, 0xd9, 0x3d, 0x1c, 0x2d, 0x61, 0xaf, 0x90, 0xa2, 0x5c, 0x3a, 0xdf, 0xfd, 0xb3, 0x03, 0x52, 0x59, 0xfe, 0xb0, 0x71, 0x7c, 0x1c, 0xba, 0x1f, 0x4c, 0x17, 0x21, 0xd9, 0xae, 0xb5, 0x97, 0x5e, 0x77, 0x34, 0x7c, 0x57, 0x54, 0xfc, 0xf4, 0x71, 0xce, 0xac, 0xaf, 0xaf, 0xef, 0x7c, 0x3c, 0x8f, 0x32, 0x91, 0xcd, 0x0f, 0x05, 0x02, 0x23, 0xc5, 0x30, 0x99, 0xfc, 0xd0, 0x27, 0x7c, 0x7b, 0xf4, 0x5b, 0xac, 0xb9, 0xf9, 0x5c, 0x5f, 0x63, 0xc7, 0x63, 0x12, 0xda, 0x00, 0x21, 0xa6, 0x08, 0x7f, 0x3a, 0x2d, 0xc7, 0xae, 0x46, 0xe3, 0xf4, 0x44, 0x49, 0x69, 0xab, 0x97, 0x27, 0x18, 0x03, 0x8f, 0x02, 0x61, 0x34, 0x89, 0xe2, 0x9f, 0x98, 0x68, 0x2c, 0x0d, 0x16, 0xdf, 0x81, 0x06, 0x59, 0x73, 0x10, 0x48, 0xaf, 0x11, 0xc3, 0x31, 0x94, 0x98, 0xb2, 0x0f, 0xe2, 0x85, 0xf6, 0xc8, 0x77, 0x11, 0x2b, 0xc7, 0x74, 0x74, 0x74, 0x4c, 0xe5, 0x7d, 0x83, 0x5b, 0xa5, 0xd6, 0x42, 0x7b, 0xb9, 0xe8, 0x43, 0xb3, 0xbc, 0xaf, 0x6a, 0x35, 0x5a, 0xa8, 0xd2, 0xfd, 0x39, 0xfc, 0x03, 0x3b, 0x70, 0x1b, 0x4b, 0x0a, 0x9f, 0x59, 0x5e, 0xff, 0xc0, 0xdb, 0x0f, 0x94, 0xca, 0x6a, 0x02, 0x4f, 0x89, 0x8c, 0xa2, 0x1c, 0xb3, 0xbd, 0xbd, 0x3d, 0x55, 0xaa, 0x4c, 0xf5, 0x41, 0x4c, 0x12, 0xb1, 0x84, 0x8a, 0x4e, 0x9a, 0x04, 0xa4, 0x40, 0xc2, 0xe1, 0x11, 0x10, 0x7a, 0x7a, 0x43, 0x90, 0x3e, 0x7d, 0xfe, 0x8c, 0x12, 0x6a, 0x68, 0x60, 0x4a, 0xda, 0x9f, 0xf9, 0xf5, 0x9b, 0xc3, 0xd6, 0xc2, 0x5c, 0x2a, 0xaf, 0x0d, 0x17, 0xe1, 0x09, 0xbe, 0x6b, 0x6b, 0xa1, 0xc0, 0xe1, 0xa7, 0x59, 0xb5, 0x4a, 0x8e, 0x40, 0x91, 0xf8, 0x3b, 0x88, 0x9c, 0xf5, 0x58, 0x51, 0x2c, 0x8c, 0xb2, 0x60, 0xb0, 0x33, 0x7f, 0xdf, 0xae, 0x67, 0xf3, 0xd7, 0xa4, 0x34, 0x1a, 0x75, 0x2f, 0xf3, 0x05, 0xd7, 0x86, 0x32, 0x2d, 0x9c, 0x9c, 0xc4, 0xd0, 0x0c, 0x13, 0xad, 0x82, 0xbb, 0x63, 0xf5, 0xba, 0x70, 0xf7, 0x6f, 0xa2, 0xa5, 0x2a, 0x5b, 0x0f, 0x0e, 0xab, 0xa2, 0xe9, 0x29, 0x25, 0xff, 0x33, 0xa2, 0xf0, 0x68, 0x68, 0xd5, 0x93, 0x85, 0x7b, 0x5d, 0xc7, 0x8a, 0xb7, 0xf9, 0x50, 0x51, 0x03, 0xbd, 0x81, 0x69, 0x64, 0x97, 0x3d, 0x3b, 0x79, 0x1f, 0xc7, 0x33, 0x8b, 0x2d, 0x4e, 0x54, 0xb0, 0x68, 0x44, 0xc8, 0xca, 0xca, 0xca, 0xce, 0x87, 0xd3, 0x30, 0x40, 0xb2, 0x59, 0xc3, 0x79, 0x5d, 0x6b, 0x35, 0xa2, 0x01, 0x5e, 0xf8, 0xb8, 0x32, 0x0a, 0x05, 0x8b, 0xec, 0x9f, 0x91, 0x91, 0xa1, 0xe5, 0xeb, 0x91, 0xb3, 0x11, 0xcb, 0x75, 0x37, 0x9a, 0x92, 0xca, 0xd1, 0x2a, 0x28, 0x13, 0x03, 0xe3, 0x39, 0x5b, 0xef, 0x30, 0xb9, 0xb2, 0x86, 0x0f, 0x41, 0xd3, 0xc4, 0x0b, 0xa2, 0x0e, 0x66, 0x59, 0xaa, 0x53, 0xf5, 0x54, 0x0e, 0x37, 0xb8, 0x40, 0x0f, 0xaa, 0x32, 0x33, 0xe7, 0xb9, 0x96, 0x16, 0xea, 0x81, 0x91, 0xd2, 0x92, 0x8c, 0x25, 0xd0, 0x69, 0x83, 0x25, 0x6a, 0x22, 0xe2, 0x53, 0x24, 0xe0, 0xdc, 0x69, 0xbb, 0x96, 0x88, 0x23, 0xda, 0x9c, 0x22, 0x3b, 0x5d, 0x37, 0x24, 0xc0, 0xc3, 0x53, 0x7d, 0xb2, 0xc3, 0x27, 0x26, 0x46, 0x0b, 0x10, 0xf2, 0x37, 0xec, 0x0b, 0x2d, 0x1d, 0x7e, 0x6f, 0xf3, 0xd5, 0xa7, 0xe2, 0x3e, 0x4c, 0x12, 0x56, 0xc4, 0x2a, 0x8e, 0x3d, 0x8a, 0x72, 0x1b, 0x42, 0x83, 0xec, 0xd2, 0xf9, 0xae, 0x9f, 0x5e, 0xec, 0x70, 0xba, 0xcc, 0x1e, 0x8d, 0xc7, 0x0a, 0x0b, 0x50, 0xba, 0x46, 0x93, 0xed, 0x67, 0x00, 0x91, 0x49, 0x70, 0xa2, 0x8e, 0xc5, 0x38, 0x73, 0x0b, 0x99, 0xc6, 0x1e, 0xaf, 0xf7, 0x99, 0x3d, 0x6f, 0xcc, 0x3f, 0xb8, 0x86, 0x8b, 0x0b, 0x2c, 0x9d, 0x4c, 0xd7, 0x13, 0x81, 0x49, 0xa5, 0xa0, 0xa0, 0x00, 0xe2, 0x88, 0x0a, 0x21, 0xca, 0x7a, 0xa9, 0x39, 0x2d, 0x7f, 0xd4, 0xa8, 0x73, 0x87, 0x95, 0x91, 0xad, 0xcf, 0x21, 0x99, 0x4c, 0x4c, 0xe3, 0xf7, 0x08, 0xd7, 0xca, 0xf2, 0x0a, 0xfd, 0x04, 0x73, 0xfd, 0xd8, 0x49, 0xf2, 0x34, 0x13, 0x6e, 0xf0, 0x1f, 0x10, 0xad, 0x44, 0xb0, 0x48, 0x8e, 0x41, 0x11, 0x8b, 0xbe, 0x2a, 0xfe, 0x48, 0xb5, 0xac, 0xb4, 0xf3, 0x85, 0x43, 0xf5, 0x1c, 0xfe, 0xe5, 0x77, 0x0b, 0xcb, 0xed, 0xf6, 0x76, 0xbe, 0x53, 0xea, 0x12, 0x38, 0x3d, 0x38, 0x25, 0x0b, 0x28, 0x4e, 0x4e, 0x4e, 0xeb, 0x7f, 0x8d, 0x28, 0x25, 0x72, 0x59, 0x22, 0xb6, 0xb6, 0x0c, 0x77, 0xe7, 0xeb, 0xfa, 0x24, 0xa0, 0xb3, 0xb5, 0x8e, 0x5f, 0x47, 0xf6, 0x26, 0x50, 0x7b, 0xfe, 0xbf, 0x32, 0x6f, 0xae, 0x1a, 0x2e, 0x5c, 0x10, 0x80, 0xcc, 0xb6, 0x6d, 0xc3, 0x6d, 0x4e, 0x36, 0x4e, 0x5c, 0xfe, 0xd5, 0xde, 0x64, 0xe2, 0x64, 0xaf, 0x62, 0xa2, 0x02, 0xa4, 0x10, 0x70, 0x1c, 0x22, 0x80, 0x07, 0xaf, 0xa8, 0xa8, 0x40, 0x07, 0x83, 0xc3, 0x99, 0x8d, 0x07, 0x0d, 0x0e, 0xa7, 0x8b, 0x9a, 0x5d, 0x8e, 0x93, 0xd5, 0xde, 0x4f, 0x81, 0xd9, 0x39, 0x9a, 0xc2, 0xf8, 0x31, 0x3b, 0xeb, 0xad, 0x97, 0x30, 0xf2, 0xf2, 0xf2, 0x1e, 0x8e, 0xab, 0xbb, 0x14, 0x74, 0x2a, 0x88, 0xb4, 0x27, 0x1b, 0x0a, 0x38, 0xdf, 0x96, 0x5a, 0x21, 0x09, 0x04, 0xbd, 0xd0, 0x02, 0x7c, 0x2b, 0xbf, 0x43, 0xb7, 0xa1, 0x5e, 0x58, 0x6d, 0x87, 0xda, 0x7e, 0xf6, 0x19, 0x95, 0x34, 0x6f, 0x94, 0x49, 0xbe, 0xe1, 0xde, 0x28, 0x63, 0x4c, 0x82, 0x87, 0x8d, 0xbe, 0x4b, 0x17, 0xc6, 0xb4, 0x14, 0x13, 0xea, 0x46, 0xcb, 0xfc, 0xd7, 0x84, 0x6b, 0x07, 0x02, 0xab, 0xda, 0x6a, 0xbe, 0xff, 0x5c, 0xbe, 0x1f, 0x53, 0xa3, 0x9e, 0xd5, 0xad, 0x5d, 0x96, 0xba, 0x9d, 0x86, 0xfb, 0xfa, 0xf5, 0xab, 0x5d, 0xb6, 0x0a, 0x54, 0xb3, 0x0e, 0x43, 0x95, 0x5e, 0x07, 0xa2, 0xd7, 0xf3, 0xb4, 0x08, 0x03, 0x20, 0x97, 0x43, 0x35, 0x86, 0x7d, 0x17, 0x80, 0x7a, 0x96, 0xff, 0xa8, 0x5e, 0x5d, 0x24, 0x21, 0x21, 0xa9, 0xa9, 0xaf, 0x57, 0x79, 0x6e, 0x6a, 0x7b, 0xdd, 0x28, 0x5d, 0x7e, 0x75, 0xf5, 0x99, 0x1c, 0x9b, 0x47, 0xac, 0xa3, 0x14, 0x35, 0x98, 0xed, 0x26, 0x5a, 0x6c, 0xbd, 0x07, 0xa3, 0x66, 0xb7, 0x42, 0x7a, 0x50, 0x84, 0x98, 0x91, 0x63, 0x20, 0x00, 0x93, 0x3f, 0x44, 0xbb, 0xc9, 0x16, 0x02, 0xa4, 0x56, 0xa9, 0x55, 0x54, 0xe6, 0xbb, 0xd0, 0xe9, 0xe3, 0xf5, 0xd1, 0x64, 0xf4, 0x5a, 0xf5, 0xbf, 0x1d, 0xba, 0xbc, 0x5a, 0x74, 0x62, 0x8f, 0x17, 0xaa, 0xb7, 0x01, 0x8e, 0x69, 0xf6, 0xbc, 0xa5, 0xd1, 0x6b, 0x77, 0x0f, 0x38, 0x38, 0x38, 0xa0, 0xd9, 0xe7, 0xe5, 0x5e, 0x34, 0x3a, 0xfa, 0xed, 0x0b, 0x5e, 0xae, 0x26, 0x60, 0xde, 0xe2, 0x09, 0xcd, 0xa7, 0xf6, 0x16, 0xf0, 0x63, 0xa1, 0x1c, 0xd3, 0x8d, 0x01, 0x26, 0x08, 0x08, 0xd4, 0xb7, 0x13, 0x06, 0x26, 0xe0, 0x8d, 0xa5, 0x65, 0x80, 0xb5, 0xa8, 0x96, 0x52, 0x08, 0x02, 0x2a, 0xdc, 0xe1, 0xfe, 0x6c, 0x7f, 0x1b, 0xaf, 0x58, 0xc8, 0xa4, 0x87, 0x9b, 0x90, 0xc3, 0xd3, 0xad, 0xda, 0x87, 0x49, 0xdb, 0x33, 0xb9, 0x15, 0xc2, 0xcd, 0xc5, 0xa5, 0xb2, 0xce, 0xf6, 0x29, 0xdf, 0xe3, 0x7a, 0x4f, 0x4b, 0x33, 0x6c, 0x68, 0xbb, 0x14, 0xcf, 0x29, 0x77, 0x67, 0x36, 0x2d, 0xb9, 0xf8, 0x6c, 0xfc, 0xe2, 0x96, 0x9e, 0xfb, 0x11, 0x1e, 0x1a, 0x52, 0x26, 0x9d, 0x0d, 0x61, 0xdd, 0xe7, 0x3e, 0xeb, 0x68, 0xa9, 0xf2, 0xf7, 0xd0, 0x4f, 0xda, 0x44, 0xf6, 0x2a, 0xa8, 0x5c, 0x59, 0xeb, 0x8a, 0xb1, 0x5a, 0x40, 0xcb, 0xc1, 0xd3, 0x25, 0xb4, 0x6b, 0xba, 0x4f, 0x9f, 0x23, 0x45, 0xed, 0x5c, 0x6b, 0x25, 0xc4, 0xc4, 0x48, 0x68, 0xca, 0x6e, 0xce, 0x72, 0x06, 0x8c, 0x02, 0x46, 0x77, 0xf3, 0x01, 0xa3, 0x0e, 0x64, 0x40, 0x14, 0x50, 0x0e, 0xea, 0xc8, 0xc0, 0x5a, 0x87, 0xc3, 0x43, 0x41, 0x6e, 0x6e, 0x3c, 0xc7, 0x16, 0xc2, 0x88, 0x88, 0x08, 0x4b, 0x18, 0xd7, 0xb2, 0x5e, 0x51, 0xf3, 0x60, 0x46, 0x1c, 0x19, 0xe1, 0x09, 0x39, 0x5f, 0x94, 0x46, 0x03, 0xc5, 0x6f, 0xfd, 0xcb, 0xbd, 0x58, 0xe7, 0xf2, 0xf8, 0x81, 0xf2, 0x0b, 0xe7, 0x0a, 0xc3, 0x91, 0x51, 0x39, 0x5e, 0x47, 0x8a, 0x14, 0x81, 0x01, 0x22, 0xc8, 0xad, 0x44, 0x35, 0x0d, 0x59, 0x16, 0x89, 0x59, 0xaf, 0xcf, 0x29, 0x26, 0x26, 0x01, 0xbe, 0xd9, 0x35, 0x0d, 0x2c, 0xd5, 0xb7, 0x5a, 0x45, 0x59, 0x69, 0x52, 0xe6, 0xff, 0xb9, 0x1d, 0xb4, 0x9e, 0x60, 0x76, 0x1a, 0x0f, 0xa1, 0xea, 0xb4, 0x38, 0x8a, 0xc9, 0xce, 0x97, 0xab, 0x33, 0xce, 0xe5, 0x00, 0xca, 0x69, 0xd3, 0x30, 0x9f, 0xed, 0x2d, 0x80, 0x46, 0x48, 0x7f, 0x27, 0xb9, 0x00, 0x08, 0xb5, 0x7a, 0x85, 0x16, 0x1b, 0x0a, 0x6d, 0xe7, 0x2b, 0x0a, 0xb7, 0x47, 0x48, 0x83, 0x67, 0x4a, 0xb1, 0x85, 0x64, 0x91, 0x92, 0x4e, 0x97, 0xaf, 0x2e, 0x6d, 0xab, 0x46, 0x6a, 0xda, 0xc7, 0x84, 0xf9, 0x5d, 0xa4, 0xf4, 0xe9, 0x28, 0x6e, 0x6d, 0x75, 0xd9, 0xf8, 0x76, 0x6f, 0x5d, 0x91, 0x8e, 0xe1, 0x71, 0x4b, 0x4c, 0x31, 0xd5, 0xdc, 0x12, 0xbf, 0xb1, 0x2a, 0x77, 0xa3, 0xe2, 0xcc, 0x89, 0x0e, 0x01, 0x05, 0xd6, 0x68, 0xf2, 0x56, 0x48, 0xee, 0x6f, 0x2d, 0x1e, 0x9b, 0xee, 0x8e, 0x86, 0xda, 0x7c, 0x93, 0x84, 0x44, 0xcc, 0x3c, 0xcb, 0x57, 0x5c, 0xd9, 0x95, 0x45, 0xa9, 0x70, 0xcb, 0x40, 0x51, 0x52, 0x61, 0x1d, 0x1d, 0x42, 0xad, 0x46, 0xeb, 0x88, 0xde, 0x5e, 0x91, 0xfe, 0xfe, 0x7e, 0x83, 0xbf, 0x99, 0xdc, 0x96, 0xf7, 0x63, 0xc0, 0x02, 0x2a, 0x5c, 0xc3, 0xbb, 0x7b, 0x79, 0xf5, 0x8d, 0x8e, 0x22, 0x31, 0x33, 0x33, 0x53, 0x40, 0x9e, 0xea, 0x7e, 0x5f, 0x88, 0x20, 0x12, 0xb6, 0xb9, 0x3c, 0x8f, 0x4d, 0x72, 0x7f, 0xe0, 0x82, 0x40, 0x23, 0x1a, 0xfa, 0x46, 0x9a, 0xb0, 0xbd, 0xe3, 0xc7, 0x39, 0xc7, 0x73, 0x64, 0x41, 0x80, 0x23, 0x56, 0xda, 0xa9, 0xd3, 0xc2, 0xc3, 0xfe, 0x0d, 0x10, 0xa1, 0x54, 0x96, 0x7c, 0xc6, 0xe8, 0x90, 0xc2, 0xaa, 0x88, 0x4e, 0xa6, 0xad, 0xeb, 0xc9, 0x96, 0x20, 0xdc, 0xbf, 0x7a, 0x9d, 0x48, 0x20, 0x03, 0xb0, 0xc3, 0x68, 0x7e, 0x7e, 0x5b, 0x1d, 0x44, 0xc5, 0x54, 0xb5, 0x29, 0xf4, 0xb7, 0x40, 0xf0, 0x8d, 0xa7, 0xf8, 0x17, 0xf8, 0x60, 0x51, 0x8c, 0x02, 0xb5, 0xc7, 0x90, 0xd1, 0xcd, 0xdc, 0x38, 0xd8, 0x33, 0xd7, 0xdc, 0xc2, 0x06, 0x4b, 0xcd, 0xe5, 0x06, 0xab, 0x66, 0x2a, 0xea, 0x3c, 0x05, 0xde, 0x4f, 0xd3, 0x52, 0x45, 0x18, 0x67, 0x67, 0x73, 0x70, 0xb8, 0x7b, 0x3b, 0x3b, 0xfe, 0xc5, 0x16, 0x0d, 0x57, 0xcd, 0x40, 0x53, 0xd0, 0x04, 0x65, 0x67, 0xa9, 0xfb, 0x67, 0xb6, 0x8b, 0x04, 0x1d, 0x20, 0x9a, 0x02, 0x93, 0xb8, 0xbb, 0x9a, 0x1d, 0xf2, 0x45, 0x4a, 0x29, 0xd5, 0x34, 0xfa, 0x2c, 0xee, 0x7a, 0xe1, 0x6c, 0xbb, 0xb7, 0xe1, 0xb9, 0xd9, 0x97, 0x11, 0x67, 0xa9, 0x05, 0xa6, 0x41, 0x2b, 0x2e, 0x9f, 0x5a, 0x01, 0x4b, 0x28, 0x40, 0x24, 0x05, 0x75, 0xad, 0x86, 0x89, 0x13, 0x02, 0xf4, 0xe0, 0xde, 0x9c, 0x2b, 0x0d, 0x67, 0xb7, 0xf8, 0x4f, 0x43, 0x48, 0xa8, 0xac, 0x15, 0x8f, 0x70, 0x37, 0x88, 0x02, 0x4f, 0xfc, 0x8a, 0x68, 0xa3, 0x15, 0x55, 0x32, 0xf7, 0xb6, 0x10, 0xa3, 0xa7, 0xfb, 0x0b, 0x6c, 0x47, 0xb6, 0x22, 0x4d, 0xd4, 0x32, 0x4b, 0xb4, 0xe4, 0xf8, 0xf2, 0x43, 0x83, 0x43, 0x50, 0x44, 0xcd, 0x9d, 0x47, 0x9b, 0x26, 0xf7, 0x63, 0x33, 0x2e, 0x66, 0x09, 0x25, 0x2b, 0x33, 0x73, 0x69, 0x46, 0xa0, 0x67, 0xa1, 0xc9, 0x68, 0xf2, 0xc1, 0x7a, 0x97, 0xa0, 0x5c, 0x26, 0x57, 0xde, 0x75, 0x07, 0x29, 0x29, 0x29, 0xcd, 0x6c, 0x2b, 0x31, 0x97, 0xfd, 0x97, 0xce, 0xf7, 0x37, 0x2f, 0x10, 0x85, 0xdb, 0x59, 0xc4, 0xd7, 0x43, 0x58, 0xc3, 0xc9, 0xd1, 0xbe, 0x5d, 0xc7, 0x49, 0xce, 0x66, 0xb2, 0x27, 0x58, 0xb7, 0xe0, 0x5f, 0xc5, 0xf1, 0xa9, 0xbf, 0x02, 0x16, 0xcd, 0x18, 0x15, 0xc8, 0x31, 0xb6, 0x4d, 0x3c, 0x39, 0x1c, 0xaf, 0xa3, 0x0c, 0x2c, 0x6c, 0x21, 0xb5, 0x69, 0x91, 0x34, 0x52, 0x09, 0xfa, 0x66, 0xc6, 0x11, 0x30, 0x4a, 0x91, 0x59, 0x5a, 0x08, 0xe7, 0x93, 0x4d, 0x99, 0xd8, 0x71, 0x44, 0xa8, 0x37, 0x0a, 0x34, 0xe8, 0x02, 0x92, 0x5a, 0xf0, 0x24, 0x75, 0xb4, 0xfb, 0xba, 0x35, 0x72, 0xcf, 0x48, 0x0c, 0xc1, 0xf1, 0xac, 0x71, 0x25, 0x99, 0x0c, 0x09, 0x86, 0x19, 0xd9, 0x2a, 0xa4, 0x60, 0x70, 0x7f, 0xee, 0x02, 0x2b, 0x8b, 0xa6, 0xa3, 0xa8, 0x87, 0x9f, 0x6d, 0x58, 0x23, 0x11, 0x7e, 0x25, 0x76, 0x4e, 0xa2, 0x9a, 0xdd, 0xe3, 0xf4, 0x2d, 0x30, 0xc1, 0xc0, 0x3c, 0xce, 0xe6, 0x1d, 0x60, 0x67, 0x46, 0xc6, 0x6a, 0x44, 0x16, 0x79, 0xf9, 0x5b, 0xae, 0x02, 0xde, 0xa9, 0x89, 0xc9, 0x1e, 0xf5, 0xba, 0x77, 0xce, 0x39, 0x92, 0xf8, 0x91, 0x9f, 0x49, 0x09, 0x71, 0xa4, 0xf1, 0xe0, 0x5a, 0x87, 0xe1, 0x70, 0xcf, 0x1b, 0xc2, 0x53, 0x6f, 0xad, 0x9e, 0xf5, 0x72, 0x0a, 0x6b, 0xba, 0x71, 0xab, 0xdd, 0x65, 0xd3, 0x3a, 0x0d, 0xf3, 0xc3, 0x59, 0x64, 0xfa, 0xac, 0xf4, 0x39, 0x2d, 0x34, 0x32, 0x81, 0x96, 0x6c, 0x0b, 0xc9, 0xfa, 0x7b, 0x87, 0xa1, 0x2a, 0x28, 0xb3, 0xd9, 0x1f, 0x2c, 0x9a, 0x83, 0x88, 0x98, 0x09, 0x3f, 0xbb, 0xa2, 0x22, 0xdf, 0x46, 0xa7, 0x12, 0xb4, 0xa0, 0xa1, 0x3e, 0x56, 0xaf, 0x7f, 0xfc, 0xd4, 0xc7, 0x56, 0xa4, 0x97, 0xf1, 0x3c, 0x59, 0x1e, 0xaf, 0xb1, 0xa9, 0x76, 0xd6, 0xbc, 0x63, 0x68, 0x22, 0x61, 0x6e, 0xd0, 0xd5, 0xd5, 0x95, 0x89, 0xc5, 0x72, 0xf1, 0x3e, 0xf3, 0x33, 0xaf, 0x6b, 0x70, 0x6d, 0xad, 0x43, 0x48, 0xa6, 0x99, 0xcd, 0x4c, 0xab, 0xcb, 0x31, 0x22, 0x0b, 0x2d, 0xed, 0x2d, 0x4b, 0x51, 0x83, 0x8b, 0x89, 0x3a, 0x9c, 0x2c, 0xeb, 0xc7, 0x12, 0x85, 0x4d, 0xe8, 0xf4, 0x84, 0x58, 0x29, 0xa2, 0x4b, 0xcf, 0x66, 0x4c, 0xbc, 0x38, 0xb1, 0x60, 0x08, 0x7d, 0x97, 0x68, 0x2c, 0x2d, 0x78, 0x32, 0x7a, 0x99, 0xac, 0x41, 0xa4, 0x62, 0x11, 0x99, 0x29, 0x76, 0x82, 0x63, 0xd4, 0xd0, 0x4c, 0x25, 0xa1, 0xaa, 0x3e, 0x99, 0x28, 0xaa, 0x6f, 0xd1, 0x78, 0xf9, 0x41, 0xe8, 0x3f, 0xfe, 0x34, 0x1d, 0x65, 0xc0, 0xf5, 0x73, 0x25, 0xc1, 0x93, 0x9c, 0xfb, 0x31, 0x58, 0xb0, 0x2f, 0x3c, 0x6b, 0x64, 0x84, 0x4f, 0x9b, 0xc7, 0xc8, 0x3c, 0xa7, 0x0a, 0xbf, 0x52, 0x5d, 0x20, 0xeb, 0x3b, 0x1d, 0x0e, 0x81, 0x68, 0xc4, 0x64, 0x2b, 0x3a, 0x3a, 0xba, 0x7f, 0xd7, 0xdb, 0x93, 0x74, 0x89, 0x57, 0x73, 0x5b, 0x9b, 0xf1, 0xc3, 0xc5, 0x26, 0xf6, 0x4e, 0x48, 0xc8, 0x51, 0xfc, 0xce, 0xae, 0x32, 0x24, 0xfb, 0xae, 0xb0, 0x35, 0x9f, 0x29, 0xdd, 0x1b, 0x7e, 0x9d, 0xc0, 0x2b, 0xea, 0x10, 0xe3, 0x4a, 0x85, 0xc1, 0xd8, 0x28, 0x69, 0xb2, 0xe4, 0x65, 0x5f, 0x15, 0x59, 0x78, 0x6a, 0x27, 0xf2, 0xd0, 0x5f, 0xdd, 0x05, 0xcb, 0x1e, 0xb0, 0x48, 0x9f, 0xb8, 0x79, 0xff, 0xd0, 0xc9, 0xf7, 0x20, 0xda, 0xff, 0x92, 0x46, 0xbc, 0xa7, 0x1f, 0x43, 0x41, 0xfe, 0xc0, 0x3b, 0x8b, 0x95, 0x8e, 0x5d, 0xd2, 0x32, 0x12, 0x60, 0x13, 0x41, 0xc6, 0x86, 0xb6, 0xfc, 0x6d, 0x79, 0x14, 0xb3, 0xdc, 0x06, 0xfa, 0x66, 0x67, 0x87, 0xcd, 0x7b, 0xe2, 0x9f, 0x3f, 0x04, 0x14, 0x60, 0x2b, 0x6f, 0xf6, 0x22, 0xf0, 0x3f, 0x4e, 0x29, 0x81, 0xb7, 0x57, 0x39, 0x1a, 0xb6, 0xb7, 0xb7, 0xf7, 0x2f, 0x30, 0xb6, 0xb8, 0x12, 0x56, 0xfb, 0x2c, 0x77, 0x20, 0x36, 0x60, 0x44, 0xd8, 0x65, 0x8f, 0x69, 0xc7, 0xf8, 0x88, 0x93, 0x80, 0x53, 0x31, 0x90, 0x15, 0x26, 0x6f, 0x75, 0xeb, 0x2b, 0xa7, 0x47, 0xf2, 0xb1, 0xc1, 0xa0, 0x6f, 0xbd, 0x12, 0x63, 0x34, 0x95, 0xe1, 0xd4, 0x8f, 0x20, 0x1b, 0x14, 0xbe, 0x96, 0x45, 0x5b, 0xd8, 0xa4, 0x84, 0x75, 0x1d, 0x20, 0xc4, 0xf4, 0x9f, 0xaa, 0x20, 0xfe, 0x27, 0x64, 0x84, 0x2d, 0xc7, 0x6a, 0x09, 0x73, 0x2d, 0x7c, 0x2d, 0x3d, 0xb5, 0x0c, 0x71, 0xba, 0xdd, 0x4b, 0xeb, 0x43, 0x0d, 0x61, 0xd3, 0x83, 0xcf, 0xad, 0x96, 0x23, 0x80, 0x8f, 0x0a, 0x17, 0x0e, 0x82, 0xb5, 0x70, 0x19, 0x07, 0xc0, 0x7a, 0x03, 0xf0, 0x30, 0xa5, 0x37, 0x6f, 0x84, 0x20, 0x2e, 0x42, 0xd4, 0xc0, 0xc0, 0xc0, 0x9f, 0x99, 0x3a, 0x8e, 0x49, 0x24, 0x95, 0x26, 0xde, 0x22, 0xc2, 0xf1, 0xf0, 0x1f, 0xf7, 0xe2, 0xaf, 0xd5, 0xcf, 0x37, 0xdf, 0x0a, 0xf6, 0x5d, 0x62, 0xed, 0x0c, 0x40, 0x84, 0x5c, 0x1e, 0x78, 0x69, 0xdc, 0x8f, 0x1f, 0x17, 0x53, 0xb2, 0xf6, 0x0e, 0x31, 0xf1, 0x61, 0x75, 0x50, 0xe1, 0x5e, 0x45, 0x20, 0x6b, 0x9e, 0xbb, 0x35, 0x3f, 0x36, 0xd6, 0x38, 0x30, 0xbe, 0xef, 0x68, 0x80, 0xf4, 0x0f, 0xe5, 0x59, 0x03, 0x49, 0x84, 0xe4, 0x0e, 0x78, 0xfa, 0x27, 0xce, 0x9b, 0x58, 0xc8, 0x70, 0x8d, 0x85, 0xf4, 0x7a, 0x44, 0xe6, 0x28, 0x9a, 0x38, 0xc9, 0xda, 0x8c, 0x56, 0xef, 0xae, 0xb0, 0xa7, 0xf1, 0x69, 0x00, 0xf6, 0x7e, 0x78, 0xdc, 0xcf, 0x31, 0x34, 0x2d, 0xce, 0xa2, 0xbe, 0x86, 0x41, 0xc2, 0xd9, 0x38, 0x5b, 0x6d, 0x53, 0xc5, 0xbf, 0x1e, 0xa1, 0xc6, 0x51, 0x3f, 0xc5, 0x67, 0x8c, 0x12, 0xc9, 0xeb, 0xef, 0x34, 0x7e, 0x37, 0xfc, 0x6f, 0x6c, 0xf7, 0xe1, 0x68, 0x48, 0xd0, 0xfe, 0x55, 0xcf, 0xba, 0x32, 0xa6, 0x45, 0xe8, 0x4b, 0x77, 0x3c, 0x99, 0x04, 0xcd, 0x6c, 0x12, 0x9c, 0xff, 0x7f, 0x19, 0x68, 0x97, 0x17, 0xdf, 0x45, 0x2a, 0xe7, 0xc9, 0xd8, 0xf4, 0x28, 0x51, 0x8f, 0x51, 0xe4, 0x5a, 0x90, 0x51, 0x22, 0x95, 0x90, 0x27, 0x13, 0x78, 0x3e, 0xaa, 0xcc, 0xf9, 0xb3, 0xa1, 0xf5, 0xca, 0x0c, 0x2d, 0xcd, 0xd1, 0xe9, 0x0c, 0x96, 0x89, 0x0a, 0xf2, 0x05, 0x69, 0xc0, 0x2c, 0x81, 0xbf, 0xce, 0xb8, 0xfa, 0xe0, 0x66, 0x0d, 0xc9, 0xef, 0x6f, 0x85, 0x0e, 0x26, 0x70, 0x8d, 0xd1, 0xd1, 0xc8, 0x31, 0x0b, 0xac, 0x6c, 0xc5, 0xf2, 0x39, 0xb1, 0x07, 0x07, 0xe6, 0xde, 0x57, 0xc3, 0x54, 0x35, 0x35, 0x35, 0x93, 0xe6, 0x28, 0x1c, 0x19, 0x31, 0xc4, 0x7e, 0x2f, 0x1f, 0x7f, 0x7a, 0x53, 0xed, 0xd2, 0xfd, 0x25, 0xee, 0xd9, 0x14, 0x6e, 0x7e, 0xbb, 0x99, 0x5c, 0x26, 0xf5, 0x1e, 0x5b, 0xcd, 0xe6, 0xad, 0xa3, 0x17, 0x5b, 0xd2, 0xa6, 0xe6, 0xcf, 0x9f, 0xde, 0x5c, 0xe1, 0xa0, 0xee, 0x4d, 0x95, 0xce, 0x7d, 0xbb, 0xf7, 0xcc, 0x52, 0x15, 0x39, 0x73, 0x4f, 0x40, 0x1a, 0xf2, 0x93, 0xa2, 0x82, 0xd2, 0xa3, 0x8b, 0x29, 0x74, 0x41, 0x29, 0xcb, 0x29, 0xe9, 0xe4, 0x6c, 0x34, 0xe1, 0xc2, 0x0b, 0x2c, 0x6f, 0x6f, 0x68, 0x3d, 0xa6, 0x6d, 0xce, 0x18, 0x51, 0x76, 0xba, 0x90, 0xe4, 0x1d, 0x78, 0xe2, 0xa4, 0xd0, 0x3f, 0x56, 0x41, 0x69, 0x6e, 0x8f, 0x2d, 0x59, 0xcb, 0x1e, 0x3d, 0xe2, 0x41, 0x8e, 0xd5, 0xd5, 0x0e, 0x2e, 0x15, 0xa9, 0x65, 0x85, 0xc7, 0x07, 0x17, 0x4f, 0x83, 0x53, 0x53, 0x9f, 0xca, 0xd5, 0x2a, 0x7b, 0x13, 0xa8, 0xe4, 0x6b, 0xdc, 0x2f, 0x8d, 0xb8, 0x78, 0x78, 0xe6, 0xff, 0xbb, 0x1d, 0xdb, 0xbf, 0x9e, 0xea, 0xf2, 0xf3, 0xcb, 0xe4, 0xf7, 0xc2, 0x39, 0xef, 0x7c, 0xae, 0x12, 0xf7, 0xaa, 0x5b, 0x57, 0x78, 0xba, 0x3d, 0xca, 0x02, 0xcb, 0xe8, 0x35, 0xa3, 0xd6, 0x3a, 0x7c, 0xc7, 0xaf, 0x3c, 0xdf, 0xda, 0x0a, 0x24, 0xf6, 0x7d, 0x80, 0x00, 0x5d, 0x00, 0xd8, 0x4d, 0xa7, 0x55, 0x0f, 0x1f, 0x86, 0x46, 0x5c, 0xe5, 0x7c, 0x56, 0x44, 0xa0, 0xd8, 0xfc, 0x7e, 0xc0, 0x5d, 0xb5, 0xee, 0x15, 0xfc, 0xd2, 0x6b, 0x44, 0x6d, 0xa1, 0x24, 0x5d, 0xf8, 0xb5, 0xce, 0x7d, 0xbe, 0xd9, 0x51, 0xac, 0x08, 0x4b, 0x07, 0x47, 0x9a, 0x47, 0xd8, 0x0e, 0xf1, 0x13, 0x32, 0xa4, 0x63, 0x98, 0x9e, 0x99, 0x0e, 0x09, 0xfa, 0x62, 0x43, 0x82, 0x64, 0xb6, 0xb3, 0x01, 0x38, 0xc4, 0x41, 0x45, 0x65, 0x03, 0x3d, 0x34, 0x3e, 0x04, 0xc2, 0x2e, 0x96, 0x03, 0xed, 0x1c, 0x5b, 0xa5, 0x24, 0x8b, 0xb6, 0xed, 0x5b, 0xf5, 0xf7, 0x84, 0x98, 0xd0, 0xf0, 0xca, 0x4a, 0x7a, 0xb5, 0x6a, 0xbd, 0x98, 0xb9, 0x72, 0x75, 0x32, 0x56, 0x56, 0x4c, 0x80, 0x87, 0xfb, 0x76, 0x47, 0x53, 0x3e, 0xc8, 0xaa, 0x7f, 0x60, 0xa0, 0x67, 0x78, 0x18, 0xc1, 0xd4, 0xd4, 0xd4, 0xfd, 0xf1, 0x8a, 0x02, 0x12, 0x12, 0x92, 0xc9, 0xec, 0x2f, 0x61, 0x03, 0xa8, 0x29, 0x5d, 0x89, 0xa3, 0xec, 0xc5, 0xc5, 0xad, 0x7c, 0x64, 0xef, 0xc5, 0xeb, 0x0d, 0x36, 0xd9, 0xef, 0x9a, 0x36, 0x51, 0x6a, 0x1c, 0xa5, 0xbc, 0xae, 0xae, 0x8e, 0x46, 0x35, 0xd6, 0x10, 0x5c, 0xa1, 0xdd, 0x54, 0x35, 0xd2, 0x82, 0x51, 0x4a, 0x98, 0x80, 0x5b, 0x01, 0xa3, 0xf0, 0xab, 0xda, 0xce, 0xc4, 0x30, 0x72, 0x6d, 0x95, 0xa7, 0xbb, 0xaf, 0x81, 0x9b, 0xf0, 0xa4, 0x92, 0x64, 0xe3, 0x1a, 0x3d, 0x27, 0x33, 0x16, 0xf7, 0xeb, 0xa1, 0xa4, 0xcc, 0xb0, 0xff, 0xa7, 0x9c, 0xb0, 0x03, 0x2a, 0x84, 0x9f, 0xc3, 0xd8, 0xf6, 0xb6, 0x86, 0x61, 0x0c, 0x9f, 0xdb, 0xa7, 0x8a, 0x3a, 0x70, 0xdb, 0x57, 0xb2, 0xd8, 0xe7, 0x53, 0x0c, 0xb8, 0xea, 0xef, 0x2d, 0x42, 0x04, 0x7a, 0x3e, 0x3b, 0x6c, 0x75, 0x65, 0x00, 0x30, 0x1a, 0x0e, 0x17, 0x50, 0x58, 0xcd, 0x6e, 0x01, 0xe4, 0x1e, 0xdd, 0xed, 0x9e, 0x42, 0x52, 0xee, 0xcd, 0xeb, 0xa7, 0x4a, 0xfa, 0x1f, 0x1d, 0x3a, 0x39, 0x64, 0x10, 0x18, 0x11, 0x34, 0x62, 0x8a, 0xd7, 0x21, 0xf0, 0x5d, 0x2d, 0xc9, 0x53, 0x65, 0x61, 0x79, 0x71, 0x45, 0x6a, 0xa5, 0xae, 0xb4, 0xb4, 0xd4, 0x45, 0xab, 0x8e, 0xc4, 0xc0, 0xca, 0x0a, 0x49, 0x5b, 0x5b, 0x1b, 0xa0, 0x57, 0xb1, 0xf2, 0xe3, 0x91, 0x5d, 0x47, 0x9d, 0x4e, 0xef, 0x96, 0x31, 0x0d, 0x88, 0x08, 0x15, 0x54, 0x32, 0x01, 0x75, 0x0a, 0x5a, 0x3a, 0x1c, 0xe3, 0xd1, 0x6c, 0xb2, 0x87, 0xed, 0x8b, 0x10, 0x9e, 0x9c, 0x5f, 0x8c, 0xba, 0xad, 0xc1, 0xd2, 0x29, 0x96, 0xeb, 0x6e, 0x59, 0x86, 0xe0, 0x1f, 0xfb, 0x38, 0x1b, 0x13, 0x05, 0xb8, 0x96, 0x6c, 0x82, 0xfc, 0xb4, 0xb8, 0x9c, 0xe7, 0x82, 0x83, 0xc5, 0x59, 0x70, 0x4c, 0xd4, 0xf5, 0xac, 0x94, 0x71, 0x07, 0x48, 0x6e, 0xea, 0xa7, 0xce, 0x8d, 0x64, 0x07, 0x71, 0x67, 0x01, 0x9d, 0xbb, 0xc8, 0x9e, 0x0e, 0xa9, 0x11, 0xdf, 0xf5, 0x4b, 0xf2, 0xf3, 0x95, 0xd3, 0x5b, 0xa2, 0xe1, 0x51, 0x88, 0x8c, 0x26, 0xd9, 0xbb, 0xfb, 0x0b, 0xb3, 0xde, 0xaf, 0xf7, 0xd7, 0xab, 0x8b, 0x0e, 0x7b, 0x3b, 0x77, 0xcb, 0x3b, 0xb9, 0xb9, 0x17, 0x49, 0xff, 0xeb, 0x42, 0xf1, 0x74, 0xbd, 0x0c, 0xb3, 0xb3, 0xc2, 0xad, 0xd1, 0xa0, 0xd3, 0xe9, 0xb8, 0x86, 0xf7, 0x42, 0xcb, 0xf9, 0x36, 0x5b, 0xb0, 0x6f, 0xe9, 0x24, 0x2b, 0x7b, 0xa4, 0xd6, 0xc6, 0xc7, 0x2b, 0xef, 0x15, 0x22, 0x0f, 0xdf, 0x3d, 0x53, 0x22, 0x3f, 0x67, 0x84, 0xee, 0xad, 0xd5, 0xf6, 0x1b, 0xef, 0x1a, 0x99, 0x94, 0x3e, 0xe7, 0xff, 0xee, 0x02, 0x00, 0x42, 0x5a, 0xbb, 0x31, 0x4a, 0x2f, 0x29, 0x37, 0x3a, 0x6d, 0xfe, 0xba, 0xc0, 0x70, 0x07, 0x90, 0xec, 0x11, 0x45, 0xc7, 0x4f, 0x43, 0x7f, 0x32, 0xb3, 0xea, 0xcd, 0x07, 0x3f, 0xce, 0x4f, 0x6b, 0xe5, 0x98, 0x6b, 0x19, 0xe0, 0x3c, 0x07, 0x45, 0xb2, 0xc0, 0xb7, 0xd2, 0xc5, 0x2c, 0xc5, 0x1e, 0xec, 0x88, 0xb3, 0x1b, 0x98, 0x1a, 0x5d, 0xe2, 0x27, 0xf4, 0x1b, 0x34, 0xe6, 0x83, 0x86, 0xee, 0x31, 0xba, 0x60, 0x65, 0x0d, 0xf0, 0xb3, 0x9c, 0xa2, 0xe2, 0x18, 0x8f, 0x50, 0xb1, 0x9a, 0xf7, 0xea, 0x70, 0x0f, 0x0e, 0x92, 0x69, 0xac, 0xa8, 0x24, 0x55, 0x17, 0xa2, 0x5b, 0xfb, 0xeb, 0x37, 0xc8, 0x8d, 0xdd, 0xb3, 0x60, 0x12, 0x56, 0x41, 0xe5, 0x61, 0x80, 0x70, 0xac, 0xa2, 0x5a, 0xc5, 0x0a, 0x9b, 0x1c, 0x6d, 0x51, 0x19, 0x52, 0xa0, 0x5a, 0x74, 0xf2, 0x7e, 0xed, 0xee, 0xaa, 0x46, 0x7b, 0x53, 0xcd, 0x46, 0x37, 0x73, 0xdd, 0xb6, 0x3e, 0x98, 0x10, 0x24, 0x92, 0x97, 0x98, 0x6e, 0x9d, 0xca, 0x77, 0x0a, 0xfb, 0xe6, 0xed, 0x31, 0x23, 0x6a, 0x6a, 0x6a, 0x86, 0x47, 0x44, 0x40, 0xe4, 0x54, 0x67, 0x0d, 0x52, 0x11, 0xa2, 0x12, 0x0c, 0x42, 0x92, 0xd5, 0x5b, 0xec, 0x42, 0x23, 0xd5, 0xfd, 0x1a, 0xfc, 0xfc, 0x18, 0x32, 0x10, 0x1e, 0x23, 0x2d, 0x62, 0x18, 0xdf, 0x2c, 0x85, 0x16, 0x08, 0x34, 0x7e, 0xde, 0x8c, 0xfa, 0xc7, 0x79, 0xc6, 0xc7, 0xad, 0x47, 0xfc, 0xa4, 0x18, 0x8a, 0x83, 0x1c, 0x21, 0x41, 0x79, 0x2e, 0xf6, 0x26, 0xb1, 0xe9, 0x51, 0x99, 0x8f, 0x33, 0x0e, 0x94, 0xea, 0x47, 0x50, 0xde, 0x1a, 0x30, 0x72, 0xc5, 0x9b, 0x03, 0xfb, 0x98, 0x51, 0xe8, 0x69, 0x5a, 0xaf, 0x31, 0xfb, 0xb0, 0x1a, 0x69, 0x9e, 0x0b, 0xfd, 0x24, 0xbf, 0x0c, 0x8a, 0xdf, 0x88, 0xfe, 0xe3, 0xb0, 0xc5, 0xe6, 0xc9, 0x49, 0x1a, 0x00, 0x62, 0x1f, 0xb7, 0xa6, 0x8f, 0x4f, 0xd6, 0x54, 0xf2, 0x89, 0x36, 0x04, 0xf3, 0x49, 0x7b, 0x47, 0x7c, 0x41, 0x9a, 0xa0, 0x59, 0xf7, 0xc0, 0x1c, 0x14, 0x21, 0x7b, 0xf0, 0x6a, 0xe8, 0xaf, 0xfc, 0x4d, 0x45, 0xa3, 0x69, 0x5b, 0xe5, 0x5a, 0x96, 0xc1, 0xce, 0x0e, 0x40, 0xb4, 0x59, 0x8e, 0x4f, 0x31, 0x65, 0x5d, 0x03, 0x4d, 0x44, 0x45, 0x89, 0x05, 0xfe, 0x68, 0xd7, 0x63, 0xa5, 0xdc, 0x20, 0x21, 0x35, 0x82, 0xc6, 0xcb, 0x41, 0x41, 0xdc, 0x51, 0x7d, 0x68, 0x56, 0x0c, 0x4c, 0x6b, 0xbd, 0x5d, 0xd0, 0xdf, 0xd3, 0x8e, 0xc9, 0x91, 0x01, 0x88, 0x0a, 0x1a, 0x48, 0xe8, 0x22, 0x16, 0xee, 0xfc, 0x1c, 0xf2, 0xad, 0xde, 0x06, 0x6a, 0x9d, 0x36, 0x5c, 0xa4, 0xf4, 0x2a, 0xf7, 0xd3, 0x84, 0xf4, 0xf8, 0x98, 0x88, 0xeb, 0xce, 0x5e, 0xce, 0x51, 0x53, 0x92, 0xff, 0xf4, 0xaf, 0x73, 0xbe, 0x05, 0xfa, 0x1a, 0xd4, 0x52, 0x43, 0x37, 0xde, 0xaa, 0xb0, 0x1e, 0x80, 0xb0, 0x7f, 0x73, 0x86, 0xc0, 0x7b, 0x86, 0x81, 0x6f, 0x38, 0xbb, 0xf7, 0xc3, 0x16, 0x87, 0x77, 0xef, 0x39, 0xbe, 0x62, 0x45, 0x90, 0x41, 0x88, 0x9b, 0xd4, 0x9e, 0xda, 0xd0, 0x5d, 0x4e, 0xf1, 0x16, 0x7c, 0x9a, 0x6f, 0xd0, 0x8d, 0xc9, 0xaf, 0xd2, 0xa4, 0xc3, 0x09, 0x7c, 0xf9, 0xb7, 0x71, 0x91, 0x56, 0x4e, 0xa3, 0xe9, 0x42, 0x21, 0x64, 0x15, 0xf9, 0xb3, 0xbe, 0x65, 0x16, 0x31, 0x24, 0x24, 0x24, 0x3c, 0x36, 0x56, 0x2d, 0x21, 0xad, 0xf3, 0x88, 0x9d, 0x18, 0x9b, 0x40, 0xff, 0x58, 0xca, 0x6e, 0x79, 0x70, 0x4c, 0x34, 0xdc, 0x6d, 0x0d, 0xdf, 0x5f, 0xc8, 0x6f, 0x82, 0x26, 0xc6, 0x5d, 0xf3, 0x81, 0x8f, 0x81, 0xe7, 0xa1, 0xb5, 0x20, 0xa8, 0x9a, 0x97, 0xe5, 0xcf, 0x95, 0xfd, 0xd5, 0xb4, 0x4d, 0x66, 0x9b, 0x27, 0x71, 0x88, 0xd8, 0xd1, 0x6e, 0x60, 0xd4, 0xff, 0xa3, 0xe9, 0xaa, 0xc3, 0xa2, 0x7e, 0xbe, 0xee, 0x22, 0x21, 0x21, 0xdd, 0x1d, 0x02, 0x22, 0xdd, 0xdd, 0x12, 0xd2, 0x48, 0x77, 0x77, 0x77, 0x97, 0x94, 0x74, 0x23, 0xdd, 0x20, 0x25, 0x25, 0xdd, 0xd2, 0xdd, 0xcd, 0x92, 0x8b, 0x34, 0x2c, 0xdd, 0xf5, 0xee, 0x7e, 0xdf, 0xe7, 0xf7, 0x3c, 0xfc, 0x39, 0xcc, 0xec, 0xdc, 0xb9, 0xf7, 0xdc, 0x73, 0x26, 0xee, 0x47, 0x12, 0x8b, 0x11, 0x92, 0x2c, 0x7c, 0xbb, 0x9f, 0x8a, 0xb1, 0xf0, 0x99, 0x7b, 0xa6, 0x33, 0x38, 0xff, 0xa0, 0xa3, 0xe5, 0x75, 0x22, 0x87, 0x81, 0xdc, 0x31, 0xaa, 0xfd, 0x28, 0xd2, 0x88, 0x6d, 0x3e, 0xa7, 0xe5, 0x7d, 0xdc, 0x3c, 0xc9, 0xa2, 0xa0, 0xb6, 0xaf, 0x22, 0x6a, 0x59, 0xe3, 0x7e, 0x29, 0x99, 0x25, 0x46, 0xb7, 0xe2, 0x0f, 0x74, 0xd3, 0x36, 0x15, 0xb6, 0x50, 0x56, 0x22, 0x59, 0x7e, 0x24, 0xf4, 0xf1, 0xb4, 0x35, 0xac, 0x3c, 0xd2, 0xa7, 0x1d, 0x3c, 0x62, 0x52, 0x29, 0x61, 0xf7, 0xce, 0x71, 0xb7, 0xdb, 0x15, 0x0f, 0xce, 0x6a, 0xf8, 0x9e, 0x91, 0x41, 0xd8, 0xe6, 0x79, 0x66, 0x70, 0x58, 0x0f, 0x41, 0xe4, 0x63, 0x6d, 0x62, 0x77, 0x48, 0x58, 0xd6, 0x82, 0x93, 0x0f, 0x0f, 0xe6, 0xab, 0x15, 0x62, 0x63, 0xbc, 0xbd, 0x4f, 0xec, 0x18, 0x59, 0x9d, 0xb5, 0x08, 0xb8, 0x03, 0x5f, 0x85, 0xc3, 0x6f, 0x8e, 0x91, 0x85, 0xe3, 0x2b, 0x6f, 0x05, 0x39, 0x04, 0xd0, 0xaf, 0xba, 0xd7, 0xde, 0xd5, 0x15, 0x5f, 0xb8, 0x81, 0x6d, 0xe9, 0x5b, 0x9a, 0x6a, 0xa5, 0xbf, 0x96, 0xfe, 0xc1, 0x2d, 0xd9, 0xdd, 0x93, 0x35, 0x9f, 0x77, 0xe9, 0xfc, 0x2c, 0x31, 0xcd, 0xd0, 0x9f, 0xaf, 0x19, 0x15, 0x8d, 0x29, 0xa9, 0x7d, 0x92, 0x30, 0x46, 0x4e, 0x0e, 0xdf, 0xef, 0x61, 0x9e, 0x27, 0x4f, 0xb6, 0x82, 0x1f, 0x6d, 0x19, 0xfb, 0x5d, 0x39, 0x44, 0x51, 0x6b, 0x57, 0x84, 0x75, 0x2c, 0xb0, 0xd6, 0xa6, 0xf7, 0xe0, 0x9c, 0x6c, 0xa1, 0xed, 0x11, 0x89, 0xeb, 0x4b, 0x81, 0x32, 0x05, 0x37, 0xb7, 0x86, 0xc2, 0xe2, 0xf8, 0x24, 0x32, 0x7b, 0xab, 0x38, 0x53, 0x52, 0x4b, 0x17, 0xf4, 0x8d, 0xca, 0xec, 0xdd, 0x90, 0x4d, 0x09, 0x4b, 0xbb, 0xf2, 0xdf, 0xa1, 0x7b, 0xca, 0xce, 0x5a, 0x97, 0x6d, 0xb3, 0x06, 0x37, 0x0d, 0x16, 0xf9, 0x4b, 0x0a, 0x6e, 0xb2, 0xe8, 0xa5, 0xe7, 0x0f, 0x99, 0xff, 0x9a, 0x79, 0x78, 0x9f, 0x57, 0x1b, 0x18, 0x3f, 0x25, 0xfe, 0x38, 0x90, 0xc4, 0x0c, 0xde, 0xa0, 0xfc, 0x99, 0x4f, 0xe2, 0xe0, 0x30, 0x16, 0xcb, 0x4b, 0x32, 0x63, 0x1c, 0x3e, 0x92, 0xf5, 0x8e, 0xb5, 0xe2, 0x31, 0x8a, 0x11, 0x0f, 0xc5, 0xf5, 0x17, 0x5a, 0xdf, 0x5a, 0x79, 0x1f, 0x67, 0x75, 0x39, 0x13, 0x4e, 0x59, 0xfb, 0x90, 0x24, 0xa8, 0x6d, 0x3f, 0x46, 0x60, 0x59, 0x7b, 0xa9, 0x9c, 0x17, 0xb5, 0x00, 0x82, 0x03, 0xcc, 0xdb, 0x10, 0x14, 0xac, 0x60, 0x93, 0xfc, 0x76, 0xb0, 0x38, 0xf3, 0x3e, 0x30, 0xaf, 0xa5, 0xd8, 0x59, 0xcd, 0x57, 0xbf, 0xae, 0xbe, 0xe9, 0x6f, 0x2f, 0x61, 0x5f, 0xe3, 0x46, 0xf3, 0xda, 0xc2, 0x0c, 0x59, 0x25, 0xbe, 0x42, 0x4f, 0xd2, 0xdd, 0x50, 0xef, 0xaf, 0x71, 0xfc, 0xb0, 0xb7, 0x6a, 0xe9, 0x6d, 0x88, 0xc3, 0x54, 0x81, 0x25, 0xa7, 0x85, 0x4e, 0xfd, 0xd7, 0x16, 0x06, 0x39, 0x99, 0x38, 0x72, 0xb9, 0x15, 0xaa, 0xb5, 0x87, 0x3e, 0x89, 0x87, 0x84, 0x13, 0x5c, 0xb3, 0x73, 0x3a, 0xbe, 0xe6, 0xba, 0x8b, 0xf7, 0x7a, 0x0e, 0xe1, 0x44, 0x8d, 0x0b, 0x9b, 0xef, 0x82, 0xab, 0x99, 0x6a, 0xfd, 0x4f, 0xdf, 0xc9, 0x13, 0x2f, 0xd4, 0x28, 0xa2, 0xb2, 0xab, 0x70, 0xfc, 0x59, 0x18, 0xd4, 0xc0, 0x5b, 0x45, 0xfa, 0x7a, 0xba, 0xd6, 0xd5, 0x20, 0xfc, 0xd0, 0xe9, 0x7b, 0xd7, 0xf0, 0xc7, 0x42, 0x75, 0x67, 0xc9, 0x30, 0x50, 0x9d, 0xb8, 0xd9, 0xc5, 0x39, 0xc8, 0xd5, 0x55, 0xf7, 0x44, 0xc8, 0x4b, 0x91, 0xe5, 0x11, 0x11, 0xde, 0x8f, 0x31, 0x9d, 0xaf, 0xa3, 0x97, 0x2b, 0xb6, 0xc9, 0xa8, 0x5e, 0xeb, 0x60, 0x6b, 0x0e, 0x39, 0xaf, 0x83, 0x47, 0x8a, 0x09, 0xcd, 0x74, 0xff, 0x55, 0x35, 0x5f, 0x66, 0x6c, 0x11, 0x21, 0x2c, 0xad, 0x1d, 0x7b, 0x5c, 0x21, 0x76, 0xec, 0x6b, 0x7f, 0x95, 0xe7, 0xd9, 0x2d, 0x59, 0x09, 0xd4, 0x37, 0x43, 0x08, 0xae, 0x35, 0x9d, 0x5a, 0xd7, 0x43, 0x09, 0x09, 0x03, 0xf3, 0x2c, 0xd2, 0xfd, 0x1a, 0xe3, 0xac, 0xc4, 0x4e, 0x57, 0x8d, 0x86, 0xda, 0xc2, 0xac, 0xce, 0xd6, 0x2b, 0x2a, 0x34, 0x6d, 0xe1, 0x14, 0xe6, 0x22, 0x02, 0x13, 0x7f, 0xd1, 0xce, 0x85, 0x13, 0xe3, 0x02, 0x20, 0xab, 0xf9, 0xeb, 0xf1, 0xea, 0x3b, 0xec, 0x7b, 0x0a, 0xbc, 0xe8, 0xca, 0x0c, 0x05, 0x3a, 0xf4, 0x3e, 0x56, 0x5e, 0x4f, 0xc5, 0x75, 0x27, 0x01, 0x9e, 0xe6, 0x2f, 0x8a, 0x01, 0x98, 0x49, 0x73, 0xec, 0x95, 0x5e, 0x72, 0x9e, 0xe9, 0x59, 0x44, 0xa6, 0x0f, 0xd9, 0x17, 0x56, 0xea, 0x93, 0x4c, 0xd5, 0x28, 0x7a, 0x3a, 0xcb, 0xc6, 0xe3, 0xf9, 0x64, 0x15, 0xce, 0x6a, 0x27, 0xd0, 0x87, 0x59, 0x33, 0x0f, 0x5d, 0x70, 0xa7, 0x3d, 0xbb, 0x4e, 0x10, 0x95, 0xea, 0x63, 0x6e, 0x1d, 0x46, 0x75, 0xa5, 0xaa, 0x3a, 0x87, 0x31, 0x9b, 0x5b, 0x13, 0x29, 0xf6, 0x81, 0x3f, 0xc8, 0xe3, 0x74, 0xf2, 0x8f, 0xd5, 0xe3, 0x21, 0x5e, 0x18, 0x55, 0xa7, 0xbf, 0xf6, 0x43, 0xd9, 0x39, 0xc6, 0xf3, 0x7d, 0x37, 0xba, 0xda, 0xcc, 0xa4, 0xfb, 0xb6, 0xb7, 0x0a, 0x11, 0x28, 0x59, 0x0e, 0x95, 0x5f, 0xf2, 0xdb, 0x6e, 0x97, 0xba, 0x6d, 0x5c, 0xb7, 0x26, 0x44, 0x70, 0x33, 0x39, 0xb7, 0xef, 0xfe, 0xfb, 0xb7, 0xd5, 0x1f, 0x89, 0xad, 0xa3, 0xdd, 0x5c, 0xee, 0xf4, 0x74, 0x6b, 0x4f, 0x4d, 0x93, 0x8a, 0xb7, 0xe4, 0xe2, 0x6a, 0x13, 0x8e, 0x5e, 0x8a, 0x16, 0x52, 0x5e, 0x07, 0xf0, 0xcb, 0xf5, 0x58, 0x5f, 0x77, 0x0c, 0xee, 0x33, 0x36, 0xdd, 0x1e, 0xdf, 0x76, 0xf2, 0x9c, 0xe9, 0x64, 0x0b, 0x54, 0xe8, 0x26, 0x23, 0xdd, 0xde, 0x53, 0xd3, 0xc1, 0xde, 0x7e, 0x5e, 0x78, 0xba, 0x69, 0xe2, 0x11, 0x13, 0xf8, 0x00, 0x9e, 0x53, 0xb7, 0x97, 0x9f, 0x7b, 0x10, 0x56, 0xb1, 0x36, 0xf8, 0x24, 0x54, 0xfe, 0x65, 0x1a, 0xbb, 0x3f, 0x1f, 0xd6, 0xeb, 0xdc, 0x68, 0x16, 0xab, 0x84, 0xdd, 0xd4, 0x44, 0x7b, 0xe5, 0xaf, 0x81, 0xd8, 0xbd, 0xd9, 0xa2, 0x56, 0xed, 0xca, 0x6a, 0x6b, 0x14, 0x3b, 0x87, 0x46, 0x0d, 0xb2, 0xa5, 0xb1, 0xc5, 0x6f, 0x8f, 0x40, 0x6d, 0x7c, 0xba, 0xa8, 0xde, 0xe2, 0xed, 0x92, 0x66, 0x38, 0x62, 0x6e, 0xbb, 0xb2, 0x3f, 0x6b, 0x8c, 0x62, 0xa4, 0xe1, 0xc6, 0xb5, 0x6e, 0x87, 0x2a, 0x0b, 0xcb, 0x11, 0x53, 0x7d, 0x4a, 0x95, 0x7b, 0xbd, 0x25, 0x61, 0x42, 0x90, 0xe8, 0x5c, 0x3b, 0xaa, 0x3b, 0x90, 0xe5, 0x20, 0x96, 0x63, 0xf4, 0x76, 0xb4, 0xeb, 0x5c, 0xd2, 0xdd, 0x77, 0x5a, 0x26, 0xe0, 0xaa, 0xbd, 0x4e, 0x79, 0x3d, 0x7b, 0x20, 0xa6, 0xe6, 0xad, 0xfe, 0x3e, 0xd3, 0xaa, 0x4f, 0x0c, 0xc1, 0x44, 0x35, 0xa9, 0x5e, 0x51, 0x66, 0xa5, 0xdf, 0x82, 0xf6, 0x21, 0xd3, 0x56, 0xd6, 0x97, 0x08, 0xfa, 0x74, 0xd7, 0x39, 0x15, 0x6a, 0xbf, 0xaa, 0xe9, 0x18, 0xea, 0x21, 0x5e, 0x35, 0x7b, 0xb7, 0xf9, 0x2e, 0xba, 0x44, 0x28, 0x5e, 0xfd, 0xa1, 0x42, 0xdf, 0x82, 0x76, 0xd0, 0xbd, 0x2d, 0x9e, 0x45, 0x29, 0x5e, 0x31, 0xa0, 0x02, 0xfb, 0x0d, 0x9a, 0x8c, 0xf7, 0x3e, 0x58, 0x37, 0x6b, 0x63, 0x43, 0x18, 0x5d, 0xa8, 0x6a, 0xa9, 0x62, 0xf9, 0x20, 0x44, 0xf2, 0x1b, 0xdb, 0xea, 0xaf, 0x56, 0x34, 0xfa, 0xfd, 0x4d, 0xac, 0x76, 0x72, 0xab, 0xed, 0xd1, 0x24, 0x57, 0x0a, 0x33, 0x24, 0x5e, 0xf2, 0x59, 0xa9, 0x11, 0xa4, 0x1d, 0x2c, 0xd1, 0x26, 0x86, 0x28, 0x0e, 0x5e, 0x6c, 0x6f, 0x4d, 0x16, 0x1f, 0x0c, 0xce, 0x90, 0x42, 0x3a, 0x79, 0xb2, 0x99, 0xe6, 0xec, 0x14, 0x5a, 0x84, 0xce, 0xc8, 0x99, 0x62, 0xd4, 0x36, 0xd1, 0x69, 0x87, 0x16, 0xad, 0x67, 0x2f, 0x62, 0xd1, 0x4a, 0xd2, 0x3e, 0xcb, 0x38, 0x62, 0xad, 0xfd, 0xc1, 0xcf, 0xbb, 0x32, 0xf2, 0x32, 0x9a, 0xc4, 0x59, 0x99, 0x56, 0x3c, 0xcb, 0x91, 0x10, 0xc5, 0x80, 0xa3, 0x73, 0x64, 0xfc, 0x04, 0x6e, 0x3f, 0x1b, 0xfe, 0xfc, 0x82, 0xba, 0xd6, 0xea, 0xfa, 0x3e, 0x1a, 0x8f, 0x49, 0x25, 0x39, 0xcc, 0x43, 0xbd, 0xdd, 0x7d, 0xc6, 0x7b, 0x9b, 0x8c, 0x2c, 0x3e, 0x7a, 0x8b, 0xc2, 0x90, 0x31, 0x4b, 0x48, 0xd1, 0x12, 0xc6, 0x29, 0xd3, 0x09, 0x4c, 0x8f, 0x54, 0x6d, 0x67, 0x75, 0x8d, 0x0a, 0x86, 0x5e, 0x88, 0xae, 0x60, 0xeb, 0x8b, 0x40, 0x40, 0x0a, 0x23, 0x3d, 0xd6, 0x30, 0xcc, 0x9c, 0xce, 0xb7, 0xfa, 0x83, 0x90, 0x33, 0x66, 0x6f, 0x4a, 0x8f, 0x37, 0xe4, 0x37, 0xc6, 0x7a, 0x74, 0x48, 0xaa, 0x87, 0x46, 0x0c, 0x49, 0x34, 0x0d, 0x5d, 0x86, 0x0f, 0xb9, 0x2b, 0xb4, 0xe2, 0xa7, 0x81, 0x5e, 0xd2, 0xd7, 0xe0, 0xdf, 0x8f, 0x57, 0x75, 0xa6, 0x43, 0xe7, 0x43, 0xe4, 0x81, 0x56, 0xfe, 0xf1, 0x83, 0xc1, 0x5f, 0xa9, 0x7b, 0x8b, 0x65, 0x92, 0x29, 0x52, 0x7f, 0x6a, 0x1c, 0xbb, 0xd6, 0xd6, 0xf7, 0xfe, 0x75, 0x61, 0xb2, 0x7f, 0xd0, 0x51, 0x24, 0xf4, 0x45, 0x8d, 0x1f, 0xeb, 0x29, 0xfb, 0xde, 0xb3, 0xdc, 0xea, 0xb1, 0xf1, 0xb6, 0xd2, 0x7e, 0x76, 0x4e, 0x37, 0x7a, 0x8a, 0xbe, 0xb5, 0xe9, 0xd9, 0x54, 0x62, 0xe7, 0x23, 0x4e, 0x51, 0x00, 0xf1, 0x25, 0x4d, 0xeb, 0xd9, 0x68, 0x3a, 0x64, 0x15, 0xbb, 0x7c, 0xcd, 0x56, 0x7a, 0xe4, 0xa3, 0x29, 0x97, 0x1b, 0x1f, 0x75, 0x9c, 0xb1, 0x46, 0x3d, 0x16, 0xc9, 0x4e, 0x6e, 0x1c, 0x78, 0x5c, 0x09, 0xb1, 0x4c, 0x0a, 0xd2, 0xe2, 0xaf, 0xe8, 0x5c, 0x70, 0x88, 0xd4, 0xa2, 0x5f, 0xcf, 0xb2, 0x26, 0x16, 0x33, 0xee, 0xee, 0xa4, 0xc7, 0x93, 0x98, 0xbe, 0xa7, 0x4c, 0x4c, 0x5a, 0xdc, 0xf9, 0xe5, 0x0e, 0xed, 0xaf, 0x78, 0x5b, 0x7a, 0xec, 0x07, 0x51, 0x5a, 0x5a, 0xee, 0xf9, 0x4f, 0xf5, 0x70, 0xa0, 0x6f, 0xee, 0x36, 0x21, 0x25, 0x81, 0xff, 0xd8, 0x9f, 0xb1, 0x91, 0xf0, 0xb9, 0xbf, 0xee, 0xbd, 0xc7, 0xaa, 0x29, 0x50, 0xa6, 0x3b, 0xff, 0x17, 0x83, 0x94, 0x2a, 0xf5, 0x3b, 0xea, 0xcf, 0x9f, 0x68, 0x0e, 0x73, 0x94, 0x08, 0xaf, 0xec, 0x4d, 0x5a, 0xb7, 0x6f, 0xe3, 0xaf, 0x88, 0xac, 0x3c, 0xae, 0x24, 0x67, 0x2b, 0xbb, 0x78, 0xa1, 0x70, 0x4b, 0x55, 0x28, 0x3a, 0xee, 0x2d, 0x47, 0xe6, 0x06, 0x77, 0x53, 0x76, 0xe1, 0x83, 0x6c, 0x89, 0x4d, 0xa7, 0xa9, 0x0c, 0x9a, 0x6d, 0x2f, 0x24, 0x5d, 0xa0, 0x3e, 0x74, 0x11, 0x37, 0xfa, 0x9b, 0xc7, 0xf1, 0x4d, 0x5a, 0x7e, 0xdc, 0xa7, 0x0c, 0x36, 0x6b, 0xea, 0x55, 0xda, 0xfe, 0xf6, 0x9b, 0xb5, 0x89, 0x1d, 0x93, 0xf3, 0x49, 0x14, 0x74, 0xd3, 0x55, 0xd2, 0x2f, 0xf9, 0x1e, 0x5f, 0x9c, 0x29, 0x3d, 0xe9, 0xe8, 0x99, 0x1b, 0x81, 0x4d, 0x51, 0x26, 0x25, 0x2e, 0x85, 0xc5, 0x05, 0x04, 0x42, 0x65, 0xf8, 0x20, 0x06, 0xfd, 0x12, 0x8e, 0x5f, 0x79, 0xa5, 0x0b, 0xb7, 0x84, 0x2e, 0x21, 0xcd, 0x18, 0xe4, 0xa0, 0x34, 0x24, 0xfd, 0xa2, 0xc3, 0xc7, 0x50, 0x6a, 0xdc, 0xd6, 0xe7, 0x3d, 0xfe, 0x1b, 0x8f, 0xa9, 0xe7, 0x93, 0x25, 0x69, 0x36, 0x82, 0x41, 0x02, 0x84, 0xbb, 0x53, 0x13, 0xa0, 0x41, 0xbb, 0x07, 0xd3, 0x62, 0x8d, 0xe1, 0xd9, 0xed, 0x15, 0xa7, 0x5b, 0x46, 0x46, 0x86, 0x56, 0x83, 0x55, 0xe2, 0xfa, 0x72, 0xfe, 0x46, 0x0e, 0x9b, 0x45, 0xc4, 0x55, 0x0e, 0x61, 0xa3, 0x6c, 0x24, 0x9e, 0x73, 0x6c, 0xf6, 0xa0, 0xad, 0x2c, 0x06, 0xc1, 0xa3, 0x5b, 0x27, 0xbc, 0xa3, 0xf0, 0x13, 0xc5, 0xeb, 0xd5, 0xa8, 0x7c, 0xbb, 0xf6, 0xee, 0x06, 0x05, 0xc7, 0x52, 0xd7, 0x75, 0x33, 0x05, 0xab, 0xdb, 0xf1, 0x96, 0xd6, 0xf7, 0x18, 0x2f, 0x81, 0x12, 0x95, 0xef, 0x23, 0x3b, 0x08, 0xc0, 0x26, 0xbe, 0x66, 0x44, 0x1f, 0xff, 0x59, 0x35, 0xc2, 0x2f, 0x54, 0x64, 0xff, 0x7e, 0x4c, 0x68, 0xeb, 0xf4, 0x9a, 0xb5, 0x9d, 0xa3, 0x07, 0x09, 0x4c, 0x7c, 0x8d, 0xfe, 0x80, 0x5e, 0x27, 0x17, 0x01, 0x4e, 0xc9, 0x30, 0xdd, 0x7c, 0x6b, 0xeb, 0xca, 0x9d, 0x88, 0x23, 0x98, 0x86, 0x15, 0x79, 0x6b, 0x22, 0x16, 0x7d, 0xf8, 0x00, 0x7e, 0xb8, 0xda, 0xdf, 0x99, 0x14, 0x38, 0xfb, 0x9d, 0xe6, 0xca, 0xa5, 0x36, 0x25, 0x74, 0x97, 0xad, 0x2f, 0x72, 0xb9, 0x95, 0x0f, 0x78, 0xde, 0x89, 0x2c, 0x57, 0x4c, 0xc6, 0xe1, 0xdb, 0xd7, 0x6a, 0x3f, 0x05, 0x78, 0x9c, 0x78, 0x06, 0xe4, 0x92, 0x90, 0x10, 0x00, 0xec, 0x9d, 0x00, 0xb2, 0xb2, 0x63, 0x18, 0x38, 0xf9, 0x62, 0xc9, 0xcb, 0x74, 0xfd, 0x52, 0x61, 0x7d, 0x76, 0x8d, 0x85, 0xea, 0xf5, 0x83, 0x56, 0x0b, 0xbf, 0xd9, 0xd4, 0x64, 0xe1, 0x19, 0x35, 0x30, 0xe9, 0x53, 0xb1, 0xd8, 0x12, 0x8d, 0x23, 0x10, 0xe7, 0x16, 0x9f, 0xf2, 0xaa, 0x9a, 0xd8, 0xff, 0x9c, 0x46, 0x93, 0x49, 0x86, 0x86, 0x79, 0xf9, 0x8d, 0x90, 0x39, 0xc7, 0xf7, 0xf8, 0xb7, 0x1b, 0x6d, 0x27, 0x19, 0x32, 0xc4, 0x96, 0xe9, 0x0c, 0xe3, 0x7d, 0xb8, 0xa0, 0xeb, 0x96, 0x3b, 0xa0, 0x57, 0x57, 0xf6, 0x8d, 0x1e, 0x48, 0xdf, 0xb2, 0xd9, 0x84, 0xf5, 0x8c, 0x0f, 0xd2, 0x51, 0x17, 0x09, 0xa4, 0xc1, 0xba, 0x1b, 0x67, 0xcf, 0xef, 0x5a, 0x5f, 0xdd, 0x6e, 0x7a, 0x5d, 0xaf, 0x7d, 0x12, 0x7d, 0xd0, 0x01, 0xe5, 0x08, 0x78, 0x82, 0x3a, 0xef, 0x36, 0xfa, 0xc6, 0x58, 0xba, 0x4f, 0x12, 0xaf, 0x7c, 0xdb, 0xfb, 0x7e, 0xa0, 0x03, 0x85, 0xa2, 0x94, 0xe9, 0xe0, 0x3a, 0x6e, 0xd6, 0xfa, 0xac, 0xc0, 0x20, 0x7a, 0xbf, 0xe3, 0x0d, 0x89, 0x71, 0xdd, 0x96, 0xf9, 0x6a, 0x17, 0x1d, 0xe5, 0x7c, 0x84, 0xc0, 0x2c, 0x41, 0xa2, 0x90, 0x47, 0xb7, 0x60, 0xd9, 0xf2, 0x5a, 0x05, 0x41, 0xb7, 0xfd, 0x28, 0x78, 0xa5, 0xfa, 0x28, 0xaa, 0xc9, 0xec, 0x6e, 0x3b, 0x1e, 0x8f, 0xa1, 0xf3, 0x57, 0x07, 0xfd, 0x5d, 0x31, 0xc1, 0x52, 0x85, 0x68, 0xde, 0x06, 0x3b, 0xa2, 0xe8, 0x86, 0xeb, 0xcb, 0xc8, 0x96, 0x6c, 0x62, 0x29, 0x38, 0xb8, 0xb5, 0x5f, 0xac, 0x44, 0x9e, 0x73, 0x1c, 0x38, 0xe4, 0xfb, 0x9e, 0xcd, 0x6b, 0x34, 0x9f, 0x1d, 0x49, 0xb6, 0x7c, 0x6e, 0xef, 0xd2, 0x7b, 0x3a, 0x8f, 0x0e, 0xb3, 0x49, 0x96, 0xfe, 0x9c, 0xd4, 0x04, 0xf1, 0x37, 0x94, 0xe7, 0xb1, 0x4c, 0x04, 0xff, 0x3d, 0x07, 0x47, 0xc7, 0x6f, 0xfd, 0x0c, 0x3d, 0x9e, 0x3a, 0x30, 0xf4, 0xde, 0xc5, 0x25, 0xe1, 0x75, 0xca, 0x37, 0x98, 0x5c, 0x4a, 0x80, 0x1e, 0xfb, 0x55, 0xb7, 0x83, 0xff, 0x54, 0xd5, 0x59, 0xc4, 0x6c, 0x2f, 0xac, 0xa0, 0x1b, 0xdd, 0x07, 0x81, 0x15, 0x87, 0xf6, 0xf0, 0x53, 0xb7, 0x3a, 0xa7, 0x7e, 0x02, 0x1f, 0x23, 0xd2, 0x6a, 0x6e, 0xc8, 0xbf, 0xb3, 0x6c, 0x78, 0x13, 0xf5, 0x39, 0x9c, 0x22, 0xa7, 0xaa, 0x18, 0x13, 0x3b, 0x0e, 0x8f, 0x64, 0xbb, 0xc6, 0x39, 0x06, 0xae, 0x84, 0x77, 0xf4, 0x62, 0x01, 0xb5, 0xa2, 0xef, 0xa5, 0xd2, 0xbd, 0xcf, 0x78, 0x09, 0x8b, 0xa8, 0xdc, 0xcd, 0x0d, 0xad, 0x06, 0xb1, 0xe8, 0x64, 0x24, 0x73, 0xb5, 0x03, 0x65, 0xcc, 0x76, 0x3d, 0x91, 0xf4, 0x71, 0xa2, 0x8b, 0xf4, 0x63, 0x39, 0x10, 0xe0, 0xda, 0x9d, 0xf7, 0x5a, 0x47, 0xec, 0x7a, 0x16, 0x85, 0xa4, 0x2f, 0xae, 0x06, 0x45, 0xce, 0x0f, 0xe4, 0xc8, 0x8d, 0xdf, 0x66, 0x8e, 0xb1, 0x6b, 0x09, 0x4c, 0xad, 0x56, 0xfb, 0xcd, 0x09, 0x1c, 0x30, 0x49, 0xca, 0x7a, 0x18, 0x94, 0xd6, 0x2d, 0xe5, 0x38, 0xb3, 0x5d, 0xe5, 0xf3, 0x84, 0x49, 0x97, 0xaa, 0x1f, 0x1c, 0x65, 0xa6, 0xea, 0x2d, 0xa7, 0x4c, 0xae, 0x0f, 0x66, 0x86, 0xc7, 0xc7, 0x1b, 0x62, 0x85, 0x38, 0xbd, 0x39, 0xc1, 0x64, 0x42, 0xd3, 0x87, 0xcb, 0xcf, 0x85, 0x58, 0x82, 0x57, 0x7b, 0x96, 0x74, 0x74, 0xb3, 0x30, 0x74, 0x6f, 0x49, 0xd7, 0xe7, 0xff, 0xbe, 0xa5, 0xb3, 0xfe, 0x11, 0x79, 0x07, 0xeb, 0xb7, 0xcf, 0xdd, 0x40, 0x27, 0x7b, 0xef, 0xbc, 0xce, 0xfc, 0xdc, 0xf5, 0x14, 0xb1, 0x7e, 0xdf, 0x6d, 0xb1, 0x79, 0xf6, 0xf3, 0x28, 0x42, 0x42, 0x58, 0xd5, 0x81, 0x3c, 0x58, 0xd9, 0x7e, 0xe0, 0x9f, 0x01, 0x12, 0x9e, 0xdc, 0xaa, 0x27, 0x25, 0x25, 0x8b, 0x6a, 0x1f, 0xde, 0x7f, 0xb6, 0xc2, 0x8d, 0xda, 0x12, 0x2e, 0xb4, 0x72, 0x21, 0x8a, 0x8f, 0xfc, 0xd0, 0xcc, 0x50, 0xfd, 0x0d, 0x7f, 0x80, 0x5f, 0x28, 0x37, 0xe0, 0x2a, 0x90, 0x37, 0xd1, 0x6d, 0x66, 0x37, 0xa0, 0x51, 0x56, 0xfb, 0xec, 0x38, 0xab, 0xdd, 0xd3, 0x2e, 0xd6, 0xf7, 0x8c, 0x24, 0x7c, 0xf7, 0x78, 0xd4, 0x36, 0xa5, 0xb4, 0xb8, 0x78, 0x2b, 0xd7, 0x17, 0xdc, 0x53, 0xad, 0xdf, 0x8e, 0x81, 0xb1, 0xb5, 0xc1, 0x75, 0xbb, 0x01, 0x3e, 0x59, 0xa9, 0x27, 0xe0, 0x73, 0xa1, 0xbe, 0xbc, 0xac, 0xf6, 0x54, 0x68, 0x77, 0x95, 0x08, 0x14, 0x7c, 0x99, 0x5e, 0x77, 0xea, 0x68, 0xd9, 0xf0, 0x3f, 0xa7, 0xde, 0xd0, 0xab, 0xfd, 0x00, 0x3f, 0xc0, 0x0f, 0x5c, 0x86, 0xf5, 0x44, 0xed, 0xbb, 0x37, 0xf6, 0x17, 0xc4, 0x75, 0xe8, 0xac, 0xd7, 0xfa, 0xad, 0x75, 0x39, 0xa6, 0x91, 0x2d, 0xaf, 0x28, 0xf9, 0xb3, 0xcf, 0xac, 0x65, 0xcf, 0x39, 0x76, 0xba, 0xd2, 0x55, 0x37, 0x83, 0xea, 0x23, 0x18, 0x0b, 0x8b, 0x24, 0x22, 0x60, 0x1d, 0x68, 0x7a, 0xbc, 0x61, 0x0a, 0x00, 0x4c, 0x46, 0x3f, 0x65, 0xc8, 0x8b, 0x8c, 0x23, 0xd4, 0x2a, 0x6f, 0x0c, 0x7f, 0xf5, 0xbf, 0xac, 0x64, 0xb8, 0x0e, 0x0a, 0x0a, 0xb0, 0xf9, 0x36, 0xdf, 0x9a, 0x3d, 0x18, 0xb0, 0x19, 0x6a, 0xac, 0xfc, 0xf9, 0xf8, 0xf6, 0x45, 0x0a, 0x44, 0xa2, 0x7b, 0x4b, 0x32, 0xe0, 0xaf, 0xd4, 0xad, 0x6b, 0xce, 0xfe, 0x3e, 0xa8, 0xec, 0x5c, 0x99, 0x2e, 0xf5, 0xe6, 0xcd, 0xdc, 0xfb, 0xb1, 0x1f, 0xd3, 0x63, 0xac, 0x16, 0x8d, 0x4c, 0x30, 0x62, 0xa6, 0x48, 0xba, 0xa8, 0xac, 0xac, 0x6c, 0x63, 0xea, 0x94, 0x29, 0x29, 0x39, 0x99, 0xcd, 0xe5, 0xdf, 0xd7, 0xf6, 0xc5, 0x32, 0x26, 0x10, 0xf1, 0x76, 0x9e, 0xd2, 0xc6, 0xfe, 0x75, 0x8c, 0xd7, 0x50, 0xde, 0xa7, 0xf3, 0x35, 0xdd, 0x3c, 0x20, 0xcd, 0x55, 0xf5, 0x29, 0xb6, 0xd3, 0x90, 0xd3, 0x53, 0xe3, 0x21, 0x6a, 0xce, 0x0c, 0x64, 0x95, 0x3a, 0x23, 0x15, 0x47, 0x04, 0x05, 0x39, 0x09, 0xde, 0x5e, 0x87, 0x8a, 0x1c, 0x18, 0x3c, 0xe5, 0xff, 0xb9, 0xeb, 0xbe, 0x39, 0x78, 0x00, 0xf1, 0xe4, 0x5e, 0x51, 0x44, 0xe5, 0xba, 0xdb, 0x23, 0xae, 0x3e, 0x05, 0xa4, 0x4e, 0x4b, 0xd6, 0x15, 0xf3, 0x19, 0x39, 0x7b, 0x5b, 0xaf, 0xd5, 0xc7, 0x69, 0xd2, 0x84, 0x0d, 0x94, 0xdc, 0xef, 0x3f, 0x19, 0xee, 0x90, 0xbf, 0xbd, 0x8e, 0x5a, 0x0f, 0xd6, 0x16, 0x29, 0xf3, 0x70, 0x99, 0xb7, 0x66, 0xb4, 0x2c, 0xd3, 0x09, 0x5e, 0xfc, 0x25, 0xf5, 0x30, 0xf5, 0xbd, 0x3d, 0xe9, 0x69, 0x71, 0xde, 0xa9, 0xf5, 0xbe, 0xb2, 0xc8, 0xab, 0xa1, 0x4e, 0xcb, 0xce, 0x8e, 0xc1, 0xfc, 0x28, 0xb5, 0x4c, 0xe3, 0x0a, 0xc1, 0x89, 0x3b, 0x83, 0xcc, 0xc3, 0xf9, 0x2c, 0x83, 0x52, 0x96, 0xbe, 0xa7, 0xbc, 0x9a, 0x5a, 0x86, 0x19, 0x60, 0x9b, 0x24, 0x49, 0x6e, 0x1e, 0xdf, 0x88, 0x25, 0x56, 0x76, 0x8f, 0xd5, 0xe0, 0x6b, 0x91, 0xcc, 0xfd, 0x7d, 0xbb, 0xbb, 0xe2, 0xdb, 0xd9, 0x02, 0x3d, 0x0d, 0x5e, 0xd7, 0x2b, 0x35, 0xff, 0xba, 0x38, 0x76, 0xa1, 0xff, 0xc0, 0x39, 0xcc, 0x3a, 0x26, 0x31, 0xa9, 0x31, 0x70, 0xaf, 0xe3, 0x77, 0xb9, 0x6c, 0x49, 0x3a, 0xb5, 0xe9, 0xd7, 0xe2, 0xdc, 0x07, 0x75, 0xf1, 0x66, 0x9d, 0x68, 0xfd, 0x9f, 0x3b, 0xc8, 0x1f, 0xa6, 0xe7, 0xcb, 0xa7, 0xe5, 0x0c, 0x8c, 0x91, 0x7e, 0x09, 0xde, 0xe0, 0x71, 0xbf, 0x39, 0xff, 0xdb, 0x7b, 0x0f, 0x7b, 0x30, 0x77, 0xfa, 0x53, 0x27, 0xaf, 0xf2, 0x17, 0x38, 0x8b, 0x75, 0xad, 0x9c, 0xec, 0x01, 0xc2, 0x3b, 0x58, 0x3d, 0x4e, 0xb4, 0xc6, 0x73, 0x85, 0x80, 0xd5, 0x2a, 0x99, 0x2c, 0x7c, 0x5e, 0xe7, 0x14, 0xe1, 0x68, 0xa4, 0x36, 0x69, 0xe3, 0x30, 0x46, 0x7b, 0x9d, 0xcd, 0xed, 0x76, 0x01, 0x97, 0x57, 0x83, 0x42, 0xc3, 0xd5, 0x6e, 0x03, 0x15, 0x2a, 0xf4, 0xe7, 0xcf, 0x45, 0xd8, 0xeb, 0x06, 0xef, 0x96, 0xb1, 0xa9, 0x23, 0x8b, 0x8a, 0x1b, 0xc6, 0x9b, 0xec, 0x9b, 0xb4, 0xea, 0xec, 0x0d, 0xa9, 0x2c, 0x3a, 0x6f, 0x91, 0x5e, 0x9f, 0x6e, 0x6a, 0x78, 0x3d, 0xf8, 0x07, 0xc0, 0xf7, 0xe9, 0xc3, 0xac, 0xe3, 0x81, 0xfe, 0x78, 0x6d, 0x0b, 0x75, 0x92, 0xac, 0x17, 0xcc, 0x62, 0x30, 0xbb, 0xae, 0xd6, 0x70, 0xdb, 0x8f, 0x35, 0xde, 0x95, 0x5c, 0x53, 0xde, 0x08, 0x74, 0x17, 0x84, 0x01, 0x1e, 0x4f, 0x03, 0xd3, 0x7d, 0x0b, 0x56, 0x7a, 0x76, 0x38, 0xef, 0x8e, 0x94, 0x41, 0x57, 0x95, 0xb8, 0xc4, 0x89, 0x9a, 0xca, 0x7a, 0xa7, 0x3b, 0x84, 0x82, 0x3c, 0x0c, 0xfc, 0xa2, 0x45, 0xbd, 0xa5, 0x57, 0x7b, 0x5b, 0x2b, 0xde, 0x6f, 0x7d, 0x05, 0xd8, 0xfb, 0x27, 0xb7, 0x2f, 0x67, 0x81, 0x6f, 0x5f, 0x54, 0x54, 0xb0, 0x34, 0xaa, 0xf5, 0x22, 0xd3, 0xd3, 0x09, 0xe2, 0x07, 0xd4, 0x36, 0xf1, 0x58, 0x0c, 0x62, 0xf8, 0x5c, 0xf7, 0xfe, 0x5a, 0x71, 0xae, 0xc6, 0x7a, 0x5a, 0xe7, 0x05, 0xfd, 0xf8, 0x24, 0xc0, 0x5d, 0x4b, 0xd7, 0xfc, 0x52, 0x63, 0x19, 0x8b, 0x8b, 0x70, 0x73, 0x18, 0x23, 0x35, 0xb3, 0xcd, 0x1c, 0x9f, 0x4a, 0xbc, 0xbf, 0xe6, 0xd0, 0x6b, 0x6a, 0x9d, 0x81, 0x59, 0x48, 0xb7, 0x0d, 0x4a, 0x95, 0xcf, 0xee, 0x74, 0x82, 0x8f, 0x94, 0xc1, 0x77, 0x7e, 0xd0, 0x41, 0x33, 0x29, 0xea, 0xa3, 0x64, 0x0d, 0x2f, 0xc4, 0x12, 0xfa, 0x40, 0x5b, 0x3f, 0xb7, 0x6f, 0xc5, 0x69, 0xd3, 0x71, 0xdd, 0xcf, 0xb9, 0xc6, 0xd6, 0x61, 0xd8, 0xc9, 0xb4, 0x44, 0x7d, 0xd9, 0x56, 0x65, 0xa8, 0x29, 0xe8, 0xb1, 0x79, 0x7a, 0xff, 0xfc, 0x03, 0x15, 0x00, 0x18, 0xfc, 0xcd, 0xa1, 0xd3, 0x40, 0x17, 0xc0, 0xc5, 0xc4, 0x14, 0xb3, 0x7a, 0xf8, 0x40, 0xd1, 0xfd, 0xa8, 0x39, 0x9e, 0x0e, 0xc2, 0xd3, 0xf4, 0xcc, 0x00, 0x36, 0xfd, 0xf6, 0xb7, 0x9e, 0xba, 0x2a, 0x3f, 0xd4, 0x6a, 0xb4, 0x56, 0x8a, 0xdd, 0x48, 0xd6, 0x0d, 0xf9, 0x77, 0x86, 0x26, 0xf6, 0x9d, 0xc8, 0xef, 0x75, 0x92, 0x63, 0xb9, 0xf6, 0x85, 0x62, 0x8f, 0x59, 0xcb, 0xc6, 0xb3, 0xdd, 0x7d, 0xa9, 0x5a, 0x1f, 0x1a, 0x15, 0x01, 0x0f, 0xbb, 0xf8, 0x0d, 0xf6, 0xc0, 0xda, 0x4f, 0x5f, 0x08, 0x63, 0xa5, 0x3a, 0xae, 0x67, 0xe5, 0x14, 0xd5, 0xb7, 0x82, 0x2e, 0x0b, 0xc5, 0xce, 0xba, 0x39, 0xeb, 0x47, 0xfb, 0xd5, 0xf5, 0x2a, 0x9a, 0x3b, 0x2d, 0x3e, 0xb4, 0xf8, 0x5e, 0x57, 0xdd, 0xe0, 0x59, 0xda, 0x3b, 0xa1, 0xe9, 0x8d, 0x4d, 0xf6, 0x7d, 0xef, 0x37, 0xcb, 0xe6, 0x4f, 0x0b, 0xb7, 0xd5, 0x7e, 0x40, 0x44, 0x47, 0x0a, 0x5e, 0xb1, 0x91, 0xd4, 0x50, 0x2c, 0x58, 0xd7, 0x79, 0x40, 0x5e, 0xf1, 0xae, 0xde, 0x97, 0xb5, 0x9a, 0xa7, 0x8f, 0x21, 0x9c, 0x25, 0xbe, 0xdb, 0xe4, 0x5a, 0x2b, 0xd8, 0xa5, 0xbd, 0x90, 0x8c, 0x57, 0x24, 0x8d, 0x16, 0x89, 0xa7, 0xd9, 0xee, 0x5f, 0x91, 0x4b, 0xa0, 0xf6, 0xf7, 0xd3, 0xd1, 0x19, 0x12, 0x06, 0xa0, 0x8d, 0x92, 0xe2, 0x3b, 0x8b, 0x74, 0xcb, 0x1e, 0x64, 0x67, 0xe9, 0xfd, 0x94, 0xe7, 0xd0, 0xfd, 0xdd, 0xf8, 0xd8, 0x31, 0xb6, 0xf4, 0x87, 0xcd, 0x12, 0xfc, 0x89, 0xab, 0xda, 0xbb, 0xea, 0x9b, 0xef, 0x6b, 0x8d, 0x3e, 0x06, 0x9c, 0x3c, 0x81, 0x3b, 0x83, 0x3c, 0x1e, 0xca, 0x6b, 0xfb, 0x3d, 0x3e, 0x41, 0xcc, 0x52, 0xcd, 0xb2, 0x62, 0xae, 0x60, 0xa4, 0xc3, 0x7a, 0xdb, 0x36, 0x24, 0x7b, 0xf6, 0xff, 0xd6, 0xae, 0x3f, 0x71, 0x98, 0xe1, 0x82, 0xcb, 0x76, 0xb5, 0x5b, 0x6f, 0xc3, 0x9d, 0x12, 0xbc, 0xfa, 0x00, 0x89, 0x9e, 0x9c, 0x5b, 0x74, 0xf2, 0x69, 0xd2, 0x9a, 0xc9, 0x00, 0x40, 0xe2, 0x36, 0x25, 0xf3, 0xa6, 0x23, 0x67, 0x86, 0xbd, 0xdc, 0x3c, 0x80, 0xa2, 0xfa, 0x1b, 0x0e, 0x88, 0x48, 0xb2, 0x4d, 0x70, 0x71, 0x2e, 0x86, 0x96, 0xa3, 0x09, 0xac, 0xd0, 0x0f, 0x71, 0xd8, 0xaf, 0xad, 0xd9, 0xdf, 0x47, 0xbd, 0xdb, 0xcb, 0x8a, 0x1b, 0x8e, 0x78, 0xda, 0xf2, 0x21, 0xee, 0x33, 0x58, 0xcf, 0xc1, 0x9a, 0xaf, 0x29, 0x2d, 0x11, 0xda, 0xfa, 0xda, 0x4e, 0xd1, 0x25, 0x5d, 0xa2, 0x62, 0x72, 0x9d, 0xb0, 0xc1, 0xeb, 0x7c, 0x8b, 0x05, 0x10, 0xc5, 0x70, 0xab, 0x69, 0xb0, 0x6b, 0xbd, 0x74, 0x10, 0xe3, 0x9d, 0x54, 0x55, 0xd9, 0x48, 0xe5, 0xe3, 0x07, 0x29, 0x06, 0xfc, 0x9c, 0x46, 0x75, 0x8e, 0x33, 0xc5, 0x34, 0xd6, 0x49, 0x0b, 0x93, 0xac, 0xd8, 0x29, 0xbd, 0x69, 0xaf, 0xec, 0x40, 0x6e, 0x4b, 0xfc, 0xeb, 0x63, 0xf0, 0xc7, 0xe3, 0x23, 0x14, 0xca, 0xd8, 0xbe, 0xf8, 0xec, 0xc4, 0x87, 0x7c, 0xaa, 0x3b, 0x00, 0x72, 0x0d, 0x8f, 0xb0, 0xc4, 0x6f, 0x1a, 0xb1, 0x1a, 0xdd, 0x9e, 0xac, 0x2c, 0xd7, 0x1a, 0xc3, 0x76, 0xbd, 0xdc, 0xea, 0xf6, 0x0f, 0xfa, 0x68, 0x56, 0x5d, 0x54, 0x14, 0xff, 0xfa, 0x05, 0x1a, 0xc0, 0x37, 0xec, 0x3f, 0x5a, 0xa8, 0xd4, 0x57, 0xbc, 0x24, 0x16, 0x6a, 0xc1, 0xdf, 0x08, 0xd8, 0x76, 0xe4, 0xe9, 0x28, 0xf1, 0xbb, 0xff, 0xe7, 0x9d, 0x42, 0x58, 0x3d, 0x45, 0xf3, 0xd5, 0x6a, 0x51, 0xeb, 0xa7, 0x09, 0x5b, 0xb6, 0x2b, 0x0e, 0xce, 0xa1, 0xd3, 0x3f, 0x35, 0x64, 0x15, 0x66, 0xc3, 0x10, 0x08, 0x44, 0x97, 0xff, 0xe3, 0x3c, 0xb8, 0x46, 0x68, 0xf6, 0x7b, 0xfd, 0x07, 0xfc, 0x61, 0xe4, 0x57, 0x82, 0xd7, 0xde, 0x1f, 0xb8, 0xb6, 0x58, 0xc3, 0x20, 0xfc, 0xea, 0x81, 0x0a, 0x99, 0x22, 0xb5, 0x0c, 0x0f, 0x25, 0xd3, 0xe9, 0xd9, 0x4a, 0xd0, 0x25, 0x39, 0xa0, 0x2b, 0x55, 0x80, 0x1b, 0x24, 0x1c, 0x90, 0x3c, 0xbd, 0x70, 0x44, 0xc6, 0x34, 0xb1, 0x87, 0xad, 0x38, 0xd0, 0x90, 0x17, 0xe0, 0x55, 0xa8, 0x4f, 0x7e, 0x91, 0xd9, 0x92, 0xf0, 0xd3, 0xa0, 0xf2, 0x6e, 0xc4, 0xdf, 0x1d, 0xa7, 0x02, 0xb5, 0x97, 0xf4, 0xe3, 0x63, 0x91, 0xe7, 0x92, 0x2e, 0xeb, 0x7e, 0xec, 0xdb, 0xb6, 0xf8, 0xd1, 0x8d, 0xc8, 0xd0, 0x59, 0xf7, 0x5b, 0x1c, 0xc4, 0xd8, 0xc6, 0x33, 0x85, 0x92, 0xe9, 0xec, 0xe6, 0x51, 0x4b, 0x1a, 0x62, 0x0c, 0xcc, 0xcc, 0x83, 0x4f, 0x67, 0xdd, 0xf1, 0x61, 0x28, 0xf8, 0x85, 0xbf, 0x7f, 0x8f, 0x3b, 0xe4, 0xfd, 0x25, 0xe0, 0x6f, 0xb0, 0xff, 0xde, 0xad, 0x40, 0x18, 0x82, 0x09, 0xdb, 0xb6, 0x79, 0x3d, 0xb5, 0xc5, 0xfb, 0x56, 0x10, 0xf9, 0x41, 0x73, 0x9f, 0xef, 0x61, 0x40, 0xab, 0x03, 0xe4, 0x49, 0x4d, 0xab, 0xff, 0xfb, 0xf6, 0x08, 0x36, 0x55, 0x36, 0x2c, 0xe0, 0xe5, 0xd1, 0x18, 0xd4, 0x1f, 0x79, 0x30, 0x5f, 0x8e, 0x9d, 0xc9, 0x6d, 0x1f, 0x45, 0x2a, 0xe0, 0xb1, 0x95, 0xaa, 0x69, 0x20, 0x66, 0x5d, 0xfe, 0xb2, 0xe0, 0x0b, 0xfc, 0x79, 0xe1, 0xf5, 0x7a, 0x96, 0x7c, 0xfc, 0xd1, 0x6d, 0x16, 0xc0, 0x69, 0x4f, 0x12, 0x7b, 0xd1, 0xf7, 0xf4, 0x72, 0xe3, 0x95, 0xf0, 0x25, 0x29, 0xca, 0x94, 0x00, 0xa5, 0x94, 0x06, 0x55, 0x78, 0xd0, 0x11, 0xcb, 0xc7, 0xeb, 0x9e, 0xa9, 0x6d, 0x6d, 0x6d, 0x8e, 0x6a, 0x3f, 0x69, 0x9d, 0xa8, 0x78, 0x55, 0x31, 0x7c, 0x27, 0x7b, 0x47, 0x56, 0xca, 0xa1, 0x6a, 0xf3, 0x18, 0x95, 0x68, 0x48, 0xc2, 0x64, 0xe4, 0xfd, 0x94, 0xe9, 0xcd, 0x9e, 0xbf, 0x56, 0x93, 0x4f, 0xe5, 0xe9, 0x4a, 0x80, 0x87, 0x07, 0xf7, 0x2f, 0x85, 0xac, 0xf0, 0xb3, 0xae, 0x27, 0x34, 0xf2, 0xc0, 0x67, 0x36, 0x9d, 0xc6, 0xcb, 0xdc, 0x6a, 0x5d, 0x1a, 0x1a, 0x9a, 0x7b, 0x50, 0x34, 0xcb, 0x79, 0xde, 0xdb, 0xf3, 0x7b, 0x3e, 0x3e, 0x3e, 0xc5, 0x27, 0x75, 0x59, 0x9a, 0xd7, 0x97, 0x78, 0x69, 0x36, 0x97, 0x84, 0xb1, 0x87, 0x78, 0xe6, 0xcf, 0x38, 0xb7, 0xf1, 0x04, 0x44, 0x92, 0xad, 0xdd, 0xd8, 0x06, 0xea, 0x51, 0xb2, 0xb2, 0x75, 0x0e, 0x40, 0x31, 0xbb, 0xd7, 0x1d, 0x3a, 0x79, 0x8b, 0x31, 0xd4, 0xf8, 0xd3, 0xb5, 0x56, 0x0e, 0x70, 0xc7, 0x95, 0x62, 0x0c, 0xa9, 0x00, 0x9e, 0x45, 0x3d, 0x21, 0x44, 0x8d, 0x49, 0x79, 0xb5, 0xbc, 0xf4, 0x77, 0x2a, 0xe6, 0xf0, 0x43, 0x0b, 0x21, 0xa4, 0xf3, 0x3a, 0x53, 0x25, 0x25, 0x25, 0xd9, 0xed, 0x68, 0x72, 0xb8, 0x26, 0xfa, 0x70, 0x55, 0x2a, 0x5e, 0x49, 0x7e, 0xed, 0xe3, 0xf6, 0x1d, 0x84, 0x3b, 0x11, 0xf1, 0x19, 0x5c, 0xa4, 0x8b, 0x72, 0x5d, 0x3f, 0x0e, 0xc6, 0x10, 0xae, 0x92, 0x49, 0xb6, 0x14, 0x30, 0x68, 0xbf, 0x0d, 0xef, 0xe8, 0xc1, 0x6c, 0x3e, 0x8f, 0x85, 0x6f, 0x5a, 0xc8, 0x5f, 0xca, 0x63, 0x63, 0xfd, 0x75, 0xfa, 0x21, 0x9d, 0x5f, 0x93, 0x8c, 0x9c, 0xaf, 0xd6, 0xb2, 0x2a, 0x60, 0x84, 0x6d, 0x50, 0x59, 0xaf, 0x70, 0xa8, 0x8e, 0xe3, 0x33, 0x8f, 0xc8, 0xf2, 0xf7, 0xea, 0x86, 0x0f, 0x77, 0x31, 0xa4, 0x27, 0xb8, 0x9a, 0xdd, 0x36, 0x8d, 0xc8, 0xeb, 0xfc, 0x0d, 0xbd, 0xe9, 0x94, 0x9d, 0x89, 0x1e, 0x5c, 0xc4, 0x9a, 0xec, 0xd5, 0x9f, 0x46, 0x50, 0xf0, 0x99, 0xb7, 0xae, 0xa6, 0x44, 0x7e, 0xf4, 0x18, 0x89, 0xfe, 0x40, 0x23, 0xcd, 0x5f, 0xb0, 0x31, 0x8f, 0x5e, 0x31, 0x63, 0xdf, 0xae, 0xac, 0xe9, 0xea, 0xfd, 0x37, 0x92, 0x5c, 0x67, 0x31, 0x41, 0x74, 0x70, 0xe3, 0xd3, 0xfe, 0x82, 0x1c, 0x16, 0x34, 0x13, 0xe2, 0xbb, 0x7d, 0x53, 0x4a, 0x2e, 0xf1, 0x96, 0x4b, 0x6a, 0x73, 0xbd, 0x62, 0x93, 0x8a, 0x2c, 0x62, 0xbf, 0x6c, 0x0e, 0x24, 0x5b, 0xae, 0xfc, 0x98, 0x39, 0xb4, 0xd4, 0x69, 0x7e, 0x34, 0x41, 0x22, 0x18, 0x80, 0xe6, 0xc8, 0xa4, 0x13, 0x37, 0xb7, 0x3f, 0x47, 0x11, 0xc5, 0x93, 0xeb, 0x46, 0x42, 0x42, 0x12, 0x33, 0x57, 0xaa, 0x64, 0xfa, 0x7c, 0x7f, 0x61, 0x35, 0x53, 0x08, 0x0f, 0x7d, 0xb0, 0x6b, 0x3e, 0xd0, 0x5d, 0x56, 0x46, 0x07, 0x3d, 0x2e, 0xab, 0xd4, 0xac, 0x69, 0xc2, 0xc5, 0xfc, 0x13, 0x45, 0x85, 0x46, 0x2a, 0xf2, 0x43, 0x40, 0xfa, 0xfa, 0x2e, 0x93, 0xec, 0xa4, 0xbf, 0xfe, 0x1d, 0x2c, 0x27, 0x84, 0xa8, 0x56, 0x5d, 0x0b, 0x44, 0x73, 0x88, 0x1a, 0x7d, 0xff, 0xfe, 0x22, 0x32, 0x7f, 0xfc, 0x96, 0xc0, 0xc5, 0x0d, 0x22, 0x43, 0xb5, 0xbd, 0x55, 0x5d, 0xcf, 0x71, 0x22, 0x49, 0x28, 0x5e, 0xad, 0xd9, 0xf0, 0xda, 0x02, 0x63, 0x42, 0xdc, 0xb9, 0x78, 0xf0, 0x4c, 0xc0, 0xf3, 0x33, 0x69, 0x46, 0x2b, 0x3c, 0x8f, 0xc8, 0x74, 0x88, 0x49, 0xd1, 0xc7, 0xf3, 0x8b, 0x2c, 0xa5, 0xed, 0x1c, 0xfc, 0xd7, 0xf0, 0xfb, 0xc1, 0xa5, 0xe3, 0xf1, 0xac, 0x09, 0x8b, 0xe7, 0xa7, 0xcd, 0x37, 0xa9, 0xb9, 0x5f, 0x0a, 0x6c, 0x10, 0xe8, 0x3f, 0xd9, 0xe8, 0x6c, 0x57, 0x0c, 0xb4, 0x5c, 0xe8, 0xe1, 0xfb, 0x41, 0x17, 0xb5, 0xeb, 0x29, 0x56, 0xad, 0xd7, 0x33, 0xa7, 0x24, 0x12, 0xbb, 0xbc, 0xac, 0x25, 0xf8, 0xf0, 0x2f, 0x79, 0x78, 0x72, 0xb2, 0x49, 0x40, 0x83, 0x12, 0xb1, 0xc5, 0x76, 0x1e, 0xf0, 0x7c, 0x3b, 0x21, 0xe0, 0xf5, 0xb6, 0x9b, 0x71, 0xb0, 0x56, 0x6d, 0x1e, 0x3b, 0xb5, 0xcf, 0x5b, 0x5e, 0xe7, 0x52, 0xd2, 0xf2, 0xe8, 0x72, 0x21, 0x8b, 0xb7, 0x17, 0xf8, 0xc2, 0x70, 0x8d, 0x50, 0x34, 0xd7, 0x05, 0x99, 0x44, 0x69, 0x64, 0x24, 0x7d, 0x2a, 0x32, 0x25, 0xe5, 0x42, 0xa0, 0xda, 0x5c, 0xb1, 0x0c, 0xb6, 0xdd, 0x46, 0x07, 0xa1, 0x42, 0xa6, 0xde, 0xdb, 0x43, 0x87, 0x1f, 0x13, 0x71, 0x74, 0x97, 0xae, 0xea, 0x53, 0xbe, 0x4c, 0x08, 0x8f, 0x8b, 0xb2, 0x52, 0xff, 0x80, 0xd4, 0x4a, 0x13, 0x1f, 0x4b, 0xf4, 0xe4, 0xd8, 0x93, 0x99, 0xe9, 0xd5, 0x1e, 0xf9, 0x08, 0x4f, 0xdd, 0x8f, 0x96, 0x58, 0x43, 0x1a, 0xb7, 0x41, 0x4e, 0x4b, 0xd2, 0xa1, 0x24, 0x16, 0xfd, 0xaa, 0x9b, 0x7d, 0xc9, 0x50, 0xeb, 0xba, 0x83, 0xd8, 0x4f, 0xb6, 0x5c, 0x23, 0x0a, 0x6d, 0x23, 0xb8, 0x19, 0x24, 0x04, 0xa6, 0x04, 0x22, 0x1d, 0xe4, 0x1a, 0x01, 0x97, 0xf4, 0xe0, 0x6e, 0xdb, 0x16, 0x7d, 0x6f, 0x9d, 0x49, 0xbe, 0x26, 0xbb, 0x95, 0xe0, 0x82, 0x2f, 0x3f, 0x0a, 0x9d, 0x77, 0x06, 0xbd, 0xb6, 0xc3, 0xf0, 0x13, 0x92, 0x92, 0x40, 0x3f, 0x87, 0xde, 0x27, 0x51, 0x17, 0x94, 0x95, 0x21, 0x0a, 0x78, 0x9c, 0xfc, 0xcd, 0xe6, 0x73, 0x9d, 0x2e, 0x92, 0x46, 0x87, 0x7b, 0xff, 0xfe, 0x23, 0x1d, 0x1d, 0x22, 0x93, 0x6e, 0x53, 0x3f, 0x44, 0xfb, 0xc4, 0x80, 0x4c, 0x9e, 0xf6, 0xd7, 0x9c, 0x63, 0x0b, 0x59, 0x7d, 0x9c, 0x58, 0x18, 0x03, 0xde, 0xf8, 0x3a, 0x2e, 0x4e, 0x3e, 0x70, 0xc6, 0x45, 0x96, 0x81, 0xe6, 0x1c, 0xc1, 0x7a, 0x15, 0x2f, 0x7a, 0x88, 0x9e, 0x0a, 0xe2, 0x95, 0x97, 0x7e, 0x69, 0xb3, 0x17, 0xb7, 0x43, 0x22, 0xbd, 0xf4, 0x06, 0x6f, 0x54, 0x05, 0x6a, 0xf4, 0x17, 0x5b, 0x21, 0xe8, 0xa0, 0x29, 0x91, 0x37, 0x09, 0x45, 0x45, 0x34, 0x28, 0x91, 0xf0, 0x7f, 0x74, 0x03, 0xbe, 0x16, 0x16, 0x52, 0xd9, 0x2d, 0xd7, 0x16, 0x48, 0xed, 0x5b, 0x03, 0x9b, 0x98, 0x7e, 0x32, 0x6a, 0x9b, 0xdc, 0xed, 0x6e, 0xed, 0x6f, 0xbe, 0xfe, 0x85, 0x00, 0x20, 0x8f, 0x17, 0xfe, 0x85, 0xf9, 0xa9, 0x2e, 0x4f, 0xdf, 0xec, 0x5b, 0x97, 0xd9, 0x52, 0x9f, 0x28, 0x0e, 0xca, 0x50, 0x49, 0x69, 0xb7, 0x12, 0xee, 0x3f, 0xbf, 0xa0, 0xe7, 0x3b, 0x3f, 0xa1, 0xaf, 0x18, 0x26, 0x8e, 0x69, 0xc5, 0x27, 0x9b, 0xf4, 0xf1, 0x37, 0xc7, 0x33, 0x30, 0x86, 0x1d, 0x57, 0xf2, 0x39, 0xc2, 0x77, 0x40, 0xc3, 0x26, 0xa3, 0x1e, 0x9e, 0x4a, 0xdb, 0xeb, 0xdc, 0x9b, 0xe8, 0x4d, 0xf1, 0x7a, 0xde, 0x33, 0xe6, 0xbd, 0x24, 0x1f, 0x2e, 0x94, 0xe8, 0xae, 0x17, 0xdc, 0x76, 0xb4, 0x6c, 0xb7, 0x8c, 0x16, 0x42, 0x08, 0x53, 0x6c, 0xf8, 0x0c, 0xc9, 0xd1, 0x51, 0xcc, 0xfa, 0x6d, 0x41, 0xae, 0x71, 0x7f, 0xfe, 0xb0, 0x4b, 0x48, 0x48, 0x6c, 0x1d, 0x2d, 0x5c, 0xb2, 0xc8, 0xe2, 0x45, 0xc3, 0x13, 0x12, 0x12, 0x1e, 0x6c, 0x74, 0x0a, 0x10, 0xf1, 0x38, 0xd8, 0xb5, 0x9b, 0x08, 0x7a, 0x82, 0x49, 0x54, 0x54, 0x54, 0x9c, 0x4e, 0x96, 0xd9, 0xb2, 0x85, 0x7c, 0x17, 0x3f, 0x1b, 0x0b, 0xa8, 0x7c, 0xc6, 0x25, 0x98, 0x2f, 0xe5, 0x00, 0x11, 0x4b, 0x17, 0x05, 0xc6, 0xc7, 0xb5, 0x34, 0x5a, 0xbe, 0xa7, 0x5b, 0x6b, 0xe8, 0x70, 0x38, 0x5d, 0x7c, 0x49, 0x17, 0x08, 0x2c, 0xb7, 0x6f, 0xf7, 0x4c, 0x6b, 0xf2, 0xf2, 0x5e, 0x54, 0x6b, 0xf6, 0x6b, 0x2a, 0xea, 0xfb, 0x34, 0x69, 0xfa, 0xca, 0xd3, 0xbd, 0xca, 0x94, 0x4a, 0x22, 0xec, 0xc7, 0x8b, 0xc7, 0xa4, 0x13, 0x0a, 0x09, 0xc7, 0x15, 0x52, 0x5b, 0x4e, 0x22, 0xe8, 0xb3, 0xfc, 0xdf, 0xbf, 0x19, 0x01, 0x7f, 0x6b, 0x8d, 0xfb, 0x6a, 0xfd, 0x9f, 0x6e, 0x89, 0x44, 0x6e, 0xbd, 0x6e, 0x16, 0x34, 0x2f, 0x20, 0x02, 0x64, 0xb9, 0x09, 0xd8, 0x10, 0xd3, 0x77, 0x19, 0x56, 0x23, 0x2a, 0x39, 0x60, 0xf6, 0xac, 0xa2, 0x18, 0xc0, 0x36, 0x28, 0x7c, 0xfd, 0xa7, 0x8a, 0xcb, 0xa9, 0x35, 0xa8, 0x58, 0x2a, 0x76, 0xd0, 0x7d, 0x6c, 0xe4, 0xa1, 0xd1, 0xc3, 0xd6, 0x2b, 0x52, 0xf3, 0xbc, 0x32, 0x70, 0x06, 0x59, 0x52, 0xed, 0x0f, 0xf5, 0x6e, 0xbe, 0x8b, 0x88, 0x5b, 0x72, 0x34, 0xb2, 0x0e, 0xd7, 0xcd, 0xb4, 0x50, 0x91, 0x11, 0xbb, 0xee, 0xc5, 0xca, 0xdd, 0x71, 0x85, 0xbb, 0x20, 0x2c, 0xc6, 0x34, 0x60, 0xd5, 0x89, 0x96, 0xd3, 0x36, 0xe6, 0xa1, 0x66, 0xa2, 0xb7, 0xeb, 0xa3, 0xe5, 0xf9, 0xed, 0x27, 0x91, 0x65, 0xda, 0x39, 0xb5, 0xad, 0xec, 0x1d, 0x08, 0x98, 0x6b, 0x41, 0xd6, 0x5d, 0x41, 0xe4, 0x38, 0xcd, 0x30, 0xa0, 0xfc, 0xd6, 0x1b, 0x62, 0x13, 0x1c, 0x5c, 0x34, 0x88, 0x80, 0x4a, 0xd8, 0x12, 0xbd, 0x3e, 0x5c, 0x44, 0xc3, 0x96, 0x46, 0x97, 0xa8, 0xdc, 0xe3, 0x0a, 0xec, 0xf8, 0x46, 0xba, 0x5d, 0x70, 0x1b, 0x4d, 0xae, 0x48, 0x5b, 0x2a, 0x5e, 0xca, 0xd3, 0xd2, 0x19, 0x66, 0x65, 0xa1, 0x08, 0x23, 0xfc, 0xea, 0x90, 0xc3, 0x94, 0xf1, 0x23, 0x34, 0x74, 0xab, 0xfd, 0xac, 0xab, 0xaf, 0x3f, 0x12, 0x5b, 0x9f, 0x8c, 0x1c, 0x03, 0x23, 0x08, 0x42, 0x29, 0xb6, 0x0c, 0xdf, 0x1e, 0xf1, 0x01, 0x46, 0x77, 0xe0, 0x75, 0x08, 0xd3, 0x96, 0xd0, 0xcb, 0x9e, 0x3b, 0x1a, 0x23, 0xf6, 0xd9, 0x89, 0xe5, 0x49, 0x48, 0x4c, 0xfc, 0x4e, 0x23, 0xf7, 0x13, 0x00, 0x50, 0x99, 0x65, 0x3f, 0xef, 0x5b, 0x25, 0x55, 0xd7, 0x98, 0xf8, 0xd8, 0x55, 0xf5, 0x4d, 0x8d, 0x80, 0xac, 0xcd, 0x92, 0x33, 0x60, 0xb5, 0xb6, 0x72, 0xd6, 0x45, 0xc1, 0x74, 0xe8, 0xf9, 0xb9, 0x8f, 0x05, 0xd6, 0x4b, 0x77, 0x72, 0xf9, 0xeb, 0xfa, 0xfd, 0x02, 0xae, 0x4f, 0xb3, 0x03, 0x39, 0xe2, 0x27, 0xa5, 0x49, 0xb9, 0x9d, 0x8e, 0x79, 0x0d, 0x32, 0xb9, 0x72, 0x35, 0xa3, 0x27, 0x74, 0x72, 0x8a, 0xdf, 0x71, 0xa8, 0xaa, 0xbc, 0xfb, 0xf7, 0x5b, 0xd1, 0xa9, 0x5a, 0x5d, 0x0e, 0xfb, 0x0a, 0xf1, 0xb8, 0x70, 0x30, 0xef, 0x97, 0x18, 0x2b, 0x5c, 0x3d, 0x79, 0x94, 0xd8, 0x09, 0x14, 0xee, 0x03, 0x26, 0x3c, 0x18, 0x1f, 0xbc, 0x51, 0x46, 0xf5, 0x04, 0xef, 0xaa, 0xa2, 0xcf, 0x95, 0x99, 0xc4, 0x1b, 0xc4, 0x0e, 0x96, 0x7f, 0xf1, 0xb5, 0x41, 0xb8, 0xf7, 0x36, 0x6c, 0x5b, 0xd1, 0x37, 0xb5, 0x96, 0x21, 0xda, 0x2d, 0x5c, 0x9c, 0x43, 0xd6, 0xbd, 0x82, 0xc0, 0x5e, 0x95, 0xc3, 0x8a, 0x87, 0xc4, 0xcf, 0x45, 0xce, 0xed, 0xc4, 0xba, 0xbf, 0x2c, 0x76, 0xf1, 0xb6, 0x62, 0xe1, 0x45, 0x28, 0x6a, 0x6a, 0xe1, 0x44, 0x1f, 0x5c, 0x2f, 0x1b, 0x6d, 0x97, 0x4c, 0xb6, 0x44, 0xf7, 0x03, 0x4e, 0x52, 0xcd, 0xcd, 0xcc, 0x28, 0x28, 0x29, 0x61, 0x20, 0xa0, 0x0a, 0x89, 0xf6, 0xbe, 0x28, 0x5c, 0x06, 0x1b, 0xf7, 0xd7, 0xd9, 0x59, 0x95, 0x06, 0x9b, 0x05, 0xe4, 0xd6, 0xd6, 0x5d, 0x06, 0x8e, 0x5e, 0xf1, 0x90, 0x3a, 0xeb, 0x11, 0x01, 0x44, 0x64, 0x3b, 0xaf, 0xc6, 0xa3, 0x48, 0xdf, 0x6c, 0xe1, 0xbc, 0xf0, 0xf7, 0x79, 0xfe, 0x35, 0x97, 0x18, 0xf8, 0xa1, 0xe7, 0xa7, 0x05, 0x05, 0x2f, 0xb4, 0x38, 0xb8, 0xf6, 0xd5, 0x9b, 0xfb, 0x8a, 0xc5, 0x06, 0xf7, 0x13, 0x8c, 0x9e, 0x80, 0xe1, 0xc9, 0x8d, 0x51, 0x42, 0xd5, 0x75, 0x64, 0x2d, 0xbb, 0x3b, 0x6e, 0x9a, 0x48, 0x53, 0x50, 0xfa, 0x77, 0x45, 0x4d, 0x6b, 0xae, 0x01, 0x82, 0x2f, 0x9b, 0x0e, 0xa7, 0x75, 0x57, 0x53, 0x3b, 0x3c, 0x39, 0x6a, 0x03, 0x04, 0x7d, 0x9b, 0x67, 0xa4, 0xfb, 0x4d, 0xba, 0x83, 0xb9, 0x90, 0x9c, 0x3f, 0x03, 0x61, 0xf5, 0xf2, 0xa4, 0x22, 0x70, 0xb1, 0x85, 0xbd, 0xdf, 0x2a, 0x78, 0x0a, 0x6b, 0xb5, 0x2c, 0x8f, 0x15, 0x7f, 0xa1, 0x22, 0x4b, 0x04, 0x49, 0xa1, 0xd6, 0xef, 0x0e, 0xca, 0xd5, 0xe8, 0x70, 0xc7, 0x4a, 0x9e, 0x31, 0x37, 0x53, 0x54, 0x3b, 0x7f, 0x08, 0x47, 0x3d, 0x88, 0x1b, 0x3a, 0x23, 0x8e, 0x0f, 0x9c, 0xe8, 0x42, 0x47, 0x5f, 0xe3, 0x22, 0x29, 0x42, 0xb8, 0x91, 0x48, 0xf3, 0x40, 0x9a, 0x46, 0x80, 0xf7, 0x71, 0xe3, 0xf6, 0x37, 0x0a, 0x42, 0x28, 0xf1, 0x09, 0xa9, 0x4a, 0xc2, 0x03, 0x14, 0xeb, 0x4d, 0xfe, 0x4d, 0xe8, 0xca, 0x59, 0x57, 0x81, 0xa3, 0xe3, 0x28, 0x05, 0x9c, 0xbd, 0x3a, 0x96, 0x54, 0x45, 0x28, 0x95, 0x2a, 0xe6, 0xd4, 0x5a, 0x4e, 0x91, 0xb9, 0x81, 0xd7, 0x1e, 0x68, 0xcf, 0x18, 0xbb, 0xa3, 0xba, 0x5d, 0x76, 0x91, 0xa1, 0xf7, 0xc7, 0x3a, 0x3a, 0x04, 0x05, 0x2f, 0x87, 0x3f, 0x22, 0x7e, 0xf8, 0xfd, 0x90, 0x03, 0xdb, 0xa8, 0x13, 0x6b, 0x31, 0x91, 0x69, 0xbc, 0x50, 0xa1, 0x0e, 0x00, 0x24, 0x8f, 0x04, 0x07, 0x01, 0x50, 0x6f, 0x84, 0xef, 0x4c, 0x35, 0xbe, 0xf5, 0xc7, 0xdb, 0x7a, 0xa8, 0x91, 0x99, 0x64, 0x13, 0xeb, 0x6a, 0x57, 0xed, 0xb9, 0xc9, 0xd0, 0x97, 0x1b, 0x94, 0x7e, 0x06, 0xa9, 0x3f, 0x1f, 0x21, 0x77, 0xea, 0xfd, 0x15, 0x08, 0xba, 0x48, 0x1d, 0xfd, 0x48, 0xfe, 0x7c, 0x75, 0x46, 0x20, 0xd4, 0x92, 0xa6, 0x2b, 0xfc, 0x32, 0x1e, 0x36, 0xe6, 0xb5, 0xdb, 0xe7, 0xe8, 0xc4, 0x27, 0xd4, 0x3e, 0x6a, 0x4a, 0xd5, 0xf7, 0xa5, 0xf6, 0xf4, 0xe9, 0x8e, 0x58, 0x2f, 0x52, 0x5d, 0xda, 0x27, 0x04, 0x53, 0xb3, 0x7a, 0x97, 0x82, 0x8e, 0x15, 0xa0, 0x40, 0x2c, 0xfd, 0x05, 0x83, 0x80, 0xdd, 0x15, 0xd9, 0x49, 0x98, 0x8b, 0x74, 0x9f, 0x39, 0x55, 0x89, 0xb3, 0x52, 0x6b, 0xdf, 0x50, 0x59, 0x2d, 0xd8, 0xb8, 0xd9, 0x43, 0x3a, 0xed, 0x16, 0xc9, 0xe0, 0x41, 0x52, 0xca, 0x91, 0x15, 0x94, 0xfb, 0x69, 0x8f, 0xb2, 0x72, 0xf6, 0x28, 0xa4, 0xe0, 0xa5, 0xdd, 0xe4, 0xf6, 0x43, 0xda, 0x42, 0x70, 0xa5, 0x24, 0x8e, 0xa4, 0xdd, 0x7a, 0x56, 0xc4, 0xd9, 0xd2, 0x49, 0xd0, 0x8c, 0xda, 0xab, 0xe4, 0x27, 0x76, 0x76, 0xac, 0x4f, 0x4a, 0xb9, 0x12, 0x7e, 0x7e, 0x37, 0x69, 0xb2, 0xb9, 0xc2, 0xfe, 0x44, 0xfa, 0x6d, 0x6e, 0x30, 0x80, 0xf1, 0x1c, 0x01, 0x7c, 0xc7, 0x8e, 0x0b, 0xa9, 0x2a, 0xd3, 0x47, 0x08, 0x8a, 0xc7, 0x0d, 0x44, 0xe3, 0xc3, 0xd2, 0xe5, 0xcd, 0x3f, 0x1c, 0xe3, 0x3b, 0xce, 0x3f, 0x8c, 0x31, 0x5a, 0xa7, 0xf3, 0xee, 0x7b, 0xed, 0x4d, 0x4c, 0x9d, 0x0f, 0x15, 0x24, 0xa3, 0xf9, 0xaa, 0x8d, 0xec, 0x5e, 0xc5, 0xce, 0xaa, 0x9a, 0x23, 0xc5, 0xcc, 0x67, 0x6e, 0xd2, 0xb8, 0xa5, 0x56, 0xac, 0x64, 0xe1, 0x8d, 0x2d, 0x2c, 0x31, 0xc4, 0x4f, 0xa4, 0x73, 0x22, 0x4f, 0x4d, 0x74, 0x0c, 0xd9, 0xef, 0xb3, 0xea, 0x32, 0x2e, 0xbb, 0x1e, 0x70, 0x5e, 0x23, 0x7c, 0xac, 0x36, 0xdf, 0xdd, 0xfe, 0xc1, 0x25, 0xa0, 0xac, 0xe3, 0xf1, 0x82, 0xa6, 0x31, 0x35, 0x69, 0x7f, 0x31, 0xf1, 0x7e, 0xaa, 0xfd, 0xd4, 0xaf, 0x5f, 0x08, 0x8d, 0x3a, 0x77, 0x20, 0xb9, 0x86, 0xe9, 0x8f, 0x02, 0x1e, 0x16, 0x41, 0x9f, 0xee, 0xd4, 0x54, 0x99, 0xba, 0xed, 0x7a, 0x3d, 0x7e, 0x0d, 0x28, 0x2b, 0x55, 0x37, 0xc1, 0x87, 0x6b, 0xcc, 0xe1, 0x19, 0x4a, 0xb0, 0xde, 0x93, 0xfb, 0x29, 0xef, 0x4c, 0xb5, 0x1f, 0x57, 0xb7, 0xd7, 0x3a, 0xac, 0xf3, 0x87, 0x42, 0xc2, 0xeb, 0xef, 0x77, 0xd8, 0x83, 0xe5, 0x3a, 0xd3, 0x58, 0x11, 0x58, 0x3a, 0x16, 0xa2, 0xf9, 0x0a, 0x75, 0x06, 0x5d, 0xf7, 0xce, 0x48, 0x53, 0x04, 0x13, 0x30, 0xc7, 0x9c, 0xe3, 0x25, 0x33, 0xa8, 0xf2, 0xcf, 0x15, 0xb2, 0xf3, 0xd4, 0x6f, 0x6f, 0x3a, 0x77, 0x9d, 0x15, 0x4c, 0x27, 0x36, 0xd6, 0x5a, 0x5b, 0xcf, 0x90, 0x6d, 0xe5, 0x09, 0x22, 0x04, 0x0c, 0x6d, 0xef, 0xcd, 0x12, 0x95, 0x4e, 0x94, 0xb7, 0x75, 0x67, 0xb3, 0x9d, 0xc9, 0x10, 0x66, 0xa0, 0xdc, 0xe2, 0x4f, 0x9d, 0x92, 0xde, 0x88, 0xef, 0x42, 0xac, 0xc6, 0xff, 0xaa, 0xd2, 0x6f, 0xb6, 0x72, 0x0e, 0xe6, 0xaa, 0x72, 0xd6, 0x5f, 0x53, 0x1a, 0x6c, 0x9b, 0x74, 0x17, 0xfa, 0x7d, 0xaf, 0xcf, 0x66, 0x60, 0xbe, 0x3c, 0x7a, 0x34, 0xda, 0xcb, 0x65, 0xef, 0x74, 0x4e, 0x69, 0x52, 0x09, 0xd4, 0x9c, 0x23, 0x9c, 0xb9, 0x34, 0xbd, 0x1d, 0x68, 0x77, 0xb0, 0xbd, 0xf9, 0x96, 0x9a, 0xa1, 0xa5, 0x4c, 0xa9, 0xd5, 0xc4, 0x7a, 0x6e, 0xfa, 0xe3, 0x43, 0xf2, 0x12, 0x7f, 0x0e, 0x9a, 0xea, 0x2f, 0x79, 0x67, 0x1b, 0x54, 0x5d, 0xfd, 0xba, 0xba, 0x3a, 0xaf, 0xa3, 0xf2, 0x52, 0x3b, 0x20, 0xb1, 0x27, 0x99, 0xb8, 0x31, 0xdb, 0xcb, 0xe4, 0xad, 0x66, 0xdd, 0x0c, 0x66, 0x3a, 0x9f, 0x7d, 0x76, 0xb4, 0xd0, 0xe0, 0x22, 0xed, 0x5c, 0xea, 0x92, 0x20, 0x19, 0x46, 0x39, 0x76, 0xb7, 0xdc, 0x41, 0x5d, 0x5d, 0x25, 0xfa, 0x3b, 0x18, 0x8f, 0x2a, 0xd8, 0x2b, 0x64, 0xb9, 0xf3, 0xa7, 0xea, 0xbe, 0x1b, 0x8f, 0x49, 0x30, 0xa9, 0x2e, 0xd0, 0xbe, 0x72, 0x81, 0xbe, 0xa6, 0x0c, 0x4b, 0x3a, 0x7b, 0x9d, 0xc3, 0x21, 0x61, 0xbd, 0xa9, 0x7a, 0x3e, 0xa8, 0x26, 0x70, 0xd5, 0x65, 0x4e, 0xd6, 0x01, 0x60, 0x54, 0xa7, 0x55, 0x77, 0xf7, 0x15, 0x4b, 0x58, 0xbb, 0xad, 0x6b, 0x94, 0xc5, 0x4e, 0xb3, 0x5a, 0xaf, 0x5c, 0x5d, 0x2f, 0x87, 0xdf, 0xbd, 0x37, 0xe5, 0xb3, 0x2a, 0x00, 0x20, 0x23, 0x23, 0xc3, 0xa5, 0xc3, 0xb5, 0x75, 0xb0, 0xe1, 0x7b, 0xd6, 0xd8, 0xc9, 0x9d, 0xc1, 0x74, 0xef, 0x3e, 0xd6, 0xa5, 0x13, 0x88, 0x67, 0x7d, 0x4f, 0xd6, 0xe2, 0xcb, 0xeb, 0x40, 0xbe, 0xb7, 0x36, 0x25, 0x9e, 0xe4, 0x62, 0xa8, 0x4c, 0x07, 0x7a, 0x3f, 0x86, 0x81, 0x55, 0x4e, 0xd3, 0x9d, 0x89, 0xf3, 0x1e, 0x40, 0x43, 0x43, 0xee, 0x5a, 0xc2, 0xce, 0x2d, 0x91, 0xe4, 0x66, 0x4a, 0x1f, 0x5f, 0x6a, 0xb9, 0xbb, 0x1d, 0xb7, 0xfd, 0xe2, 0xb0, 0x9c, 0x5a, 0xd9, 0xd4, 0xfb, 0xa5, 0xf1, 0xde, 0xba, 0xcf, 0x01, 0xd8, 0xf4, 0x97, 0x80, 0x2c, 0x57, 0x10, 0x21, 0x58, 0x54, 0x66, 0x1d, 0xc8, 0x69, 0x8f, 0x15, 0x12, 0x4c, 0x45, 0x3a, 0x69, 0xd0, 0x62, 0x47, 0x3c, 0x36, 0xce, 0xf4, 0x77, 0x37, 0x86, 0xc4, 0xcd, 0x6a, 0x8e, 0x44, 0x0c, 0x2d, 0xf9, 0x9f, 0xbc, 0x05, 0xca, 0x2d, 0xa9, 0x4c, 0x6f, 0x73, 0x65, 0x93, 0xf1, 0x45, 0xd4, 0x66, 0xdd, 0x9b, 0xd5, 0x2c, 0xea, 0x59, 0x97, 0x5e, 0x97, 0x1f, 0x61, 0xbd, 0xc5, 0x44, 0x85, 0xba, 0x9d, 0xb3, 0xb3, 0xb3, 0xd6, 0x1f, 0x33, 0x24, 0xde, 0xfd, 0x16, 0xaf, 0x0b, 0xaa, 0x5f, 0x4a, 0x79, 0x68, 0x8d, 0x6d, 0x7b, 0x63, 0xe4, 0xc4, 0x3c, 0x0e, 0x31, 0x45, 0xd2, 0xf1, 0xa0, 0xe7, 0x87, 0x2b, 0x40, 0x90, 0xea, 0xfe, 0x2c, 0xab, 0xf3, 0x89, 0xa8, 0x76, 0x3b, 0x00, 0xeb, 0x81, 0x0e, 0x0e, 0xa6, 0xef, 0xbd, 0xdb, 0x50, 0xb9, 0x6b, 0x79, 0x4b, 0xa6, 0x76, 0xab, 0x08, 0xbc, 0x65, 0xcc, 0xe7, 0x47, 0xe7, 0x8d, 0x7b, 0xd7, 0xfc, 0x61, 0x01, 0x22, 0xe5, 0x04, 0xe2, 0xcb, 0xf6, 0x50, 0x34, 0x40, 0xf0, 0xf4, 0x67, 0xb9, 0xa4, 0xd9, 0xbc, 0x2a, 0x41, 0x0d, 0xad, 0xdf, 0x7d, 0x0b, 0xe3, 0x7a, 0xcd, 0x0a, 0x71, 0x95, 0x8c, 0x82, 0x6a, 0xd1, 0xa7, 0x4f, 0x58, 0xf6, 0x42, 0xcd, 0xea, 0xf4, 0x34, 0xaf, 0xdc, 0x61, 0x58, 0x6d, 0x3c, 0x10, 0xcf, 0x4a, 0xe8, 0xd2, 0xc7, 0xc0, 0x26, 0x0c, 0xff, 0xf2, 0x69, 0x72, 0xa5, 0xa2, 0xd5, 0xdc, 0x6c, 0xdf, 0xf4, 0x0a, 0xfc, 0xf1, 0xab, 0xcc, 0x98, 0xa8, 0x47, 0x00, 0x26, 0x96, 0x92, 0x61, 0x3f, 0x38, 0xa4, 0xb4, 0xf6, 0xbe, 0x74, 0x62, 0xd9, 0xf5, 0x9e, 0xd3, 0xe5, 0x32, 0x9a, 0x04, 0xd9, 0x1d, 0xc0, 0x04, 0x32, 0xbd, 0x88, 0x1f, 0x2a, 0x2d, 0xd4, 0xaf, 0xfc, 0xc5, 0xeb, 0xf2, 0x47, 0xd0, 0x7b, 0xef, 0xdf, 0x3f, 0xa3, 0xa3, 0xf9, 0xf2, 0x88, 0xc8, 0x72, 0xef, 0x6f, 0x05, 0x90, 0x48, 0xdf, 0x1e, 0xcf, 0xe0, 0xf8, 0x2a, 0x2b, 0x2b, 0x0e, 0xa1, 0xab, 0x31, 0x52, 0x1f, 0x07, 0x63, 0x08, 0x5d, 0xaf, 0x78, 0xf8, 0x8d, 0x62, 0x0a, 0x14, 0xb2, 0xb8, 0x9b, 0x46, 0x9c, 0xf1, 0x2a, 0x71, 0x29, 0x57, 0x29, 0xae, 0x8b, 0x09, 0xcf, 0x02, 0xa2, 0xd9, 0xc2, 0x2d, 0x9c, 0xd9, 0x20, 0xba, 0x2d, 0x68, 0x7d, 0x8a, 0x6d, 0x7f, 0x90, 0x60, 0x90, 0xe0, 0x7d, 0x4c, 0xbb, 0xe3, 0xb9, 0x07, 0x88, 0xe6, 0x19, 0xfc, 0x53, 0x00, 0x00, 0x87, 0x10, 0xbe, 0x0b, 0x40, 0x2e, 0xbd, 0x51, 0x07, 0xde, 0x91, 0xf6, 0x95, 0x30, 0x4c, 0x4e, 0x09, 0xad, 0x17, 0x5c, 0xe2, 0x87, 0x6d, 0xe5, 0x03, 0x64, 0xf7, 0x0c, 0xc0, 0xb9, 0xce, 0x21, 0x75, 0xce, 0x23, 0x02, 0x04, 0xcb, 0x4f, 0x3e, 0x37, 0xdc, 0xd1, 0xea, 0xfd, 0x89, 0xaa, 0xf8, 0xb5, 0x7e, 0xeb, 0xcc, 0xcf, 0x6d, 0xe6, 0x22, 0x1e, 0xe4, 0x82, 0x61, 0x49, 0x2a, 0x4f, 0x8b, 0x55, 0x31, 0x6c, 0x12, 0x92, 0xa1, 0x26, 0xab, 0xa4, 0x5f, 0x2e, 0xfa, 0x82, 0xd3, 0xd8, 0x02, 0xbc, 0x44, 0x04, 0xd9, 0xdd, 0x19, 0x21, 0xe8, 0xde, 0x64, 0xea, 0x71, 0xba, 0xaa, 0x7e, 0xdc, 0x02, 0x7d, 0x9c, 0x03, 0x07, 0x9f, 0x1a, 0xb8, 0x68, 0x99, 0xe7, 0x1f, 0x0e, 0xa1, 0xbf, 0x8b, 0x47, 0xae, 0x3e, 0x37, 0x47, 0x61, 0x65, 0x65, 0xc7, 0x5c, 0x9d, 0x9e, 0x27, 0x22, 0x60, 0x2e, 0x7d, 0x40, 0xa4, 0x60, 0x5b, 0x93, 0x63, 0x18, 0x26, 0xac, 0x2f, 0x7f, 0xac, 0x6b, 0x75, 0xa0, 0x64, 0x89, 0x0d, 0x8f, 0x68, 0x78, 0xc2, 0x57, 0xd4, 0x07, 0x73, 0xf1, 0xa5, 0x43, 0xee, 0x34, 0x36, 0x3c, 0xb7, 0x09, 0x67, 0xbd, 0x24, 0x5e, 0x6e, 0x30, 0xff, 0xc1, 0x11, 0x93, 0x3b, 0xb7, 0xf5, 0x09, 0x05, 0x1d, 0xee, 0x2e, 0x8f, 0x84, 0xcb, 0x55, 0xb4, 0x9d, 0xe6, 0x71, 0xbf, 0xaf, 0x64, 0xf8, 0x0f, 0xa3, 0xed, 0xb5, 0x4f, 0x75, 0x4e, 0x60, 0x55, 0x02, 0xae, 0x96, 0x25, 0x54, 0xb9, 0x12, 0xee, 0x78, 0xdb, 0x50, 0xf3, 0x2b, 0xc3, 0x5e, 0x70, 0x9e, 0x70, 0xef, 0xcf, 0x92, 0x33, 0xe8, 0x5e, 0x08, 0xca, 0xa9, 0x61, 0xea, 0x9e, 0x9a, 0x2c, 0x4d, 0x5b, 0x83, 0x5c, 0x2d, 0xa9, 0xef, 0xc1, 0x74, 0x81, 0xce, 0xd0, 0x7c, 0x93, 0xbd, 0xae, 0xe0, 0xeb, 0xfd, 0x0e, 0x60, 0x54, 0xae, 0x0f, 0x92, 0xfe, 0x71, 0x11, 0xbe, 0x4c, 0xd8, 0x06, 0xd1, 0xe1, 0x20, 0x0b, 0x3e, 0x9d, 0xdc, 0x64, 0xa9, 0xed, 0x33, 0xeb, 0xbb, 0x1f, 0xf7, 0x2b, 0xcf, 0xb2, 0xde, 0x1c, 0xcc, 0x0f, 0x0e, 0x94, 0x69, 0xdb, 0xd7, 0x15, 0xbf, 0x16, 0x2b, 0x37, 0x5c, 0x83, 0x75, 0x16, 0xfa, 0x45, 0xb0, 0xf9, 0x01, 0xac, 0xbf, 0xbc, 0xc7, 0x16, 0xee, 0x2b, 0x14, 0x7c, 0x13, 0xb2, 0x02, 0x77, 0xda, 0x40, 0x8d, 0x98, 0x84, 0x64, 0xef, 0x62, 0x7f, 0x75, 0xd8, 0xd3, 0xec, 0x8b, 0x26, 0x2a, 0x06, 0x26, 0x7b, 0x62, 0x38, 0xe6, 0xab, 0xd1, 0x39, 0xe9, 0x76, 0x33, 0xdf, 0x9f, 0xe7, 0x05, 0x0e, 0x81, 0x71, 0xc9, 0x8d, 0x67, 0x88, 0x95, 0xb6, 0x9b, 0x02, 0xf4, 0x67, 0x18, 0x99, 0x11, 0x20, 0xec, 0x6c, 0xba, 0x40, 0xc1, 0x55, 0x50, 0xc4, 0x95, 0x5d, 0xc3, 0xef, 0x99, 0xc5, 0xcd, 0x3a, 0x2d, 0x48, 0xd9, 0x3e, 0x41, 0x35, 0xd0, 0x1d, 0x40, 0x30, 0xdb, 0x1c, 0x7d, 0xea, 0x6e, 0x62, 0x62, 0x92, 0x63, 0x92, 0x29, 0xe8, 0xfd, 0xe7, 0xd4, 0xdd, 0xc2, 0x82, 0x36, 0xe0, 0xe9, 0xb4, 0x99, 0x98, 0x44, 0xbf, 0x31, 0x83, 0xc3, 0x72, 0xd5, 0x86, 0x32, 0xa2, 0x30, 0xd4, 0xad, 0x7d, 0xbf, 0xb4, 0x9f, 0x5c, 0x01, 0x92, 0x7b, 0x9a, 0xd1, 0x8f, 0x8f, 0x4d, 0xe2, 0x5b, 0x3f, 0x2b, 0x3f, 0xb7, 0x0e, 0xc1, 0x52, 0x71, 0x81, 0xd2, 0xa6, 0xa6, 0x61, 0x44, 0x4b, 0x6c, 0x3c, 0xc5, 0x31, 0xe6, 0xfd, 0xa9, 0xcb, 0x97, 0xc1, 0x3d, 0x05, 0x33, 0x66, 0x52, 0xab, 0x8d, 0x76, 0x31, 0xed, 0x55, 0x2c, 0x6b, 0x7c, 0x98, 0x9d, 0xe3, 0x46, 0xbd, 0xa0, 0x3c, 0xee, 0x95, 0x5c, 0xa5, 0x1b, 0x48, 0xf2, 0xd5, 0xf0, 0x5f, 0x8e, 0xf4, 0x53, 0xa3, 0xa7, 0xd1, 0xe9, 0x1f, 0x32, 0x59, 0x9b, 0x16, 0x6e, 0x09, 0xec, 0x75, 0x12, 0x74, 0xba, 0x43, 0x94, 0x27, 0xe3, 0x21, 0x80, 0x28, 0x86, 0x36, 0xeb, 0xa2, 0x64, 0x88, 0xe7, 0x68, 0xd5, 0x05, 0xe0, 0xff, 0x2e, 0x8c, 0x58, 0x5b, 0xd3, 0x83, 0xda, 0x6a, 0xda, 0xc6, 0x56, 0x73, 0x9a, 0x46, 0x58, 0x98, 0x0c, 0x5a, 0xff, 0x71, 0x38, 0xf1, 0xa3, 0xf3, 0xb3, 0xd7, 0x43, 0xd5, 0x65, 0xb9, 0xaa, 0xed, 0x86, 0xbc, 0x54, 0xe5, 0x02, 0x68, 0xab, 0x27, 0xe4, 0xab, 0xcc, 0xe7, 0xb3, 0xf8, 0x2a, 0x8d, 0x4a, 0xd6, 0x5a, 0xcd, 0xd2, 0xac, 0x8e, 0xe8, 0x7b, 0xf6, 0x41, 0x02, 0x1d, 0x2e, 0xc7, 0xe0, 0x3c, 0x1e, 0x70, 0xf8, 0x0e, 0x36, 0xc1, 0xa4, 0xc2, 0x29, 0x44, 0x49, 0x4a, 0x4b, 0xb2, 0x1d, 0x77, 0x08, 0xce, 0x24, 0x66, 0x5d, 0x00, 0x19, 0xdc, 0xea, 0xf9, 0xbe, 0xfd, 0xd1, 0x0a, 0x15, 0x20, 0x44, 0xf1, 0xd4, 0x79, 0xab, 0xbf, 0x3b, 0xff, 0xfc, 0x7b, 0xfd, 0xb6, 0x54, 0x77, 0x0a, 0x9f, 0x04, 0xc7, 0x88, 0xe7, 0x30, 0x62, 0xb1, 0xe0, 0x29, 0xad, 0x36, 0xc1, 0xc8, 0xad, 0xad, 0x84, 0x26, 0xe8, 0xd2, 0xa3, 0x4e, 0xb7, 0xc9, 0xae, 0xfc, 0xc6, 0x12, 0x29, 0x38, 0x48, 0x49, 0xe4, 0x05, 0x67, 0x4a, 0xe8, 0x8e, 0x84, 0xea, 0xe3, 0xc7, 0x3a, 0xeb, 0x39, 0xda, 0x94, 0x9f, 0x8b, 0x0e, 0x4c, 0x0f, 0xd3, 0x05, 0x5f, 0xec, 0x6b, 0xee, 0xc8, 0x84, 0xf5, 0x8f, 0xd3, 0x23, 0xce, 0x20, 0x5a, 0x81, 0x60, 0x27, 0xbc, 0xad, 0x4d, 0x76, 0x7f, 0xdc, 0x84, 0xaf, 0x99, 0x82, 0xb5, 0x36, 0x7e, 0x74, 0x47, 0x2c, 0xd1, 0xe6, 0x02, 0x18, 0x6a, 0xc0, 0xac, 0x10, 0x15, 0x49, 0xf8, 0x4a, 0x95, 0x5f, 0xd7, 0xfe, 0x36, 0xc1, 0x77, 0xbe, 0x58, 0x68, 0x0e, 0x25, 0x27, 0xcd, 0x8a, 0x38, 0x44, 0x42, 0x07, 0x8f, 0xa1, 0xc9, 0x07, 0x11, 0xca, 0xcd, 0xfe, 0xcc, 0xd6, 0x04, 0xfc, 0x4d, 0xd6, 0x0e, 0xbe, 0xfe, 0x10, 0xdd, 0xc9, 0xef, 0xaf, 0x11, 0x4f, 0x26, 0x04, 0xbd, 0x98, 0xde, 0x01, 0x11, 0x81, 0xd3, 0xc7, 0x37, 0x8d, 0x5d, 0xa7, 0x06, 0xad, 0xa0, 0xec, 0xf6, 0x2c, 0x70, 0x42, 0xf8, 0x71, 0xf9, 0x21, 0x76, 0xfe, 0x37, 0x81, 0x7d, 0xfb, 0xc9, 0x31, 0x9d, 0x2c, 0x79, 0x6b, 0xf4, 0x51, 0x08, 0xac, 0x21, 0x88, 0x28, 0x1d, 0x88, 0x2a, 0x4e, 0x1e, 0x71, 0x0e, 0x06, 0x0b, 0xbb, 0x91, 0xe0, 0x4b, 0x22, 0xbd, 0x3d, 0x5c, 0x5a, 0x76, 0x9c, 0x83, 0x35, 0xa7, 0xdb, 0x0f, 0xf1, 0xd7, 0x97, 0x0b, 0xfc, 0x31, 0x30, 0x35, 0x02, 0xb2, 0x6e, 0xc4, 0x33, 0xe7, 0xb2, 0x05, 0x41, 0x3b, 0x3a, 0x9c, 0xb1, 0x8d, 0x9d, 0x1b, 0x1d, 0xde, 0xf5, 0xba, 0xc2, 0xae, 0x93, 0xd9, 0x7c, 0x07, 0x0b, 0x95, 0x10, 0x19, 0xff, 0x64, 0xff, 0xb5, 0xb1, 0xe5, 0x98, 0xc3, 0x08, 0xa0, 0x60, 0x40, 0x3b, 0x09, 0x32, 0x29, 0x72, 0xda, 0x1f, 0xd6, 0xad, 0x5c, 0xae, 0x0c, 0xe4, 0xa0, 0x36, 0xd3, 0x5a, 0x5f, 0x55, 0x4d, 0xf2, 0xd9, 0xbe, 0x43, 0x22, 0x05, 0xe0, 0x44, 0x0d, 0xef, 0xaa, 0xa7, 0x36, 0x6e, 0x76, 0x9d, 0x11, 0x90, 0x3d, 0xed, 0xbf, 0xd3, 0xeb, 0xd2, 0x70, 0xaf, 0x4f, 0x3d, 0x9a, 0x45, 0x80, 0x2f, 0x94, 0x2e, 0xbd, 0x04, 0x82, 0xbd, 0xe1, 0x69, 0xdc, 0x5f, 0x05, 0x67, 0x6b, 0xaf, 0x4f, 0xe6, 0x07, 0xb9, 0x59, 0x76, 0x20, 0x88, 0xd1, 0xe2, 0x76, 0x38, 0xeb, 0xe0, 0x26, 0x5f, 0xf7, 0xbf, 0xbb, 0x00, 0xb1, 0x9b, 0xca, 0xa8, 0xb4, 0xc9, 0x48, 0x17, 0x17, 0x17, 0xd0, 0xf7, 0x2b, 0x8b, 0x35, 0x86, 0x86, 0x3b, 0x77, 0x79, 0x10, 0x36, 0x7d, 0xbb, 0x6a, 0xc4, 0x0e, 0x5c, 0x5c, 0xc7, 0x66, 0xf7, 0x07, 0x7d, 0x4d, 0xc3, 0x65, 0xa2, 0x29, 0xff, 0x9d, 0xd1, 0xe3, 0xe4, 0x91, 0xf4, 0x81, 0x32, 0x31, 0x2b, 0x3f, 0x14, 0xcd, 0x68, 0x30, 0xe6, 0x1f, 0x0a, 0xb2, 0xa4, 0x44, 0x6a, 0x18, 0xf6, 0x64, 0xb6, 0x52, 0x5f, 0xa7, 0xeb, 0x46, 0x0f, 0xbe, 0xc8, 0x2b, 0x42, 0xf2, 0xc3, 0xe0, 0xa9, 0x98, 0x23, 0x6d, 0x77, 0xad, 0x1f, 0xc2, 0x4b, 0x93, 0xff, 0x90, 0x51, 0xb1, 0xb9, 0x78, 0x40, 0x89, 0xfa, 0x15, 0xed, 0xc1, 0x52, 0x67, 0x88, 0xfd, 0xd3, 0xd5, 0xd4, 0xb1, 0xb0, 0xf5, 0x3d, 0x24, 0x2f, 0x0c, 0xb4, 0xb9, 0x1f, 0x03, 0x00, 0x35, 0xdd, 0xaf, 0x8f, 0x0a, 0x71, 0x4d, 0x43, 0x7c, 0x43, 0xc1, 0xf0, 0x28, 0x76, 0x40, 0x55, 0x07, 0x72, 0x13, 0x5d, 0x1d, 0x99, 0xaf, 0xd1, 0xf7, 0x52, 0x04, 0x1e, 0xb6, 0x3c, 0x69, 0x4f, 0xbf, 0x17, 0x93, 0x7c, 0xf5, 0xc1, 0x14, 0x7f, 0x0a, 0x43, 0xd1, 0xb6, 0xb2, 0x1c, 0xd5, 0xf4, 0x8a, 0x5a, 0x5d, 0x89, 0x4c, 0x8d, 0xd5, 0x35, 0x0e, 0x59, 0x09, 0x26, 0xee, 0x4f, 0x9e, 0x6e, 0x5a, 0xae, 0x66, 0x96, 0xce, 0xf3, 0x58, 0x02, 0x07, 0x77, 0x6d, 0xf9, 0x1a, 0xf9, 0x35, 0xad, 0xb5, 0x1f, 0x4e, 0x9f, 0x6c, 0xb5, 0xbd, 0x97, 0x1f, 0x2c, 0xd7, 0x73, 0x8b, 0x92, 0xc2, 0x2d, 0x95, 0x4b, 0xc4, 0xb9, 0x0c, 0x03, 0x5f, 0xb8, 0x18, 0x79, 0x0e, 0xc9, 0x03, 0x39, 0x70, 0x6f, 0xd6, 0x61, 0xb6, 0xe6, 0xcb, 0x55, 0x17, 0x02, 0xb8, 0xa7, 0xf8, 0x86, 0xd0, 0x45, 0x9e, 0x8d, 0x8e, 0xe3, 0xab, 0x51, 0xd1, 0xfa, 0x7f, 0xbf, 0x07, 0x97, 0xa9, 0x32, 0xf6, 0xdf, 0x8d, 0x07, 0x1c, 0x38, 0xa4, 0x8d, 0xb1, 0xc2, 0xec, 0xf0, 0x36, 0xb6, 0xa9, 0x7a, 0xc6, 0xbf, 0x97, 0x70, 0x88, 0xc0, 0x7a, 0x34, 0x1c, 0x1d, 0xed, 0x1a, 0xdb, 0x13, 0xf4, 0x6b, 0x51, 0x21, 0xbc, 0x9b, 0x8b, 0x8d, 0x1b, 0x1b, 0x61, 0xe9, 0xbd, 0xb3, 0x6d, 0xda, 0x01, 0x0f, 0xed, 0x81, 0xb6, 0xf1, 0x85, 0xfb, 0x37, 0xfa, 0x4a, 0x6d, 0x39, 0x9d, 0xab, 0x5b, 0xfe, 0x3d, 0xda, 0xfd, 0x83, 0xa8, 0x5f, 0x1b, 0x52, 0x16, 0xeb, 0xf4, 0xcc, 0x21, 0xc3, 0xc0, 0x38, 0x03, 0x65, 0xe5, 0xa0, 0x1c, 0x01, 0xcf, 0xc5, 0xc3, 0x2b, 0x17, 0xd7, 0x9a, 0x1a, 0xd2, 0xfd, 0xec, 0x22, 0xcf, 0xb3, 0x0d, 0x68, 0xb5, 0x05, 0x88, 0xa8, 0x81, 0xcb, 0xa9, 0xee, 0xf0, 0x4a, 0x5c, 0xb0, 0x91, 0x84, 0xc8, 0xac, 0xc9, 0x1c, 0x81, 0x1f, 0xbb, 0x63, 0x69, 0x3b, 0x13, 0x3c, 0x9b, 0xfd, 0x10, 0x3e, 0x01, 0x95, 0x5c, 0x4e, 0x93, 0x33, 0x74, 0xf4, 0x24, 0x67, 0x1d, 0xe7, 0x3c, 0x65, 0xfa, 0xf2, 0xc1, 0x54, 0xaf, 0x55, 0xea, 0xf5, 0x83, 0x1e, 0xa4, 0x88, 0x35, 0xc9, 0xe9, 0x74, 0x16, 0xc2, 0xbb, 0x26, 0xef, 0x13, 0x31, 0x17, 0xc8, 0xdd, 0x67, 0x93, 0x3e, 0xa7, 0xfe, 0x92, 0xae, 0x5a, 0x0c, 0x5e, 0x82, 0x51, 0xad, 0x3f, 0xea, 0xd8, 0x59, 0xcc, 0x25, 0xbd, 0xd8, 0xea, 0xc7, 0x3c, 0x00, 0x56, 0x91, 0xaa, 0x8d, 0x56, 0x2c, 0x7d, 0xd4, 0x65, 0xd4, 0xf8, 0xd0, 0x79, 0x06, 0x7f, 0xf0, 0xd6, 0x26, 0xdb, 0xed, 0xd8, 0xcb, 0x0a, 0xdd, 0x02, 0xbc, 0x0b, 0x55, 0x20, 0x82, 0x4b, 0x5e, 0x09, 0x96, 0x89, 0xef, 0x8e, 0xb4, 0x5d, 0xf1, 0x06, 0x04, 0x01, 0x1d, 0xbb, 0x3b, 0x17, 0x39, 0xe6, 0xbf, 0x5f, 0x4e, 0xda, 0x42, 0x1f, 0x8e, 0x1e, 0x80, 0x56, 0x9a, 0x65, 0x4b, 0xc4, 0xb3, 0xb8, 0xed, 0xa1, 0xcf, 0x79, 0x20, 0xc4, 0x32, 0xed, 0x8c, 0x7c, 0xb6, 0x99, 0x61, 0x4f, 0x88, 0x07, 0x76, 0xbb, 0xa0, 0x51, 0x17, 0x5b, 0xc9, 0x6f, 0x33, 0xb7, 0xaf, 0x94, 0xd5, 0x12, 0x5c, 0xca, 0x7c, 0x6b, 0x15, 0x23, 0x6b, 0x7e, 0x6c, 0x55, 0xc9, 0x15, 0x59, 0x61, 0xe6, 0x8d, 0xe4, 0x63, 0xb4, 0x57, 0x8c, 0x98, 0xa4, 0xe6, 0x23, 0x5f, 0xd9, 0x79, 0x6c, 0x3b, 0xe8, 0x86, 0x27, 0xf3, 0x07, 0x0e, 0xf6, 0x37, 0x1b, 0xc5, 0xd7, 0xa0, 0x7f, 0x97, 0x71, 0x52, 0x3e, 0x16, 0xcc, 0xdc, 0x60, 0xc1, 0x50, 0xf2, 0xa5, 0x93, 0xbf, 0xb7, 0xfe, 0x43, 0x4e, 0xec, 0x7c, 0xb8, 0x32, 0xf8, 0xb3, 0x09, 0xa9, 0xba, 0x11, 0x2d, 0xcb, 0x56, 0xc0, 0xcb, 0xf8, 0x2b, 0xeb, 0x43, 0xad, 0x2e, 0xf0, 0x23, 0xae, 0x76, 0x19, 0x37, 0xe2, 0xce, 0x0f, 0x81, 0x66, 0x26, 0xea, 0x2e, 0xb9, 0x72, 0xe5, 0x7c, 0xfd, 0xe3, 0x5f, 0x5a, 0x77, 0x9a, 0x39, 0x21, 0xd1, 0xf8, 0x2c, 0xa0, 0xae, 0x27, 0x70, 0x7d, 0x65, 0xa5, 0x01, 0x36, 0x1b, 0x1b, 0xdb, 0xf0, 0xc8, 0x48, 0xcf, 0x76, 0xdf, 0xe4, 0x69, 0x20, 0x8d, 0x8c, 0xb8, 0x81, 0x01, 0xd9, 0xe8, 0xe8, 0x68, 0xf6, 0xad, 0xa4, 0x74, 0xb8, 0xf1, 0x86, 0x2b, 0xba, 0xe9, 0x62, 0x88, 0xa7, 0x4a, 0x1a, 0x97, 0xcb, 0x97, 0x8b, 0xd8, 0xa2, 0xba, 0xa3, 0xbb, 0x4e, 0x56, 0x02, 0x05, 0x34, 0x5f, 0x89, 0x12, 0xd9, 0x92, 0x4e, 0xba, 0x28, 0x49, 0x77, 0x06, 0xff, 0xaf, 0x6b, 0xe1, 0x0e, 0xad, 0x9a, 0x05, 0x0d, 0x6e, 0xee, 0x91, 0x23, 0x29, 0xc2, 0x69, 0xae, 0x5f, 0xf2, 0xda, 0xc1, 0xf4, 0x88, 0xa8, 0x28, 0x59, 0xc4, 0xbf, 0x55, 0xd6, 0xd9, 0xc9, 0x10, 0x03, 0xbe, 0x16, 0x44, 0xf8, 0x93, 0x21, 0x3a, 0x1d, 0x81, 0x0a, 0x79, 0x08, 0x12, 0x53, 0x5c, 0xe0, 0x6d, 0x9b, 0xc1, 0x43, 0x9a, 0x0c, 0xdc, 0xdb, 0x37, 0x6f, 0x01, 0x3f, 0xca, 0x95, 0x3a, 0xc3, 0x9e, 0x7b, 0x2f, 0x09, 0x4f, 0x81, 0x77, 0x2b, 0x6f, 0x6b, 0x79, 0xed, 0x29, 0x60, 0xb5, 0xd8, 0xc8, 0xfb, 0x2e, 0x87, 0x53, 0xdd, 0x15, 0xda, 0x3c, 0x99, 0xa4, 0x50, 0x5c, 0x06, 0x8d, 0xf9, 0xc3, 0x2b, 0x04, 0x54, 0x22, 0xb7, 0xab, 0x90, 0xd7, 0x42, 0x8d, 0xcf, 0xce, 0x77, 0x07, 0xdf, 0xb5, 0x1e, 0x46, 0x2a, 0x09, 0xf8, 0x6a, 0xdf, 0x73, 0x21, 0x51, 0xf1, 0x94, 0xa8, 0xd1, 0xb1, 0x36, 0x04, 0xa6, 0x26, 0xef, 0x50, 0x09, 0x91, 0xa0, 0xb5, 0xc2, 0xdc, 0xf1, 0xbc, 0xdd, 0x8a, 0xd9, 0x2e, 0x85, 0xab, 0xad, 0xa9, 0xac, 0x22, 0x02, 0x0a, 0xcb, 0xa4, 0xfd, 0x9e, 0xaf, 0x4b, 0xb4, 0xb5, 0x75, 0x2d, 0xa3, 0x4d, 0x7a, 0x28, 0x82, 0x36, 0x11, 0xb4, 0xf4, 0x5e, 0xf5, 0x2d, 0xf6, 0x70, 0xb6, 0xe6, 0xcc, 0x8f, 0x2f, 0xae, 0xfb, 0x3c, 0x7b, 0xec, 0x9a, 0x56, 0x4f, 0xc7, 0x58, 0x18, 0x7b, 0x0e, 0xaf, 0xca, 0x3d, 0x62, 0x05, 0x22, 0xce, 0x54, 0xe9, 0x71, 0xad, 0xc8, 0x36, 0x11, 0xd3, 0xaa, 0xcd, 0xde, 0x01, 0xf0, 0x18, 0xb5, 0x82, 0x3e, 0xe5, 0xf9, 0x61, 0xcd, 0xcc, 0xcc, 0x34, 0x3e, 0x76, 0x40, 0x0b, 0x99, 0xdc, 0x41, 0x72, 0x21, 0x05, 0x33, 0x37, 0xf2, 0x36, 0xa5, 0xce, 0x87, 0x43, 0x20, 0x7c, 0x1f, 0x82, 0x9b, 0xb4, 0xbc, 0x99, 0x56, 0xd5, 0xe4, 0x97, 0xe7, 0x25, 0x58, 0x4f, 0xf4, 0xa1, 0xa3, 0xcd, 0x3b, 0xfe, 0x09, 0xfc, 0x24, 0x6a, 0xc5, 0x4d, 0xc4, 0x4e, 0xc4, 0x97, 0x29, 0xa7, 0x90, 0xe1, 0xe1, 0x8b, 0x19, 0x49, 0xc9, 0x7d, 0x5d, 0x14, 0xf1, 0x1e, 0xaf, 0x4a, 0x75, 0x4f, 0x01, 0xa3, 0x43, 0xf8, 0xe5, 0xb7, 0x2d, 0x8e, 0x41, 0x3d, 0xc5, 0x5c, 0x5d, 0xde, 0x3b, 0x99, 0xb5, 0xc5, 0xa9, 0x85, 0x62, 0x6c, 0xd0, 0xd8, 0x1e, 0xb3, 0x56, 0x54, 0xa3, 0xee, 0x2d, 0xb0, 0x29, 0x2f, 0xe0, 0xd1, 0x9a, 0x51, 0xaf, 0xa5, 0x56, 0x2a, 0x2f, 0x31, 0x3d, 0x3d, 0x02, 0x12, 0xc3, 0x44, 0xd0, 0x18, 0x8b, 0x19, 0x3c, 0x1e, 0x88, 0x27, 0x30, 0x25, 0x58, 0x6e, 0xc7, 0x96, 0x42, 0x3d, 0x8a, 0xac, 0x6b, 0xbe, 0x71, 0xd6, 0xbe, 0x88, 0x4e, 0xc8, 0x84, 0xa8, 0xd9, 0x82, 0x7d, 0x91, 0xfe, 0x11, 0xb3, 0xa1, 0x55, 0xa4, 0x60, 0xc9, 0xa2, 0xc3, 0xcd, 0x31, 0xb3, 0xd5, 0x40, 0xd9, 0x9f, 0x7f, 0x23, 0x48, 0x65, 0x0f, 0x1c, 0x16, 0xff, 0x98, 0xb3, 0x8d, 0x4d, 0x92, 0xb1, 0x6e, 0x58, 0x75, 0x08, 0xe6, 0xba, 0x5e, 0xe5, 0x04, 0x3d, 0x84, 0x93, 0x6a, 0x75, 0xe5, 0xbd, 0xb1, 0xf3, 0x37, 0xdb, 0x1e, 0x16, 0x1c, 0x44, 0x34, 0x7f, 0x95, 0x9b, 0x1a, 0xf4, 0x57, 0xea, 0xb6, 0xf5, 0x65, 0x2e, 0xd7, 0xa8, 0x74, 0xbe, 0x39, 0x52, 0xe7, 0xb4, 0x99, 0x2f, 0x5b, 0xcd, 0x63, 0xb3, 0x9a, 0xa6, 0x38, 0x01, 0x36, 0x4f, 0x39, 0xc8, 0x13, 0x93, 0x44, 0x2c, 0xe5, 0x05, 0x60, 0x14, 0xbd, 0xbf, 0x73, 0xb1, 0xed, 0x08, 0xb5, 0x03, 0xa6, 0x45, 0xe0, 0x6f, 0x3c, 0xf4, 0x5a, 0xeb, 0x15, 0x58, 0xb1, 0xeb, 0xe2, 0x70, 0xe8, 0x4f, 0x64, 0x7e, 0x24, 0x93, 0x4a, 0x06, 0xad, 0xfd, 0x2e, 0x3b, 0x10, 0xd2, 0xaa, 0x6a, 0xdd, 0x87, 0xb9, 0x72, 0xec, 0xe9, 0xf1, 0x17, 0x4e, 0xa4, 0xbe, 0x40, 0xa6, 0xa0, 0x01, 0xfc, 0xd4, 0xd2, 0x1c, 0x42, 0x07, 0x03, 0x09, 0x91, 0x26, 0x88, 0x7c, 0xf9, 0xe5, 0xa9, 0xea, 0xa1, 0x8a, 0x34, 0x18, 0xd6, 0x1e, 0xf5, 0x9b, 0xc4, 0x37, 0x09, 0x0d, 0x0d, 0x3c, 0x22, 0x08, 0x2d, 0xb4, 0x98, 0x70, 0xe8, 0x68, 0x01, 0x41, 0x50, 0xf3, 0xfe, 0x7a, 0x4e, 0xa9, 0xce, 0x64, 0x00, 0xb9, 0xdd, 0xa5, 0x06, 0xd6, 0xc7, 0xbd, 0xdf, 0xd2, 0x51, 0x24, 0xa4, 0xfa, 0x54, 0x77, 0xc1, 0xf6, 0xa4, 0x5f, 0x84, 0x86, 0xd3, 0x31, 0xd8, 0xff, 0x87, 0xd2, 0xc7, 0x4f, 0xdd, 0xc3, 0xce, 0x9a, 0x04, 0x46, 0xaf, 0x52, 0x71, 0xe9, 0x11, 0x42, 0x6d, 0xe2, 0x77, 0x11, 0x3f, 0x19, 0x29, 0x44, 0xb9, 0xe6, 0xcc, 0xda, 0x6e, 0xd1, 0x27, 0xc7, 0x56, 0xd5, 0x36, 0x38, 0xf6, 0xb7, 0xdb, 0x2f, 0x0e, 0xe6, 0xeb, 0x5c, 0xe0, 0xa5, 0xcc, 0xcc, 0xea, 0xb4, 0x2e, 0x96, 0x19, 0x50, 0x12, 0xbc, 0x68, 0x07, 0xb8, 0x07, 0x09, 0xfa, 0x48, 0x3d, 0xd7, 0xbe, 0xff, 0x64, 0xd2, 0x2d, 0x34, 0x1d, 0x8a, 0x4b, 0x17, 0xf4, 0x66, 0x17, 0xff, 0xf2, 0xc5, 0xf9, 0xfe, 0xdc, 0x58, 0xaf, 0xcd, 0x0d, 0xc9, 0xd0, 0xef, 0x02, 0xfe, 0xf6, 0x6c, 0xd3, 0xd1, 0xd7, 0x6f, 0xee, 0x8f, 0xb5, 0x29, 0x44, 0x0a, 0x90, 0xd9, 0xeb, 0x0c, 0xee, 0x80, 0x67, 0x60, 0xcb, 0x66, 0x89, 0xcb, 0x35, 0x45, 0xec, 0x97, 0xc3, 0x02, 0xdf, 0xa6, 0x9c, 0xb1, 0x4a, 0x29, 0xac, 0x39, 0x61, 0x33, 0xd3, 0xe5, 0x7d, 0x6d, 0x35, 0xed, 0xa3, 0x5b, 0x50, 0x69, 0xdc, 0xd0, 0x67, 0x6d, 0xde, 0xd3, 0x8d, 0xef, 0x05, 0x03, 0x19, 0x7f, 0x5e, 0x07, 0x3a, 0x1b, 0xf0, 0x93, 0x00, 0xc0, 0x44, 0x5c, 0x00, 0xc7, 0xd7, 0xcd, 0x0f, 0xad, 0x5f, 0x3e, 0xb2, 0x8f, 0x40, 0xbc, 0x09, 0x76, 0xaa, 0xeb, 0xc7, 0xef, 0xb5, 0x77, 0x69, 0x4f, 0x5c, 0x44, 0xa8, 0x29, 0xb2, 0x34, 0xd7, 0x8f, 0xc7, 0x72, 0xfe, 0x0b, 0xf4, 0x34, 0x83, 0x1f, 0x0e, 0x63, 0x9f, 0xce, 0xc8, 0xe2, 0x3c, 0xaa, 0x32, 0xc5, 0x9c, 0xbe, 0x39, 0x66, 0x25, 0x3c, 0xe6, 0xf3, 0x10, 0x38, 0x4f, 0x61, 0x3b, 0x52, 0x31, 0x34, 0x4f, 0x1b, 0x2b, 0xed, 0xe4, 0x8a, 0xe2, 0x31, 0x19, 0x26, 0x13, 0xfa, 0xe7, 0xdc, 0x51, 0xd4, 0x3f, 0xd0, 0xe3, 0x0f, 0x74, 0xa8, 0x95, 0xfc, 0x99, 0x30, 0x96, 0x19, 0xcd, 0x82, 0x0f, 0xda, 0xc5, 0x4f, 0x55, 0x5b, 0x81, 0xfb, 0x7e, 0xdf, 0x95, 0x2f, 0x8a, 0xda, 0xe6, 0x6e, 0x17, 0x56, 0xe5, 0x1b, 0xdf, 0x63, 0x57, 0xc7, 0x7f, 0x8a, 0x2f, 0x39, 0xa3, 0x41, 0xc6, 0x4d, 0xc5, 0x08, 0x87, 0xae, 0x48, 0xf2, 0xdd, 0x7b, 0x4a, 0x28, 0x06, 0xa9, 0xc8, 0x41, 0x52, 0xde, 0x8c, 0xe0, 0x65, 0x0d, 0x23, 0x5e, 0xa5, 0x32, 0x45, 0xb9, 0x52, 0x7d, 0xf9, 0x6a, 0xa9, 0xa8, 0x10, 0x39, 0xe6, 0xf3, 0x78, 0x90, 0xb5, 0xaa, 0xbe, 0x88, 0x61, 0xd1, 0x21, 0xf1, 0x5c, 0xd7, 0x8b, 0x9e, 0xaa, 0x03, 0xd8, 0x47, 0x67, 0x5a, 0x17, 0xe5, 0x1a, 0x28, 0x4a, 0x1b, 0x13, 0x76, 0xb2, 0xaf, 0xe7, 0xc9, 0x00, 0xf8, 0xfd, 0x70, 0xa9, 0xd0, 0x60, 0x77, 0x74, 0x89, 0x29, 0x70, 0x81, 0x0d, 0x3d, 0x8c, 0xf2, 0xbf, 0x33, 0xb6, 0x03, 0xfa, 0x7e, 0x28, 0x9d, 0x2a, 0xa5, 0x84, 0x28, 0x53, 0xfd, 0xd5, 0x4f, 0x14, 0x54, 0xf2, 0xd1, 0xe9, 0x11, 0xac, 0x9c, 0x0e, 0x38, 0x50, 0x27, 0x0c, 0xe7, 0xa6, 0x53, 0x06, 0x2b, 0x47, 0xe6, 0xcd, 0xa5, 0x11, 0xb2, 0xf9, 0x3c, 0x8e, 0xa1, 0xd9, 0x97, 0x2c, 0xfc, 0x3c, 0x3f, 0x17, 0x3b, 0x8d, 0x8a, 0xf2, 0x28, 0x7e, 0xf7, 0x77, 0xf3, 0xd5, 0x02, 0x8f, 0x9d, 0x63, 0x0c, 0x47, 0xc0, 0x13, 0x2d, 0x8c, 0x3a, 0xd5, 0xbd, 0x49, 0xc7, 0xf5, 0x91, 0xe3, 0x17, 0xa7, 0x0c, 0x96, 0xe2, 0xbb, 0x20, 0x71, 0xcc, 0x32, 0xcc, 0x81, 0x5e, 0xee, 0xe0, 0x7c, 0x02, 0x66, 0x99, 0x5f, 0x8b, 0x41, 0x5c, 0x08, 0x46, 0x62, 0x41, 0x04, 0xe8, 0x74, 0xb2, 0x80, 0xdc, 0x89, 0x74, 0x7a, 0x58, 0x51, 0xa4, 0x7d, 0xc6, 0x6f, 0x05, 0x88, 0x42, 0x84, 0x58, 0xec, 0x66, 0x9e, 0xdf, 0x66, 0x46, 0xfd, 0xf8, 0x5e, 0xc7, 0x51, 0xe1, 0x69, 0xdc, 0x32, 0x10, 0xc5, 0x4f, 0xbc, 0x64, 0x46, 0x37, 0x00, 0x80, 0xab, 0x5c, 0x5f, 0x44, 0xec, 0x8a, 0x13, 0x21, 0xf9, 0xe7, 0xd8, 0x11, 0xbb, 0xef, 0x2a, 0x05, 0x65, 0x85, 0x9f, 0x11, 0x28, 0x2f, 0x7d, 0xff, 0x91, 0x93, 0x6f, 0x2f, 0x1f, 0xa2, 0xa0, 0x15, 0xc9, 0x92, 0xfe, 0x55, 0x81, 0xa1, 0x44, 0x4b, 0x78, 0x47, 0x80, 0x8d, 0x93, 0x1d, 0x0d, 0xf8, 0xed, 0xf0, 0x80, 0x37, 0x9a, 0x3e, 0x48, 0x81, 0x38, 0x33, 0x25, 0x21, 0x21, 0xff, 0x48, 0xcb, 0x72, 0x66, 0x7a, 0x74, 0x75, 0xfc, 0xee, 0x65, 0x30, 0x21, 0x52, 0x6a, 0xee, 0xd9, 0x53, 0x34, 0x07, 0x09, 0x20, 0xad, 0xc4, 0xf7, 0xda, 0x47, 0xf1, 0x2a, 0x5f, 0xa4, 0xf1, 0x8d, 0xfd, 0x93, 0xc1, 0xe9, 0x24, 0xe6, 0x8b, 0x7e, 0x8c, 0xce, 0x17, 0x80, 0x9c, 0xe6, 0x5f, 0x1c, 0x54, 0xad, 0x86, 0xec, 0xac, 0x77, 0xb6, 0x99, 0xe3, 0x84, 0xa6, 0xea, 0xc2, 0x52, 0xa0, 0x35, 0x1c, 0xba, 0xa8, 0xa5, 0x2e, 0x46, 0xba, 0xfb, 0x57, 0x89, 0xaf, 0xc3, 0xf9, 0x8b, 0x8d, 0x91, 0xc0, 0xa5, 0x19, 0xdc, 0xb6, 0x18, 0x02, 0x14, 0x9d, 0x51, 0xef, 0x95, 0x6b, 0x40, 0x2c, 0x91, 0xee, 0xcf, 0xce, 0x1f, 0x10, 0xae, 0xb9, 0x46, 0x89, 0x29, 0x3e, 0xac, 0xa0, 0x2d, 0x89, 0x79, 0x27, 0xf2, 0xe2, 0x98, 0xad, 0xa4, 0x50, 0xb3, 0x78, 0xa1, 0x53, 0x85, 0xb7, 0xde, 0xee, 0x29, 0x1d, 0x8d, 0xc7, 0x04, 0x00, 0x4c, 0x64, 0xf1, 0x40, 0x6b, 0x75, 0xce, 0xd4, 0x99, 0x4a, 0xeb, 0x92, 0x87, 0xb4, 0xb4, 0xf0, 0x96, 0xa9, 0xed, 0x4a, 0x26, 0xb8, 0xf1, 0x93, 0xba, 0xb8, 0xb8, 0x38, 0xed, 0x8e, 0xe2, 0xda, 0x2d, 0xd7, 0xc2, 0x40, 0xdc, 0x33, 0x6c, 0xbd, 0x5f, 0x59, 0x54, 0x3b, 0x5f, 0x59, 0xa2, 0x8b, 0x29, 0x4a, 0xec, 0xea, 0x3b, 0xa7, 0xe7, 0xeb, 0x0c, 0x11, 0xa7, 0xec, 0x01, 0xbb, 0x0a, 0x5d, 0xa6, 0x20, 0x63, 0x54, 0x86, 0x1c, 0x60, 0xab, 0xbe, 0x39, 0x6f, 0xb0, 0x4a, 0x48, 0x60, 0x94, 0x14, 0x8b, 0x32, 0x54, 0x6d, 0x4c, 0xda, 0xf0, 0x25, 0xd8, 0xbc, 0xdb, 0xa1, 0x9e, 0xb8, 0xfd, 0xe5, 0x16, 0xc8, 0xe6, 0xb0, 0xc6, 0x2b, 0x9f, 0x2b, 0x48, 0x08, 0x70, 0x82, 0x16, 0xe3, 0x7c, 0xff, 0xbe, 0xc8, 0x71, 0xb3, 0x6b, 0xda, 0xca, 0x66, 0x13, 0x8e, 0x4e, 0x44, 0x84, 0xfc, 0xac, 0xeb, 0x89, 0x59, 0xf8, 0xe9, 0x84, 0x83, 0xe0, 0x03, 0x02, 0xb0, 0x45, 0x6a, 0xce, 0x27, 0x4c, 0x6a, 0xce, 0xc5, 0x47, 0x66, 0xc4, 0x63, 0x9f, 0xb0, 0x24, 0x20, 0x02, 0xab, 0x2d, 0x06, 0x27, 0xca, 0x23, 0xb1, 0xd0, 0xeb, 0x33, 0x71, 0x2d, 0x5d, 0x5e, 0x96, 0x37, 0xba, 0x85, 0x3c, 0x11, 0x8d, 0xe7, 0xd7, 0x50, 0x0c, 0x15, 0xa6, 0x48, 0x4b, 0x95, 0xf3, 0xe1, 0xe8, 0xb7, 0x3a, 0xdc, 0xd6, 0xb8, 0xb8, 0x38, 0x29, 0x45, 0x45, 0xc5, 0xce, 0xea, 0x8e, 0xe1, 0x89, 0x89, 0x81, 0x5c, 0x21, 0xdf, 0xf3, 0xc7, 0xe3, 0x1a, 0x28, 0x09, 0x02, 0x00, 0xc2, 0xa8, 0x3c, 0x92, 0xe9, 0x10, 0x14, 0x01, 0xb3, 0xcf, 0xc2, 0xe5, 0x73, 0x21, 0xfc, 0x84, 0x91, 0xa0, 0xd6, 0x77, 0xa2, 0xcb, 0xef, 0x01, 0x4f, 0x71, 0xd9, 0x89, 0x02, 0x24, 0xe2, 0x88, 0xe5, 0x4d, 0x64, 0x39, 0xab, 0xf9, 0xea, 0xd1, 0xbc, 0xc0, 0xa6, 0x11, 0xb3, 0xe0, 0x05, 0x9d, 0x6e, 0x3e, 0x2e, 0x5a, 0x5a, 0x84, 0x64, 0x5a, 0x85, 0xde, 0x38, 0x52, 0x81, 0xe9, 0x5f, 0x0a, 0xde, 0xb1, 0xcc, 0xdf, 0xc6, 0xc9, 0x3e, 0x21, 0xb6, 0xb5, 0xde, 0xf8, 0x80, 0x10, 0x82, 0xb1, 0xda, 0xc6, 0x53, 0x46, 0xa7, 0x27, 0x00, 0x4e, 0xa0, 0x13, 0xc9, 0x94, 0x14, 0xfe, 0xbb, 0x2a, 0xda, 0x50, 0x0c, 0x47, 0x2e, 0x1b, 0x65, 0x25, 0xa0, 0x6d, 0x8e, 0xe2, 0x8f, 0x9b, 0xe3, 0x25, 0xdf, 0x7f, 0x1d, 0xb1, 0x44, 0x5c, 0xbd, 0xbf, 0xb5, 0xeb, 0xed, 0x80, 0xd9, 0xc7, 0x79, 0xaa, 0x95, 0xed, 0xf7, 0x2f, 0xd4, 0xd4, 0x10, 0x3b, 0x61, 0x0f, 0xe4, 0xe7, 0xc1, 0x20, 0x14, 0x8d, 0x04, 0x77, 0x4a, 0x2b, 0x6e, 0x3e, 0xa3, 0x86, 0x62, 0x80, 0x68, 0xc2, 0xd7, 0x57, 0xd7, 0x1d, 0x9e, 0x86, 0xc8, 0x03, 0xaf, 0x97, 0x5b, 0x4b, 0x15, 0xb2, 0x10, 0x06, 0x0c, 0x4b, 0xe2, 0xf8, 0x78, 0x10, 0xb4, 0xab, 0xbc, 0x55, 0x05, 0x3d, 0x5c, 0x58, 0x24, 0x91, 0xf4, 0x2d, 0xb2, 0x0d, 0x15, 0x61, 0xd4, 0xf8, 0x00, 0xb5, 0xde, 0x77, 0x98, 0xad, 0x7d, 0x94, 0xa1, 0x09, 0x36, 0xed, 0x34, 0x94, 0x1b, 0xd5, 0xad, 0xf3, 0xe1, 0xa8, 0xc4, 0x24, 0x16, 0x45, 0x4b, 0x79, 0xf7, 0xf7, 0x5e, 0x1f, 0x08, 0xd9, 0xfb, 0x9b, 0x26, 0x5a, 0xc1, 0x30, 0xf1, 0xd9, 0xcb, 0xd1, 0xdf, 0xc4, 0xef, 0xde, 0x05, 0x63, 0x38, 0xc1, 0x01, 0xe2, 0xb2, 0xf9, 0xd1, 0x93, 0x47, 0x18, 0x3d, 0x79, 0xa1, 0x96, 0x8a, 0x61, 0x8b, 0x21, 0xf1, 0x7a, 0x69, 0x6a, 0x1f, 0x31, 0xeb, 0x1d, 0x8c, 0x25, 0x5e, 0x0f, 0xc8, 0x85, 0x47, 0xc1, 0xcb, 0xf7, 0x7f, 0xba, 0x6d, 0x79, 0x7b, 0x7d, 0xaa, 0x73, 0xd9, 0x95, 0xd5, 0x4d, 0xeb, 0x99, 0x29, 0x92, 0x06, 0xc6, 0x6d, 0xaf, 0x09, 0xca, 0x57, 0x91, 0x29, 0x3f, 0x95, 0x5f, 0x0b, 0x07, 0x61, 0xb5, 0xe1, 0x27, 0x50, 0xdb, 0xbd, 0x1b, 0x95, 0xa3, 0xcf, 0xfd, 0xaa, 0x98, 0xfa, 0xff, 0xa6, 0x12, 0x90, 0xbe, 0xfd, 0x41, 0xa1, 0xa7, 0x44, 0x03, 0x7d, 0x9a, 0x07, 0x9c, 0xaa, 0xb3, 0x07, 0x72, 0x67, 0x43, 0x62, 0x6a, 0x2c, 0x8d, 0x65, 0xa8, 0xc1, 0x7a, 0x8e, 0xd5, 0x75, 0x4f, 0x1e, 0x20, 0x5a, 0xa9, 0xe1, 0x51, 0x15, 0x4c, 0x33, 0x88, 0x13, 0xa0, 0x0f, 0x9b, 0x9b, 0x59, 0xef, 0x05, 0x53, 0xf2, 0xa7, 0x5c, 0x3b, 0x09, 0x39, 0x0f, 0x10, 0x54, 0x16, 0xa1, 0x0c, 0x81, 0x35, 0x31, 0x70, 0x02, 0x22, 0x65, 0xb1, 0x8e, 0x78, 0xa3, 0x18, 0x6f, 0x82, 0xd7, 0xe2, 0xe2, 0x77, 0x26, 0x2e, 0x2e, 0x5c, 0x4c, 0x4c, 0x4c, 0xe8, 0x5e, 0x6f, 0x8a, 0x6c, 0x89, 0xee, 0x24, 0x9b, 0xcd, 0x3c, 0xdd, 0x81, 0x1b, 0x3f, 0x09, 0x9f, 0xca, 0xab, 0xd6, 0xe5, 0xfd, 0xc5, 0x8e, 0xd5, 0x7c, 0x19, 0xe6, 0xe5, 0xe5, 0x65, 0xad, 0xfb, 0xb1, 0x06, 0x20, 0x88, 0x22, 0xf4, 0x77, 0x9d, 0xce, 0x14, 0x8b, 0xe7, 0x18, 0x12, 0x31, 0x9d, 0xec, 0x81, 0x81, 0x68, 0x91, 0x75, 0x8e, 0x63, 0xe3, 0x9e, 0x08, 0x6a, 0x04, 0xcc, 0xa1, 0xb6, 0x77, 0x3a, 0xff, 0x2b, 0x37, 0x5d, 0xea, 0x75, 0x77, 0x38, 0x06, 0xe8, 0x85, 0xc0, 0x74, 0x3a, 0x95, 0xe8, 0x7c, 0xbf, 0x8e, 0x1a, 0x10, 0x44, 0x2d, 0xb3, 0xdc, 0x60, 0x8d, 0xcd, 0x49, 0x14, 0xbb, 0xce, 0x01, 0x6e, 0x83, 0x7e, 0x1e, 0x00, 0x8a, 0xc1, 0xae, 0xfb, 0x93, 0xdb, 0xd7, 0x87, 0x97, 0x23, 0x7d, 0xc4, 0x3c, 0x0e, 0x0d, 0x34, 0x57, 0x2e, 0xab, 0x9f, 0xbe, 0xff, 0x19, 0x73, 0xe0, 0x33, 0x86, 0x95, 0x6c, 0x5e, 0xeb, 0x0c, 0xea, 0x71, 0xea, 0xa7, 0x42, 0x14, 0xb3, 0x85, 0xa1, 0xa8, 0xc9, 0x27, 0xc8, 0x7a, 0xe3, 0xa5, 0xff, 0xcf, 0xdb, 0xec, 0xfb, 0x1c, 0x4e, 0xf7, 0x38, 0xf1, 0xf0, 0xf0, 0xf6, 0x6e, 0xaf, 0xfc, 0xae, 0x67, 0xa4, 0xa7, 0x6d, 0x1a, 0x21, 0xfc, 0xe8, 0x03, 0x91, 0xc2, 0x55, 0x88, 0x83, 0x88, 0x31, 0xec, 0x17, 0xa4, 0x75, 0x39, 0x27, 0xb2, 0x96, 0xfc, 0x42, 0xa7, 0xcd, 0x4c, 0xa6, 0x27, 0x8a, 0xa8, 0x79, 0xf9, 0x08, 0x8c, 0x59, 0xd6, 0x7e, 0x89, 0xb0, 0x2f, 0xc4, 0x76, 0x9b, 0x3f, 0x76, 0x21, 0x9c, 0xcf, 0x41, 0x44, 0x49, 0x4f, 0x8f, 0xc4, 0x62, 0x2a, 0xf7, 0x94, 0x93, 0x19, 0x11, 0x86, 0x38, 0x76, 0xd0, 0x54, 0x0a, 0xdf, 0xf1, 0x82, 0x21, 0x65, 0xba, 0x13, 0x6e, 0xff, 0x68, 0x27, 0x06, 0xbe, 0x14, 0x66, 0x97, 0x06, 0x57, 0x44, 0xbb, 0x4d, 0x71, 0x2f, 0x02, 0x62, 0x21, 0x1f, 0x4e, 0x1b, 0x5c, 0xb2, 0x16, 0xdb, 0x96, 0xf5, 0xe5, 0x29, 0x91, 0xb7, 0x98, 0xe0, 0xe0, 0x77, 0xcd, 0x79, 0xc7, 0xad, 0xfb, 0xb9, 0x5f, 0x44, 0x45, 0x83, 0xec, 0xb3, 0xea, 0x00, 0x21, 0xb2, 0x0b, 0xcf, 0xa8, 0xcd, 0x79, 0x65, 0x30, 0x85, 0xa1, 0x60, 0xae, 0x59, 0x5e, 0xd3, 0xa3, 0x12, 0x5c, 0xdd, 0x4a, 0xee, 0xd3, 0x82, 0x51, 0xe7, 0xd0, 0x04, 0x84, 0x22, 0xfd, 0x4a, 0x0b, 0x0f, 0x20, 0x5e, 0x34, 0x7c, 0x46, 0x46, 0x06, 0x64, 0x54, 0x79, 0xf9, 0x0f, 0xd0, 0xa3, 0x70, 0xe0, 0x9e, 0xde, 0x45, 0xc1, 0x88, 0x5b, 0x54, 0x85, 0xcb, 0x77, 0xac, 0x36, 0x4d, 0x63, 0xc6, 0x23, 0x55, 0x51, 0x63, 0x84, 0xa0, 0xa4, 0x59, 0xf6, 0x67, 0xc7, 0x0c, 0xcb, 0x51, 0x3a, 0x2c, 0xf1, 0xaf, 0xfa, 0xee, 0x67, 0xcb, 0x44, 0xf4, 0xa9, 0x2f, 0xbf, 0x6f, 0x0f, 0x0e, 0x0e, 0x7c, 0xf8, 0xd2, 0x56, 0xf4, 0x5a, 0x0d, 0x7e, 0xa8, 0xa9, 0xb1, 0x7c, 0xb2, 0x0e, 0xa2, 0x2b, 0xf0, 0xc5, 0xfc, 0xd6, 0x91, 0xf0, 0x11, 0x51, 0xec, 0x89, 0xbe, 0x49, 0xf3, 0xf7, 0x66, 0x64, 0xe7, 0x8f, 0xc3, 0xe8, 0x4f, 0x94, 0xfd, 0x4f, 0x10, 0x12, 0x92, 0xef, 0x6f, 0xfb, 0x54, 0x79, 0xdd, 0x68, 0xbb, 0xb4, 0x38, 0xd6, 0xaa, 0xa2, 0xa2, 0x62, 0x57, 0xa3, 0x5e, 0x61, 0x61, 0x7d, 0xe3, 0x92, 0x84, 0x00, 0x89, 0xdd, 0x25, 0x24, 0x6d, 0x3d, 0xef, 0xe3, 0x3e, 0x96, 0xc0, 0xf0, 0x01, 0xd0, 0x9d, 0x3e, 0x0c, 0x12, 0x25, 0xea, 0xdf, 0xa0, 0x5c, 0xd2, 0xd3, 0xa6, 0xb7, 0xfb, 0x1d, 0xf4, 0xe6, 0xbc, 0xa2, 0xda, 0x5a, 0x0c, 0x3e, 0x3e, 0xbe, 0x40, 0xfb, 0x72, 0x89, 0xc6, 0xb6, 0x4d, 0xb4, 0xe6, 0xbc, 0xe2, 0xef, 0x2e, 0x53, 0x15, 0x81, 0x20, 0x6e, 0x1b, 0xf7, 0x1d, 0x75, 0x0b, 0xd7, 0x8b, 0xf7, 0x49, 0xc5, 0xf1, 0xef, 0x83, 0xc6, 0x96, 0xfe, 0xd4, 0x79, 0x00, 0xf3, 0xd2, 0x05, 0x1d, 0x6a, 0xd7, 0x0a, 0x20, 0x48, 0x86, 0xea, 0x6e, 0x9d, 0x66, 0xd4, 0x0c, 0xad, 0x00, 0x0e, 0x02, 0x0d, 0x44, 0x4f, 0x5b, 0x71, 0x46, 0xc4, 0xc6, 0x4a, 0xee, 0x4f, 0xe6, 0xcc, 0x54, 0xa8, 0x33, 0x40, 0x1f, 0xbc, 0xd5, 0xd5, 0xd5, 0x35, 0xe1, 0x95, 0x71, 0x5d, 0x40, 0x2b, 0x28, 0x5b, 0x31, 0xe6, 0x4d, 0x57, 0xab, 0x85, 0x3b, 0x2e, 0x1c, 0xa7, 0xe1, 0xb6, 0xd3, 0x78, 0x91, 0x2b, 0x07, 0xe6, 0x1c, 0xc8, 0x54, 0x7d, 0xc6, 0x71, 0xbe, 0x8b, 0x30, 0xd9, 0x9b, 0x02, 0x58, 0x02, 0xa6, 0x1b, 0x64, 0x3e, 0x2c, 0x06, 0x3c, 0xd0, 0xe2, 0x20, 0xb7, 0x15, 0x88, 0x23, 0x5e, 0x18, 0x58, 0xaa, 0x56, 0x6f, 0x75, 0x95, 0x6e, 0x56, 0x2d, 0xd6, 0x41, 0x62, 0x86, 0x54, 0x00, 0xaf, 0xa6, 0xe3, 0x12, 0xd9, 0xa1, 0xf3, 0x46, 0x43, 0x77, 0xbf, 0xa1, 0x22, 0xa2, 0x30, 0x22, 0x0c, 0x05, 0x1f, 0xb4, 0xa0, 0x69, 0x18, 0xd6, 0x63, 0x04, 0xf8, 0xfb, 0x57, 0x2b, 0xd9, 0x20, 0xdb, 0x92, 0xc4, 0xf5, 0xcb, 0x81, 0xf0, 0x77, 0xf6, 0x50, 0x7c, 0xac, 0x81, 0x18, 0x75, 0xd1, 0xe9, 0x3f, 0x51, 0xa7, 0xd7, 0xe3, 0x7a, 0x24, 0x42, 0xee, 0x06, 0x93, 0x10, 0x47, 0xff, 0xf7, 0x6b, 0xb5, 0xd1, 0x26, 0xea, 0x5c, 0x59, 0x33, 0xcc, 0x30, 0xdb, 0x79, 0x12, 0xaa, 0x5e, 0x3f, 0x90, 0x09, 0x12, 0x40, 0x04, 0xc3, 0xa0, 0x63, 0xf7, 0x4b, 0x38, 0x08, 0x64, 0xf2, 0x6f, 0x77, 0xb7, 0xc7, 0xa6, 0xf3, 0x35, 0xbd, 0x2e, 0x3f, 0x1f, 0x70, 0xb5, 0x37, 0xf1, 0x05, 0xd8, 0x64, 0x7f, 0xf1, 0x7c, 0x35, 0xf5, 0x96, 0x3a, 0x0e, 0x09, 0x9c, 0xc3, 0xcc, 0x83, 0x03, 0xf8, 0x94, 0x71, 0x86, 0x02, 0x5d, 0xb0, 0x81, 0x6c, 0x79, 0x8c, 0xae, 0x59, 0xe3, 0xaf, 0x71, 0xc0, 0xa8, 0x2f, 0x2a, 0xe3, 0x8b, 0xbb, 0xc0, 0xa3, 0x87, 0x23, 0x8b, 0xab, 0x1a, 0xc4, 0x2f, 0xb9, 0xc4, 0x30, 0xf2, 0x35, 0x16, 0x04, 0xab, 0xa8, 0x3f, 0x7d, 0xda, 0x89, 0x13, 0x00, 0xd7, 0xda, 0xdb, 0x36, 0xea, 0x40, 0x1f, 0x5d, 0xb6, 0xb6, 0xb6, 0x0e, 0x0f, 0x0f, 0x8b, 0x6a, 0x6b, 0xef, 0xd2, 0x74, 0x54, 0x50, 0x89, 0x45, 0xf8, 0xfd, 0x32, 0x1f, 0x3b, 0x14, 0x29, 0x2e, 0x96, 0x77, 0xff, 0x32, 0xdf, 0x15, 0x82, 0x1c, 0xee, 0x5b, 0x9e, 0x90, 0xe0, 0xa0, 0x6d, 0xe1, 0x3a, 0xd9, 0x19, 0x44, 0x43, 0x44, 0xd7, 0x2d, 0x7b, 0xb6, 0x59, 0xff, 0x91, 0x68, 0x48, 0x62, 0x98, 0x94, 0x08, 0x02, 0xde, 0x87, 0x12, 0x97, 0x34, 0x7a, 0x6d, 0x26, 0xdd, 0xaf, 0x7a, 0x05, 0xd3, 0x16, 0x80, 0xed, 0xb9, 0xa0, 0xb2, 0x56, 0x59, 0xf3, 0x2d, 0xed, 0xc1, 0x14, 0xfa, 0xc9, 0x15, 0x0b, 0x51, 0xef, 0x08, 0x36, 0x05, 0x4e, 0xa3, 0xba, 0xa7, 0x01, 0x0b, 0xee, 0xac, 0xc4, 0xdc, 0xdc, 0x38, 0x88, 0x77, 0x6a, 0x31, 0xe2, 0x01, 0x79, 0x4d, 0x57, 0x3f, 0xda, 0xb8, 0x2f, 0xb1, 0x69, 0x1c, 0x3f, 0xe4, 0xc0, 0xc3, 0xfb, 0x3e, 0xb7, 0xd5, 0x67, 0x32, 0xb8, 0x8d, 0xad, 0xcb, 0xe1, 0xe2, 0x9f, 0xfd, 0x8b, 0x81, 0x0f, 0xd4, 0xae, 0x63, 0x72, 0x8e, 0x6b, 0x16, 0x79, 0xc0, 0x4c, 0x92, 0x10, 0xe9, 0x0b, 0xc5, 0x38, 0x4b, 0x9d, 0xe6, 0x5c, 0xb4, 0x96, 0x4f, 0x32, 0x8a, 0x8a, 0xca, 0x6c, 0x83, 0x6f, 0x71, 0x99, 0xb1, 0x99, 0x78, 0xd4, 0xc3, 0x89, 0x1e, 0x7c, 0x17, 0xbe, 0x12, 0xe4, 0xac, 0xe8, 0x75, 0xff, 0xde, 0x3e, 0x75, 0x74, 0xf9, 0x53, 0xd0, 0x96, 0x42, 0xd0, 0x9f, 0xfe, 0xd7, 0x9c, 0x18, 0xd8, 0xef, 0x69, 0x84, 0x28, 0x06, 0x55, 0x6a, 0xdc, 0x81, 0x82, 0xf4, 0x36, 0xe3, 0x10, 0x4a, 0xa2, 0x1c, 0x35, 0x87, 0x84, 0x08, 0x68, 0xdb, 0x05, 0x2f, 0x04, 0x07, 0xb7, 0x05, 0x54, 0x2f, 0x91, 0xdf, 0x13, 0xef, 0x97, 0xe4, 0xc0, 0x6c, 0x89, 0xdb, 0xf0, 0x63, 0x25, 0xab, 0x40, 0x6f, 0xe1, 0x40, 0x08, 0x50, 0x28, 0x46, 0xda, 0x3c, 0x7d, 0xea, 0x1c, 0xc1, 0x7e, 0x09, 0xd2, 0xc0, 0x40, 0x96, 0xef, 0x3b, 0xde, 0x93, 0x96, 0x9a, 0xda, 0xf3, 0xcf, 0x48, 0x7f, 0xf1, 0x01, 0x5d, 0xca, 0x95, 0x02, 0x12, 0xef, 0x68, 0x92, 0xab, 0x34, 0xa2, 0x65, 0x4a, 0x90, 0xdb, 0xf3, 0x17, 0x9a, 0x9a, 0xa2, 0x0a, 0x6f, 0x94, 0xbf, 0xcd, 0x70, 0x6b, 0x55, 0xf9, 0xfc, 0xdb, 0xd5, 0x2f, 0x7f, 0x13, 0x11, 0x85, 0x95, 0x42, 0x5a, 0x8f, 0x4e, 0xfd, 0xe9, 0xc0, 0xa0, 0x4a, 0x97, 0xf9, 0xa6, 0x8a, 0x23, 0x67, 0x4f, 0xb3, 0xf3, 0xb3, 0x7a, 0x43, 0x0a, 0x29, 0x07, 0x03, 0xd4, 0x58, 0xf8, 0x51, 0xdf, 0x53, 0xbb, 0x5e, 0xc7, 0x7d, 0x62, 0x9b, 0xaa, 0x40, 0xd3, 0x82, 0x3b, 0x8f, 0x09, 0x70, 0x4e, 0x03, 0x48, 0x97, 0xe7, 0x63, 0xcd, 0x60, 0x6e, 0x11, 0x12, 0x36, 0x94, 0x82, 0x00, 0x89, 0x9e, 0xb2, 0xf2, 0x98, 0x42, 0xd0, 0x20, 0xf7, 0xc0, 0xcb, 0xfc, 0x8a, 0x9c, 0x1b, 0x10, 0xfa, 0x5f, 0x26, 0x15, 0x5f, 0x0f, 0x62, 0x52, 0x15, 0x6e, 0x9d, 0xe8, 0x02, 0x7e, 0x60, 0xb5, 0xa5, 0xcd, 0x1d, 0xbe, 0x62, 0xe0, 0x46, 0xd5, 0xd2, 0xe0, 0x02, 0xe1, 0x07, 0xf8, 0xff, 0xe1, 0x29, 0x93, 0xc2, 0x8b, 0x47, 0x78, 0x1e, 0xcd, 0x55, 0x91, 0xc2, 0xf5, 0xb4, 0xf6, 0x47, 0x52, 0x1f, 0x9e, 0x21, 0xa1, 0xe6, 0x38, 0x45, 0x7f, 0xa0, 0x7c, 0x40, 0x95, 0x3d, 0x40, 0x15, 0x75, 0xbb, 0xde, 0x9a, 0x02, 0x28, 0x48, 0x0d, 0xdc, 0x46, 0xd6, 0xe3, 0xef, 0x7e, 0xf8, 0x81, 0x21, 0x5e, 0xa1, 0xa6, 0x57, 0x58, 0x03, 0x62, 0x2e, 0x2c, 0x9b, 0x3d, 0x7c, 0x25, 0xd8, 0xbe, 0x08, 0x7a, 0x46, 0xa4, 0xb9, 0x46, 0xa0, 0x10, 0xf0, 0x55, 0x67, 0x33, 0x3d, 0x8a, 0x67, 0x68, 0xba, 0x23, 0xe1, 0xa7, 0xb1, 0x84, 0xe2, 0x7f, 0xc9, 0xf9, 0xb4, 0x11, 0x9c, 0xd5, 0x3c, 0xf3, 0x9d, 0x33, 0x73, 0x6b, 0x17, 0xb9, 0xd2, 0x5a, 0x30, 0x96, 0x0f, 0x2c, 0x26, 0x4e, 0x4a, 0x2d, 0x99, 0x11, 0x16, 0xe0, 0x44, 0xe4, 0x27, 0x5c, 0x67, 0x0f, 0x1d, 0x14, 0xe3, 0x40, 0x12, 0x55, 0x1a, 0x94, 0xec, 0x82, 0xfd, 0xbb, 0xc2, 0x83, 0xf7, 0x56, 0xe8, 0x3f, 0x76, 0x34, 0xe9, 0x0a, 0x78, 0x30, 0x7c, 0x5e, 0x46, 0x38, 0x62, 0xe0, 0xc9, 0xe1, 0x82, 0x9e, 0x7b, 0xb1, 0xec, 0x96, 0x03, 0x94, 0xa1, 0xf8, 0xdd, 0x5f, 0xa2, 0x6c, 0x5f, 0x3b, 0xe6, 0x3c, 0x79, 0xd3, 0x0c, 0x0f, 0x8f, 0x5a, 0xed, 0x2d, 0x8d, 0xa7, 0xc2, 0x94, 0x32, 0x4d, 0x8c, 0x11, 0x46, 0x05, 0xba, 0x8a, 0x5a, 0xaa, 0x0c, 0xdc, 0xfc, 0x68, 0x49, 0x07, 0x1d, 0x35, 0x31, 0xc4, 0x47, 0xad, 0x4e, 0x1a, 0x2b, 0x45, 0x96, 0x41, 0x21, 0xa6, 0xf2, 0x13, 0xb4, 0x45, 0xa5, 0x7a, 0x5d, 0x0a, 0xdb, 0xa9, 0x05, 0x60, 0x78, 0x82, 0x25, 0x7c, 0xc4, 0xae, 0x75, 0x45, 0x17, 0xd2, 0xd7, 0x4e, 0x26, 0x77, 0x5c, 0xb5, 0x8b, 0xa1, 0x8c, 0x0c, 0xad, 0xc2, 0xbb, 0x0a, 0x68, 0xab, 0x14, 0x4e, 0xc0, 0x76, 0x3d, 0x4c, 0x58, 0x63, 0xbe, 0xd6, 0x0f, 0xdc, 0x63, 0xcf, 0x11, 0x12, 0x74, 0xca, 0x50, 0x5e, 0xdb, 0x59, 0xba, 0x8a, 0x51, 0xff, 0x60, 0x0a, 0x8f, 0x1b, 0x23, 0xba, 0x80, 0x30, 0xc8, 0xcf, 0xef, 0xf3, 0xf6, 0x41, 0x36, 0xed, 0x21, 0x06, 0x18, 0xad, 0x1c, 0x55, 0xd1, 0x2d, 0x10, 0xff, 0x43, 0x8b, 0xc4, 0x10, 0x3f, 0xe9, 0xe7, 0x89, 0x43, 0x30, 0x9d, 0xb4, 0x9d, 0x81, 0x09, 0xba, 0xea, 0x45, 0x22, 0x43, 0x1b, 0x72, 0x54, 0x16, 0x77, 0x0c, 0x22, 0x40, 0x31, 0x40, 0x04, 0x78, 0x87, 0xd1, 0xdc, 0x9b, 0x3c, 0x38, 0xba, 0xfc, 0xf8, 0x82, 0x48, 0xe9, 0x51, 0xf8, 0x51, 0x1c, 0x13, 0x97, 0xec, 0xc8, 0x85, 0x7c, 0x1f, 0x6f, 0x1f, 0xcc, 0xd4, 0xcf, 0x04, 0x99, 0xa6, 0x68, 0x62, 0xa2, 0xea, 0x1d, 0x1d, 0x8e, 0xf1, 0x3e, 0x8c, 0xd1, 0xc4, 0x9e, 0xff, 0x74, 0xda, 0x0c, 0x16, 0x37, 0x64, 0x25, 0x08, 0x85, 0xf3, 0xdb, 0xc7, 0x9c, 0x07, 0x71, 0xbe, 0x88, 0x8b, 0x83, 0x7f, 0x2d, 0xae, 0xdf, 0x04, 0xbd, 0xaa, 0x10, 0xe7, 0xff, 0xf9, 0x13, 0x92, 0x5d, 0x37, 0x6c, 0x32, 0x29, 0xf7, 0x29, 0x93, 0x49, 0x43, 0x42, 0x32, 0xb4, 0xd0, 0xf6, 0x09, 0xae, 0xb5, 0x8f, 0x2a, 0x14, 0x23, 0x0b, 0x0a, 0x54, 0x6f, 0x5a, 0x49, 0xd1, 0x42, 0x3f, 0x45, 0xeb, 0xf9, 0x3c, 0x51, 0x8c, 0x5a, 0x8e, 0x2e, 0xf2, 0xfd, 0x48, 0xf4, 0x0b, 0x78, 0x94, 0x6d, 0xdc, 0x4f, 0x58, 0x82, 0x68, 0x89, 0x01, 0x5d, 0x4f, 0xe6, 0x28, 0xa3, 0x31, 0xb4, 0xad, 0x5f, 0xa0, 0xcd, 0xff, 0x02, 0x14, 0x52, 0x9f, 0xe0, 0xc4, 0x08, 0xf6, 0x7a, 0x94, 0x9f, 0x11, 0x20, 0x0b, 0x37, 0x6a, 0x25, 0xe8, 0x60, 0xc4, 0xb8, 0xe5, 0x0f, 0x18, 0x1e, 0x61, 0xe9, 0xbd, 0x6c, 0x14, 0xd8, 0x85, 0xce, 0xc9, 0xae, 0xa2, 0x02, 0x4f, 0x73, 0x92, 0x75, 0xdd, 0xf4, 0xfb, 0x3d, 0x26, 0xc4, 0x07, 0xb4, 0x8c, 0x8c, 0xce, 0xce, 0x60, 0x52, 0x61, 0x00, 0x3f, 0x5f, 0xda, 0x70, 0x11, 0x8a, 0xb4, 0xc1, 0xff, 0x81, 0x0c, 0xf5, 0x08, 0xc1, 0x67, 0xcf, 0x0f, 0x5d, 0x11, 0x10, 0xbb, 0x68, 0x68, 0x34, 0x09, 0xa5, 0xd5, 0xfd, 0xad, 0x01, 0xe4, 0x97, 0x49, 0xc4, 0x37, 0xea, 0xde, 0x8d, 0x41, 0xc9, 0x18, 0x00, 0x60, 0x52, 0xe4, 0x98, 0x52, 0x5f, 0xf2, 0x75, 0x10, 0x04, 0xf4, 0x66, 0x24, 0x10, 0x11, 0x43, 0xea, 0xfc, 0x6e, 0xca, 0x78, 0x69, 0x2a, 0x9a, 0x00, 0xd8, 0x1a, 0x6a, 0x04, 0x1a, 0xd7, 0x69, 0xfd, 0x37, 0x56, 0x3e, 0x2a, 0xb2, 0x13, 0x91, 0x2d, 0xb0, 0xe9, 0xd4, 0xb0, 0x86, 0x1a, 0x66, 0x5a, 0x95, 0x41, 0x9d, 0xa7, 0x28, 0x74, 0xe3, 0xaf, 0x8c, 0x8a, 0x0e, 0x72, 0x7e, 0x0b, 0x00, 0xa0, 0xc9, 0xee, 0x52, 0xe7, 0x76, 0xc3, 0xfd, 0xdf, 0x6f, 0x97, 0x08, 0xb5, 0xce, 0x89, 0x1a, 0x83, 0xe4, 0x69, 0xa0, 0xed, 0xa4, 0x77, 0x57, 0xa9, 0xe9, 0xa5, 0x7b, 0xca, 0xb4, 0x3f, 0x24, 0x3d, 0xaf, 0xea, 0xd4, 0x30, 0xe9, 0x77, 0xe2, 0x0e, 0xf0, 0x77, 0x66, 0x6f, 0x63, 0x88, 0x23, 0x06, 0x87, 0xbc, 0xc3, 0xc4, 0xb6, 0xde, 0x7c, 0x15, 0x64, 0x60, 0x18, 0xbb, 0xcd, 0x64, 0xdb, 0x58, 0x9a, 0x63, 0x7b, 0xe0, 0x97, 0x3d, 0x10, 0x0e, 0x72, 0x5d, 0x00, 0x45, 0x2d, 0x0d, 0xf0, 0x0b, 0x05, 0xe8, 0x49, 0x73, 0x6c, 0x20, 0x51, 0x5e, 0x62, 0xc1, 0x85, 0x37, 0x21, 0x5d, 0xa8, 0x83, 0xf7, 0xd7, 0x96, 0x67, 0x42, 0xb6, 0xef, 0xe1, 0x21, 0x6d, 0x44, 0x0b, 0x22, 0xee, 0x93, 0xeb, 0x82, 0x66, 0xa3, 0x4e, 0xcf, 0x34, 0x1d, 0xbf, 0x18, 0x18, 0x47, 0x66, 0x43, 0x58, 0x2c, 0xe2, 0x6a, 0xc3, 0x6f, 0xfe, 0x02, 0xd8, 0x77, 0xfa, 0x05, 0xed, 0x84, 0x34, 0x6e, 0xe4, 0x46, 0x8d, 0xb9, 0x8d, 0xc8, 0xe2, 0xd3, 0x97, 0x51, 0xf6, 0x9d, 0x3d, 0x11, 0xea, 0x59, 0x65, 0x86, 0xfc, 0x94, 0xea, 0x75, 0x5a, 0x55, 0x74, 0x1c, 0x04, 0xc6, 0x75, 0x51, 0x00, 0x40, 0xc8, 0x4c, 0x0c, 0x7b, 0x48, 0xe2, 0xcf, 0x80, 0xb6, 0x0c, 0x65, 0xc9, 0x90, 0x9f, 0x2e, 0x1a, 0xfb, 0xda, 0xae, 0xc5, 0x8a, 0x0e, 0xd7, 0xcd, 0x0a, 0x44, 0x09, 0x7f, 0xff, 0xe6, 0xd6, 0x21, 0xf4, 0x95, 0xcb, 0x05, 0xd1, 0x20, 0x02, 0xde, 0xc1, 0xce, 0xdf, 0x07, 0xbc, 0x8e, 0x59, 0xad, 0x53, 0x29, 0x82, 0xa7, 0x11, 0x2f, 0x5a, 0x5c, 0xf1, 0x6b, 0x40, 0x4f, 0x5c, 0x10, 0xab, 0xfc, 0xac, 0x79, 0x1c, 0x66, 0xa0, 0x13, 0x93, 0x52, 0x14, 0xce, 0xe4, 0x8a, 0x14, 0x0b, 0x92, 0x8a, 0x2d, 0x2a, 0x65, 0x16, 0x75, 0x64, 0xa5, 0xa2, 0x53, 0x86, 0x8d, 0xd5, 0x09, 0x83, 0x64, 0xce, 0x88, 0x42, 0xb8, 0x30, 0x71, 0xd1, 0x74, 0x6e, 0x02, 0x7b, 0x6c, 0xd0, 0x4c, 0x97, 0x3b, 0x47, 0xe8, 0x0f, 0x1b, 0x36, 0x8b, 0xaf, 0x8e, 0x9c, 0xd6, 0x12, 0x63, 0xbf, 0x6c, 0x4d, 0xa7, 0xb6, 0xe7, 0xd2, 0x39, 0xee, 0x92, 0xe9, 0x6f, 0x91, 0xf5, 0x8a, 0x0e, 0x71, 0x6d, 0xd9, 0x49, 0x27, 0x6f, 0xac, 0x94, 0x85, 0x63, 0xb0, 0xda, 0xd0, 0x8d, 0x19, 0xfd, 0x84, 0xf7, 0x25, 0xa7, 0x34, 0xec, 0xee, 0x4e, 0xd6, 0xf0, 0xa2, 0x37, 0x9f, 0x44, 0x10, 0xdf, 0xad, 0x47, 0x50, 0xbe, 0x16, 0xd5, 0xb6, 0xe0, 0x24, 0xe7, 0x7a, 0xc1, 0x42, 0xf4, 0x0e, 0x8f, 0x48, 0x0b, 0xd1, 0xfc, 0xff, 0x8b, 0x34, 0xe7, 0xbe, 0xc7, 0x42, 0xc7, 0x66, 0x0f, 0x65, 0xfa, 0x32, 0x78, 0x29, 0xf7, 0xc3, 0xb1, 0x18, 0x02, 0x8f, 0x4d, 0x14, 0x56, 0xcd, 0xba, 0x6c, 0x8d, 0x02, 0xab, 0x45, 0x43, 0x9c, 0x1a, 0x32, 0xb7, 0xd6, 0xe4, 0x79, 0x82, 0x17, 0xb3, 0x47, 0x8c, 0xd4, 0x8a, 0x15, 0x78, 0x19, 0xfa, 0x5c, 0x78, 0x27, 0x78, 0x80, 0xd9, 0x1e, 0x4e, 0xbe, 0xbd, 0xb8, 0x6a, 0x83, 0xcd, 0x86, 0x04, 0x74, 0x4a, 0xe9, 0xa8, 0x40, 0x74, 0xa3, 0xb1, 0xdc, 0x22, 0x87, 0x27, 0xc1, 0x6f, 0x49, 0xd0, 0xc3, 0xbc, 0xee, 0x53, 0xde, 0x08, 0x08, 0x37, 0x97, 0x06, 0x65, 0xe0, 0x84, 0xfe, 0x08, 0xcf, 0xd7, 0x4e, 0xae, 0xf0, 0x0d, 0x48, 0x76, 0xb1, 0x49, 0xc5, 0xf2, 0x45, 0xcb, 0x13, 0xf7, 0x30, 0x48, 0x1c, 0x7b, 0x41, 0x96, 0xdc, 0x89, 0xa7, 0xfe, 0x2c, 0x32, 0xd5, 0x67, 0xfc, 0xc0, 0x08, 0x59, 0x0d, 0x89, 0x24, 0x64, 0x64, 0x42, 0x94, 0x43, 0xb8, 0x74, 0x7e, 0xcd, 0x98, 0x12, 0x83, 0x89, 0xde, 0xf5, 0xa2, 0xf7, 0xe2, 0x05, 0xf9, 0x95, 0x6e, 0x20, 0x72, 0x45, 0x5a, 0x43, 0xe8, 0xa9, 0x76, 0xf6, 0xe0, 0x82, 0x0d, 0xd7, 0xbc, 0x0d, 0x57, 0x26, 0x8f, 0x63, 0x1c, 0xad, 0x42, 0x26, 0x05, 0x84, 0x43, 0x43, 0x75, 0xc5, 0x54, 0xae, 0x10, 0x26, 0x01, 0x01, 0x62, 0xd1, 0x0c, 0x62, 0xf2, 0xe1, 0xa0, 0x42, 0xdc, 0x6f, 0x0d, 0x4c, 0x4d, 0x0e, 0x97, 0x3a, 0xe7, 0x7d, 0xb1, 0x13, 0x61, 0x2f, 0x64, 0x05, 0x22, 0xc9, 0x42, 0xed, 0x64, 0xa9, 0xfc, 0x0e, 0x03, 0xae, 0x6f, 0xa0, 0xfb, 0x9d, 0xe9, 0xcf, 0x69, 0x4f, 0xef, 0xde, 0xe9, 0x04, 0x3a, 0xd6, 0xe9, 0xb5, 0xef, 0x6d, 0x27, 0xf8, 0xe1, 0xbd, 0x10, 0x3c, 0xa6, 0x27, 0x24, 0x6c, 0xe8, 0xbb, 0xb5, 0x61, 0x4b, 0x03, 0xa2, 0xdb, 0x4c, 0x4e, 0x22, 0xdf, 0x83, 0xff, 0x62, 0xa3, 0xaf, 0x51, 0x5a, 0x6a, 0x85, 0x7a, 0x8d, 0xd7, 0xcd, 0xe1, 0x9f, 0x0f, 0x8b, 0x08, 0xbf, 0x03, 0x08, 0x5e, 0x4f, 0x7f, 0x49, 0x17, 0xf6, 0xe7, 0x87, 0xa8, 0xe9, 0x99, 0x12, 0x39, 0x7c, 0x38, 0x38, 0x35, 0x21, 0xf4, 0x31, 0x13, 0x48, 0x46, 0xcd, 0xff, 0xdb, 0x94, 0x03, 0x49, 0x4f, 0x45, 0xd2, 0xf1, 0x26, 0x77, 0xe0, 0x75, 0x5e, 0x67, 0x10, 0x5c, 0x52, 0x52, 0xd2, 0x5f, 0xbe, 0x66, 0x5f, 0x74, 0xd3, 0x0f, 0x42, 0xfc, 0x8d, 0x3d, 0x27, 0x84, 0xd8, 0xd3, 0xf5, 0xae, 0xba, 0x43, 0xf1, 0xd4, 0x00, 0x37, 0x1f, 0x58, 0xa9, 0xb5, 0xb7, 0xc2, 0x31, 0x20, 0x38, 0x26, 0x4c, 0x68, 0xca, 0xfb, 0x22, 0xd0, 0x1c, 0x71, 0xec, 0xd3, 0x8c, 0x79, 0x56, 0xfc, 0xcc, 0x61, 0x5c, 0x36, 0x56, 0x68, 0xbe, 0x23, 0x7d, 0x3c, 0xd3, 0x83, 0x37, 0x07, 0xbb, 0x4b, 0x19, 0x1d, 0xf6, 0x05, 0x7a, 0x92, 0x9b, 0xd0, 0x61, 0x1c, 0x11, 0x17, 0xf2, 0x47, 0xa9, 0x18, 0xd1, 0x3c, 0x61, 0x7f, 0x87, 0xf4, 0x71, 0x18, 0xd1, 0x12, 0x15, 0x4a, 0x6e, 0xee, 0xc5, 0x5b, 0xc3, 0x1a, 0x83, 0xce, 0xf3, 0x65, 0xd3, 0xf8, 0xed, 0x1f, 0xe4, 0x01, 0x7f, 0x0f, 0xe7, 0x4a, 0x29, 0x65, 0xb0, 0xb0, 0xb0, 0xb1, 0xd9, 0xbc, 0x2f, 0xcd, 0x80, 0xbe, 0xbc, 0xfb, 0xbc, 0x1e, 0x8f, 0xef, 0xa0, 0xbb, 0xb7, 0x7e, 0xcd, 0x36, 0x95, 0xaa, 0xbd, 0x9f, 0x44, 0xbf, 0x3a, 0x51, 0x10, 0x0d, 0xb5, 0xe4, 0xaa, 0x0d, 0xb7, 0x7e, 0x6d, 0xac, 0x58, 0x87, 0xf0, 0x25, 0x74, 0x95, 0x72, 0xd0, 0xa6, 0x25, 0xe3, 0x5f, 0x0d, 0xe6, 0x49, 0xb3, 0xa6, 0xad, 0x10, 0x16, 0x8d, 0x59, 0x16, 0x62, 0x10, 0xbe, 0x0a, 0xb3, 0x61, 0x77, 0x48, 0x56, 0x42, 0xc2, 0xd6, 0xe2, 0x14, 0x18, 0x42, 0x94, 0xa1, 0x97, 0x08, 0xfb, 0x7e, 0xa0, 0x9b, 0x82, 0xfa, 0x23, 0x95, 0xcb, 0xd5, 0x00, 0x80, 0x4a, 0x3a, 0x93, 0xd7, 0xa5, 0xca, 0xf3, 0x9b, 0xd1, 0x09, 0x07, 0xa1, 0xbc, 0x1a, 0x65, 0xfa, 0x4a, 0x9f, 0xb6, 0x31, 0x57, 0x41, 0xa2, 0x88, 0xf8, 0xa2, 0x50, 0x70, 0x88, 0xfc, 0xaf, 0xe2, 0x86, 0xfc, 0x7c, 0x34, 0x55, 0x98, 0x9e, 0x5b, 0x51, 0xa7, 0xbb, 0xbc, 0x4f, 0x4e, 0xff, 0xfe, 0x79, 0xf3, 0xf5, 0x51, 0x15, 0x6f, 0x38, 0x4f, 0x42, 0xbc, 0xb6, 0xb0, 0xa8, 0x68, 0xa6, 0x54, 0x89, 0xbc, 0x39, 0x2f, 0x84, 0x2d, 0x7c, 0xa3, 0xd3, 0xd7, 0xf4, 0xe6, 0x68, 0x01, 0x5a, 0x6a, 0xe9, 0x97, 0x7c, 0x86, 0x09, 0xf0, 0x6e, 0xe5, 0xee, 0xd8, 0x89, 0x26, 0xc4, 0x25, 0xa5, 0x48, 0x17, 0x2b, 0xb3, 0x8d, 0xc4, 0x52, 0xde, 0xbb, 0x68, 0x94, 0xa3, 0x38, 0x9c, 0xae, 0xe0, 0x89, 0xae, 0x53, 0xd8, 0xb9, 0x48, 0x1c, 0xd3, 0xdc, 0x97, 0x7b, 0x00, 0xc6, 0xef, 0x79, 0x5d, 0xe7, 0x6b, 0x12, 0xb5, 0xa9, 0x5a, 0xe8, 0x7c, 0x77, 0xf2, 0x48, 0x39, 0x20, 0x48, 0xd8, 0xff, 0x71, 0xb9, 0x3a, 0xff, 0x58, 0x6e, 0xec, 0x27, 0x13, 0x54, 0x5a, 0x74, 0xdc, 0xae, 0xda, 0x02, 0x00, 0xdf, 0x52, 0xce, 0x57, 0xa5, 0x37, 0x7b, 0x1f, 0x35, 0x7b, 0x88, 0x54, 0xaa, 0xb5, 0x93, 0xd3, 0xe9, 0x6f, 0xbf, 0x8a, 0x91, 0xa1, 0xf6, 0x0f, 0x41, 0xe4, 0x8a, 0x71, 0x21, 0x81, 0x20, 0x3e, 0x62, 0x2d, 0xae, 0x3d, 0x6f, 0x86, 0x1f, 0x12, 0xf0, 0x96, 0x66, 0x94, 0x10, 0x8b, 0xf2, 0x86, 0xfe, 0x01, 0xa4, 0xae, 0x9d, 0x74, 0x98, 0xe5, 0xd8, 0x15, 0x99, 0x66, 0x18, 0x40, 0x08, 0x95, 0x5b, 0x34, 0x8c, 0x2f, 0xa9, 0x6d, 0x64, 0x1a, 0x8b, 0xbf, 0x4a, 0x8e, 0xdf, 0x69, 0x66, 0x67, 0x65, 0x79, 0xf3, 0xe2, 0xe4, 0x41, 0xf2, 0x73, 0x69, 0x89, 0x76, 0xca, 0x68, 0xd9, 0x14, 0x7d, 0xfc, 0xb3, 0xe7, 0x05, 0xcb, 0x7c, 0x6c, 0xec, 0x3d, 0x63, 0xaa, 0xac, 0xb5, 0x6f, 0x4e, 0x62, 0xe2, 0x76, 0xdd, 0x15, 0xfb, 0xe0, 0xf9, 0x20, 0xb1, 0xe3, 0x72, 0xee, 0x4a, 0xe0, 0xdd, 0x18, 0x1e, 0x0e, 0xce, 0xa1, 0xc3, 0x25, 0xf3, 0x1b, 0x66, 0xfe, 0x37, 0xcd, 0x3a, 0x69, 0x5c, 0xf0, 0x8c, 0xa8, 0x1f, 0x09, 0x04, 0x42, 0x96, 0xda, 0x6e, 0x6c, 0x1d, 0x19, 0x70, 0x14, 0xba, 0xca, 0x96, 0x27, 0x47, 0x99, 0xfa, 0x3f, 0xc9, 0x2d, 0x8d, 0x40, 0xc7, 0xa7, 0xe5, 0x79, 0xf3, 0x81, 0x49, 0x4e, 0x4f, 0xaf, 0x70, 0xb8, 0x5a, 0x44, 0x8f, 0x95, 0x0a, 0x59, 0xa9, 0xb7, 0x84, 0xa5, 0x3b, 0xf3, 0xe1, 0x75, 0x9c, 0xb9, 0xe3, 0xc4, 0xbc, 0x61, 0xb1, 0xaf, 0xa0, 0x13, 0x9b, 0x48, 0xbf, 0x99, 0x4c, 0x4f, 0x3f, 0x54, 0x9b, 0x5b, 0x57, 0x80, 0x98, 0xa4, 0xc5, 0x75, 0x3f, 0xb7, 0x56, 0x42, 0x6a, 0x32, 0x40, 0x1c, 0xc3, 0xc4, 0x43, 0x3d, 0xa6, 0x0a, 0xd8, 0x46, 0xfe, 0x00, 0xfd, 0x35, 0xf9, 0xbf, 0xd7, 0xc4, 0x81, 0xb6, 0xdf, 0x70, 0x28, 0xa3, 0x72, 0x3b, 0x5f, 0x84, 0x5d, 0xfe, 0x7d, 0x05, 0x1e, 0xeb, 0xbf, 0x57, 0xdc, 0xda, 0xba, 0x30, 0x8b, 0xcf, 0xdd, 0xd4, 0x1d, 0x18, 0x90, 0x2a, 0xf8, 0x96, 0x72, 0x35, 0xc0, 0xbb, 0x3f, 0x18, 0xb4, 0xb6, 0x26, 0x14, 0x6b, 0x86, 0x38, 0xf2, 0x09, 0x62, 0x12, 0xd8, 0xd6, 0xd6, 0xb7, 0x60, 0x8a, 0x06, 0x1f, 0xb8, 0xe9, 0x83, 0xa0, 0x4b, 0x73, 0x3b, 0x94, 0x9f, 0xcf, 0xb2, 0x9a, 0xe8, 0xfd, 0xfb, 0xd9, 0xf2, 0x5d, 0x66, 0xbe, 0x9d, 0xae, 0xfb, 0x8a, 0xbf, 0x0d, 0xbb, 0x37, 0x8a, 0xf6, 0xcf, 0xd6, 0x5a, 0x39, 0x56, 0x9b, 0x1d, 0x1d, 0x81, 0x06, 0xf5, 0xe6, 0xdd, 0xd2, 0x53, 0x67, 0x55, 0x04, 0xa6, 0x88, 0xe8, 0x0b, 0xa3, 0xa4, 0xe1, 0x53, 0x90, 0x75, 0xff, 0xf4, 0x7b, 0x31, 0xa4, 0x3c, 0x26, 0x4c, 0x10, 0x8d, 0x15, 0x0d, 0x70, 0xdc, 0xfc, 0x12, 0x39, 0x11, 0x48, 0x92, 0x28, 0xc0, 0x28, 0xbe, 0x56, 0x71, 0x89, 0xeb, 0x6c, 0x67, 0xc7, 0x28, 0x15, 0x4b, 0xb4, 0x3b, 0x73, 0x85, 0x12, 0x0c, 0xad, 0x73, 0xb6, 0xdc, 0xe4, 0x49, 0x2e, 0x08, 0x53, 0x34, 0x02, 0x9a, 0x21, 0xe8, 0x48, 0x95, 0xd2, 0xef, 0x66, 0x40, 0x43, 0xa4, 0x71, 0xeb, 0xee, 0xf5, 0xde, 0x70, 0x09, 0xa3, 0xf2, 0x51, 0x18, 0xb8, 0x7d, 0xae, 0xd1, 0x2c, 0x1a, 0xf7, 0xda, 0x59, 0x5d, 0x08, 0xe5, 0xa4, 0xc6, 0x3d, 0x55, 0x81, 0xd9, 0xda, 0xf0, 0x3d, 0x93, 0x74, 0x72, 0x72, 0xea, 0xcc, 0xb1, 0x5d, 0xa8, 0x50, 0x87, 0x1e, 0x3d, 0xd7, 0x7a, 0x9e, 0x19, 0xb4, 0x5f, 0x20, 0x61, 0xd3, 0x2e, 0x1b, 0x10, 0xc7, 0x58, 0x90, 0xf0, 0x8b, 0x35, 0xaf, 0xc3, 0x50, 0xf0, 0xb3, 0xcf, 0xef, 0xb6, 0x88, 0x17, 0x94, 0xe8, 0x82, 0x1d, 0xc4, 0x91, 0xd6, 0xa7, 0xca, 0x16, 0x72, 0xc8, 0xde, 0xbf, 0xab, 0x81, 0x11, 0xf5, 0x30, 0xa0, 0x7c, 0x6d, 0xf7, 0x4a, 0x5d, 0xa3, 0xc4, 0x54, 0x61, 0x21, 0xf3, 0x3b, 0xef, 0xf1, 0x79, 0x79, 0x4e, 0x48, 0xc0, 0xf0, 0x7b, 0x7b, 0xb9, 0x23, 0xe0, 0xb6, 0x83, 0xfc, 0x2d, 0x1b, 0x11, 0x3b, 0x6e, 0x76, 0x09, 0xf5, 0xf6, 0xf6, 0xda, 0x01, 0xd5, 0xb9, 0x68, 0x2f, 0x78, 0x62, 0x0b, 0xa9, 0x2a, 0x96, 0x93, 0x85, 0x5b, 0xa3, 0x48, 0xff, 0x73, 0x3e, 0xc2, 0x10, 0x63, 0xcd, 0x6a, 0x71, 0x4c, 0xb6, 0x76, 0xd0, 0xe2, 0x13, 0x0b, 0xf1, 0xdb, 0xdf, 0x78, 0x5b, 0xcf, 0xd9, 0x2b, 0xb7, 0xd9, 0x2d, 0xe7, 0xc9, 0x9e, 0xb7, 0x8a, 0x1d, 0x61, 0xb3, 0x61, 0x8c, 0xeb, 0xa3, 0x85, 0x4a, 0x83, 0x29, 0x1e, 0x9f, 0x6b, 0x2b, 0xbf, 0x87, 0xdd, 0xb4, 0x5a, 0x9d, 0x2a, 0xa8, 0xcc, 0x4d, 0xcc, 0xd6, 0x0b, 0xa0, 0xa9, 0x56, 0xa6, 0x63, 0xb5, 0x9e, 0xa5, 0x06, 0x3a, 0xe3, 0xab, 0xcc, 0x1d, 0x73, 0xc5, 0x85, 0x8b, 0x13, 0x93, 0x1c, 0xb8, 0xe8, 0x25, 0xc9, 0xc3, 0x0a, 0x92, 0x44, 0x4d, 0x41, 0xa4, 0xd4, 0x0f, 0x09, 0x36, 0xd3, 0x58, 0x0a, 0x3d, 0xc3, 0xbc, 0xd7, 0xed, 0x34, 0x86, 0xf2, 0xad, 0x0f, 0xd6, 0xe7, 0x2e, 0x28, 0x51, 0x89, 0x86, 0x6a, 0x5d, 0x3e, 0x3b, 0xe5, 0xa5, 0xb9, 0x97, 0x5f, 0x6b, 0x2e, 0xcb, 0x55, 0x4b, 0x0b, 0xa5, 0xe3, 0xc9, 0xa6, 0x0f, 0xdd, 0xbc, 0x6e, 0x57, 0x2c, 0xed, 0x0d, 0x63, 0x18, 0x44, 0xda, 0x95, 0x5a, 0xb3, 0xc5, 0x52, 0x77, 0x00, 0x0d, 0xb6, 0xbb, 0x6d, 0xcf, 0x0c, 0xfb, 0x85, 0x83, 0x7d, 0x05, 0xf7, 0x10, 0xcc, 0x0c, 0xa0, 0xe7, 0x7f, 0x1c, 0xb0, 0x5c, 0x38, 0xfa, 0xa5, 0xfb, 0xfd, 0x92, 0x21, 0xab, 0x59, 0xf8, 0x75, 0xc3, 0x61, 0x04, 0x9d, 0x12, 0x75, 0xe2, 0x8f, 0x61, 0xf3, 0x77, 0x57, 0x0a, 0x41, 0x41, 0x92, 0x9d, 0xa1, 0xf8, 0xbb, 0x61, 0x3e, 0x42, 0x53, 0x02, 0x7e, 0x37, 0x3a, 0x00, 0xf4, 0x3b, 0x2a, 0xd0, 0x8f, 0x51, 0x00, 0x96, 0xdd, 0x3d, 0xe6, 0xd2, 0x08, 0x13, 0x33, 0x74, 0xb7, 0x8e, 0x4e, 0x03, 0x4a, 0x8e, 0x40, 0xec, 0x07, 0x24, 0x04, 0xbc, 0x41, 0x16, 0xe3, 0xad, 0x30, 0x34, 0x6e, 0x22, 0xa9, 0xc9, 0x57, 0x49, 0x03, 0x36, 0xa8, 0x2d, 0x28, 0xd3, 0xd9, 0xef, 0x83, 0xb0, 0xf4, 0x09, 0xf1, 0xfc, 0xea, 0x75, 0xc0, 0xb5, 0x88, 0xe5, 0xa9, 0x72, 0x9a, 0xf5, 0xb5, 0x26, 0xeb, 0x8a, 0x00, 0xd1, 0xee, 0x80, 0x97, 0x23, 0x77, 0xf6, 0xec, 0x22, 0xeb, 0xb9, 0x5f, 0x2b, 0x06, 0x53, 0x79, 0x22, 0xe4, 0x10, 0x85, 0x73, 0x78, 0x53, 0x39, 0x93, 0x3e, 0xcc, 0xca, 0x69, 0xfd, 0xaf, 0xcd, 0xbf, 0x4c, 0xc4, 0x7a, 0xa1, 0x43, 0x06, 0xd7, 0xf7, 0xb7, 0x18, 0x42, 0x9f, 0xfa, 0x12, 0xc7, 0xde, 0xd7, 0x58, 0x65, 0xf1, 0x3b, 0xd3, 0xa4, 0x14, 0x93, 0x69, 0xab, 0xcc, 0x0e, 0xe4, 0x94, 0xcd, 0xcc, 0xb5, 0xb6, 0x3b, 0x3a, 0xe6, 0x62, 0x83, 0xf6, 0x91, 0x76, 0xc4, 0x0b, 0xe6, 0x47, 0xf6, 0x8f, 0x06, 0x01, 0x8e, 0x6c, 0x8c, 0x81, 0xeb, 0x8b, 0x0e, 0xc0, 0xa6, 0x2a, 0xe9, 0xa9, 0xcd, 0x1a, 0x43, 0x91, 0x35, 0x0f, 0xa0, 0x3d, 0x20, 0x48, 0x21, 0x8b, 0x7b, 0x3b, 0x59, 0x49, 0x18, 0x5a, 0x6b, 0xc6, 0xfe, 0xc9, 0xd7, 0xb3, 0x13, 0x5e, 0x56, 0x52, 0xfd, 0xf4, 0xcb, 0x8b, 0xb4, 0x5e, 0xd1, 0x57, 0x09, 0xc9, 0x96, 0x51, 0x20, 0x16, 0x5c, 0x8f, 0xdb, 0x8f, 0x21, 0xd8, 0x4b, 0xb1, 0x94, 0xe9, 0x17, 0x3d, 0x23, 0xa3, 0xac, 0x3c, 0x42, 0x14, 0xc3, 0x0f, 0x29, 0x9e, 0x51, 0x3e, 0xae, 0x33, 0xec, 0xe9, 0xe3, 0x0d, 0x0e, 0x3f, 0x39, 0x49, 0xa0, 0xbb, 0x9a, 0x57, 0xa9, 0xb4, 0xb9, 0x2f, 0xf7, 0x3b, 0xf1, 0xd3, 0xc7, 0x39, 0x4f, 0xb8, 0x4e, 0x93, 0x89, 0xa9, 0xa9, 0xf0, 0x32, 0x49, 0xa3, 0x9f, 0xa6, 0x5f, 0x6e, 0xf2, 0x04, 0xdc, 0x4e, 0x57, 0x71, 0x01, 0x14, 0x32, 0x58, 0x7b, 0xe3, 0x19, 0x21, 0xe4, 0x01, 0xf7, 0x3d, 0x4d, 0x4a, 0x25, 0x6a, 0x1a, 0x37, 0xdc, 0xdd, 0x54, 0x88, 0xef, 0x74, 0xb8, 0x63, 0xdd, 0x5b, 0x95, 0x92, 0x62, 0xae, 0xe5, 0x86, 0x50, 0x0f, 0x3e, 0x4d, 0x4c, 0xe1, 0xe2, 0xda, 0x7f, 0xd1, 0x5a, 0xfe, 0x6d, 0x19, 0x1d, 0x9d, 0x16, 0x03, 0x88, 0x41, 0x2a, 0x9d, 0x2a, 0xd9, 0x0e, 0xf3, 0xec, 0xee, 0xf5, 0x65, 0x11, 0x0a, 0xde, 0x12, 0xa5, 0xaf, 0x93, 0xef, 0xc8, 0xea, 0xb1, 0xea, 0x3d, 0x6b, 0x3f, 0x45, 0xa1, 0xc6, 0xc5, 0xc1, 0x31, 0x82, 0x74, 0x08, 0xbd, 0x60, 0xca, 0x6c, 0xd8, 0x15, 0xd3, 0xdb, 0x2b, 0x4e, 0x22, 0x12, 0x40, 0xe2, 0xed, 0xed, 0x4d, 0xc7, 0xcc, 0x8c, 0x00, 0x08, 0x0d, 0x0b, 0xa3, 0xa4, 0xa2, 0x7a, 0x07, 0x11, 0xa5, 0x56, 0x4b, 0xd5, 0xa4, 0x90, 0x28, 0x09, 0xab, 0x33, 0x1d, 0x2a, 0xb4, 0x9c, 0xca, 0xf5, 0x90, 0x9b, 0xac, 0xa8, 0xd4, 0x6d, 0x76, 0x50, 0x07, 0x57, 0xda, 0x78, 0x34, 0x8b, 0x1c, 0xf9, 0xc9, 0xbd, 0x8b, 0xcb, 0x6d, 0xa3, 0xf0, 0x24, 0x10, 0xae, 0x7c, 0x2d, 0xfd, 0x9e, 0x84, 0x20, 0x86, 0xd1, 0xbb, 0x99, 0x58, 0x5c, 0xa8, 0x49, 0xdf, 0xa4, 0xcb, 0xe5, 0x18, 0x5c, 0xf3, 0xfa, 0x12, 0xa8, 0xbe, 0x46, 0xf5, 0x51, 0x22, 0xa0, 0xf5, 0x61, 0x20, 0xfd, 0x66, 0x95, 0xaa, 0xb8, 0xb8, 0xf5, 0x8c, 0xed, 0x5b, 0x34, 0x1e, 0xd3, 0xf9, 0x41, 0x51, 0x3c, 0xe8, 0x61, 0x3f, 0x4f, 0x5a, 0x59, 0xf9, 0x46, 0xd7, 0x3d, 0xf0, 0x66, 0x41, 0xd3, 0xeb, 0xa4, 0x6e, 0x28, 0x7b, 0x90, 0xd0, 0xf4, 0x3e, 0xa0, 0x67, 0xec, 0x60, 0xbe, 0x29, 0x0c, 0x68, 0x62, 0x37, 0x3c, 0x59, 0xfa, 0xcb, 0xf4, 0x48, 0xd5, 0x51, 0x20, 0x96, 0xe3, 0xd7, 0x0b, 0xfa, 0x7e, 0x09, 0xcb, 0x28, 0x46, 0x92, 0x12, 0x44, 0x05, 0xc2, 0x01, 0xf2, 0xd5, 0x06, 0x6b, 0x00, 0x70, 0xc0, 0xd5, 0x4c, 0x39, 0x4d, 0xf6, 0x8b, 0xd9, 0xa7, 0xe8, 0x02, 0x16, 0x8e, 0x51, 0x42, 0x3c, 0x4a, 0x6e, 0xc8, 0x42, 0x69, 0xd8, 0x41, 0xac, 0x59, 0xbe, 0x44, 0x11, 0x45, 0x65, 0x90, 0xf7, 0xa6, 0x1f, 0x9b, 0xdc, 0xaa, 0x52, 0x2e, 0x0a, 0xe1, 0x2c, 0xa1, 0x16, 0xb1, 0x94, 0x88, 0x93, 0xdd, 0xaf, 0xd0, 0xc9, 0x2e, 0x19, 0x06, 0x92, 0xde, 0xad, 0x7b, 0x92, 0x8f, 0x5b, 0xb8, 0x36, 0x8a, 0x78, 0xbe, 0x05, 0x2c, 0x71, 0x01, 0x7f, 0xac, 0xaf, 0xe6, 0x24, 0x79, 0xd3, 0xd8, 0xeb, 0xf4, 0x53, 0x52, 0x31, 0xf6, 0x0f, 0x90, 0x29, 0x6a, 0xa2, 0x39, 0x88, 0x6a, 0x1e, 0xf4, 0x4b, 0x61, 0xf4, 0x76, 0x27, 0x17, 0x17, 0x12, 0xa6, 0x0e, 0x3d, 0xde, 0x1d, 0x04, 0x4d, 0x6d, 0x04, 0xac, 0x7e, 0xb4, 0xf5, 0x41, 0x72, 0x2e, 0x81, 0x50, 0x94, 0xb1, 0x80, 0xf5, 0xf0, 0x85, 0xee, 0x33, 0xc9, 0x6f, 0x32, 0x9f, 0x0d, 0x72, 0xae, 0x00, 0x93, 0xd9, 0xdd, 0x31, 0x86, 0x3c, 0x69, 0x69, 0x7a, 0xea, 0xf4, 0xb8, 0x2d, 0x77, 0x93, 0x05, 0x2d, 0x5e, 0x7c, 0xd8, 0x69, 0xd5, 0x66, 0xe2, 0x29, 0xd4, 0x56, 0xf3, 0xf4, 0x70, 0x65, 0xea, 0x04, 0x6b, 0xcd, 0x28, 0xfc, 0x0d, 0xd6, 0x71, 0x4d, 0x4c, 0x3b, 0x98, 0x44, 0x58, 0x31, 0x5b, 0xf9, 0x00, 0xb8, 0xd7, 0x46, 0x3f, 0xfa, 0xee, 0x5a, 0xb8, 0xf7, 0x58, 0x53, 0xa0, 0x76, 0x75, 0xdd, 0xd3, 0xdc, 0x1e, 0x4d, 0x68, 0xe8, 0x6b, 0x54, 0xe9, 0x84, 0x45, 0x44, 0x54, 0xd0, 0x67, 0xa7, 0xee, 0x64, 0x7f, 0x14, 0x16, 0x26, 0xcb, 0xc8, 0xc8, 0xf0, 0xd8, 0x39, 0xd5, 0xe1, 0x1a, 0xe8, 0x6d, 0x55, 0x2a, 0x70, 0x1e, 0x8f, 0xdd, 0x3c, 0x73, 0x74, 0x78, 0x03, 0x76, 0x27, 0x24, 0xe6, 0x38, 0xf2, 0x0c, 0x6a, 0x0d, 0xef, 0x67, 0x1f, 0x5b, 0x8c, 0xe0, 0x24, 0x4d, 0xe5, 0x6f, 0xce, 0xf6, 0xd3, 0x52, 0x81, 0x9c, 0xed, 0x8d, 0xb7, 0x9b, 0x9f, 0x60, 0x54, 0xd3, 0x46, 0x77, 0xde, 0xbc, 0x77, 0xd9, 0x62, 0x48, 0xe6, 0x55, 0xab, 0x6b, 0x23, 0xc8, 0x19, 0x3e, 0x33, 0xf5, 0xfd, 0xd3, 0xbe, 0x4a, 0xb8, 0xd2, 0xcc, 0xbb, 0x6a, 0x97, 0x42, 0x0d, 0xa2, 0x96, 0xd1, 0xea, 0x7e, 0x01, 0x00, 0x44, 0x29, 0x11, 0xbd, 0xf6, 0x07, 0xa4, 0x59, 0x6f, 0x9b, 0x36, 0x00, 0x46, 0x59, 0xff, 0x34, 0x92, 0x59, 0xf2, 0xcd, 0x11, 0xb0, 0x0d, 0x1e, 0xce, 0x89, 0x4f, 0xf8, 0x9d, 0x7a, 0xad, 0x0d, 0xfd, 0xfc, 0x04, 0xa1, 0x65, 0xb1, 0x7e, 0x90, 0xf9, 0x20, 0x46, 0xd1, 0x5b, 0x54, 0xb0, 0x18, 0x76, 0x91, 0xdc, 0x6d, 0x06, 0x76, 0xdb, 0x0b, 0xf0, 0xb3, 0x7f, 0x78, 0xcb, 0x76, 0x67, 0x09, 0x47, 0x3f, 0x50, 0x34, 0x0c, 0xd5, 0x77, 0xca, 0x99, 0x86, 0x9d, 0xed, 0xeb, 0x23, 0xb7, 0x52, 0xd7, 0xba, 0xe7, 0x52, 0x88, 0xab, 0x84, 0x6d, 0xdb, 0x55, 0xb4, 0x43, 0x46, 0xe9, 0xa6, 0x53, 0xaf, 0xc4, 0xce, 0x35, 0x96, 0xa7, 0x51, 0x27, 0x7b, 0x33, 0x3b, 0xe4, 0x27, 0x50, 0x58, 0xe8, 0x7e, 0xf9, 0x1a, 0xd1, 0xfe, 0x7b, 0xe5, 0xcf, 0xe6, 0xcf, 0xf1, 0xef, 0x97, 0x20, 0xea, 0x2c, 0x0f, 0x52, 0x04, 0xe5, 0xdc, 0x06, 0x43, 0x5f, 0x9f, 0x36, 0xa6, 0x0c, 0xcd, 0x98, 0x05, 0xce, 0x48, 0x04, 0x78, 0x9b, 0xf3, 0xcd, 0xa5, 0xdc, 0xbf, 0x02, 0x2c, 0xc2, 0xa0, 0x79, 0xcc, 0x93, 0xd5, 0x46, 0x5b, 0xaf, 0xeb, 0x19, 0x69, 0xe8, 0x4b, 0xff, 0xe7, 0xc7, 0xe3, 0x9a, 0xe1, 0x29, 0x16, 0x25, 0x09, 0x8b, 0x7a, 0xc2, 0x52, 0xc5, 0x9c, 0xde, 0x0e, 0xef, 0xab, 0xf3, 0xf3, 0x3e, 0x74, 0x60, 0x5c, 0x7c, 0x74, 0x6c, 0x6f, 0xf3, 0x9b, 0x37, 0xe6, 0x47, 0x84, 0xdb, 0x7c, 0x33, 0x03, 0xd8, 0xec, 0xac, 0x4c, 0x3c, 0x3c, 0x87, 0x3b, 0xbd, 0x0b, 0x00, 0xb9, 0xa4, 0x88, 0x73, 0x7f, 0xa4, 0x38, 0xe6, 0x5d, 0x26, 0x9d, 0xc5, 0x78, 0xa5, 0x20, 0xb7, 0xf5, 0x89, 0x51, 0x07, 0xff, 0x7e, 0x00, 0xe2, 0xb5, 0x5c, 0x94, 0x17, 0xe2, 0x3e, 0x09, 0x84, 0x62, 0x62, 0x97, 0x6b, 0xd6, 0xeb, 0x81, 0x03, 0x6f, 0x13, 0x65, 0xbc, 0xbc, 0x2e, 0xad, 0x9a, 0x73, 0x39, 0x3e, 0xef, 0x22, 0x77, 0xe9, 0x74, 0x61, 0xfa, 0xa2, 0xe5, 0x04, 0xab, 0xbb, 0x31, 0x2f, 0x55, 0x28, 0xd3, 0x61, 0x60, 0x62, 0x7e, 0xff, 0xf3, 0x87, 0x3d, 0x25, 0x35, 0x75, 0xe5, 0x34, 0x1a, 0x19, 0x7d, 0x00, 0x74, 0x97, 0xf7, 0x45, 0xbc, 0x7e, 0xd0, 0x21, 0x76, 0x64, 0xa9, 0xa5, 0x4d, 0x9c, 0x45, 0x49, 0x92, 0x89, 0x2a, 0xa8, 0x81, 0x4a, 0xf3, 0x8c, 0x72, 0xe1, 0x0b, 0xc4, 0x5d, 0x64, 0x24, 0x24, 0x9a, 0x1d, 0x01, 0xea, 0xd6, 0xbb, 0x75, 0x10, 0xcf, 0xe8, 0x09, 0xc4, 0xaf, 0x29, 0xa4, 0x65, 0xee, 0x37, 0x55, 0x61, 0xb6, 0xa4, 0x98, 0x90, 0x64, 0xc7, 0x87, 0x83, 0x61, 0x11, 0xe4, 0x86, 0x47, 0x5f, 0xdf, 0x79, 0x35, 0xd8, 0x27, 0x05, 0x72, 0x0e, 0x3d, 0x43, 0x26, 0xba, 0x44, 0x2e, 0x18, 0x8f, 0x77, 0x31, 0x69, 0xfb, 0x4b, 0xf2, 0x9b, 0x84, 0x81, 0x41, 0xae, 0x3e, 0xfb, 0x12, 0x02, 0xbc, 0xc9, 0x63, 0x71, 0xa2, 0x56, 0xd3, 0x16, 0x8d, 0xec, 0xde, 0x02, 0x06, 0xe6, 0x2f, 0x77, 0x3e, 0x66, 0x44, 0xc1, 0x35, 0x08, 0x98, 0x92, 0xd0, 0x1b, 0x4a, 0x64, 0xa7, 0xa4, 0x96, 0x1c, 0xe0, 0x44, 0xfd, 0x5a, 0xe2, 0x65, 0x69, 0x45, 0x49, 0x05, 0x83, 0x20, 0xb9, 0x10, 0x6e, 0x90, 0xc0, 0xc7, 0xb3, 0x53, 0x72, 0xf0, 0x20, 0xa2, 0x5b, 0xab, 0xc9, 0x87, 0x38, 0xee, 0x93, 0x7e, 0x03, 0xb1, 0x2a, 0xe2, 0xbb, 0x8d, 0xe7, 0xee, 0x1f, 0xac, 0xbb, 0xb7, 0x3d, 0x37, 0x3e, 0x72, 0xed, 0xce, 0xf2, 0x70, 0x60, 0x42, 0x1e, 0x44, 0xb6, 0x6f, 0x98, 0xc3, 0x2c, 0xf4, 0xdf, 0xd5, 0x71, 0x30, 0x09, 0xf2, 0xa5, 0x82, 0xa4, 0xec, 0x35, 0xbd, 0x0e, 0x9b, 0x5e, 0xd7, 0xcf, 0x57, 0x74, 0x5d, 0x59, 0x5d, 0x8c, 0x94, 0x42, 0xe1, 0x34, 0x03, 0x33, 0xb2, 0x44, 0xe4, 0xe4, 0xa6, 0x06, 0x47, 0xea, 0xd3, 0xb2, 0x07, 0xf9, 0x34, 0x59, 0xe0, 0x47, 0xf5, 0x36, 0xe3, 0x28, 0x17, 0xc4, 0xc3, 0xcc, 0x23, 0xe4, 0x0a, 0xbd, 0xcc, 0x3f, 0x9b, 0xae, 0xfa, 0xf2, 0xb2, 0xe4, 0x28, 0x7b, 0x3f, 0x8f, 0xed, 0x76, 0x17, 0x48, 0x97, 0x72, 0x1f, 0x2c, 0x75, 0x76, 0xea, 0x15, 0x60, 0x8a, 0x38, 0x71, 0x71, 0xe0, 0x57, 0x72, 0x9f, 0x86, 0x51, 0xb0, 0x0a, 0xbe, 0xdd, 0x7d, 0x3e, 0x98, 0xad, 0xa6, 0x31, 0xf0, 0xba, 0x93, 0x83, 0x5e, 0x8a, 0x01, 0x93, 0xcc, 0x4c, 0x7d, 0x64, 0x2b, 0x53, 0xa7, 0x87, 0xde, 0x1a, 0x54, 0x1d, 0x42, 0x87, 0xd9, 0x07, 0x98, 0x06, 0x51, 0x3b, 0xe3, 0xa4, 0xa6, 0x80, 0xfc, 0x6c, 0xf8, 0xd5, 0xe8, 0x69, 0xda, 0x3c, 0xed, 0x50, 0xc3, 0xa2, 0x77, 0x1d, 0x8b, 0x6d, 0x0a, 0x74, 0x96, 0x0c, 0xfd, 0x52, 0x46, 0x11, 0x43, 0x16, 0x32, 0x8f, 0xb7, 0xad, 0xfc, 0x50, 0x84, 0x30, 0x68, 0xd4, 0x55, 0xca, 0xf9, 0xb9, 0xeb, 0xb4, 0x98, 0x69, 0xdf, 0xd1, 0xb6, 0xfb, 0xc6, 0x6f, 0x17, 0xf4, 0xdc, 0x83, 0x8b, 0xd2, 0xa6, 0xa9, 0xba, 0x12, 0x21, 0x83, 0x92, 0xff, 0x4c, 0x36, 0x0c, 0xfd, 0xf4, 0xda, 0x88, 0x01, 0x59, 0xc3, 0xf3, 0xc7, 0xb9, 0x39, 0x36, 0x67, 0x79, 0xef, 0x76, 0x3b, 0x19, 0x10, 0x06, 0xdc, 0x63, 0xea, 0xc2, 0xb4, 0x7f, 0xb3, 0x0d, 0xc3, 0x5e, 0x60, 0xe7, 0xa8, 0xb1, 0x9a, 0xf9, 0xb4, 0xcd, 0x7b, 0xe9, 0x9f, 0x3f, 0xc1, 0xf9, 0xbd, 0xf8, 0xee, 0xa2, 0x86, 0x4c, 0x32, 0xc3, 0xed, 0x77, 0x28, 0xff, 0xbb, 0x0b, 0x90, 0xca, 0xf8, 0xb3, 0x58, 0x5e, 0x0c, 0xf1, 0x61, 0xda, 0xb9, 0x03, 0x22, 0x13, 0xf7, 0x37, 0x5e, 0xb3, 0x2d, 0xba, 0xb0, 0x9b, 0x19, 0xe8, 0x3f, 0x0f, 0x8c, 0xa7, 0xed, 0xef, 0xcc, 0xa6, 0xca, 0x0b, 0xb2, 0x9b, 0x7f, 0x00, 0x93, 0xf9, 0x57, 0xda, 0x93, 0xd3, 0xb8, 0x6e, 0x4e, 0xd7, 0x29, 0xb8, 0x96, 0xb2, 0x89, 0x29, 0xff, 0x8c, 0x34, 0x29, 0x8f, 0x2e, 0x92, 0x51, 0x50, 0x16, 0xff, 0xc4, 0x33, 0xff, 0x7b, 0x25, 0x85, 0x26, 0x88, 0x1e, 0xe8, 0xfc, 0x0c, 0xda, 0xfd, 0xf0, 0xdc, 0x71, 0x81, 0xce, 0x27, 0x4e, 0x25, 0x2c, 0x6f, 0x68, 0x21, 0x21, 0x3e, 0xa7, 0x25, 0xf8, 0x34, 0x4c, 0x2d, 0xc8, 0x67, 0xfa, 0x8e, 0xe9, 0xe5, 0x52, 0x2c, 0x07, 0x48, 0x23, 0x7a, 0x5a, 0x2b, 0xa8, 0x9c, 0xf4, 0xe1, 0x1b, 0xc2, 0x17, 0x9b, 0xf7, 0x19, 0xe2, 0x97, 0x84, 0x9c, 0x9f, 0xe3, 0xd6, 0x94, 0x9d, 0x2f, 0x30, 0x43, 0xc4, 0x31, 0x69, 0x5c, 0x0c, 0xb8, 0x07, 0x9d, 0x37, 0x23, 0xeb, 0xd3, 0x58, 0x1d, 0xb4, 0xc8, 0x33, 0x3f, 0x48, 0xac, 0xd1, 0xaa, 0x11, 0x87, 0x3a, 0x7f, 0x79, 0xca, 0xf7, 0x1d, 0x5a, 0x6c, 0x90, 0x98, 0x95, 0x2e, 0x4f, 0x41, 0x3e, 0x11, 0xc9, 0x0c, 0xfd, 0xbd, 0x16, 0x2c, 0x5b, 0x34, 0x3a, 0x3b, 0x3c, 0x6c, 0x5d, 0x43, 0xfc, 0x21, 0xd2, 0x6d, 0xac, 0x13, 0xed, 0x00, 0x39, 0x67, 0x4d, 0xed, 0xe9, 0x56, 0xc9, 0x1f, 0xa1, 0xac, 0x86, 0x37, 0x2e, 0x8d, 0x30, 0xc6, 0xeb, 0x72, 0x21, 0xfe, 0x9b, 0x72, 0x71, 0xf2, 0x47, 0x46, 0xf1, 0xaf, 0xb0, 0xb8, 0x24, 0x66, 0x9b, 0x23, 0xdf, 0x30, 0xde, 0xdd, 0xe1, 0xe0, 0xf8, 0x29, 0xd8, 0x4e, 0x1f, 0x47, 0x60, 0xf1, 0xb7, 0x96, 0x73, 0x58, 0x6e, 0xb0, 0xb2, 0xe3, 0x35, 0x0d, 0x2f, 0x74, 0x35, 0x5c, 0x33, 0xfa, 0xdd, 0xf6, 0xf9, 0x28, 0xfd, 0x90, 0x40, 0xbc, 0xf8, 0x9c, 0xa9, 0xef, 0x22, 0xbd, 0x85, 0x42, 0x57, 0x90, 0x6c, 0xf3, 0xad, 0x32, 0x8b, 0x19, 0x27, 0x74, 0x7a, 0xa7, 0xfa, 0xb6, 0x6a, 0xa3, 0x01, 0x7f, 0x48, 0xb1, 0xd4, 0x8b, 0x9f, 0x5a, 0x3c, 0x22, 0x7e, 0x6b, 0xad, 0x38, 0x51, 0x00, 0xc1, 0x50, 0x14, 0x29, 0x47, 0x2d, 0x7a, 0x24, 0xc5, 0xca, 0x9c, 0x11, 0x8c, 0x34, 0xa8, 0xa6, 0x58, 0x02, 0x92, 0x90, 0xe9, 0x8d, 0xba, 0x11, 0xd8, 0x45, 0x8c, 0xc6, 0x00, 0xc1, 0xaa, 0x55, 0xe0, 0xf9, 0xee, 0xc6, 0xf5, 0xe0, 0x43, 0x4c, 0xb3, 0x40, 0x1b, 0x35, 0xf2, 0xfe, 0x7b, 0xd9, 0x5b, 0xeb, 0x6a, 0xf3, 0xd3, 0x96, 0x8c, 0xd9, 0x3e, 0xae, 0x0f, 0xb4, 0x17, 0x74, 0x8c, 0x81, 0x6c, 0x4a, 0x97, 0xa1, 0xff, 0x06, 0x22, 0xfa, 0x56, 0x4e, 0xd4, 0x09, 0x80, 0xa3, 0xe6, 0x8f, 0xcb, 0x1a, 0xc7, 0xf3, 0x7b, 0xed, 0x73, 0x74, 0x09, 0x95, 0x40, 0xb4, 0xde, 0x92, 0xa8, 0xe3, 0x95, 0x00, 0x13, 0xf8, 0x41, 0xf2, 0xbc, 0xca, 0x47, 0x8b, 0x2b, 0x99, 0x22, 0xa9, 0xb9, 0x13, 0x24, 0x51, 0x27, 0x1b, 0xc9, 0x46, 0x07, 0x60, 0x80, 0x5e, 0xd7, 0xcf, 0x8f, 0xd2, 0x5a, 0xa1, 0x09, 0x08, 0xa1, 0x3f, 0xdb, 0x16, 0xd1, 0x65, 0x0f, 0x8a, 0x07, 0xe5, 0x7f, 0xa1, 0xfc, 0x48, 0x19, 0x5d, 0x36, 0x8f, 0xdb, 0x29, 0xa4, 0x33, 0x7e, 0x12, 0x2e, 0x8d, 0xf6, 0x14, 0x47, 0xac, 0xc3, 0xae, 0x40, 0x6d, 0x00, 0x5a, 0xc8, 0x63, 0x33, 0xa9, 0xd2, 0x09, 0x87, 0x61, 0xf1, 0x97, 0xe3, 0x0e, 0xf6, 0xee, 0xb3, 0xfe, 0x72, 0xb7, 0xc9, 0x68, 0x78, 0x88, 0xef, 0xc3, 0xa0, 0x91, 0x89, 0x4b, 0x40, 0xa4, 0x44, 0xc5, 0xd9, 0x0f, 0x8f, 0x24, 0x9a, 0x30, 0xca, 0x3c, 0x34, 0x90, 0x4e, 0x99, 0x96, 0xa9, 0xd2, 0x62, 0xb4, 0x94, 0x83, 0xb0, 0x94, 0x7a, 0x18, 0x0b, 0x9e, 0xe3, 0x97, 0xb5, 0x12, 0x37, 0x3b, 0xa0, 0xaf, 0x7c, 0x75, 0x2d, 0xa4, 0x1d, 0xd6, 0x98, 0xed, 0xe6, 0x2b, 0x47, 0xf2, 0xda, 0x37, 0x4e, 0x37, 0x68, 0xbb, 0x0c, 0xf9, 0x91, 0x2c, 0xc0, 0x29, 0x4f, 0xdc, 0x8e, 0x21, 0xf3, 0x26, 0xe2, 0xb7, 0xe2, 0x4a, 0x37, 0xf1, 0xaf, 0xee, 0xf0, 0x01, 0x3e, 0x20, 0x09, 0xcb, 0xd6, 0x10, 0xab, 0x73, 0xc8, 0xb4, 0xf8, 0xa3, 0x7c, 0xf0, 0x94, 0x77, 0x35, 0xc9, 0x5a, 0xbd, 0xf8, 0x60, 0x4b, 0xa7, 0x4a, 0x47, 0x70, 0xd0, 0x29, 0x8b, 0x8d, 0x8d, 0x11, 0xd1, 0xc0, 0x9d, 0x3a, 0x60, 0xba, 0xff, 0xa6, 0x25, 0x6d, 0x5d, 0x42, 0xaf, 0x3e, 0x1e, 0x1f, 0x57, 0x14, 0x48, 0x26, 0x97, 0xf4, 0x91, 0x00, 0xb2, 0x50, 0x4e, 0x34, 0x1f, 0x9b, 0x67, 0xf1, 0x76, 0x82, 0xca, 0xb5, 0x9a, 0x8c, 0xfc, 0x20, 0xb4, 0x53, 0xc5, 0x12, 0x2f, 0xfa, 0x52, 0x9d, 0x62, 0xda, 0xa1, 0x73, 0x75, 0x14, 0xb5, 0xbd, 0x80, 0xa5, 0x68, 0x50, 0x26, 0x14, 0xc3, 0x37, 0xa9, 0x9f, 0x14, 0xbc, 0xc5, 0x76, 0x70, 0x73, 0x88, 0xd0, 0x0a, 0xba, 0xa0, 0x49, 0x99, 0x8e, 0x24, 0xd6, 0xfb, 0x6c, 0xcc, 0x78, 0x7e, 0x3c, 0xfa, 0x11, 0x7e, 0x80, 0xff, 0x84, 0xcf, 0x4f, 0xb6, 0x3a, 0x08, 0x91, 0xd2, 0xa0, 0xa2, 0x58, 0x2d, 0x5e, 0xc5, 0x7f, 0xf7, 0x99, 0x29, 0x1d, 0xf6, 0x1d, 0xd1, 0x4c, 0x31, 0x31, 0x4f, 0x7e, 0xa8, 0xe2, 0x9a, 0x78, 0x25, 0xe9, 0x2d, 0x19, 0x86, 0xd9, 0x52, 0x81, 0xf9, 0xcd, 0x9e, 0xff, 0xd6, 0x5a, 0xf9, 0xb5, 0x00, 0x65, 0x7f, 0x7c, 0xd8, 0x0f, 0x9b, 0x19, 0x3a, 0xfe, 0x8e, 0xd9, 0x08, 0x50, 0xe1, 0x8c, 0xd7, 0x30, 0xa3, 0xae, 0xa8, 0x70, 0x28, 0x16, 0xbf, 0x33, 0x4a, 0x8e, 0x83, 0x3a, 0x92, 0xa9, 0x58, 0x8d, 0x3a, 0x99, 0x80, 0x9b, 0x20, 0xa1, 0xa5, 0x6a, 0xf5, 0x28, 0x2e, 0x16, 0x65, 0xbf, 0x1c, 0x3c, 0xbc, 0x9a, 0x81, 0x0b, 0xb3, 0x0a, 0x36, 0x22, 0x4f, 0x01, 0xa4, 0x3f, 0x5a, 0xde, 0xfb, 0xef, 0x8d, 0xa2, 0xd3, 0xbb, 0xa3, 0xa6, 0xed, 0x68, 0x2d, 0x27, 0x2d, 0xb2, 0x88, 0x94, 0x81, 0xdf, 0x24, 0x86, 0x49, 0xbf, 0xd7, 0x40, 0x07, 0xfb, 0xd5, 0xe0, 0x56, 0x20, 0x56, 0xe5, 0x70, 0x21, 0xbf, 0x5b, 0x17, 0xdb, 0x8e, 0xf6, 0xa5, 0x10, 0xba, 0x1b, 0x2f, 0x2b, 0x4f, 0x2b, 0x57, 0xc2, 0x64, 0xeb, 0x95, 0xfa, 0x3e, 0x89, 0x08, 0xda, 0x41, 0x14, 0xdb, 0x84, 0x63, 0x30, 0x86, 0x96, 0x72, 0x5d, 0x4e, 0x6e, 0x46, 0x34, 0x44, 0x30, 0xb9, 0x84, 0x43, 0x9c, 0x90, 0x3d, 0xf8, 0x2f, 0xbd, 0xfd, 0xe7, 0x32, 0xf1, 0xec, 0x2c, 0x88, 0x03, 0x39, 0x98, 0xb3, 0x93, 0x36, 0xbf, 0xeb, 0x21, 0xd7, 0x20, 0x7b, 0x72, 0x3e, 0x45, 0x6b, 0xed, 0xa5, 0x0c, 0xf5, 0x2a, 0x00, 0xe7, 0xe8, 0x68, 0xae, 0x26, 0xb1, 0x9b, 0xa1, 0xf4, 0x0f, 0x41, 0x5b, 0xe0, 0x63, 0xce, 0xdc, 0x75, 0x07, 0x63, 0xf8, 0x14, 0x9a, 0x3c, 0xfd, 0xbd, 0x30, 0xa3, 0x87, 0x97, 0x43, 0xac, 0xfb, 0x56, 0xa9, 0xe6, 0xf2, 0x63, 0x2b, 0x99, 0xae, 0x00, 0xbb, 0x79, 0x6c, 0x6a, 0xd3, 0x0a, 0x41, 0x7c, 0x5f, 0xc3, 0x2e, 0xed, 0xe0, 0x9a, 0xd7, 0x8d, 0x4a, 0x1b, 0xba, 0x13, 0x6d, 0x40, 0xfd, 0xa9, 0xbb, 0xec, 0xd2, 0x22, 0x58, 0xcf, 0xf9, 0x9e, 0x08, 0xe2, 0x3e, 0x06, 0x70, 0xef, 0x3f, 0xd9, 0xc1, 0xcd, 0x37, 0xed, 0xd2, 0x45, 0x5a, 0xaa, 0x38, 0xb8, 0xf1, 0x52, 0xf6, 0x3b, 0xd6, 0x05, 0x6d, 0x74, 0xe2, 0x33, 0xec, 0xc6, 0xf5, 0x42, 0x9d, 0xf8, 0x46, 0xbc, 0x14, 0x68, 0x8a, 0x19, 0x1a, 0x74, 0x83, 0x0b, 0x14, 0x78, 0x13, 0x14, 0x93, 0xb4, 0x40, 0xa4, 0xdc, 0xca, 0xfe, 0x78, 0x63, 0xa3, 0x51, 0x82, 0xe9, 0xfa, 0xaf, 0x5c, 0xf5, 0xea, 0x2c, 0x85, 0x89, 0x82, 0x5c, 0x1c, 0x29, 0x67, 0x9e, 0x78, 0x12, 0x36, 0x4d, 0xb3, 0x43, 0x51, 0xa6, 0x3d, 0x1c, 0xc5, 0x9a, 0xf3, 0x2e, 0x0c, 0x23, 0x70, 0x88, 0xe0, 0x4b, 0xf5, 0x0b, 0x93, 0x67, 0xfa, 0xc4, 0xe1, 0x84, 0x39, 0xf2, 0x50, 0x29, 0xb4, 0x2f, 0xa9, 0xa2, 0x48, 0x20, 0x4c, 0xd9, 0x15, 0x4c, 0x10, 0xac, 0xd7, 0xd1, 0x4d, 0xfc, 0x37, 0x15, 0x1d, 0x5a, 0xe8, 0xce, 0x35, 0x1f, 0x6e, 0x6a, 0x4a, 0xaf, 0x0d, 0xee, 0xe9, 0x20, 0x2f, 0x0f, 0x57, 0xf2, 0x67, 0x92, 0xbc, 0xff, 0x7a, 0x2b, 0x62, 0x9b, 0x19, 0x4f, 0x9f, 0x6d, 0xb2, 0x50, 0xd0, 0xd4, 0x41, 0xf0, 0x28, 0xe2, 0xc1, 0x10, 0xff, 0x3f, 0x9a, 0xbe, 0x3a, 0x20, 0xaa, 0xe7, 0x7b, 0x7b, 0x01, 0x69, 0x84, 0xa5, 0x3b, 0x56, 0x52, 0xa5, 0xa5, 0xbb, 0xa4, 0x45, 0x96, 0x92, 0x06, 0x59, 0x5a, 0xa4, 0x96, 0x96, 0x12, 0x97, 0x90, 0x0e, 0x49, 0x97, 0x06, 0x91, 0x2e, 0xe9, 0xee, 0x92, 0x12, 0x90, 0x6e, 0x49, 0xe9, 0x96, 0x7c, 0xef, 0x7e, 0xbe, 0xbf, 0x97, 0x7f, 0x77, 0x38, 0x73, 0xe6, 0x9c, 0xe7, 0x3c, 0xf3, 0x9c, 0xb9, 0xbb, 0x77, 0x7c, 0x19, 0x60, 0x23, 0x6d, 0x98, 0x64, 0xe1, 0x4c, 0x45, 0x14, 0x5b, 0x58, 0x00, 0x0c, 0x5b, 0x2c, 0xd4, 0xe1, 0x3f, 0xd6, 0x6a, 0x14, 0x4b, 0xe5, 0x34, 0x35, 0x03, 0x51, 0x87, 0x4c, 0x96, 0x14, 0x14, 0x24, 0x04, 0xf9, 0x5a, 0x6f, 0x85, 0xd9, 0xc2, 0x43, 0xb4, 0x52, 0x3b, 0x8f, 0x9f, 0xa2, 0x06, 0xad, 0x19, 0x7b, 0x67, 0xad, 0xb9, 0x57, 0x6a, 0xc4, 0xec, 0x19, 0xef, 0x76, 0xc9, 0x84, 0xb5, 0x45, 0xe0, 0xe0, 0xbb, 0x50, 0xc5, 0xd9, 0x6a, 0x21, 0x69, 0x51, 0xfe, 0x3c, 0xe3, 0xf8, 0xbe, 0x4f, 0x2d, 0xf3, 0xb6, 0x74, 0xa6, 0x35, 0x2d, 0xf5, 0x39, 0xea, 0x80, 0x94, 0x67, 0xac, 0xc1, 0x44, 0x2d, 0x94, 0x38, 0xce, 0xb1, 0xa1, 0x09, 0x05, 0xd3, 0xf2, 0xb3, 0xeb, 0x3b, 0xef, 0xc0, 0x35, 0xb9, 0x9e, 0x8b, 0xfc, 0xe7, 0xa9, 0xae, 0x21, 0xf2, 0x38, 0xc7, 0xe8, 0xe3, 0xc4, 0xd9, 0x1e, 0xf3, 0x41, 0x60, 0x24, 0xcf, 0xff, 0x0a, 0xeb, 0x18, 0x94, 0x5d, 0xbf, 0x36, 0xb5, 0xd4, 0x55, 0xb0, 0x41, 0x80, 0x00, 0xaf, 0x05, 0x8b, 0xd8, 0x34, 0xfd, 0xf9, 0x5f, 0xf1, 0x67, 0xc4, 0xea, 0x1f, 0xaf, 0x6d, 0xef, 0xe0, 0x73, 0xbc, 0xd0, 0x84, 0xb3, 0xca, 0xdd, 0x1a, 0xa8, 0x14, 0x76, 0x38, 0x7e, 0x85, 0xfb, 0x51, 0xa6, 0xca, 0xa1, 0x1c, 0xfb, 0x8c, 0xcd, 0x6b, 0xd2, 0xf3, 0x3c, 0x77, 0x20, 0xf2, 0x4e, 0x69, 0xb4, 0x9f, 0x9a, 0x00, 0xa2, 0x60, 0x2d, 0xd6, 0xa2, 0x2d, 0x89, 0xb7, 0xfb, 0x7b, 0xed, 0xbf, 0xa5, 0x69, 0x73, 0xc8, 0x8d, 0xe8, 0x2e, 0x99, 0xb6, 0xdd, 0xc9, 0xe8, 0x86, 0x92, 0xc8, 0xdd, 0xca, 0x28, 0x3b, 0xc7, 0x2e, 0xd6, 0x6a, 0x51, 0xaf, 0x89, 0xec, 0xa7, 0x4f, 0xa2, 0xb3, 0xba, 0xad, 0xa1, 0x15, 0x45, 0x24, 0xd6, 0x5d, 0xd0, 0x49, 0x05, 0xff, 0x38, 0x73, 0x68, 0x08, 0x82, 0x20, 0xfa, 0x39, 0x75, 0x68, 0x6d, 0xeb, 0x86, 0x1b, 0xdc, 0xb2, 0xc3, 0xe5, 0x55, 0x1e, 0xa3, 0x56, 0xc6, 0xcd, 0x92, 0xb7, 0x0c, 0x95, 0x79, 0xdb, 0xd4, 0xc7, 0xa6, 0x42, 0x37, 0x7f, 0x41, 0x9f, 0xf0, 0x02, 0x60, 0x1e, 0xca, 0x38, 0x16, 0x28, 0xb3, 0x27, 0x41, 0x6b, 0x20, 0xc0, 0x07, 0x9e, 0x2f, 0x5f, 0x16, 0xab, 0xa1, 0xe5, 0x2f, 0xfa, 0xd4, 0x00, 0xfd, 0xe0, 0x47, 0x85, 0xc5, 0x69, 0x9c, 0x63, 0x35, 0xb6, 0xea, 0x29, 0xc0, 0x45, 0x58, 0xe6, 0xef, 0xd2, 0xe5, 0x6c, 0x5f, 0x1d, 0xa5, 0x33, 0x4a, 0x65, 0x09, 0x05, 0x11, 0x63, 0xef, 0xbf, 0x72, 0xbb, 0x82, 0x74, 0x92, 0x2f, 0x3d, 0x67, 0x71, 0x8e, 0x95, 0x68, 0x6a, 0x60, 0x37, 0xf0, 0xb2, 0x91, 0xfe, 0x19, 0x65, 0xf7, 0x6c, 0x14, 0x97, 0x1e, 0x83, 0x33, 0xf6, 0x44, 0xaa, 0x4e, 0x47, 0xd7, 0x5d, 0x1f, 0xc9, 0xe1, 0xc4, 0x19, 0xc8, 0x56, 0xc2, 0x76, 0x3c, 0x56, 0x9b, 0x3b, 0x2a, 0x62, 0x0c, 0xf9, 0x7e, 0x13, 0x03, 0x8e, 0x12, 0x07, 0x65, 0x0d, 0xbb, 0xd2, 0xcd, 0xfb, 0x1d, 0xb1, 0x28, 0xa8, 0xc4, 0x33, 0xd3, 0xc9, 0x85, 0x45, 0x12, 0x28, 0xf6, 0x19, 0x92, 0x2d, 0xec, 0x9e, 0xc8, 0x68, 0x31, 0x03, 0x61, 0x50, 0xe2, 0xa5, 0x70, 0xed, 0x77, 0xd9, 0x33, 0xd4, 0x63, 0xf0, 0x60, 0x14, 0x79, 0xaa, 0x04, 0x64, 0x80, 0x7a, 0x83, 0x32, 0xa9, 0x9f, 0x3e, 0xe8, 0x75, 0x0e, 0x42, 0x43, 0x42, 0x8e, 0xcc, 0x3b, 0xba, 0xf8, 0x78, 0xff, 0x86, 0xd4, 0xe4, 0x31, 0xa9, 0x9c, 0xaf, 0x7e, 0x75, 0x3d, 0x55, 0xd3, 0xfb, 0x5e, 0xf4, 0xd1, 0x21, 0xb2, 0xf0, 0xd7, 0x40, 0x01, 0x49, 0x3c, 0x61, 0xb3, 0x76, 0x66, 0xc8, 0x12, 0x12, 0x8f, 0x66, 0x94, 0xf2, 0x26, 0x54, 0x4c, 0x98, 0xe0, 0x85, 0x74, 0x2b, 0xb9, 0x8c, 0x40, 0xff, 0xdc, 0x12, 0xf8, 0xd5, 0x71, 0x76, 0x5c, 0x51, 0xa9, 0x6e, 0x77, 0x33, 0xbb, 0xc2, 0x93, 0x53, 0x41, 0xab, 0x61, 0xeb, 0x5e, 0x1a, 0xa6, 0xc4, 0x42, 0xfb, 0x62, 0x7b, 0xbb, 0x5c, 0x08, 0x30, 0xa3, 0x8e, 0xa1, 0xb5, 0x5b, 0x65, 0x27, 0x6b, 0x20, 0x9e, 0x76, 0x3d, 0x90, 0xe5, 0x35, 0xd9, 0xf8, 0x21, 0xec, 0xcd, 0x26, 0xc2, 0x8c, 0x23, 0x37, 0x26, 0x04, 0x38, 0x95, 0xea, 0x95, 0x75, 0xc1, 0x40, 0x45, 0x10, 0x93, 0xed, 0xff, 0x81, 0x96, 0xa1, 0x2b, 0x65, 0xee, 0x58, 0x8a, 0x16, 0xb4, 0xb2, 0x17, 0xfc, 0x7c, 0x45, 0xc7, 0x32, 0x04, 0xdc, 0x06, 0xce, 0x82, 0xca, 0x43, 0x66, 0x0a, 0x18, 0x7a, 0x83, 0x4c, 0x46, 0x2a, 0x21, 0x82, 0xf2, 0xb8, 0xe9, 0x5e, 0x91, 0x86, 0x8b, 0x5e, 0x99, 0xc5, 0xc7, 0xc8, 0xdb, 0x27, 0x45, 0xfb, 0x1a, 0x61, 0x99, 0x60, 0x2a, 0x0c, 0xd8, 0x4f, 0x47, 0x75, 0xb2, 0xd3, 0xeb, 0x41, 0xb2, 0xe8, 0xff, 0x7c, 0xed, 0xb5, 0x7f, 0xbc, 0x8c, 0xcd, 0x9b, 0x7c, 0x73, 0xc1, 0xa8, 0x76, 0xe2, 0x2c, 0x00, 0x60, 0x9e, 0x4e, 0xd2, 0x0f, 0x4d, 0x0f, 0xea, 0x46, 0x25, 0xf8, 0x3a, 0x91, 0x95, 0x8a, 0x11, 0x65, 0x43, 0xdd, 0xd6, 0x36, 0x99, 0xa4, 0x17, 0x1d, 0xdf, 0x64, 0x5f, 0xad, 0x65, 0x57, 0xc7, 0x33, 0x04, 0xbc, 0xf6, 0x29, 0xe8, 0x13, 0xf2, 0x79, 0x33, 0x3f, 0x45, 0x5e, 0x02, 0x84, 0x2c, 0xf3, 0xbf, 0x21, 0x6f, 0x57, 0x49, 0x48, 0xb7, 0x3a, 0xb7, 0xca, 0x2e, 0x4c, 0x94, 0x5f, 0x5d, 0xba, 0xa1, 0xc2, 0xe5, 0x76, 0x38, 0x46, 0xf3, 0x2c, 0xd1, 0x8f, 0xcb, 0xb3, 0xa6, 0xb1, 0x6f, 0x9e, 0x3f, 0x78, 0x5d, 0x1b, 0xa8, 0xfb, 0x18, 0xad, 0x67, 0xb0, 0xe9, 0x06, 0x9a, 0xd7, 0x6a, 0xa3, 0x1e, 0x2e, 0xb4, 0xd1, 0xe0, 0xb5, 0x77, 0xbf, 0xaa, 0x4f, 0xcc, 0x6b, 0xe6, 0xde, 0xf8, 0xd4, 0x18, 0x8e, 0x7a, 0xc4, 0xff, 0xaf, 0xc2, 0xbc, 0xbe, 0x30, 0x3d, 0x62, 0xb4, 0xe6, 0xe4, 0x9d, 0x70, 0x69, 0xd6, 0x2f, 0x50, 0xf2, 0x28, 0x1b, 0x6a, 0x3a, 0x06, 0x22, 0xe3, 0xba, 0xe9, 0x4b, 0xb3, 0x47, 0x59, 0x83, 0x83, 0x83, 0xff, 0xb7, 0x55, 0xbb, 0xcc, 0xcb, 0x17, 0x17, 0x08, 0x0f, 0x14, 0xd8, 0x82, 0xe2, 0xe0, 0xb5, 0x0b, 0x53, 0xad, 0xdd, 0x79, 0x11, 0x19, 0x84, 0xa1, 0xe0, 0xb5, 0xb7, 0xa9, 0xa2, 0x98, 0x84, 0xcc, 0x24, 0xe1, 0xe1, 0x24, 0xf3, 0xfd, 0x24, 0x91, 0x31, 0xa8, 0xf5, 0x69, 0x64, 0x87, 0x39, 0x1b, 0x6c, 0x1e, 0x2f, 0xf4, 0x14, 0x67, 0x10, 0x06, 0x03, 0x23, 0xde, 0xf0, 0xd3, 0x25, 0x7f, 0x7f, 0x76, 0x86, 0x86, 0x56, 0x67, 0x1a, 0xff, 0x7f, 0xeb, 0x43, 0xca, 0x11, 0x37, 0xd0, 0x6b, 0x8a, 0x9c, 0x4b, 0x49, 0xbd, 0x26, 0x5d, 0xc7, 0x39, 0xb6, 0x8b, 0xef, 0x76, 0xd9, 0x53, 0x0f, 0xef, 0xb2, 0x3d, 0xd2, 0x6a, 0xb9, 0xb7, 0xb9, 0xee, 0x3b, 0x04, 0x90, 0xff, 0xb9, 0x2f, 0x75, 0xb8, 0xe0, 0x0c, 0xef, 0xe5, 0x36, 0x5b, 0xdf, 0xf1, 0xba, 0x0a, 0x25, 0xaa, 0xa7, 0x21, 0x06, 0x98, 0x17, 0x63, 0xc4, 0xa4, 0x31, 0xbc, 0x98, 0xba, 0xc1, 0x03, 0x16, 0x89, 0xeb, 0xf6, 0x6e, 0xe4, 0x15, 0xb0, 0x44, 0x83, 0xb0, 0x9c, 0x13, 0xf9, 0x3e, 0xbe, 0x84, 0xd9, 0x20, 0x85, 0x02, 0xa7, 0x43, 0x04, 0xd8, 0x0c, 0xaa, 0x55, 0xe4, 0x49, 0x05, 0xa5, 0x22, 0x0f, 0x8f, 0x1e, 0xb2, 0xc4, 0xed, 0xc5, 0x86, 0xca, 0xb1, 0xf3, 0xe3, 0x36, 0xae, 0x15, 0xd9, 0x2f, 0x64, 0x74, 0x15, 0x58, 0x86, 0x01, 0x2e, 0xe1, 0x5a, 0x61, 0xf5, 0xe9, 0x0d, 0xa8, 0xe6, 0x4e, 0x35, 0x66, 0x3a, 0xd6, 0x35, 0x01, 0x0b, 0x7b, 0x12, 0x11, 0x1b, 0x6b, 0xca, 0x1a, 0x59, 0x98, 0x9e, 0x91, 0xeb, 0x74, 0xbf, 0xce, 0x41, 0xa0, 0x98, 0x40, 0x07, 0x21, 0x96, 0xdb, 0x35, 0x78, 0x5b, 0x09, 0x93, 0x15, 0xe1, 0xdb, 0xbb, 0xbf, 0x79, 0xac, 0x9a, 0x8c, 0x9d, 0x40, 0x93, 0x8b, 0xd0, 0xb0, 0xcc, 0x9e, 0x28, 0xfd, 0x0d, 0x2f, 0xbb, 0x05, 0x62, 0xf5, 0x3d, 0x8f, 0x0c, 0x68, 0x56, 0x50, 0x5e, 0xe5, 0x65, 0x6c, 0x50, 0x8a, 0xb2, 0xb9, 0x75, 0x18, 0x6a, 0x9a, 0xeb, 0x01, 0x51, 0x20, 0x02, 0x00, 0x6b, 0xd9, 0x95, 0xd2, 0x69, 0xc5, 0x7c, 0xc6, 0xdf, 0x28, 0xc7, 0xde, 0xcd, 0xbe, 0xf1, 0x67, 0x9e, 0x32, 0xc6, 0x42, 0xdd, 0xfb, 0xcf, 0xe5, 0x72, 0xd7, 0x36, 0x63, 0x33, 0x8a, 0xcf, 0xab, 0x56, 0x8d, 0x9b, 0x37, 0xed, 0x17, 0x2c, 0xab, 0xbc, 0xc4, 0xc8, 0xe4, 0xc2, 0xb0, 0x45, 0x84, 0xde, 0x5a, 0x70, 0xba, 0xb5, 0xa8, 0x67, 0x5f, 0xb1, 0xa8, 0x6e, 0x2b, 0x08, 0xa9, 0x5a, 0xd5, 0x0f, 0x59, 0x90, 0xfc, 0x60, 0x48, 0x07, 0x2f, 0xbb, 0xed, 0x84, 0xfb, 0x4d, 0xd9, 0x8c, 0x0c, 0xbb, 0xb9, 0x1f, 0x28, 0x02, 0x51, 0x71, 0xa0, 0x9a, 0xc8, 0xf0, 0x10, 0x9c, 0xf0, 0xdb, 0xca, 0x64, 0x37, 0x77, 0xb1, 0x5d, 0x92, 0xc1, 0x39, 0x96, 0x44, 0x26, 0xd7, 0x26, 0x03, 0x52, 0x04, 0x48, 0x64, 0x3f, 0x1b, 0x53, 0xd6, 0x38, 0xab, 0x2c, 0x8e, 0x6b, 0xe3, 0x7e, 0x46, 0xfa, 0x9b, 0xb0, 0x89, 0xad, 0x5f, 0x96, 0x61, 0x61, 0x60, 0x2d, 0x33, 0x05, 0x95, 0xa0, 0x29, 0xfb, 0x65, 0x28, 0x14, 0x1c, 0x94, 0x4e, 0x23, 0x18, 0x37, 0x87, 0x5a, 0x46, 0xee, 0xc4, 0x7e, 0x1c, 0x8b, 0x8a, 0xf3, 0xac, 0x46, 0xcd, 0x8f, 0x9f, 0x2b, 0x3b, 0xce, 0x38, 0x90, 0xf3, 0xef, 0x15, 0xfa, 0xd8, 0xe9, 0x4b, 0xfe, 0xf9, 0x45, 0x2c, 0xb8, 0xf3, 0x00, 0xde, 0xd9, 0x81, 0xb0, 0x55, 0x59, 0x44, 0x92, 0x37, 0xd1, 0x38, 0x91, 0x90, 0xee, 0xec, 0x68, 0x02, 0x23, 0xfa, 0x6d, 0x05, 0xc4, 0x7f, 0xbc, 0xc2, 0x7c, 0x24, 0x5b, 0x9a, 0xc4, 0x4e, 0xb3, 0xac, 0x00, 0xcc, 0xa7, 0xde, 0x32, 0x35, 0xf5, 0x5d, 0x4e, 0x45, 0x4d, 0x1b, 0xf7, 0x98, 0xf5, 0x59, 0x3e, 0xc9, 0x4f, 0xbb, 0xc1, 0x48, 0x41, 0x85, 0x68, 0x7d, 0x5f, 0x72, 0x20, 0xa4, 0xcf, 0x47, 0xa6, 0xa8, 0xcb, 0x7a, 0xab, 0xe1, 0xf8, 0xa8, 0x8a, 0xa5, 0xf9, 0xfe, 0x89, 0x3d, 0x9e, 0xbe, 0x6c, 0x4c, 0x70, 0xb3, 0xbf, 0xdf, 0xf4, 0xe6, 0x4f, 0x78, 0x1f, 0x25, 0xca, 0x3c, 0x1e, 0xd1, 0x61, 0x3a, 0xda, 0xf7, 0xfa, 0xf5, 0x7a, 0xc3, 0x7c, 0x14, 0x23, 0x28, 0x4b, 0x36, 0x78, 0xcd, 0xba, 0xdc, 0x7f, 0xf5, 0x82, 0xf0, 0x1c, 0x5e, 0xd2, 0x19, 0x04, 0x1d, 0x43, 0x81, 0x05, 0x97, 0x84, 0x87, 0xff, 0x4e, 0x04, 0xed, 0x45, 0xae, 0x7b, 0xa9, 0x5b, 0xa6, 0xd0, 0x01, 0xdc, 0xbe, 0x3b, 0xd0, 0x9a, 0x1b, 0xfd, 0xf0, 0x33, 0x58, 0xcb, 0x00, 0xfd, 0xf8, 0x2d, 0x30, 0x80, 0x12, 0x8c, 0x4c, 0xfb, 0xf1, 0xe7, 0x0f, 0xe5, 0x00, 0x31, 0x0e, 0x24, 0x8f, 0xc1, 0x79, 0x24, 0x2e, 0x35, 0xe1, 0x90, 0x77, 0x10, 0x79, 0xbf, 0x98, 0xd0, 0x08, 0xa0, 0xb1, 0x39, 0x50, 0x70, 0xc9, 0x05, 0x91, 0x54, 0x4a, 0xbc, 0x26, 0x5e, 0xa2, 0x47, 0x1c, 0xcf, 0x22, 0x1a, 0xa9, 0xda, 0x22, 0x98, 0x76, 0x20, 0x30, 0xb4, 0x18, 0x05, 0x40, 0x67, 0x96, 0xef, 0x9b, 0x6b, 0x1a, 0x9a, 0xe7, 0x3d, 0x49, 0x62, 0x00, 0x6b, 0xf7, 0x1b, 0xe3, 0x81, 0xfe, 0x8f, 0x1d, 0xdb, 0x33, 0xf8, 0x8b, 0x24, 0x39, 0xe3, 0xdd, 0x2c, 0xfd, 0x24, 0xb1, 0x31, 0xa8, 0x44, 0xf6, 0x89, 0x7a, 0x88, 0x45, 0x53, 0xab, 0x47, 0x3f, 0x5c, 0xe1, 0x42, 0x1e, 0x27, 0xc2, 0xb4, 0x29, 0x40, 0xe6, 0x9c, 0x2b, 0xae, 0x7f, 0x7f, 0xc3, 0x4c, 0x2e, 0xe0, 0x4c, 0x35, 0x28, 0x34, 0xa3, 0x1d, 0xb8, 0x05, 0x33, 0xd0, 0x51, 0x31, 0x29, 0x31, 0x21, 0x62, 0x7d, 0x2a, 0x2e, 0xfb, 0xed, 0x0a, 0xf8, 0x7a, 0x83, 0xfc, 0xd5, 0xd4, 0x7d, 0x33, 0x0c, 0x9f, 0x37, 0x02, 0xd4, 0xf7, 0x44, 0xbc, 0x57, 0x80, 0x35, 0x1a, 0x36, 0x67, 0xae, 0xba, 0x8d, 0xb8, 0x42, 0xff, 0x0c, 0xdf, 0x13, 0xfd, 0x83, 0x1c, 0x63, 0x1d, 0xf0, 0x51, 0x0e, 0x71, 0xf6, 0xa5, 0x41, 0x7d, 0x1c, 0xfc, 0xe4, 0xb6, 0x62, 0x7d, 0xa6, 0x63, 0x7d, 0xeb, 0x0f, 0x0e, 0x80, 0x4e, 0xeb, 0xa7, 0x76, 0xd3, 0xb1, 0x66, 0x7f, 0xce, 0xd2, 0xe9, 0x41, 0x9e, 0x06, 0x17, 0xa9, 0x93, 0x0c, 0xa8, 0x21, 0xc5, 0xe4, 0x76, 0xd1, 0x30, 0xb6, 0x17, 0x92, 0xf2, 0xec, 0xdd, 0x94, 0xc6, 0xad, 0x9b, 0x45, 0x1e, 0x91, 0xbf, 0x72, 0xc6, 0x7f, 0xa8, 0x9e, 0x78, 0xf1, 0x4a, 0x45, 0x93, 0x88, 0xc5, 0x99, 0x68, 0x6a, 0xc2, 0xe9, 0x99, 0x66, 0x74, 0x23, 0x26, 0xb0, 0x30, 0x07, 0xc9, 0x09, 0x21, 0xdd, 0x51, 0x91, 0x8a, 0x09, 0x11, 0x50, 0x8f, 0x4e, 0x4b, 0x31, 0x97, 0xa5, 0xf5, 0x8e, 0x2b, 0x11, 0x00, 0x55, 0x1e, 0x56, 0x56, 0x1f, 0xf0, 0xd0, 0x3a, 0x1c, 0xe3, 0xec, 0xc3, 0x84, 0x94, 0xcb, 0x80, 0x94, 0x3b, 0xe6, 0x4d, 0x88, 0x4f, 0x7f, 0x31, 0x57, 0x5f, 0xd7, 0xb7, 0x0a, 0x41, 0xb1, 0xdf, 0x93, 0xa6, 0xf6, 0x76, 0xb4, 0xb8, 0x40, 0xcb, 0xcb, 0xea, 0x99, 0x7f, 0x49, 0x14, 0xae, 0xc1, 0xf2, 0x38, 0x2e, 0xb9, 0x70, 0x6e, 0x7b, 0x55, 0x5e, 0x8a, 0x2a, 0xf5, 0x10, 0x4d, 0xdf, 0xff, 0xfc, 0xf8, 0x04, 0x91, 0xc7, 0x57, 0xf6, 0x88, 0x22, 0x17, 0xff, 0xe1, 0xc8, 0xfd, 0x06, 0x20, 0x1d, 0xe1, 0x67, 0x2f, 0xa8, 0xe8, 0x15, 0xc9, 0x14, 0x65, 0xc7, 0x18, 0x92, 0x81, 0xe2, 0x56, 0x02, 0x40, 0x11, 0xcd, 0x17, 0xdc, 0x25, 0x24, 0x9f, 0x30, 0xc3, 0x91, 0x9a, 0x03, 0x41, 0xd4, 0x47, 0x8c, 0x5b, 0xf6, 0x76, 0x90, 0x0e, 0x78, 0xc0, 0x82, 0xc0, 0xf7, 0xb5, 0x53, 0x3e, 0x1d, 0x85, 0x10, 0xd2, 0x42, 0x71, 0x94, 0x37, 0x26, 0x8d, 0x3f, 0x5f, 0x61, 0xeb, 0xd4, 0xb2, 0x72, 0x46, 0xf2, 0x3d, 0xc2, 0xd2, 0xfc, 0x6c, 0x23, 0x47, 0xd3, 0x98, 0x87, 0x9f, 0x0c, 0xcd, 0xa9, 0x3e, 0xec, 0xe8, 0x6c, 0x48, 0x75, 0x6c, 0x9b, 0x22, 0x45, 0x8d, 0x62, 0x7f, 0x3d, 0x12, 0x4b, 0xa5, 0x3d, 0x3f, 0xd8, 0xe6, 0x3a, 0x02, 0x2d, 0xc9, 0x55, 0x54, 0x47, 0x08, 0xb8, 0x51, 0xcf, 0x96, 0x6d, 0xb6, 0x16, 0xbe, 0xf6, 0x96, 0x00, 0x4b, 0xcb, 0x02, 0xd1, 0xc7, 0x1c, 0xe1, 0xaa, 0xed, 0x29, 0x8a, 0xe4, 0x43, 0x04, 0x8f, 0x71, 0x7a, 0x02, 0x46, 0xde, 0xdf, 0x90, 0xa4, 0xf7, 0x52, 0x69, 0xe7, 0x79, 0x4b, 0x91, 0x3c, 0xc8, 0xa0, 0x3e, 0xef, 0x25, 0xab, 0xb5, 0xdb, 0xff, 0x48, 0x23, 0xf8, 0xa8, 0x17, 0xa5, 0x69, 0xf2, 0xd0, 0xea, 0xdd, 0x58, 0x27, 0xec, 0xd4, 0xe3, 0x39, 0x75, 0x20, 0x65, 0x19, 0x40, 0x25, 0x9a, 0xca, 0xbd, 0x6d, 0x92, 0x73, 0x9a, 0xe0, 0x27, 0xc4, 0x0b, 0x5e, 0x53, 0xc4, 0x26, 0x95, 0x6b, 0x36, 0x4e, 0x1d, 0x47, 0x00, 0xec, 0x5d, 0xe0, 0x92, 0xf8, 0x6c, 0x49, 0x74, 0x88, 0xb4, 0x0e, 0x10, 0x71, 0xcd, 0xe8, 0x5b, 0x7a, 0x46, 0xd4, 0xca, 0xd5, 0x3d, 0xcf, 0x50, 0x0f, 0x31, 0x85, 0x45, 0x12, 0x91, 0x78, 0xb9, 0xda, 0xb4, 0x96, 0xc1, 0x82, 0xbc, 0x15, 0x4f, 0x59, 0xcf, 0x7c, 0xe4, 0xfe, 0x9b, 0xe6, 0x4b, 0xad, 0xbb, 0xbd, 0x5e, 0x31, 0xc7, 0x7f, 0x23, 0x9c, 0x4d, 0x03, 0x08, 0x41, 0x83, 0xbf, 0xe2, 0xe3, 0x97, 0xcf, 0x19, 0x88, 0x7a, 0x5f, 0xa3, 0xa6, 0x09, 0x9a, 0xc5, 0x93, 0xaa, 0x7b, 0x15, 0x96, 0xfc, 0x02, 0x0c, 0x00, 0x1d, 0xca, 0x21, 0x10, 0x30, 0x48, 0xff, 0x89, 0x07, 0x28, 0xc5, 0x66, 0x44, 0xa7, 0x1e, 0xe3, 0x89, 0xd7, 0xaf, 0x97, 0xca, 0x24, 0x6d, 0xe3, 0x1d, 0x80, 0x9a, 0x0f, 0x83, 0xef, 0xdb, 0x37, 0xc0, 0x8e, 0xac, 0x00, 0x6c, 0xbf, 0x01, 0x3f, 0xda, 0xdf, 0x09, 0x9f, 0x36, 0x68, 0x08, 0x06, 0xb3, 0x36, 0xee, 0x6b, 0x28, 0xcb, 0x27, 0xa5, 0x6f, 0x49, 0x40, 0x34, 0xc0, 0x64, 0x65, 0x07, 0x5d, 0xa4, 0x28, 0xe9, 0xd9, 0x1c, 0xc4, 0x42, 0x2d, 0xf7, 0xcc, 0x14, 0x3e, 0x02, 0x35, 0x54, 0x7c, 0x38, 0xc0, 0xb5, 0xfb, 0x2e, 0x82, 0xed, 0xbf, 0xec, 0x37, 0xd3, 0x93, 0x91, 0x95, 0x00, 0xcc, 0x1b, 0x83, 0x9a, 0x57, 0x16, 0x8c, 0xf8, 0x4d, 0x5e, 0x4e, 0x0d, 0x1b, 0xc3, 0xc2, 0xec, 0xa7, 0x26, 0x84, 0xe4, 0x11, 0x72, 0x9b, 0x0d, 0xf5, 0x7e, 0xae, 0xa6, 0xa4, 0x57, 0x14, 0x4c, 0x86, 0x59, 0x30, 0xa8, 0xbb, 0xfe, 0xc3, 0x5a, 0xa3, 0x40, 0xcd, 0x65, 0xce, 0x69, 0xff, 0xa6, 0xe7, 0xdd, 0x88, 0xa8, 0xaa, 0xc9, 0x99, 0x26, 0x1b, 0x42, 0x80, 0xe0, 0x26, 0x26, 0x03, 0xcd, 0x33, 0x05, 0xab, 0x2b, 0xe5, 0x44, 0xc6, 0x7a, 0xf3, 0xdd, 0x0f, 0xb6, 0x1a, 0x06, 0x28, 0xca, 0x1c, 0xd9, 0x50, 0xa4, 0x8c, 0xb7, 0xbb, 0xc8, 0x88, 0x28, 0xd0, 0x00, 0xe0, 0xda, 0xc5, 0x8a, 0x6c, 0xcd, 0xf8, 0x8d, 0xed, 0x8c, 0x88, 0x11, 0x11, 0xa8, 0xeb, 0x43, 0x94, 0x24, 0xee, 0x01, 0xd1, 0x7c, 0x8c, 0x17, 0x99, 0xe8, 0x8e, 0x5d, 0x16, 0x90, 0x6f, 0x93, 0xf5, 0xab, 0x1c, 0x21, 0xa0, 0xf0, 0x92, 0xd5, 0x87, 0x4e, 0xd4, 0x7b, 0xc9, 0x31, 0xb2, 0x32, 0x6b, 0x6f, 0x6c, 0x8c, 0xfd, 0xf7, 0x00, 0x59, 0xfc, 0x72, 0xd6, 0xff, 0x7c, 0x2f, 0xfc, 0xfd, 0x1c, 0x22, 0xb5, 0xb2, 0xd7, 0xf3, 0x1c, 0xcc, 0x3a, 0xe0, 0x72, 0xa5, 0xaf, 0xf7, 0xdb, 0xa1, 0x40, 0x76, 0xcd, 0x14, 0x30, 0x0c, 0x20, 0xe7, 0xd5, 0xdc, 0x14, 0x67, 0x01, 0xdf, 0x48, 0xf0, 0x22, 0x3f, 0x62, 0xcd, 0x13, 0x28, 0xd6, 0xf2, 0xf6, 0x14, 0xfe, 0xaa, 0x93, 0x5a, 0xc3, 0xd2, 0x2f, 0xcf, 0xc9, 0xe4, 0x94, 0xb9, 0x5c, 0x46, 0x2a, 0xdf, 0xf6, 0xc9, 0x16, 0xb8, 0xf4, 0x7e, 0x61, 0xe5, 0x47, 0xac, 0xff, 0x37, 0x80, 0x09, 0x87, 0xe6, 0xf4, 0x7c, 0x1a, 0xfd, 0x49, 0x97, 0xfc, 0x7f, 0xea, 0x15, 0x3f, 0xf5, 0x27, 0x05, 0xb2, 0xc9, 0x6d, 0xaa, 0x87, 0xe1, 0xe9, 0x4f, 0xa0, 0x06, 0x20, 0x80, 0x08, 0x78, 0xee, 0x5c, 0xb6, 0x64, 0x74, 0x6c, 0x18, 0xcf, 0x82, 0x54, 0xd5, 0x48, 0x7c, 0x01, 0x50, 0x0e, 0x97, 0x33, 0xe1, 0xd1, 0x83, 0xd3, 0xe1, 0x48, 0x6e, 0xee, 0xf7, 0x5f, 0x6d, 0x1f, 0x03, 0x9c, 0x74, 0xcf, 0x97, 0x66, 0x95, 0x95, 0x71, 0x3e, 0x82, 0x0d, 0xc8, 0xa8, 0x92, 0x64, 0xc1, 0x9a, 0xd8, 0xc6, 0x20, 0x4c, 0x32, 0x6c, 0x1b, 0xf0, 0xa5, 0xcb, 0xa4, 0x0b, 0xdd, 0x42, 0x08, 0x54, 0x13, 0xec, 0xe6, 0x6b, 0xa2, 0x49, 0x96, 0x9c, 0xd9, 0x25, 0x12, 0x48, 0x10, 0xc4, 0xc1, 0xd1, 0x99, 0xf5, 0xc4, 0x36, 0x56, 0x12, 0xed, 0x23, 0x02, 0x21, 0x43, 0xa2, 0x8c, 0x3e, 0xdb, 0xdf, 0x7a, 0xd8, 0x32, 0xed, 0xf7, 0xc0, 0xf4, 0x79, 0x51, 0x85, 0x94, 0x29, 0x4f, 0x3b, 0x7d, 0xe4, 0x54, 0x94, 0x7d, 0x2b, 0xef, 0xa0, 0x74, 0x63, 0x47, 0x2c, 0x9b, 0xd1, 0x71, 0xca, 0x64, 0x41, 0x7d, 0xbe, 0x44, 0xeb, 0x25, 0xcb, 0x53, 0xb0, 0x46, 0x1d, 0x8a, 0x39, 0x30, 0x55, 0xf0, 0x7e, 0xb4, 0x17, 0xda, 0x34, 0x35, 0xb9, 0x7f, 0xc1, 0x85, 0x2c, 0x95, 0x66, 0xe5, 0xd1, 0xb9, 0x46, 0xa0, 0x6d, 0x47, 0xee, 0xc4, 0x3f, 0x0e, 0x91, 0x1a, 0xc7, 0x0b, 0x9e, 0x2c, 0x45, 0x25, 0xf0, 0x63, 0xdd, 0x15, 0x09, 0x2f, 0x8d, 0x1b, 0xde, 0x4b, 0x39, 0x1c, 0xbb, 0xf2, 0xc8, 0x12, 0x09, 0xe1, 0xfc, 0x90, 0xc4, 0xc4, 0x44, 0xe9, 0x09, 0x7b, 0xb5, 0xf4, 0x40, 0x54, 0xb0, 0x85, 0x8c, 0xd2, 0x87, 0x68, 0x06, 0x04, 0x08, 0xd3, 0x63, 0xcb, 0xd8, 0x8b, 0x75, 0x89, 0x3c, 0xb1, 0x3e, 0xad, 0x16, 0xc1, 0xc2, 0x1f, 0x4d, 0x3c, 0xfe, 0x2f, 0x5d, 0x60, 0x85, 0xa8, 0xd3, 0xda, 0x45, 0xd9, 0xe2, 0x52, 0xe2, 0x5f, 0x89, 0xce, 0x23, 0xc4, 0xb4, 0x99, 0x6b, 0x5a, 0x6c, 0xe1, 0x1d, 0xcb, 0x67, 0x87, 0x0f, 0x9c, 0xa5, 0x1f, 0x97, 0x54, 0x80, 0xb0, 0xf1, 0x40, 0xc5, 0x07, 0xbd, 0xbf, 0xd5, 0x57, 0x85, 0xdb, 0x63, 0xc2, 0x20, 0x08, 0xe3, 0xb2, 0xb3, 0x12, 0xdf, 0x3c, 0x6b, 0x4b, 0xf1, 0x44, 0xde, 0x32, 0xbd, 0xcb, 0x80, 0xbf, 0xdd, 0x9f, 0xa5, 0x9f, 0x92, 0x6b, 0xfd, 0xcf, 0x5b, 0x03, 0xc7, 0xb1, 0xe7, 0xf4, 0x18, 0x90, 0xbc, 0x3b, 0xc2, 0x5e, 0xf6, 0x26, 0xce, 0xfe, 0xce, 0x14, 0xbe, 0x1e, 0x4b, 0x31, 0xd5, 0x96, 0x79, 0x71, 0x94, 0xbe, 0x23, 0x7f, 0x24, 0x2b, 0xb9, 0xe0, 0x2d, 0xde, 0x56, 0x6f, 0x5c, 0x08, 0x6c, 0x16, 0xfb, 0xb1, 0x71, 0x26, 0x63, 0x39, 0x88, 0xf1, 0x3d, 0xe7, 0xf4, 0x48, 0x94, 0x93, 0x55, 0xc6, 0xd3, 0x13, 0xde, 0xe2, 0x63, 0xcb, 0xdf, 0x75, 0x38, 0x10, 0xb1, 0x43, 0xdd, 0xa2, 0x4a, 0xae, 0x86, 0x7a, 0x11, 0xfc, 0x7b, 0x50, 0x0e, 0xa4, 0x63, 0x04, 0xf0, 0x39, 0x49, 0x50, 0xdb, 0xa9, 0x9e, 0xfb, 0xfb, 0xbb, 0x60, 0x0f, 0x16, 0x84, 0x17, 0xb5, 0xc1, 0x26, 0x07, 0x67, 0xa9, 0xf3, 0x53, 0x98, 0x3a, 0xe5, 0x42, 0xf9, 0x32, 0x7a, 0xf0, 0x93, 0xdd, 0x0c, 0xdb, 0x4e, 0x87, 0x35, 0x2e, 0x45, 0x51, 0xa7, 0x3f, 0xe4, 0x49, 0xcf, 0xc8, 0xb1, 0x21, 0x7f, 0xf8, 0xd3, 0xc5, 0x12, 0xf0, 0x9b, 0x16, 0xdd, 0x2d, 0xf1, 0xb6, 0x58, 0x8b, 0x5d, 0xe1, 0xd2, 0xfe, 0xa9, 0x7c, 0x5d, 0x68, 0x32, 0xea, 0xd6, 0xea, 0x89, 0xa3, 0x29, 0x42, 0x31, 0x7c, 0x0f, 0x2c, 0x4d, 0x77, 0x64, 0xe7, 0x3e, 0xe7, 0x20, 0x20, 0xe5, 0xf8, 0x0a, 0x68, 0x1c, 0x91, 0x9a, 0x62, 0x78, 0x72, 0xca, 0x37, 0x7b, 0x91, 0x2e, 0xc2, 0x93, 0xc8, 0x4f, 0xa7, 0x21, 0x1c, 0xc8, 0x07, 0xec, 0x83, 0xc9, 0xb7, 0x65, 0x63, 0x1d, 0x29, 0x07, 0x64, 0x4c, 0xf4, 0x5f, 0xf2, 0xda, 0x4d, 0xb0, 0xba, 0x86, 0xe7, 0x8b, 0x8a, 0x7e, 0x1b, 0x89, 0xb1, 0x6b, 0x2d, 0x2b, 0xe2, 0xa6, 0x73, 0x68, 0xe4, 0xe2, 0xee, 0x58, 0x55, 0xfe, 0xa1, 0xfa, 0x12, 0xfd, 0x09, 0xec, 0xfa, 0xef, 0x59, 0xd1, 0xbb, 0xca, 0x8d, 0x82, 0x94, 0xcd, 0xfd, 0x8f, 0x18, 0xd8, 0x16, 0xd7, 0x67, 0x3b, 0x38, 0x44, 0x44, 0xa1, 0x7a, 0xc5, 0x2f, 0x4d, 0x4d, 0x19, 0xf8, 0xf9, 0xf9, 0x9d, 0x0f, 0x16, 0x44, 0x59, 0xd8, 0xd8, 0xd0, 0x63, 0x5f, 0x8e, 0xbc, 0xea, 0x02, 0x11, 0x54, 0xcf, 0xda, 0x67, 0x96, 0x14, 0x5d, 0x37, 0x12, 0x8c, 0xd1, 0xc5, 0xe7, 0x05, 0xc2, 0x90, 0x37, 0xa5, 0xae, 0x22, 0x23, 0xb5, 0xa6, 0x01, 0x89, 0xc6, 0x24, 0x00, 0xa3, 0xb9, 0xe8, 0xbd, 0x7b, 0x4b, 0xd5, 0x6e, 0xf2, 0x2d, 0xa4, 0x7a, 0xd6, 0xce, 0x82, 0x5a, 0xae, 0x31, 0x48, 0xf0, 0x6b, 0x0e, 0x74, 0xd9, 0xdc, 0x71, 0xc9, 0xb4, 0xca, 0x12, 0xf7, 0xa0, 0x61, 0x8b, 0xa1, 0xee, 0xe6, 0xdb, 0xb7, 0x6f, 0x16, 0x5b, 0x23, 0xe9, 0xca, 0xca, 0xca, 0xed, 0xc7, 0xeb, 0x7d, 0x2e, 0x17, 0x7b, 0x06, 0x02, 0x02, 0x02, 0x08, 0x50, 0xfd, 0x90, 0x23, 0x4f, 0x03, 0x3e, 0x87, 0x59, 0x9e, 0xd6, 0x4b, 0x07, 0x0f, 0x11, 0xb9, 0x8c, 0xc4, 0x8d, 0x3c, 0xbc, 0x3a, 0x76, 0x08, 0x25, 0xb0, 0x11, 0x7b, 0x7d, 0x0c, 0x81, 0x72, 0xa9, 0x85, 0xab, 0xee, 0x2c, 0xf3, 0x43, 0x96, 0x0e, 0x1c, 0x34, 0xd0, 0x84, 0xfc, 0x0f, 0xe7, 0x52, 0xfd, 0x6e, 0xaf, 0x8e, 0x29, 0x17, 0x02, 0xb6, 0xc7, 0xb2, 0x51, 0xef, 0xed, 0x3d, 0x05, 0xf8, 0x9f, 0x75, 0x73, 0x24, 0x3d, 0x62, 0x54, 0xfa, 0xa1, 0xb9, 0xb2, 0x3b, 0xbb, 0x76, 0xf6, 0x84, 0x11, 0x34, 0xe8, 0x5f, 0x30, 0x1e, 0x99, 0xf6, 0xbe, 0x92, 0xa5, 0xd6, 0xd4, 0x38, 0xdd, 0x18, 0x7c, 0xee, 0xca, 0x6e, 0x1a, 0x58, 0x97, 0xa6, 0xf3, 0xed, 0x3b, 0x50, 0xc6, 0x80, 0xa5, 0xa1, 0xc3, 0x8b, 0xf6, 0xd5, 0xd8, 0xaf, 0x75, 0xcc, 0x4f, 0x9e, 0x8c, 0x35, 0x79, 0x1e, 0xaa, 0x49, 0x49, 0x71, 0x70, 0xe0, 0xbc, 0x9b, 0x2e, 0xeb, 0x59, 0xed, 0x0a, 0x75, 0xf9, 0x5b, 0x5a, 0x27, 0x36, 0xa5, 0xff, 0x84, 0x2b, 0x89, 0xf4, 0x46, 0xb7, 0xa8, 0x3f, 0x5f, 0x3e, 0xd4, 0x1f, 0xe2, 0x61, 0xde, 0x2f, 0x15, 0x45, 0x22, 0x06, 0xa5, 0xdb, 0xda, 0xac, 0xd0, 0xb3, 0x5a, 0x29, 0xd5, 0x33, 0x67, 0x46, 0x78, 0xc5, 0x84, 0xef, 0x1a, 0x3a, 0x2c, 0xaf, 0xcf, 0x05, 0x66, 0x48, 0x07, 0x48, 0x29, 0x1c, 0x9f, 0x9c, 0xf0, 0xc0, 0x08, 0xd6, 0x7b, 0xa3, 0xba, 0xca, 0x4c, 0x9a, 0x9c, 0x57, 0xda, 0xd1, 0xce, 0x76, 0x26, 0x0a, 0x2a, 0x7b, 0xb3, 0x2b, 0x67, 0x5d, 0xcd, 0xd4, 0x5f, 0x07, 0xd8, 0xf9, 0x63, 0x07, 0xef, 0x9d, 0xa2, 0x8a, 0x59, 0xc7, 0x64, 0x1e, 0x94, 0x30, 0x5b, 0xe4, 0x46, 0x85, 0x88, 0xc5, 0x9f, 0xf1, 0xe3, 0x25, 0xa6, 0x28, 0x2e, 0xf5, 0x9e, 0x37, 0xe7, 0x5d, 0x59, 0x0d, 0x65, 0x74, 0xbc, 0xfc, 0x47, 0x05, 0x4b, 0xe1, 0x7d, 0x8b, 0x6e, 0x01, 0x83, 0xf1, 0x01, 0x36, 0x36, 0x5d, 0x9b, 0x5a, 0x6c, 0xd1, 0xc0, 0xae, 0xfb, 0xe4, 0x98, 0xf3, 0xa8, 0x83, 0xa8, 0x70, 0x98, 0xba, 0xd1, 0xef, 0xaa, 0x48, 0xb8, 0x7d, 0x36, 0xe9, 0x5a, 0x29, 0x40, 0x50, 0xe4, 0x5f, 0x57, 0xb4, 0x84, 0xfc, 0x6f, 0xbd, 0xce, 0xb6, 0xc7, 0xd7, 0xc3, 0x47, 0x17, 0xcb, 0xcd, 0xa4, 0xf7, 0x66, 0xab, 0xb1, 0xa1, 0x50, 0x68, 0x14, 0x6b, 0x34, 0x28, 0xeb, 0x02, 0x3b, 0x6b, 0x34, 0x31, 0x73, 0xa1, 0x0f, 0x28, 0x97, 0xf0, 0xf5, 0x05, 0xc3, 0xf9, 0x2a, 0x87, 0xb5, 0x99, 0xd5, 0xb1, 0xbf, 0x02, 0x07, 0x1e, 0xec, 0x08, 0x8e, 0x3d, 0x7d, 0x57, 0xac, 0x68, 0x3a, 0xe9, 0x7d, 0x2d, 0x21, 0xf8, 0xe6, 0x4f, 0x42, 0xf1, 0x80, 0xe5, 0x56, 0x3f, 0xd4, 0x0d, 0xed, 0x0a, 0x8a, 0x8a, 0x42, 0x49, 0xfa, 0x9d, 0x1f, 0xab, 0xd2, 0x65, 0xc8, 0xfc, 0x9e, 0xfe, 0xf8, 0x08, 0x40, 0x58, 0x4c, 0x38, 0xf2, 0xfe, 0xb1, 0x94, 0xfe, 0xad, 0x30, 0x6f, 0x2f, 0x77, 0xeb, 0x0b, 0x48, 0x9e, 0x36, 0x40, 0x50, 0x17, 0x5f, 0xd3, 0xb9, 0xad, 0x14, 0x73, 0x89, 0x89, 0x24, 0x8e, 0x64, 0x42, 0x4d, 0x6d, 0xfa, 0x63, 0x21, 0xca, 0x2a, 0x2a, 0x1d, 0xb9, 0x31, 0x52, 0x73, 0xfa, 0x16, 0x0c, 0xc3, 0xfa, 0x3b, 0x8e, 0xa5, 0x1e, 0xb7, 0x59, 0x84, 0x2d, 0xb1, 0x44, 0x28, 0x2a, 0xd7, 0x80, 0xda, 0x61, 0xa6, 0xc8, 0x0c, 0x20, 0xc1, 0x4e, 0x64, 0x9e, 0x4f, 0xe8, 0x2b, 0x8f, 0x07, 0xb8, 0xad, 0x5e, 0x4b, 0x9e, 0xeb, 0x84, 0x4a, 0x38, 0x3a, 0x0d, 0xd8, 0x0a, 0x58, 0x9c, 0xef, 0x4e, 0xa5, 0x88, 0xb9, 0x3f, 0x03, 0x05, 0x9e, 0x5e, 0xd3, 0x96, 0xfe, 0xfe, 0xc2, 0x2c, 0xb6, 0x78, 0xe5, 0x4f, 0xef, 0xcf, 0xc7, 0x08, 0xec, 0x71, 0x1c, 0xd1, 0x7c, 0x85, 0x85, 0x46, 0xcf, 0x7f, 0xd0, 0x08, 0x5a, 0x2f, 0x79, 0x30, 0x73, 0xa4, 0x93, 0xae, 0xa5, 0xb7, 0xce, 0xd5, 0x4e, 0x5b, 0x19, 0xe5, 0x8e, 0x9b, 0x1f, 0x2c, 0x34, 0x30, 0x34, 0x65, 0x30, 0xe1, 0xe8, 0x57, 0xac, 0x4c, 0xbf, 0x34, 0xb5, 0x6c, 0x10, 0xea, 0xb7, 0x50, 0xb9, 0x69, 0xea, 0xe3, 0x9e, 0x09, 0x46, 0xd1, 0x43, 0xa0, 0x70, 0x0c, 0x7c, 0x67, 0xaa, 0x1a, 0xfb, 0xfe, 0x2c, 0x74, 0xe0, 0xac, 0x3e, 0x1d, 0xcc, 0xf3, 0xc5, 0x87, 0x8d, 0xf2, 0x86, 0x28, 0xd3, 0xf9, 0xe9, 0x87, 0x95, 0x8f, 0xd8, 0x60, 0x06, 0x86, 0x83, 0xf1, 0xbf, 0x1a, 0x48, 0x91, 0x71, 0x2b, 0xa4, 0xd8, 0xd6, 0xef, 0x26, 0x09, 0x9f, 0x0e, 0xee, 0x70, 0x60, 0xa9, 0xe8, 0x69, 0xeb, 0xaa, 0x4a, 0x32, 0x38, 0x76, 0xf3, 0xff, 0x3c, 0xb7, 0xc6, 0x9d, 0xfb, 0xdb, 0x34, 0x58, 0x98, 0xc3, 0x9f, 0x6c, 0x0e, 0x7f, 0xdd, 0x3a, 0x7e, 0xf7, 0xa2, 0xb7, 0xc2, 0x61, 0x96, 0x5f, 0x39, 0x7e, 0x92, 0x2a, 0xa2, 0xc1, 0x4c, 0xa6, 0x9d, 0xfe, 0xc7, 0xbd, 0x3c, 0x3e, 0xb0, 0xb9, 0xac, 0x89, 0x08, 0xb3, 0x3d, 0x43, 0x51, 0xc7, 0xfb, 0x59, 0xef, 0x9e, 0x99, 0x1b, 0xb5, 0x78, 0xb5, 0xd9, 0xe5, 0x87, 0x7b, 0xcf, 0xe4, 0x42, 0x63, 0x71, 0x2d, 0x7f, 0x7f, 0x29, 0xb6, 0xd7, 0x19, 0x91, 0x01, 0xb7, 0xeb, 0x8c, 0xb1, 0x56, 0xd4, 0xb9, 0x8a, 0x51, 0x9d, 0xe9, 0x9e, 0x4b, 0xb3, 0xfa, 0x7f, 0x63, 0xed, 0xed, 0xe3, 0xcb, 0x4e, 0xfa, 0x83, 0x9b, 0x78, 0x51, 0x65, 0x13, 0x79, 0x27, 0xa6, 0x6d, 0x2c, 0xeb, 0x42, 0xad, 0x6e, 0x6d, 0xa8, 0x12, 0x07, 0x76, 0xb2, 0xa8, 0x9c, 0xab, 0xf0, 0x9a, 0xb5, 0xa9, 0x98, 0xdd, 0x1f, 0xb6, 0x32, 0x2c, 0xa5, 0x88, 0xa0, 0xe4, 0xb9, 0x98, 0x11, 0x5c, 0xfe, 0x70, 0x28, 0xb9, 0xb7, 0xd4, 0x42, 0xcb, 0xe8, 0x77, 0x46, 0x7c, 0x71, 0xb8, 0x4c, 0x04, 0xc2, 0x21, 0x24, 0x74, 0x2c, 0xdb, 0x6a, 0xde, 0xa4, 0x88, 0x31, 0x69, 0x8e, 0x00, 0xc4, 0x1c, 0x59, 0x5f, 0x43, 0x83, 0x37, 0xb7, 0x67, 0xf1, 0x70, 0x74, 0x75, 0x43, 0xb0, 0x2a, 0xd0, 0xc4, 0xbb, 0x74, 0x8a, 0xf6, 0x35, 0x3d, 0x17, 0x86, 0xb0, 0x32, 0xf7, 0xe5, 0xfb, 0xce, 0x54, 0xbc, 0xc5, 0xc1, 0xc3, 0x3b, 0x99, 0x71, 0x4f, 0x2f, 0x88, 0x35, 0x69, 0x74, 0x7b, 0x1a, 0x78, 0x0a, 0xef, 0x11, 0x26, 0x7e, 0x24, 0xb1, 0x5d, 0x19, 0xe1, 0x89, 0x92, 0xa2, 0x6b, 0x8f, 0x64, 0xc9, 0xb7, 0x9b, 0xfd, 0xca, 0x2a, 0x74, 0x50, 0x0c, 0xc7, 0xe5, 0x70, 0xeb, 0xcf, 0x53, 0x7b, 0x4b, 0x05, 0x3f, 0xa6, 0x17, 0xd7, 0xf7, 0xf6, 0xf6, 0x3e, 0x3d, 0x14, 0xf7, 0x3c, 0x50, 0x50, 0x57, 0x27, 0xc0, 0xc3, 0xc3, 0x4b, 0x1b, 0xb2, 0x6c, 0x80, 0x74, 0x2e, 0xba, 0x2c, 0x52, 0xb3, 0xba, 0xe5, 0x88, 0xf4, 0x4e, 0x72, 0x27, 0xd4, 0x66, 0xda, 0x8f, 0x93, 0x30, 0x21, 0x38, 0xd6, 0xdb, 0xc7, 0x2d, 0x9b, 0xdb, 0x7c, 0xaa, 0xe7, 0x1b, 0x11, 0x88, 0x47, 0x48, 0x11, 0x97, 0xce, 0xf7, 0x26, 0x4a, 0xce, 0x8e, 0x77, 0xf0, 0x11, 0x97, 0x89, 0x57, 0xc2, 0x6f, 0x81, 0x1c, 0x0f, 0x5b, 0x45, 0x16, 0xee, 0x44, 0xe4, 0x60, 0xfe, 0xb7, 0x66, 0xcc, 0x6e, 0xf4, 0xf8, 0x5c, 0xbb, 0xa6, 0xbc, 0x66, 0xc3, 0x01, 0x40, 0xaf, 0x81, 0x06, 0x8b, 0xed, 0x2b, 0xb6, 0x5b, 0x1e, 0x1a, 0x39, 0x63, 0x76, 0xd5, 0x93, 0xac, 0x9a, 0x1f, 0xee, 0x6f, 0x18, 0x8c, 0xe0, 0xab, 0xc1, 0x94, 0xa6, 0xb6, 0x89, 0x93, 0x46, 0xfd, 0x47, 0xa8, 0x50, 0x19, 0xda, 0x24, 0x71, 0x68, 0x24, 0xa9, 0x95, 0x46, 0xda, 0x15, 0xa0, 0xd7, 0xb6, 0x82, 0x9c, 0xe7, 0xbb, 0xf9, 0xa8, 0x24, 0x91, 0xd6, 0x9e, 0x2c, 0x0a, 0x4f, 0x91, 0xf0, 0xdb, 0xd3, 0xdc, 0x73, 0x11, 0x77, 0xb6, 0xba, 0xe1, 0xbb, 0xf8, 0xf8, 0xf8, 0xd8, 0xb8, 0x38, 0x34, 0x69, 0x69, 0x69, 0xa4, 0x84, 0x37, 0x09, 0xe0, 0xfd, 0xf7, 0xb2, 0xb2, 0x10, 0xbd, 0xe2, 0x60, 0xbd, 0xe2, 0x96, 0x9c, 0x7f, 0x2c, 0xb7, 0x77, 0x77, 0xc4, 0x0c, 0x0c, 0xd1, 0x4e, 0x6d, 0x77, 0x17, 0xe8, 0x1f, 0x6c, 0xa5, 0x30, 0x4a, 0x94, 0xb8, 0x35, 0x67, 0xb9, 0xc6, 0xf7, 0xe8, 0xbb, 0x9f, 0x87, 0x59, 0xc4, 0xe4, 0x13, 0x2a, 0xf5, 0x44, 0x80, 0x8e, 0xfa, 0xec, 0x48, 0x8f, 0x06, 0xab, 0x27, 0x97, 0x83, 0xc1, 0xf9, 0xbe, 0x77, 0x5d, 0xfe, 0xcd, 0x77, 0x03, 0xbd, 0xf8, 0x93, 0xe1, 0xd6, 0x81, 0xba, 0x20, 0x1c, 0x6c, 0x4b, 0xac, 0x7a, 0xa7, 0x0e, 0x22, 0x7a, 0x31, 0xb2, 0x6a, 0x9b, 0xd1, 0xde, 0x66, 0xef, 0x53, 0x73, 0xde, 0x1f, 0x4e, 0xfd, 0xf5, 0x3d, 0x16, 0xb2, 0xe5, 0xa6, 0x2d, 0x9a, 0xba, 0xba, 0x53, 0x45, 0x1a, 0xe0, 0x4e, 0xa7, 0xc4, 0x8d, 0xce, 0x16, 0x47, 0xc2, 0xbf, 0xb5, 0xdb, 0x71, 0xe2, 0xc7, 0x24, 0x68, 0x4d, 0x69, 0xfe, 0x43, 0x62, 0x4a, 0x2d, 0x0b, 0xb8, 0xd0, 0xc1, 0x54, 0x24, 0xba, 0x6f, 0xb3, 0x47, 0xf1, 0x57, 0x9a, 0x0e, 0x4e, 0x1c, 0xc9, 0x65, 0x8b, 0x12, 0xa7, 0x43, 0x68, 0xae, 0x87, 0xe2, 0x23, 0xcc, 0xe1, 0xc8, 0x31, 0xdb, 0x6f, 0xd8, 0xf8, 0x72, 0xe5, 0xa2, 0x91, 0xff, 0x7a, 0x40, 0x41, 0xc3, 0xde, 0x87, 0x93, 0x93, 0x3a, 0xa8, 0xaf, 0x12, 0x50, 0x49, 0xfa, 0x08, 0xf0, 0xbf, 0x78, 0x31, 0x4f, 0x1e, 0xa1, 0x98, 0x2b, 0xab, 0xaf, 0x9f, 0x32, 0x2f, 0xa6, 0xf2, 0xcb, 0x68, 0x51, 0xcf, 0x0d, 0x86, 0x92, 0x35, 0xce, 0x22, 0xf6, 0x69, 0x66, 0x48, 0xca, 0x44, 0x9d, 0x67, 0xd4, 0x78, 0x90, 0x45, 0xbd, 0xf7, 0x2d, 0xb8, 0xa3, 0x6d, 0x95, 0xe8, 0xe7, 0x8f, 0x37, 0x29, 0x04, 0xd5, 0x29, 0x10, 0x15, 0x4a, 0x96, 0x0d, 0x6e, 0x7c, 0x5b, 0xb3, 0x89, 0x9f, 0x3f, 0xd7, 0xe5, 0x54, 0xb9, 0xc2, 0xb3, 0x7b, 0x4e, 0xe4, 0x83, 0x39, 0x29, 0x4b, 0x57, 0x9a, 0x3d, 0x72, 0x0c, 0x25, 0x2d, 0x85, 0x98, 0x52, 0x0d, 0x33, 0x5e, 0x70, 0x71, 0x3d, 0x46, 0xfd, 0xae, 0x7a, 0x27, 0xdb, 0xbf, 0x50, 0x64, 0xeb, 0x7b, 0xe9, 0xfb, 0x9a, 0x46, 0x7e, 0xaa, 0x17, 0x79, 0x6a, 0x5a, 0xa3, 0xb9, 0xc9, 0x7e, 0x72, 0x28, 0xcd, 0xeb, 0x85, 0xf9, 0xe9, 0xad, 0x3a, 0x1a, 0xd3, 0xec, 0xc7, 0xd3, 0x74, 0x97, 0x12, 0xbd, 0xf9, 0x1e, 0x42, 0x08, 0xc2, 0x8d, 0x09, 0x40, 0x19, 0xa6, 0xda, 0x43, 0xc4, 0x42, 0x50, 0x3c, 0x85, 0x60, 0xe4, 0x5f, 0xb7, 0x36, 0x6f, 0xed, 0x24, 0x7c, 0xe1, 0x1a, 0xef, 0x66, 0xc1, 0x0d, 0x23, 0x95, 0xdd, 0x4b, 0x71, 0x99, 0xf9, 0xa2, 0x6a, 0x43, 0x6b, 0x6b, 0x36, 0x06, 0xdf, 0x23, 0xd9, 0x99, 0x74, 0xb6, 0x6f, 0x0d, 0x64, 0xac, 0xac, 0xac, 0x1c, 0xcf, 0x9e, 0xb9, 0x46, 0x85, 0x60, 0xf2, 0x3c, 0x7e, 0x9c, 0xee, 0x63, 0x22, 0xdf, 0xf5, 0xf6, 0x3a, 0xde, 0xf6, 0xa3, 0x58, 0x0f, 0x71, 0xb9, 0x79, 0x75, 0x7a, 0xe9, 0x5b, 0x75, 0x69, 0xbc, 0x0a, 0x42, 0x17, 0x11, 0xcb, 0x05, 0x11, 0x6b, 0x2a, 0x9f, 0xf3, 0xbd, 0xab, 0x0d, 0x2a, 0x5c, 0x48, 0xe9, 0x40, 0x55, 0xe4, 0x1b, 0x69, 0xe3, 0x50, 0xc9, 0x50, 0xc3, 0x91, 0x4e, 0x4e, 0x99, 0x72, 0xc6, 0x5a, 0xcb, 0xb1, 0x2c, 0xef, 0x72, 0x0a, 0x4a, 0xb3, 0xef, 0xf0, 0xb4, 0x53, 0xef, 0x67, 0xf8, 0x77, 0xb7, 0xa6, 0xc6, 0xfb, 0xce, 0x7f, 0x36, 0x31, 0x92, 0x96, 0xd1, 0x3c, 0xde, 0x6b, 0x9b, 0x78, 0x78, 0x08, 0xd1, 0x11, 0x62, 0xb3, 0xbd, 0x4a, 0x73, 0x1b, 0x70, 0x19, 0x4e, 0x17, 0xa7, 0xc4, 0xc5, 0xc5, 0xd5, 0x60, 0x4d, 0x5b, 0x97, 0x39, 0xda, 0xbb, 0xbe, 0x36, 0xb3, 0x15, 0x53, 0x11, 0xfe, 0x1e, 0xac, 0xd1, 0x8c, 0xb5, 0xd5, 0xe8, 0xfe, 0xaa, 0x8d, 0x51, 0x5c, 0x85, 0x59, 0x0b, 0x67, 0x87, 0x00, 0x09, 0x6f, 0xae, 0xb3, 0x7f, 0xe1, 0xb1, 0xe7, 0xee, 0x17, 0x34, 0x9c, 0xc2, 0x52, 0xac, 0x13, 0xf7, 0x5a, 0xf1, 0xe5, 0xdd, 0x8f, 0x2b, 0x40, 0x19, 0x98, 0x9d, 0xfc, 0xb3, 0x7f, 0x97, 0x9c, 0x42, 0x17, 0x8d, 0x7c, 0xa0, 0x22, 0x98, 0xc0, 0xc2, 0x93, 0x5b, 0xe1, 0xdb, 0x6a, 0xbc, 0x5c, 0x0e, 0x60, 0x54, 0x51, 0x51, 0xa1, 0x14, 0x9b, 0x7c, 0x69, 0x67, 0xf7, 0xf4, 0x77, 0x99, 0xc9, 0x5f, 0xad, 0x6f, 0xe3, 0x67, 0x06, 0x8f, 0x2d, 0x3f, 0x58, 0x23, 0x91, 0x44, 0x28, 0xe1, 0x17, 0xe6, 0x5c, 0xbb, 0x53, 0xa7, 0x93, 0x66, 0x1c, 0x02, 0x8e, 0x59, 0x47, 0xc2, 0xa6, 0x7a, 0x19, 0x2b, 0x8f, 0x6f, 0x24, 0xb9, 0xec, 0x1f, 0x71, 0xab, 0xc4, 0xbd, 0x9e, 0x77, 0x98, 0x2d, 0xd6, 0xd2, 0x9e, 0x17, 0x86, 0x18, 0x99, 0x2c, 0xfe, 0xe6, 0x97, 0x6e, 0xdb, 0xa9, 0xc3, 0x97, 0x6b, 0xff, 0xf8, 0x8d, 0x3f, 0xa2, 0x27, 0x88, 0x3d, 0xc3, 0x0b, 0xbd, 0x6a, 0xaf, 0xd5, 0xa6, 0xb9, 0x7a, 0x7b, 0xdb, 0x56, 0x84, 0x6e, 0x78, 0x42, 0x3b, 0xb0, 0x32, 0x50, 0x24, 0xa2, 0xe7, 0x38, 0xd3, 0x03, 0x73, 0x02, 0xc5, 0xfb, 0xa6, 0xf2, 0x05, 0x11, 0x25, 0xf6, 0x3e, 0xf8, 0x6e, 0x1c, 0x10, 0x4c, 0x3d, 0xda, 0x96, 0x27, 0xcc, 0xdd, 0xda, 0x22, 0x5b, 0xfa, 0x0d, 0x2e, 0xd8, 0xf7, 0xa7, 0x3d, 0x97, 0x80, 0x7d, 0x47, 0x5e, 0x82, 0x80, 0x09, 0xeb, 0x21, 0x63, 0x97, 0xfc, 0xe9, 0xef, 0x65, 0x4b, 0x9a, 0xdc, 0x43, 0xb2, 0x13, 0x68, 0xc3, 0x03, 0xdf, 0xaa, 0xea, 0xeb, 0x45, 0x9a, 0x4f, 0x06, 0x9f, 0xbf, 0x67, 0x48, 0x8e, 0x8d, 0x0d, 0xdc, 0xca, 0x0c, 0x58, 0x2a, 0x54, 0xd0, 0x2e, 0xd4, 0x32, 0x39, 0xc5, 0x66, 0xba, 0x59, 0x7b, 0x20, 0xdd, 0xee, 0x45, 0x6d, 0x47, 0x7c, 0x5e, 0x47, 0xbf, 0x24, 0x64, 0x54, 0x31, 0x41, 0xd5, 0x3d, 0xe1, 0x73, 0x8d, 0x7a, 0xf4, 0xd6, 0xb8, 0x10, 0xfa, 0x76, 0x47, 0xcf, 0x95, 0x8d, 0xcb, 0xdf, 0xe6, 0x3d, 0x94, 0xf3, 0x86, 0x93, 0xb6, 0xbb, 0x98, 0x90, 0xbd, 0xd7, 0x71, 0x71, 0xf3, 0x66, 0xfb, 0xf5, 0xc5, 0x56, 0xd3, 0xef, 0x6a, 0xb4, 0xfd, 0x89, 0x6c, 0xd7, 0xbf, 0xaa, 0x26, 0x71, 0x1a, 0x04, 0x25, 0x9b, 0xf9, 0xcf, 0xe6, 0x63, 0x12, 0x22, 0x0f, 0x1f, 0x5d, 0x2e, 0xc0, 0x47, 0x57, 0xaf, 0xff, 0x96, 0x2b, 0xd9, 0xd9, 0x4d, 0xa4, 0x11, 0xc6, 0x97, 0xe8, 0x99, 0x9d, 0x46, 0x4e, 0xf9, 0x08, 0x94, 0xaf, 0x5b, 0x9c, 0xbc, 0x9a, 0x7c, 0x1a, 0xed, 0x15, 0x95, 0x93, 0xe3, 0x6e, 0xae, 0xfe, 0x02, 0xab, 0x22, 0x0a, 0x3d, 0xb0, 0x03, 0xe3, 0xda, 0x62, 0x4c, 0xf7, 0xc7, 0x3d, 0x3a, 0x84, 0x7e, 0x00, 0x32, 0xa4, 0x7f, 0x72, 0x58, 0x5e, 0xf1, 0x7e, 0x9a, 0x87, 0xcb, 0xfe, 0xec, 0x69, 0x64, 0xf0, 0x42, 0xa7, 0x77, 0x47, 0x6b, 0x55, 0x15, 0x91, 0xd8, 0x59, 0x9a, 0xc7, 0x07, 0x1f, 0x5d, 0xe7, 0x23, 0x7a, 0xda, 0xfd, 0x8b, 0xb4, 0xe5, 0x01, 0x57, 0x13, 0x69, 0x50, 0x58, 0x54, 0x54, 0x0f, 0xb0, 0x49, 0x8d, 0xb5, 0x05, 0x04, 0xe8, 0xbc, 0x79, 0x03, 0x9b, 0xaf, 0x7d, 0x9f, 0x22, 0xf9, 0x41, 0xe8, 0x62, 0x6f, 0x76, 0xfd, 0xcb, 0xb6, 0x20, 0xab, 0xd8, 0x62, 0x2c, 0x3b, 0xb0, 0x67, 0xd3, 0x8a, 0x09, 0x30, 0x31, 0xbe, 0x7c, 0x01, 0x60, 0x2b, 0x67, 0x22, 0x2a, 0xc5, 0x8e, 0x3f, 0x7d, 0x06, 0x0f, 0x74, 0x39, 0x5a, 0x8f, 0xc9, 0x33, 0xdc, 0xf0, 0x66, 0x27, 0x16, 0xe7, 0x98, 0x5a, 0x57, 0xd0, 0xdd, 0xeb, 0x6e, 0x9d, 0xa7, 0x62, 0x6b, 0xec, 0x98, 0x42, 0x70, 0x97, 0x80, 0xc9, 0x4d, 0x22, 0xf6, 0xcd, 0xea, 0xc0, 0xdf, 0xcb, 0xfd, 0x9b, 0xe6, 0xca, 0x8a, 0xa3, 0x21, 0x2e, 0x8f, 0x0f, 0xc7, 0xef, 0xdf, 0x1f, 0x16, 0x16, 0x59, 0x94, 0xf4, 0xd1, 0x8c, 0xb8, 0x97, 0xa3, 0xcd, 0x96, 0x62, 0xe7, 0x90, 0xd6, 0xa1, 0xf4, 0x24, 0x29, 0x26, 0x53, 0x39, 0x55, 0x45, 0x68, 0xc8, 0x19, 0x4e, 0x7b, 0xcc, 0xbb, 0x64, 0x19, 0xd6, 0xf1, 0x4f, 0x2c, 0x72, 0x65, 0x3a, 0xb2, 0x2e, 0xa2, 0x9b, 0xcd, 0x27, 0x7c, 0xae, 0x27, 0xe1, 0x26, 0x83, 0xd4, 0x13, 0x94, 0x8f, 0x1e, 0xa9, 0xa7, 0x41, 0x75, 0x6b, 0xb8, 0x56, 0xd1, 0x43, 0x3d, 0xbe, 0x7f, 0xff, 0x6e, 0x5f, 0x99, 0x65, 0x3e, 0xb9, 0xfc, 0xbe, 0xb6, 0x33, 0x18, 0xf9, 0x55, 0x0e, 0xf9, 0xf7, 0x51, 0x87, 0xb4, 0x69, 0xd2, 0x3f, 0x9a, 0xf6, 0x07, 0x38, 0x53, 0x5b, 0xeb, 0x8b, 0xff, 0x9d, 0xef, 0x53, 0xfe, 0x62, 0xc0, 0xfc, 0x39, 0x8d, 0xd6, 0x1e, 0x24, 0x7a, 0xf9, 0xf6, 0x82, 0x5e, 0x58, 0x16, 0xbc, 0xfd, 0x3a, 0x31, 0xf6, 0xe2, 0x19, 0x77, 0x71, 0xe7, 0x3a, 0x4f, 0x4b, 0x4c, 0x73, 0xe7, 0x2f, 0x0a, 0xc1, 0x34, 0x85, 0x28, 0xeb, 0x5b, 0x81, 0x08, 0xab, 0x80, 0xca, 0x79, 0x0c, 0x49, 0xdb, 0xed, 0xb1, 0x37, 0x6e, 0x76, 0x76, 0x0f, 0xf4, 0x5b, 0xce, 0x93, 0x34, 0x68, 0x32, 0xc5, 0xf4, 0xb1, 0x05, 0x13, 0x92, 0xfe, 0x39, 0x55, 0x27, 0x06, 0xbb, 0x57, 0xbf, 0x35, 0xce, 0xb8, 0x54, 0x9a, 0xa3, 0x39, 0xb0, 0xde, 0x3b, 0x8b, 0x3c, 0x3b, 0x74, 0x9a, 0xf3, 0xbf, 0x88, 0x4b, 0xf5, 0xba, 0x5d, 0x2a, 0x54, 0x0d, 0x51, 0x50, 0x4e, 0xd6, 0x35, 0x31, 0x8a, 0x61, 0xa7, 0xf0, 0x0f, 0x3b, 0xfb, 0x99, 0xe4, 0x37, 0x28, 0x40, 0x6d, 0x7f, 0x7e, 0xd5, 0x54, 0xf2, 0xfb, 0xae, 0x80, 0x1c, 0x37, 0xd2, 0x4d, 0x64, 0x77, 0x43, 0xa3, 0x99, 0x10, 0x26, 0x9b, 0x29, 0xea, 0xd4, 0xd7, 0x9d, 0xde, 0x3c, 0x56, 0x86, 0x88, 0x15, 0x22, 0x4b, 0xd2, 0x5b, 0x1b, 0xf7, 0x1e, 0x32, 0x64, 0x83, 0x73, 0xab, 0x64, 0xdf, 0xdc, 0xdd, 0x39, 0x51, 0x29, 0x0d, 0x2c, 0xd4, 0xa1, 0xe0, 0xd8, 0x37, 0xea, 0xd4, 0x3e, 0x1a, 0x28, 0x54, 0x66, 0xd7, 0x94, 0x55, 0x4f, 0x87, 0x9c, 0xf8, 0xa3, 0x89, 0x30, 0x8e, 0x0e, 0x8a, 0xc7, 0x93, 0xa8, 0x5c, 0xc1, 0xb0, 0x6c, 0x2c, 0x31, 0xed, 0xaf, 0x67, 0x3a, 0xbb, 0xb5, 0x71, 0x3e, 0x42, 0x18, 0xbd, 0xb3, 0xbf, 0xf8, 0xf5, 0x4c, 0x59, 0x2a, 0xc4, 0x87, 0x96, 0xb8, 0x1c, 0x26, 0x64, 0x23, 0x47, 0x86, 0x71, 0x8e, 0x14, 0x56, 0xc7, 0x0c, 0xc4, 0xaa, 0xc6, 0x84, 0x29, 0x11, 0x2a, 0x7a, 0x71, 0x0c, 0xef, 0x6b, 0xf4, 0xe7, 0x8b, 0x7c, 0x35, 0x0a, 0x13, 0x8d, 0xb8, 0x27, 0xfa, 0xf7, 0xd2, 0x4a, 0x23, 0x3f, 0xc8, 0x04, 0xdc, 0x49, 0x31, 0xe8, 0x3a, 0x30, 0x7f, 0x7e, 0x5e, 0xb0, 0x1d, 0xd0, 0x2f, 0x15, 0x66, 0xb8, 0xdd, 0xad, 0xf6, 0xcf, 0x8f, 0x88, 0x97, 0x10, 0x99, 0x39, 0xbe, 0x9b, 0xa0, 0x47, 0x6a, 0x0e, 0x96, 0x5b, 0x50, 0xd1, 0x18, 0xed, 0x5d, 0xe7, 0x69, 0x8d, 0x09, 0x5a, 0x73, 0x2d, 0xd0, 0x2a, 0x54, 0x20, 0xbb, 0x19, 0x89, 0xdd, 0xc8, 0xb9, 0x24, 0xc3, 0x8f, 0xf4, 0xa2, 0x03, 0x14, 0x7b, 0x22, 0x5d, 0x74, 0x09, 0xa7, 0x4c, 0xe2, 0xfc, 0x0f, 0x3f, 0x89, 0x73, 0x02, 0xd5, 0xa1, 0xe2, 0x2f, 0x04, 0x9f, 0xc1, 0xe5, 0xbd, 0xa2, 0x7d, 0xb5, 0x8b, 0x4a, 0x47, 0x57, 0x11, 0x87, 0xb9, 0x45, 0xdf, 0x46, 0x0a, 0x15, 0x93, 0xa9, 0xc9, 0x04, 0xbc, 0xe3, 0xbb, 0xe2, 0x4e, 0x13, 0x2c, 0x3a, 0xe2, 0x34, 0x64, 0x63, 0x16, 0x3e, 0x53, 0x92, 0x32, 0x60, 0xfe, 0xe1, 0x05, 0xc5, 0x5a, 0x11, 0xca, 0x82, 0x9d, 0xef, 0x6a, 0xe4, 0xbf, 0x10, 0x86, 0x83, 0xcb, 0xd7, 0x9d, 0xfb, 0xf5, 0x9b, 0x36, 0x6c, 0x9a, 0x9b, 0xd6, 0xde, 0xcd, 0xec, 0x8f, 0xe0, 0xa7, 0x5d, 0xed, 0x5f, 0x9e, 0x36, 0x59, 0x19, 0xba, 0x9f, 0x47, 0x73, 0x62, 0x76, 0x31, 0xa7, 0x23, 0x00, 0xef, 0x9e, 0xab, 0xfc, 0x0a, 0x84, 0x04, 0x76, 0xb1, 0x7e, 0x08, 0xf8, 0xb7, 0xef, 0x98, 0x37, 0xf6, 0xcc, 0x01, 0x51, 0xaf, 0xac, 0x2e, 0xfa, 0x29, 0x34, 0xd3, 0x2c, 0x3c, 0x46, 0x7a, 0x7e, 0xf7, 0x47, 0x78, 0x6a, 0xff, 0x4b, 0xbe, 0xb5, 0xc7, 0xb9, 0xc7, 0x85, 0x4f, 0x6b, 0x6a, 0xa4, 0xdd, 0xae, 0xa9, 0xe0, 0x39, 0x04, 0x80, 0x82, 0x2b, 0x67, 0xc6, 0xf1, 0x2b, 0xc7, 0x1c, 0x0c, 0xf8, 0xb3, 0x40, 0xb2, 0x6d, 0xcc, 0x0d, 0x8f, 0x0e, 0x2f, 0x32, 0x54, 0x6f, 0xd9, 0x11, 0xcb, 0x97, 0x63, 0xee, 0x2e, 0xf6, 0xad, 0x79, 0xcf, 0x48, 0xc1, 0x69, 0x12, 0x15, 0xcf, 0xbf, 0x35, 0x0d, 0x0d, 0x32, 0x29, 0x67, 0xbc, 0x27, 0x2a, 0x16, 0x84, 0x15, 0x4e, 0xf9, 0xc4, 0xb2, 0xd9, 0xed, 0x28, 0xb2, 0xe4, 0x63, 0x30, 0x75, 0xa7, 0xaa, 0x0a, 0x9a, 0x87, 0x0f, 0x27, 0xd5, 0xd0, 0xc7, 0xea, 0x1e, 0xec, 0x12, 0xf5, 0xb2, 0x33, 0xb7, 0xd5, 0x13, 0x10, 0xbf, 0x85, 0x1c, 0x14, 0xe1, 0x1e, 0x7b, 0x23, 0xe1, 0xdd, 0xdd, 0xac, 0xb0, 0xe1, 0x6f, 0x99, 0xce, 0x12, 0xe7, 0x25, 0x6a, 0xf4, 0xb0, 0x39, 0xad, 0x9a, 0xeb, 0xb4, 0xd9, 0xc7, 0x8f, 0x55, 0x6e, 0xbe, 0x7c, 0x8e, 0xe6, 0xf8, 0x0c, 0xf8, 0xfc, 0x8e, 0x80, 0xfe, 0xba, 0x56, 0xc7, 0xf0, 0x7a, 0x62, 0x1a, 0x69, 0x74, 0x2d, 0x90, 0xc8, 0xd7, 0x9b, 0x35, 0x65, 0xff, 0xb6, 0x6e, 0x1e, 0x0d, 0x19, 0x90, 0x5c, 0x36, 0x61, 0xcf, 0x7b, 0x50, 0xf7, 0x89, 0x3c, 0x22, 0x01, 0x9c, 0xaf, 0xf3, 0x7b, 0xf2, 0xed, 0x4e, 0x78, 0xf9, 0xf1, 0x78, 0xda, 0x43, 0xf6, 0xf7, 0x49, 0x77, 0x2a, 0x51, 0x58, 0xaf, 0x97, 0x0a, 0x0d, 0xef, 0x94, 0xbd, 0x64, 0xdc, 0x77, 0x4d, 0x2f, 0x85, 0xb7, 0x67, 0x84, 0xe9, 0x5e, 0x51, 0x67, 0x67, 0xe4, 0xd5, 0x96, 0x0d, 0x17, 0x73, 0xdf, 0xf6, 0x2b, 0x2a, 0x78, 0x15, 0x94, 0x94, 0x72, 0x1b, 0x1b, 0x69, 0xaa, 0xad, 0x87, 0xed, 0x97, 0x9c, 0xfa, 0x96, 0x98, 0x2b, 0xf4, 0x4b, 0xc2, 0xbb, 0x95, 0xc3, 0xb4, 0x08, 0x19, 0xd4, 0x3a, 0x4a, 0x44, 0xcb, 0xd7, 0xe7, 0xd3, 0x43, 0x57, 0xc4, 0x46, 0xe3, 0x39, 0xd4, 0xb4, 0x66, 0xd2, 0xc2, 0xc2, 0xb6, 0x1c, 0x6b, 0x67, 0x35, 0xac, 0x9f, 0x91, 0x33, 0x42, 0x19, 0x86, 0x01, 0x00, 0x2a, 0x7c, 0x69, 0xd7, 0x77, 0x91, 0xd8, 0xfa, 0x06, 0x05, 0xf1, 0x5a, 0x0d, 0x92, 0xa1, 0x5e, 0x42, 0x85, 0xba, 0x59, 0x34, 0x70, 0x61, 0xc1, 0x38, 0x92, 0x4e, 0x94, 0x44, 0x57, 0x77, 0x6b, 0x99, 0x5c, 0xea, 0x21, 0xd9, 0xe0, 0x6a, 0x82, 0x91, 0xed, 0x39, 0x25, 0x37, 0x24, 0xbd, 0xfb, 0xc0, 0x79, 0xe5, 0xf4, 0x61, 0xbf, 0xf3, 0xc4, 0x7d, 0x59, 0x2e, 0xc9, 0x64, 0xeb, 0x13, 0xf1, 0xa3, 0x07, 0x33, 0x2a, 0xfc, 0xaf, 0xeb, 0xce, 0x96, 0x2c, 0x4f, 0xc9, 0x18, 0x8e, 0x9f, 0xfc, 0x77, 0xd2, 0x80, 0x28, 0xce, 0x88, 0xdd, 0x28, 0xd1, 0x05, 0x81, 0xc9, 0xc9, 0x83, 0xaf, 0xae, 0xbc, 0x1e, 0x61, 0x63, 0x37, 0xed, 0x9d, 0x76, 0x11, 0x49, 0x9b, 0xf7, 0x46, 0x52, 0x83, 0x02, 0x57, 0x64, 0x02, 0xf6, 0xf4, 0x6f, 0x28, 0x04, 0xec, 0xeb, 0xca, 0xe7, 0x70, 0x77, 0x4e, 0x44, 0xb6, 0xc2, 0xc4, 0xe3, 0xa2, 0xad, 0x32, 0xfd, 0xd7, 0xad, 0xdf, 0x92, 0x0f, 0x7c, 0xd3, 0x0a, 0xe6, 0xa9, 0x9e, 0xed, 0xee, 0x91, 0x11, 0x72, 0xf7, 0x65, 0x06, 0x6d, 0xd3, 0x03, 0x0a, 0xb1, 0xe5, 0xc3, 0xf2, 0x72, 0x6e, 0xd9, 0xc1, 0x0c, 0xe1, 0xc8, 0x7b, 0x1a, 0x10, 0xea, 0xd5, 0x69, 0xbc, 0xae, 0x7f, 0xfa, 0xf5, 0x6e, 0x1e, 0xd3, 0x08, 0xe0, 0x18, 0x18, 0x18, 0x28, 0xab, 0xaa, 0x06, 0x0d, 0x38, 0xc8, 0xb6, 0x85, 0xf1, 0x1a, 0x4f, 0xb4, 0xbd, 0x2e, 0xbe, 0xc3, 0xd9, 0xd9, 0x2d, 0xb2, 0xdf, 0xad, 0xb4, 0x9d, 0xb5, 0xb9, 0x9a, 0x6e, 0x2c, 0xe5, 0x28, 0x2f, 0xb1, 0x83, 0x16, 0x8b, 0x16, 0x6b, 0x3d, 0x6e, 0x5c, 0xb4, 0x16, 0xbf, 0xc1, 0xd4, 0x7c, 0xa9, 0x5d, 0x1f, 0x6f, 0x3d, 0x09, 0xc8, 0x73, 0x52, 0x44, 0xac, 0x41, 0x95, 0xf1, 0xc5, 0x63, 0xd0, 0xcf, 0xd4, 0x17, 0xd8, 0x99, 0xbe, 0x27, 0x03, 0x98, 0x97, 0xef, 0x6d, 0x6d, 0x51, 0x77, 0x4f, 0xc7, 0x02, 0xcc, 0x0d, 0xf8, 0xe8, 0x60, 0x72, 0x4e, 0x73, 0x1b, 0x75, 0xad, 0x11, 0x91, 0x08, 0x7e, 0xbd, 0x86, 0x84, 0x5d, 0x66, 0xaf, 0x7b, 0x39, 0x6d, 0xb0, 0x91, 0x25, 0xd7, 0x18, 0x8b, 0x07, 0xbb, 0xc8, 0xe2, 0x2c, 0x32, 0xe1, 0x40, 0x47, 0x67, 0xf6, 0x95, 0x6c, 0xe7, 0x14, 0x7e, 0xe1, 0xa1, 0xa4, 0x19, 0x74, 0x4f, 0x70, 0x62, 0x95, 0x63, 0x8e, 0x86, 0x86, 0x26, 0xbc, 0xa4, 0x84, 0x73, 0xfb, 0xfc, 0x3d, 0xfb, 0x36, 0xa0, 0xcb, 0x22, 0x19, 0x24, 0x69, 0x40, 0x47, 0x63, 0x8b, 0x09, 0x7c, 0x87, 0x9f, 0x0d, 0xde, 0x1f, 0xbc, 0x56, 0x7e, 0x13, 0x9b, 0xfe, 0x06, 0x61, 0x95, 0xe9, 0xa8, 0xe8, 0x60, 0xec, 0x5a, 0x2c, 0x26, 0xcb, 0xfb, 0xed, 0x9d, 0x00, 0x46, 0x86, 0x70, 0x6a, 0x7c, 0xed, 0x73, 0x30, 0xcd, 0xce, 0x13, 0x5b, 0x3a, 0x31, 0x28, 0xb2, 0x2b, 0x5b, 0xed, 0x51, 0xe0, 0xd8, 0xd8, 0x58, 0x04, 0x1b, 0x7c, 0xe5, 0x36, 0xd7, 0x53, 0x25, 0xde, 0xbc, 0x6e, 0xbe, 0x72, 0x75, 0x7e, 0x91, 0x4a, 0xf8, 0x84, 0x46, 0x9d, 0x4a, 0x7c, 0x61, 0xdd, 0x85, 0x64, 0x0d, 0x17, 0x10, 0xbf, 0x57, 0x87, 0xd3, 0xd2, 0x6b, 0x7d, 0x7e, 0x2e, 0x15, 0xe2, 0x74, 0x5c, 0xf6, 0x53, 0xd6, 0x32, 0x6d, 0xed, 0xb6, 0xcd, 0x17, 0xd2, 0x82, 0x82, 0x1f, 0x6c, 0x6d, 0xb1, 0xed, 0x48, 0x6b, 0x00, 0x95, 0xc9, 0x62, 0xd7, 0x4e, 0xd5, 0x74, 0xe7, 0x80, 0xd4, 0x28, 0x90, 0x37, 0x30, 0x98, 0x65, 0x65, 0x3d, 0xef, 0xf8, 0x84, 0xcd, 0x0c, 0x48, 0x10, 0x10, 0x98, 0x82, 0x04, 0x51, 0x9e, 0xcc, 0x23, 0x97, 0xd5, 0x36, 0x3e, 0x91, 0x4d, 0xf2, 0xeb, 0xed, 0xe0, 0xf3, 0x77, 0x47, 0x07, 0x45, 0x4e, 0x15, 0xe2, 0x17, 0x54, 0x7b, 0xd1, 0xbf, 0xef, 0xe6, 0x1e, 0x75, 0xa4, 0x0c, 0x36, 0x3c, 0xb4, 0x20, 0x29, 0x7f, 0x38, 0x56, 0x91, 0xae, 0x61, 0x45, 0xc9, 0xb3, 0x87, 0xe3, 0xe3, 0xd4, 0x73, 0x91, 0x6a, 0x7e, 0x55, 0x67, 0x23, 0x45, 0x5d, 0x61, 0x91, 0x92, 0x92, 0x22, 0x74, 0x19, 0x13, 0x11, 0x21, 0xaf, 0x31, 0x52, 0x0e, 0x6f, 0xa4, 0x4c, 0xd6, 0x5d, 0x1b, 0x3d, 0x4d, 0x82, 0x70, 0x9d, 0x22, 0x0b, 0xe4, 0x59, 0xff, 0x84, 0x0b, 0xda, 0x4b, 0x74, 0x83, 0x40, 0xc4, 0x43, 0xa8, 0xef, 0x02, 0xe8, 0x4e, 0xff, 0x5e, 0xcf, 0x15, 0x7c, 0xe8, 0x3a, 0x7c, 0xb8, 0x7e, 0xad, 0x70, 0x18, 0x03, 0x4f, 0xf8, 0xc9, 0x5a, 0xcc, 0xa1, 0xc8, 0x3d, 0x6e, 0x8b, 0x15, 0x93, 0x63, 0xa9, 0xc1, 0x8d, 0x0d, 0x34, 0x8a, 0xe1, 0x2f, 0x52, 0xd7, 0x5e, 0xe5, 0xcc, 0x34, 0x25, 0x9d, 0xce, 0xd9, 0x89, 0x8a, 0xce, 0xea, 0xb7, 0xf9, 0x4b, 0xda, 0xdb, 0xdb, 0xaf, 0x1c, 0x1e, 0x12, 0x45, 0xf4, 0xa0, 0x1b, 0x24, 0x41, 0x54, 0x48, 0x44, 0xfe, 0xbb, 0xde, 0x1f, 0xd5, 0xd3, 0xea, 0x73, 0x52, 0x24, 0xc3, 0x75, 0xa6, 0x26, 0xb3, 0x73, 0x8a, 0x28, 0xea, 0x5e, 0xd3, 0xe5, 0x8e, 0x15, 0x30, 0xe5, 0xbd, 0x7f, 0xa5, 0x5d, 0x7b, 0xff, 0x7e, 0xfc, 0x61, 0xd5, 0x79, 0xed, 0xa9, 0xfe, 0xfb, 0x0b, 0xbd, 0x9b, 0x30, 0x0b, 0x19, 0x3a, 0xb0, 0xc8, 0xab, 0xa4, 0xd3, 0xb6, 0xda, 0x79, 0x7c, 0x43, 0xa9, 0x00, 0xf6, 0xbc, 0x57, 0x67, 0xfd, 0xe9, 0x5e, 0xc1, 0xd0, 0xdc, 0x8b, 0x8a, 0x3f, 0x7f, 0xfa, 0xcc, 0x6a, 0x80, 0x0e, 0x11, 0x93, 0xae, 0x34, 0x83, 0x6e, 0xe7, 0xdc, 0x87, 0xb7, 0x57, 0xd3, 0xcc, 0x2c, 0xa0, 0x03, 0x4e, 0x75, 0x2e, 0xe6, 0xf0, 0xb0, 0xf7, 0xea, 0xd1, 0x15, 0xb5, 0x04, 0xcd, 0x73, 0x48, 0x72, 0x71, 0x87, 0x65, 0xc7, 0x7c, 0xa6, 0x43, 0x37, 0xd1, 0x87, 0xe8, 0x40, 0xb8, 0x27, 0xf3, 0xf0, 0x19, 0x66, 0x10, 0xf8, 0xa4, 0xa4, 0xed, 0x61, 0xca, 0xa8, 0xb8, 0xc8, 0x63, 0x5c, 0x53, 0xe0, 0x17, 0x37, 0x0a, 0xea, 0xc4, 0x88, 0x30, 0xf1, 0xc0, 0xa2, 0xf3, 0x2a, 0x63, 0xc6, 0xc9, 0x8c, 0x75, 0x9b, 0x65, 0x6f, 0x52, 0x8a, 0x91, 0x06, 0xa2, 0xc8, 0xf1, 0x4c, 0x21, 0x68, 0x86, 0x7c, 0x52, 0xa5, 0xe0, 0x35, 0x93, 0xd4, 0x62, 0x7d, 0xd7, 0x30, 0xaf, 0x00, 0x08, 0xfc, 0x2a, 0x87, 0xaa, 0xfe, 0x97, 0x2d, 0xf2, 0x4c, 0xd1, 0xfd, 0xfc, 0x5b, 0xb8, 0x06, 0x51, 0xec, 0x15, 0xd9, 0xf5, 0x6f, 0x66, 0x53, 0x76, 0xde, 0x23, 0x62, 0xf9, 0xf7, 0xef, 0xcf, 0x72, 0xab, 0x8c, 0x4f, 0x95, 0x46, 0xe8, 0x73, 0xd1, 0x42, 0xa1, 0xe0, 0x1f, 0xec, 0xa2, 0xd3, 0x25, 0x30, 0xf5, 0xc4, 0x27, 0x43, 0xd6, 0xd5, 0x4c, 0xb6, 0x04, 0x55, 0xc6, 0xb4, 0x78, 0xa0, 0xa0, 0xac, 0x74, 0xae, 0x21, 0xf2, 0x89, 0xb4, 0xe8, 0xb6, 0x87, 0x32, 0x23, 0xbe, 0x87, 0xf2, 0x4b, 0x19, 0xf0, 0xf6, 0xe8, 0x57, 0x8e, 0x82, 0x92, 0x2a, 0x9a, 0x72, 0xbf, 0x1f, 0x4b, 0xfb, 0xc0, 0x0c, 0xe6, 0x3f, 0x9d, 0x0d, 0xc9, 0x3e, 0x2c, 0xdb, 0xd4, 0x4d, 0xfc, 0x28, 0xcd, 0x83, 0x8d, 0x09, 0x33, 0x1c, 0xdb, 0x63, 0x75, 0x0d, 0xc7, 0xf7, 0x68, 0x3d, 0x7b, 0x4c, 0x2f, 0xb6, 0xec, 0xbb, 0xd6, 0x9d, 0xb9, 0x78, 0xf0, 0xc2, 0x79, 0x85, 0xd6, 0xc2, 0x7a, 0x13, 0xdb, 0x6c, 0xc0, 0xd5, 0xea, 0x34, 0xf0, 0x6c, 0x7a, 0x53, 0x2a, 0x32, 0xb5, 0x6e, 0x71, 0xc6, 0xe0, 0x2d, 0xc9, 0xaf, 0x92, 0xb2, 0x25, 0xc4, 0xa8, 0x90, 0xd2, 0x7a, 0xf1, 0xe1, 0x65, 0xf6, 0x92, 0xa5, 0x23, 0x74, 0xc8, 0xb2, 0xbd, 0x5e, 0x3e, 0x1f, 0xef, 0x4a, 0x2b, 0x7f, 0xb7, 0x3a, 0x3f, 0x7b, 0xb5, 0xe2, 0x55, 0x1c, 0xd3, 0x67, 0xd4, 0xe3, 0x33, 0x5f, 0x39, 0xe5, 0xfe, 0xc9, 0xd8, 0xaa, 0x2a, 0xc9, 0x3e, 0xd0, 0x3b, 0x16, 0xd0, 0xf6, 0x0f, 0x9a, 0x12, 0x9f, 0x0f, 0xdc, 0x21, 0x66, 0xf0, 0xc4, 0x5f, 0xd9, 0x71, 0x8e, 0x81, 0xf0, 0x68, 0xe6, 0xbe, 0xd7, 0xeb, 0x4d, 0x99, 0x44, 0xab, 0x63, 0x95, 0x3a, 0x3a, 0xd3, 0xb5, 0x07, 0x7f, 0x21, 0x38, 0xbd, 0x4f, 0x64, 0x71, 0x7c, 0x07, 0x1d, 0x47, 0xe7, 0x8b, 0x64, 0xc2, 0xf2, 0x68, 0x01, 0xd1, 0xe6, 0x1b, 0xa2, 0x27, 0xbe, 0x26, 0x14, 0xc1, 0xba, 0x8f, 0x3d, 0xc2, 0xf5, 0x0c, 0xb4, 0x3d, 0xcb, 0x0c, 0xfa, 0x7a, 0x7f, 0x87, 0x17, 0x84, 0x6e, 0xeb, 0x2b, 0x76, 0x8c, 0x1c, 0xdc, 0x3d, 0x7d, 0xf7, 0xe5, 0xe1, 0x87, 0xf4, 0x01, 0xd0, 0x2e, 0x0c, 0x61, 0xca, 0xb6, 0x19, 0x17, 0xb7, 0xdc, 0x2c, 0x86, 0x84, 0x3c, 0x08, 0xb9, 0xd9, 0x3b, 0xe7, 0x19, 0x65, 0xbf, 0x7d, 0xd7, 0x6d, 0x33, 0xb3, 0xdf, 0x63, 0x73, 0x77, 0xdb, 0x9b, 0x37, 0xe3, 0x60, 0xe5, 0x89, 0x41, 0x58, 0xd9, 0x61, 0x29, 0xfb, 0xca, 0x04, 0xc3, 0x91, 0x46, 0x18, 0x29, 0x36, 0x10, 0x47, 0xf8, 0xc6, 0x10, 0x1a, 0x25, 0xf8, 0xd5, 0xbf, 0xb3, 0x98, 0xb1, 0x44, 0x5e, 0xd5, 0xa7, 0xf6, 0xab, 0xe4, 0xe4, 0x96, 0x02, 0xdf, 0x9f, 0x4c, 0xfb, 0x73, 0x5d, 0xa2, 0xd9, 0x7d, 0x83, 0x26, 0x87, 0x5a, 0x05, 0x9f, 0x66, 0x0d, 0x89, 0xf0, 0xd6, 0x8d, 0xb0, 0x51, 0xe2, 0x9e, 0xa3, 0x1b, 0xba, 0xe8, 0x9c, 0xc7, 0x20, 0x1b, 0x50, 0xc5, 0x4a, 0xe1, 0x8d, 0xf3, 0x72, 0xba, 0xf0, 0x73, 0x3a, 0xf2, 0x63, 0x4c, 0x24, 0x3c, 0xcf, 0x66, 0x03, 0x76, 0x1a, 0x8d, 0x31, 0xd3, 0x7a, 0xc9, 0x41, 0x63, 0xd8, 0xc2, 0x8c, 0x0d, 0xd2, 0x8d, 0x62, 0x7a, 0xe4, 0x4b, 0x43, 0x26, 0x60, 0x6f, 0xe7, 0xfd, 0x6f, 0x34, 0x3f, 0x9d, 0x81, 0x65, 0xa7, 0x16, 0x90, 0x27, 0x99, 0x2c, 0x38, 0x92, 0xd2, 0x49, 0x1b, 0xbf, 0x6c, 0xd0, 0x64, 0xc8, 0x30, 0x9b, 0xef, 0x6f, 0x73, 0xeb, 0xd7, 0x93, 0xfe, 0x7e, 0x21, 0x8c, 0x70, 0x83, 0x9e, 0x3f, 0xb6, 0xa6, 0x0b, 0x13, 0xff, 0x7c, 0xe8, 0xc1, 0xd0, 0x19, 0xb7, 0x5e, 0xb0, 0xe2, 0xc1, 0x21, 0xaa, 0xd3, 0x10, 0x04, 0xbe, 0x62, 0x54, 0xd9, 0x6d, 0xf8, 0x65, 0xff, 0xca, 0x5d, 0x58, 0x31, 0x0a, 0x8c, 0x7a, 0x22, 0xe0, 0xab, 0xf3, 0x85, 0x05, 0xc7, 0x2a, 0xd4, 0xaa, 0xc1, 0x51, 0x00, 0xa4, 0x1c, 0x1f, 0x26, 0x78, 0x38, 0xd2, 0x15, 0xd6, 0x31, 0xa9, 0x12, 0x6d, 0x4c, 0x03, 0x28, 0xfe, 0x6d, 0x8c, 0xe3, 0x99, 0xca, 0x4b, 0x0e, 0x12, 0xed, 0x91, 0x76, 0x87, 0x86, 0xb1, 0x39, 0x0e, 0xad, 0x16, 0xa6, 0x47, 0x7e, 0xdf, 0x27, 0x4c, 0x1e, 0xa0, 0x7e, 0x77, 0x97, 0x1b, 0xe9, 0x34, 0x2c, 0x10, 0x0d, 0x94, 0x0f, 0x3d, 0xfa, 0x57, 0x4c, 0xbd, 0xf6, 0x24, 0x96, 0x0d, 0x4b, 0x38, 0xa0, 0x7b, 0x7f, 0x2c, 0xdf, 0xab, 0x41, 0xba, 0x48, 0x06, 0x21, 0xcd, 0x9d, 0xb1, 0x30, 0xca, 0xe7, 0x9c, 0x85, 0xed, 0x49, 0x99, 0x16, 0x47, 0xeb, 0xad, 0x22, 0x7f, 0x28, 0x13, 0x6b, 0x2a, 0x0b, 0x98, 0xd4, 0xb4, 0x34, 0x39, 0xb7, 0x56, 0x03, 0xdc, 0x45, 0xe2, 0x27, 0xc4, 0xb8, 0x64, 0xe4, 0xb8, 0x51, 0xa7, 0x7e, 0x76, 0xcf, 0xa6, 0x2a, 0xde, 0xed, 0x5f, 0xfc, 0xe4, 0x42, 0x0a, 0x2b, 0xa0, 0x6d, 0x85, 0x56, 0x73, 0x05, 0xdc, 0x51, 0x03, 0x16, 0x94, 0x57, 0xfb, 0xc3, 0xea, 0x44, 0x13, 0xb4, 0x03, 0x13, 0x69, 0x6b, 0x61, 0x0f, 0xab, 0x2c, 0x75, 0xa7, 0x25, 0x0f, 0xe1, 0x2e, 0x50, 0x82, 0x05, 0xcc, 0xb3, 0x7f, 0xa1, 0x5d, 0x2e, 0xfc, 0xf9, 0x13, 0xe8, 0x2c, 0x7f, 0x9e, 0xa0, 0x3c, 0x28, 0x98, 0xba, 0xe7, 0xeb, 0xb7, 0x8e, 0x30, 0x58, 0x77, 0xfe, 0xf2, 0xf3, 0x11, 0x28, 0x20, 0x97, 0xc1, 0xec, 0x7e, 0x59, 0xee, 0xec, 0xf1, 0x61, 0xa1, 0x9b, 0xad, 0xc2, 0x5b, 0x24, 0xdc, 0x72, 0x8b, 0x12, 0xb6, 0x91, 0x3c, 0x7f, 0x0c, 0xdf, 0xe3, 0x13, 0x59, 0xe0, 0x84, 0xcd, 0x21, 0xf8, 0xde, 0x3f, 0xde, 0xfa, 0x85, 0x97, 0x58, 0x34, 0xca, 0xf6, 0x75, 0xff, 0xac, 0x52, 0x83, 0x20, 0x21, 0x56, 0x4d, 0x0e, 0x37, 0xdd, 0x0d, 0x9f, 0x59, 0xd1, 0x97, 0x9b, 0x95, 0x5d, 0xba, 0x4d, 0x37, 0x69, 0xe8, 0xe0, 0x51, 0xa0, 0xa9, 0xe4, 0x87, 0x95, 0xae, 0x37, 0x0f, 0x21, 0x10, 0x8c, 0x27, 0x89, 0x84, 0x51, 0x1c, 0x2c, 0xe2, 0xe5, 0x54, 0xb4, 0x75, 0xfb, 0x3d, 0x49, 0xf4, 0x7c, 0x15, 0xe2, 0x0b, 0xdc, 0x0e, 0xbd, 0xd4, 0x13, 0x5b, 0x38, 0x41, 0x62, 0x23, 0xab, 0x9a, 0xa5, 0xb8, 0xf8, 0x4d, 0x9e, 0x66, 0x2e, 0xc7, 0xae, 0x9e, 0x8b, 0x73, 0xb8, 0xc7, 0x78, 0x5f, 0xc6, 0x54, 0xea, 0xb2, 0xf5, 0x5e, 0xef, 0xda, 0xd5, 0x31, 0x4a, 0xb2, 0x0d, 0xd5, 0xf8, 0xa1, 0xb5, 0x67, 0x4d, 0xaf, 0xb5, 0x04, 0x07, 0xf4, 0x3c, 0xce, 0x0d, 0x7d, 0x46, 0x4f, 0xb3, 0xf3, 0x08, 0x09, 0x47, 0x3e, 0xe7, 0xec, 0xb9, 0x90, 0x54, 0x02, 0xfb, 0xad, 0x50, 0xb9, 0x9e, 0x46, 0x40, 0x9a, 0x0e, 0xcb, 0x08, 0x65, 0x78, 0x23, 0x2c, 0xba, 0xbf, 0x2a, 0xae, 0x23, 0xf2, 0xa7, 0xa6, 0x68, 0xe7, 0x7c, 0xee, 0x35, 0xc2, 0xa6, 0x01, 0xa4, 0x36, 0x26, 0xb6, 0xb7, 0x37, 0x85, 0xe8, 0xe8, 0xee, 0x2f, 0xe0, 0xa5, 0x94, 0xa3, 0x81, 0x54, 0xc8, 0xf8, 0xde, 0xee, 0xf1, 0x4a, 0x08, 0x7d, 0x78, 0xf6, 0x8a, 0xf4, 0x6f, 0x2e, 0x5e, 0xf8, 0x50, 0xa5, 0xdf, 0x28, 0x31, 0x9d, 0x44, 0x52, 0x10, 0x69, 0x41, 0x35, 0xd3, 0x10, 0xa5, 0x7f, 0x09, 0x21, 0x28, 0x68, 0x25, 0xf9, 0xbb, 0x9e, 0x92, 0x84, 0xb5, 0x50, 0xa6, 0xd4, 0x92, 0x0a, 0x84, 0xe4, 0x17, 0x84, 0x23, 0x3b, 0xc1, 0x91, 0x5d, 0xe0, 0xac, 0x75, 0xc9, 0xca, 0x6a, 0x5c, 0x7a, 0xd0, 0x75, 0x23, 0xec, 0x1b, 0x3f, 0x94, 0xec, 0xe8, 0xe6, 0xa9, 0xb0, 0xf9, 0x01, 0x2c, 0x20, 0xb0, 0x0d, 0x5a, 0x6e, 0xe9, 0x95, 0x87, 0x91, 0xc2, 0xa5, 0x77, 0xfb, 0x43, 0x9a, 0x41, 0x9c, 0xa8, 0x9b, 0xf9, 0x40, 0x81, 0xc6, 0xc1, 0xa3, 0x2e, 0x66, 0xd2, 0x04, 0x27, 0x28, 0x3b, 0x05, 0xbe, 0x98, 0x73, 0x74, 0x44, 0x9d, 0x49, 0x49, 0xe6, 0xab, 0x58, 0xdd, 0x18, 0xc7, 0x1d, 0x4a, 0x22, 0xb6, 0x93, 0x74, 0x76, 0xed, 0xe2, 0x2f, 0x64, 0x34, 0x12, 0x23, 0x64, 0x14, 0x37, 0x14, 0xef, 0xe0, 0xf7, 0xe1, 0xb2, 0xfb, 0x26, 0xe2, 0x3e, 0xa4, 0xb8, 0x3c, 0x5c, 0xf3, 0x99, 0xc0, 0x2f, 0x0d, 0x8f, 0x26, 0x8c, 0xcf, 0x85, 0x36, 0xc4, 0x7e, 0x4c, 0x0c, 0x4d, 0x44, 0x6c, 0x39, 0x55, 0x8d, 0x17, 0x24, 0xd1, 0x24, 0x96, 0xb2, 0x63, 0xf4, 0x36, 0x3f, 0x9d, 0xf2, 0x59, 0xce, 0x0d, 0x9d, 0x2a, 0xe9, 0x84, 0xbd, 0x25, 0x34, 0xe5, 0x24, 0x10, 0x80, 0xa9, 0xda, 0xeb, 0xb3, 0x7f, 0x01, 0xf7, 0x98, 0x98, 0x8c, 0xfe, 0x6c, 0x43, 0xba, 0x01, 0xce, 0xdc, 0xd3, 0xf6, 0x93, 0xfa, 0xbc, 0x5b, 0x52, 0xb7, 0xfe, 0x83, 0xe7, 0x02, 0xd8, 0xcd, 0xc9, 0xeb, 0xc8, 0xdc, 0xef, 0x3f, 0xd0, 0xe7, 0x3d, 0x18, 0x3b, 0x1e, 0xfc, 0xc3, 0x5f, 0x42, 0xed, 0x7a, 0x58, 0xe9, 0x7a, 0x44, 0xb2, 0xd4, 0x48, 0x5e, 0x76, 0x11, 0x8e, 0xd4, 0xfc, 0xb5, 0xfc, 0x67, 0xdc, 0xd8, 0x87, 0xc1, 0x9a, 0x47, 0x3a, 0x56, 0x47, 0xbe, 0xb3, 0x99, 0xc3, 0xa2, 0xc2, 0xff, 0x72, 0x7e, 0xbf, 0xa7, 0xae, 0xb6, 0x24, 0xd5, 0xff, 0x54, 0x5f, 0xe2, 0xae, 0xff, 0x90, 0x98, 0x98, 0xa2, 0x44, 0xc1, 0x3c, 0xef, 0x71, 0x30, 0x2b, 0xf9, 0x0c, 0x8d, 0x1f, 0xf8, 0x43, 0x80, 0x68, 0xf4, 0x0b, 0xd1, 0x7f, 0x94, 0x29, 0xe1, 0x53, 0x98, 0xd8, 0x3f, 0xfe, 0x45, 0xda, 0xb5, 0xc5, 0xe5, 0x99, 0x66, 0xce, 0x3b, 0x9c, 0xf9, 0x23, 0xaf, 0x18, 0x54, 0xb7, 0xf3, 0xe6, 0x23, 0x22, 0x91, 0x5b, 0xc9, 0xc9, 0x75, 0x1e, 0xf2, 0x13, 0xb1, 0x42, 0x36, 0x41, 0x4c, 0xe6, 0xbd, 0x79, 0xc7, 0x5e, 0xf7, 0x3c, 0x01, 0x0a, 0x81, 0x99, 0xab, 0xe1, 0x65, 0xda, 0x86, 0xa6, 0xc1, 0x66, 0x24, 0xaf, 0xb3, 0x9b, 0xab, 0xb0, 0x40, 0xed, 0x54, 0x5d, 0x82, 0x40, 0x3b, 0xf3, 0xf3, 0xa8, 0x38, 0x3b, 0xde, 0x76, 0xb5, 0x2b, 0x62, 0x15, 0xb9, 0x7e, 0x36, 0x0b, 0x9f, 0xa9, 0xbd, 0xe1, 0x15, 0x3a, 0x14, 0x71, 0x8e, 0x1b, 0x30, 0x4b, 0xfb, 0x6e, 0x0f, 0x10, 0x87, 0x19, 0xd8, 0xc7, 0xcf, 0xa1, 0xae, 0xe0, 0x6e, 0xef, 0x98, 0x09, 0x17, 0x0a, 0x66, 0x75, 0x93, 0x03, 0x81, 0xa0, 0xe0, 0x47, 0x13, 0x0e, 0x23, 0xef, 0xa4, 0x37, 0x9a, 0x3b, 0xda, 0xac, 0xde, 0xeb, 0x8f, 0x32, 0x35, 0x9f, 0x77, 0xe6, 0x52, 0xbd, 0x58, 0xdb, 0x55, 0x93, 0x82, 0x79, 0x5b, 0x3d, 0x8e, 0xd7, 0xb0, 0x5a, 0xb3, 0x34, 0xa4, 0x20, 0x89, 0x7f, 0x11, 0x8b, 0xcc, 0xd8, 0xf7, 0x58, 0x8b, 0xbf, 0x8f, 0x5b, 0xd5, 0xe7, 0x7f, 0xe0, 0x23, 0x60, 0x18, 0xbb, 0x1c, 0x94, 0x0a, 0x22, 0xaa, 0x9a, 0xdd, 0x53, 0x1e, 0xfa, 0xd9, 0xc5, 0xf3, 0xb9, 0x00, 0x0c, 0xc4, 0xd7, 0xa6, 0xea, 0x94, 0xe7, 0x58, 0xd9, 0xbd, 0x52, 0x95, 0xfc, 0x24, 0x69, 0xf8, 0x9b, 0x29, 0xa6, 0xa5, 0x91, 0x04, 0x50, 0x92, 0xa6, 0x41, 0x24, 0x62, 0x10, 0x0d, 0x05, 0x97, 0x76, 0xf3, 0x2c, 0xb7, 0xe4, 0x2e, 0xe8, 0x44, 0xd1, 0x1b, 0x24, 0x07, 0x5e, 0x8a, 0xa0, 0xdf, 0x93, 0x4d, 0x09, 0x2f, 0x76, 0xf4, 0xbb, 0x28, 0x4a, 0x89, 0xd0, 0x01, 0x87, 0x8e, 0xb6, 0x69, 0xa7, 0xae, 0x37, 0xf3, 0x17, 0x9d, 0xfe, 0xb8, 0x2d, 0xc5, 0x68, 0xed, 0xa3, 0x59, 0x7d, 0xe2, 0x3c, 0x92, 0xd1, 0xb4, 0x8a, 0x44, 0xfb, 0x17, 0x87, 0xfb, 0xb4, 0xea, 0xd6, 0x7b, 0xe2, 0xbe, 0xe8, 0xd2, 0x7d, 0x6c, 0x4c, 0x00, 0x16, 0x76, 0x77, 0x79, 0x0a, 0x32, 0xd3, 0xe6, 0xf2, 0xb4, 0x82, 0xef, 0xd4, 0x92, 0x6a, 0xca, 0xc5, 0xe9, 0xa8, 0xcf, 0x19, 0xf0, 0xe3, 0xc1, 0x3c, 0x93, 0x2d, 0x6d, 0xa2, 0x38, 0x2e, 0xcc, 0x22, 0x5e, 0xbd, 0x53, 0xba, 0xba, 0xd8, 0x17, 0x62, 0x74, 0x53, 0x2d, 0x8b, 0x53, 0xd8, 0x98, 0x57, 0xab, 0x1d, 0xa9, 0x09, 0x47, 0x47, 0x8b, 0x09, 0x59, 0xd0, 0xe2, 0xb4, 0x21, 0x51, 0x6c, 0x8f, 0xde, 0x6e, 0x60, 0xf3, 0x35, 0x82, 0xea, 0xbb, 0xfe, 0x8b, 0x70, 0xe4, 0xc3, 0x5a, 0x90, 0x3a, 0x16, 0xfb, 0x19, 0x70, 0xc2, 0xf0, 0x08, 0xbb, 0xd6, 0x47, 0x79, 0x65, 0x02, 0x90, 0x5e, 0xa2, 0x69, 0x91, 0x28, 0x9e, 0x09, 0x60, 0xc1, 0x75, 0x7f, 0x9c, 0x2c, 0x0e, 0xf9, 0xda, 0xa8, 0x49, 0x86, 0xf1, 0x1b, 0xfd, 0x9e, 0x51, 0x84, 0xce, 0x66, 0xde, 0x10, 0x1a, 0x0c, 0xce, 0x7c, 0x89, 0x9b, 0x0e, 0x16, 0x26, 0x08, 0xd9, 0x69, 0xa1, 0xa5, 0x21, 0x6c, 0xf9, 0xe9, 0x3d, 0xbc, 0x1e, 0x58, 0xe2, 0x5e, 0x37, 0x2a, 0xe9, 0xb9, 0x80, 0x78, 0xf9, 0x7a, 0x99, 0x08, 0xc4, 0x9b, 0x5a, 0xea, 0x75, 0x9c, 0xfe, 0x9a, 0x18, 0x7e, 0x66, 0x09, 0xf7, 0x5b, 0x6e, 0xf5, 0x43, 0xbd, 0x29, 0x55, 0x39, 0x1e, 0x21, 0xfb, 0x09, 0x2b, 0xdb, 0x69, 0xf9, 0x34, 0x66, 0xf2, 0xdd, 0xbb, 0x77, 0xc4, 0xb4, 0xb4, 0x11, 0x3f, 0x7f, 0xaa, 0xe7, 0xe5, 0xe5, 0xb5, 0x8f, 0x5b, 0xcc, 0x8d, 0x33, 0x7c, 0xf4, 0xf7, 0x3a, 0x1e, 0xf8, 0xc0, 0x67, 0xd5, 0x59, 0x03, 0xc6, 0xec, 0xd0, 0x66, 0x84, 0xba, 0xe8, 0x15, 0x3f, 0x0e, 0x8d, 0xc9, 0xec, 0x3d, 0xf8, 0xf4, 0x59, 0x24, 0x09, 0xf9, 0x11, 0xe8, 0xbe, 0x86, 0xc4, 0x32, 0xf8, 0x12, 0x09, 0x6c, 0x3d, 0x78, 0x37, 0xeb, 0xd4, 0x73, 0x77, 0xe0, 0xed, 0x96, 0xe1, 0x4d, 0x5e, 0xd3, 0x22, 0x72, 0xbe, 0x54, 0x40, 0x16, 0xe7, 0xb2, 0xa6, 0x63, 0x5a, 0x17, 0x2d, 0x55, 0xef, 0xe2, 0xe1, 0xda, 0xc5, 0x65, 0x07, 0x1d, 0xb2, 0xf7, 0x5e, 0x4e, 0xab, 0xa4, 0x54, 0xfc, 0x15, 0x8c, 0x52, 0xf3, 0x74, 0x51, 0xba, 0xb4, 0xb5, 0xc2, 0xd3, 0x5c, 0x46, 0xb5, 0x04, 0xf0, 0xad, 0x91, 0x60, 0x8e, 0xda, 0xc5, 0xd9, 0xd2, 0xac, 0x2c, 0x10, 0xea, 0xf7, 0xe3, 0xa1, 0x8c, 0xfe, 0x38, 0xd5, 0xb3, 0x35, 0xba, 0x73, 0xd2, 0xfc, 0x74, 0x9e, 0x0b, 0x62, 0x84, 0x01, 0x48, 0x31, 0xb4, 0x8f, 0xf7, 0x6f, 0x7e, 0x43, 0x46, 0x69, 0x75, 0xf4, 0xa6, 0x01, 0x31, 0x81, 0x55, 0x30, 0x92, 0xd1, 0xc5, 0x83, 0x5b, 0x18, 0xf6, 0x59, 0x4d, 0xf1, 0xd5, 0xfe, 0x86, 0x04, 0xb9, 0x8d, 0xb9, 0x7a, 0x32, 0xd6, 0x77, 0x61, 0x17, 0xee, 0xbb, 0x3f, 0x5b, 0x97, 0x5f, 0x4b, 0xe6, 0xe6, 0xee, 0x82, 0x19, 0xf0, 0x53, 0x62, 0xb9, 0x43, 0x80, 0x04, 0x53, 0x66, 0x4f, 0x98, 0xd0, 0x5a, 0x56, 0x93, 0x4b, 0xaf, 0x38, 0xeb, 0x2c, 0xa3, 0xcf, 0x14, 0xb8, 0x38, 0x7a, 0xa4, 0xaa, 0x6a, 0x98, 0xff, 0xb4, 0xd2, 0x70, 0x86, 0x92, 0xc5, 0xa5, 0xa6, 0x7e, 0xee, 0xef, 0x57, 0x33, 0xbb, 0x62, 0x85, 0x40, 0xd0, 0xea, 0x96, 0xfd, 0xc5, 0x07, 0x07, 0x0d, 0xa5, 0xb9, 0x2e, 0x84, 0x77, 0x8f, 0x3b, 0x49, 0xab, 0x9d, 0xa7, 0xff, 0x94, 0x09, 0x73, 0xb7, 0x36, 0xd6, 0x32, 0xcc, 0x5f, 0xd2, 0xc9, 0xca, 0x0d, 0x52, 0xef, 0x89, 0x23, 0xdd, 0x06, 0xfc, 0xf0, 0x46, 0x60, 0x74, 0x9a, 0x6f, 0xd0, 0x25, 0xa0, 0xf1, 0xb7, 0xa3, 0x22, 0x74, 0xbb, 0x53, 0x68, 0x68, 0xf2, 0x31, 0xba, 0xba, 0xfb, 0x39, 0x49, 0x22, 0x10, 0x47, 0xb7, 0x52, 0x27, 0x6c, 0x39, 0x32, 0x0a, 0x32, 0x37, 0xb8, 0x8e, 0xae, 0xee, 0x9a, 0xdc, 0xc8, 0x30, 0x11, 0x1a, 0x45, 0x1d, 0xbc, 0x5b, 0xea, 0xdf, 0x9f, 0x04, 0xfd, 0x4a, 0x8b, 0x1e, 0xab, 0x4c, 0x71, 0x76, 0x76, 0xec, 0x4c, 0xff, 0xeb, 0xa7, 0x1e, 0x7b, 0x33, 0x1f, 0xbb, 0xbb, 0xbb, 0xf5, 0xce, 0x3d, 0x97, 0xef, 0xc5, 0x39, 0x91, 0x70, 0x9e, 0x49, 0x8d, 0xc3, 0xfd, 0x96, 0x38, 0x4e, 0x78, 0x5e, 0xc6, 0x40, 0xc7, 0x68, 0x25, 0xee, 0x95, 0xd0, 0x35, 0x53, 0x11, 0x4f, 0x31, 0x39, 0x21, 0x88, 0x86, 0x14, 0x96, 0xf6, 0xfa, 0x63, 0x20, 0x39, 0x32, 0x53, 0x7c, 0x23, 0x8e, 0x09, 0xf7, 0x58, 0x16, 0xf5, 0xfc, 0x2d, 0xb4, 0xbd, 0x1d, 0xfb, 0x8e, 0x96, 0x26, 0x5a, 0xbd, 0xce, 0x10, 0x9e, 0x84, 0x5e, 0xbb, 0xf9, 0x4d, 0x04, 0x46, 0x80, 0xba, 0x81, 0x9a, 0xd7, 0x5c, 0xa6, 0x69, 0x74, 0x58, 0xb4, 0x4f, 0x78, 0xd9, 0xf7, 0x93, 0x4d, 0x86, 0x37, 0x56, 0x7e, 0x7e, 0xd9, 0x61, 0xe2, 0x4d, 0xc8, 0x65, 0x37, 0x32, 0xd4, 0xda, 0x7c, 0x6e, 0x78, 0xda, 0x5b, 0xf7, 0x5d, 0x0b, 0x20, 0x1e, 0xae, 0x12, 0x76, 0x44, 0x5c, 0x6f, 0x05, 0x08, 0xe9, 0x24, 0x3f, 0xdf, 0xe6, 0xa8, 0x1d, 0x26, 0xf7, 0xa6, 0x40, 0xa2, 0xe0, 0xf3, 0x2a, 0x32, 0x08, 0x96, 0x7f, 0x8c, 0x98, 0x41, 0x6f, 0xe6, 0xf7, 0x0b, 0x13, 0x19, 0x08, 0x92, 0xc1, 0x99, 0x7f, 0x24, 0x97, 0x71, 0x10, 0x6e, 0x2a, 0x1d, 0x13, 0x81, 0x27, 0xf4, 0xaf, 0x8c, 0x84, 0x97, 0xbc, 0x98, 0x2d, 0x60, 0x30, 0xf1, 0x3f, 0x3f, 0x05, 0x05, 0x05, 0xbd, 0xb6, 0xd2, 0x3d, 0x8f, 0x0e, 0x9a, 0x0e, 0x6b, 0x77, 0x45, 0x2e, 0xbb, 0xef, 0x3c, 0x57, 0x0a, 0x43, 0x0f, 0x74, 0x38, 0x0b, 0xa7, 0x85, 0x53, 0xe2, 0xcc, 0x8c, 0x43, 0xcc, 0x48, 0x34, 0x20, 0x42, 0x07, 0x2c, 0x1a, 0xdf, 0xac, 0xba, 0x1c, 0x2a, 0x4d, 0x7f, 0x8b, 0x52, 0x4d, 0x6c, 0x28, 0x6b, 0x1d, 0x3d, 0xa9, 0x11, 0x73, 0x85, 0xf9, 0xdd, 0x65, 0xd7, 0x26, 0xcb, 0x30, 0x23, 0x8c, 0xc9, 0x00, 0x80, 0x94, 0x05, 0x32, 0x21, 0xa4, 0x9f, 0x0e, 0x05, 0x0f, 0x8f, 0x4e, 0xb7, 0x5d, 0xef, 0x3e, 0x5f, 0xf8, 0x70, 0xd8, 0x42, 0xef, 0x13, 0xe5, 0x77, 0x73, 0xb1, 0x5a, 0xd9, 0xc7, 0x20, 0xaf, 0xa7, 0x97, 0xa4, 0xf6, 0x8f, 0xb9, 0xda, 0xb1, 0x8b, 0xf4, 0x52, 0xe3, 0xd3, 0x78, 0xd6, 0xdf, 0xb1, 0xbf, 0xa2, 0xeb, 0x51, 0x7e, 0x18, 0x45, 0xef, 0xfe, 0x02, 0x10, 0x66, 0xb1, 0x58, 0xd7, 0x8e, 0x35, 0xd2, 0x0c, 0x7a, 0x21, 0x8a, 0x59, 0x61, 0xf2, 0x4b, 0xfd, 0x7d, 0x59, 0x01, 0x86, 0x00, 0xc0, 0x54, 0xc2, 0x85, 0x3a, 0xb2, 0xd2, 0xf8, 0x72, 0x47, 0x8e, 0xd5, 0xff, 0xa8, 0x4a, 0xed, 0x15, 0x95, 0xb1, 0xb3, 0x11, 0x1a, 0xca, 0xe2, 0xd4, 0x51, 0xc2, 0xaa, 0xee, 0xee, 0x7d, 0x1a, 0x68, 0x9b, 0x1f, 0x41, 0x47, 0xf3, 0xcb, 0xf7, 0x14, 0xb8, 0xb8, 0xb8, 0x0c, 0x76, 0x82, 0xc9, 0x5f, 0xbe, 0xac, 0x34, 0xfe, 0x2d, 0x93, 0x77, 0x74, 0x2c, 0x53, 0xfb, 0x37, 0x13, 0x37, 0x6d, 0xbe, 0x11, 0xdf, 0x40, 0xd9, 0xc2, 0xb6, 0x45, 0xe7, 0x1d, 0x6c, 0x05, 0x34, 0x3a, 0x58, 0xb9, 0x4b, 0xee, 0x64, 0xa6, 0xfe, 0x2a, 0x98, 0x27, 0xb4, 0xa1, 0x91, 0xe7, 0x78, 0xfb, 0x2e, 0xfe, 0x53, 0x55, 0x5f, 0x5e, 0x70, 0x70, 0x16, 0x06, 0x4e, 0x59, 0x2b, 0xd9, 0x79, 0x93, 0x5b, 0x8e, 0x7c, 0x4d, 0xf8, 0x30, 0xaf, 0x23, 0x18, 0x49, 0x5d, 0x0b, 0x77, 0x1c, 0xb9, 0xad, 0x51, 0x47, 0x30, 0x6d, 0xbf, 0x98, 0xdc, 0x95, 0x52, 0xb1, 0x86, 0x3f, 0x19, 0xce, 0xd6, 0x08, 0x0b, 0x55, 0x56, 0xc5, 0x96, 0x51, 0x7e, 0x33, 0x35, 0x16, 0x7b, 0xaf, 0xa9, 0xcd, 0x8f, 0x1d, 0xa8, 0xc4, 0xe0, 0xdd, 0x0d, 0x8b, 0x69, 0x97, 0x97, 0x97, 0x3f, 0xde, 0xab, 0x1e, 0xb5, 0xb8, 0xbf, 0xfd, 0xc7, 0xbd, 0x71, 0xcc, 0x3e, 0x11, 0x97, 0x60, 0x86, 0x0e, 0x25, 0x8b, 0x35, 0xd3, 0xf9, 0x2d, 0xd1, 0xd6, 0xb0, 0x78, 0xd0, 0xbe, 0xda, 0xad, 0x3d, 0xe3, 0xce, 0x8b, 0x46, 0xf1, 0xf7, 0x9f, 0x62, 0xc5, 0xac, 0x43, 0xb0, 0xfc, 0xc1, 0x36, 0xfb, 0x7c, 0x8e, 0x09, 0xd8, 0x4d, 0xc9, 0xca, 0xe0, 0x5e, 0x83, 0xec, 0xbc, 0x07, 0x0d, 0x6d, 0xfa, 0xe0, 0xfb, 0xf7, 0x99, 0x59, 0x7b, 0x99, 0x06, 0xce, 0xe9, 0x2e, 0x87, 0xd6, 0x66, 0x97, 0x4d, 0x04, 0x58, 0x4e, 0x99, 0x3d, 0x8c, 0x84, 0xea, 0x45, 0x1e, 0xda, 0x0a, 0xa8, 0xbe, 0xad, 0x4d, 0x9a, 0x87, 0x9b, 0x7b, 0x33, 0x43, 0xc7, 0xc4, 0x64, 0xd8, 0x5d, 0x8c, 0xde, 0xa9, 0xd1, 0x7a, 0x82, 0x08, 0x66, 0xab, 0xbb, 0xd9, 0xc0, 0x38, 0x80, 0x65, 0x1b, 0x13, 0x61, 0x31, 0x26, 0xc6, 0xe4, 0xfc, 0x4d, 0x43, 0x98, 0xbb, 0xfb, 0xf4, 0x32, 0x0d, 0x2c, 0x87, 0x73, 0x0c, 0x8e, 0xda, 0xdc, 0xad, 0x74, 0x56, 0x75, 0x8b, 0xa0, 0xe0, 0x3a, 0xb1, 0xe5, 0x77, 0xe2, 0xf7, 0xbd, 0x3a, 0xd2, 0x50, 0x5f, 0x1a, 0x56, 0x59, 0x60, 0xc1, 0xf1, 0xe7, 0x8b, 0xc4, 0x94, 0x7c, 0x82, 0xf3, 0x09, 0x5d, 0x6c, 0xf5, 0x82, 0x44, 0x6e, 0xee, 0x23, 0x43, 0x03, 0xe9, 0x2f, 0x42, 0x21, 0xa3, 0x9d, 0x92, 0x6f, 0xcb, 0x1f, 0xce, 0xb6, 0x3f, 0x6e, 0x65, 0x7c, 0x18, 0x59, 0x9f, 0x96, 0xf8, 0x70, 0xc1, 0xa9, 0xa5, 0xad, 0xbd, 0x38, 0xf9, 0x1d, 0x0e, 0xfa, 0x82, 0x1e, 0x86, 0x6e, 0xc9, 0x6c, 0xee, 0xe9, 0xa3, 0x52, 0x56, 0x0b, 0x9a, 0xc1, 0xce, 0x4a, 0xe3, 0x73, 0x47, 0xdb, 0x12, 0xc2, 0x87, 0x59, 0x48, 0x07, 0x12, 0x6d, 0x2d, 0x50, 0x60, 0x85, 0x11, 0xf6, 0x22, 0x2c, 0x03, 0x37, 0xd0, 0x8a, 0x2c, 0x47, 0xde, 0xd7, 0x80, 0x98, 0x70, 0x7a, 0xe5, 0x64, 0x71, 0xfa, 0x6b, 0xe7, 0x5f, 0x7d, 0x8b, 0x8d, 0xa5, 0x3d, 0x1d, 0x1a, 0x6c, 0x75, 0x04, 0x81, 0x46, 0xec, 0x04, 0xa8, 0x21, 0x08, 0x70, 0x66, 0x8e, 0x8a, 0x0c, 0x0c, 0xdf, 0x63, 0x63, 0x30, 0x91, 0xc1, 0x29, 0x75, 0xa8, 0xea, 0xa7, 0xcd, 0x68, 0xc6, 0xfe, 0xb7, 0xf3, 0x92, 0x1b, 0xcc, 0xed, 0x69, 0x64, 0x3b, 0x06, 0xfa, 0x37, 0xda, 0x8f, 0x15, 0x71, 0x41, 0x63, 0x7f, 0x85, 0xa0, 0x91, 0x34, 0xf3, 0xd5, 0x5b, 0x99, 0xb7, 0x5f, 0x1a, 0xa4, 0x81, 0x30, 0x84, 0x25, 0x4f, 0xfc, 0x55, 0x52, 0x07, 0xa5, 0xd0, 0x83, 0x50, 0xb7, 0x67, 0xd6, 0x19, 0x96, 0x32, 0xbc, 0xde, 0xfe, 0xfb, 0xbb, 0x14, 0xe8, 0x64, 0x5e, 0x56, 0x77, 0xf0, 0xfa, 0xa7, 0xe4, 0x08, 0x7f, 0x02, 0x96, 0xbc, 0x13, 0x8e, 0x8e, 0xce, 0xf6, 0x39, 0x72, 0x67, 0x7d, 0x2c, 0x45, 0xa7, 0xce, 0x71, 0x71, 0xf7, 0xd8, 0xd2, 0x54, 0x53, 0xb3, 0x1d, 0x03, 0x03, 0xc3, 0x88, 0xd5, 0x4d, 0x16, 0xc7, 0xcf, 0x68, 0xe0, 0x83, 0x2c, 0x0e, 0x04, 0xe1, 0x66, 0x10, 0x4f, 0xf6, 0x8f, 0x84, 0x86, 0x74, 0x77, 0xa6, 0x12, 0xd6, 0xc0, 0x39, 0xc4, 0xf0, 0x6a, 0xb3, 0x8a, 0xf3, 0xb4, 0xed, 0x76, 0x83, 0xc7, 0x31, 0xde, 0x5b, 0xd3, 0x57, 0xa6, 0xdd, 0xb2, 0x0e, 0x3e, 0x40, 0x2a, 0x87, 0x03, 0xc9, 0x7b, 0x1c, 0x79, 0x4e, 0x84, 0xad, 0xe3, 0x0e, 0xaa, 0x67, 0xc2, 0x91, 0x10, 0x12, 0xfa, 0xbd, 0x3e, 0x70, 0x3b, 0x2c, 0xbc, 0xec, 0x90, 0xf8, 0xf3, 0x25, 0x1f, 0x6f, 0x66, 0x65, 0x71, 0x27, 0x59, 0x0b, 0x35, 0x2a, 0x41, 0x6f, 0x26, 0xcb, 0xcd, 0xf2, 0xdb, 0xf5, 0x57, 0x3c, 0x6d, 0xd5, 0x8b, 0x88, 0x24, 0xcf, 0x62, 0x95, 0x12, 0x44, 0xb7, 0x90, 0x6d, 0x27, 0x83, 0xcf, 0x1d, 0x97, 0xbe, 0x16, 0x0f, 0xd6, 0xcc, 0xbd, 0x7d, 0xf3, 0xdc, 0x9b, 0x07, 0x98, 0x36, 0x96, 0x5b, 0xad, 0x78, 0xff, 0x01, 0x87, 0x26, 0xc1, 0x5e, 0x46, 0x06, 0x34, 0x3a, 0x3c, 0x7c, 0x6e, 0xcb, 0x6f, 0x56, 0x63, 0x9f, 0xf8, 0xd5, 0x92, 0x5b, 0x9f, 0xa5, 0xf0, 0x41, 0x80, 0xf5, 0x10, 0x03, 0x88, 0xce, 0x2f, 0x2b, 0xbb, 0x9a, 0xe9, 0x5d, 0xaa, 0x09, 0xf2, 0x2c, 0xbe, 0x4a, 0xc7, 0x99, 0x8a, 0x8e, 0xdc, 0x81, 0xe6, 0xbc, 0x3c, 0xc4, 0xcd, 0xbf, 0x7f, 0xa2, 0x2d, 0x3c, 0xc2, 0x3a, 0x20, 0xb4, 0x00, 0x2c, 0x39, 0xc5, 0x67, 0x3e, 0xcc, 0x28, 0x73, 0x65, 0xea, 0x64, 0xb9, 0xf7, 0xe1, 0xbd, 0x7f, 0x7c, 0x96, 0xfd, 0x2e, 0xbd, 0x05, 0x52, 0x8d, 0x4a, 0xf5, 0xa4, 0x60, 0xbd, 0x04, 0x5b, 0x06, 0x73, 0x83, 0x18, 0xe8, 0x8e, 0x0c, 0xb9, 0x7b, 0xf4, 0x4c, 0x80, 0x77, 0x8d, 0x22, 0x35, 0xd7, 0x21, 0xad, 0xaf, 0x4a, 0xe1, 0x50, 0x32, 0x6f, 0x6b, 0xeb, 0x6f, 0x4a, 0xa4, 0xd7, 0x7f, 0xcb, 0xdb, 0x0e, 0xf8, 0x47, 0x8c, 0xcb, 0x19, 0xfd, 0x9a, 0x3a, 0xeb, 0x02, 0x51, 0x41, 0x9b, 0x53, 0x8c, 0x56, 0x0f, 0x61, 0x7a, 0xb4, 0xa7, 0x08, 0x0b, 0x4a, 0x97, 0xf0, 0xae, 0x52, 0x4a, 0x00, 0x46, 0xb2, 0x4d, 0xdb, 0xd7, 0x68, 0x44, 0x94, 0x9d, 0xa5, 0x2c, 0x7b, 0x20, 0x00, 0x33, 0x38, 0x0d, 0x1c, 0xb2, 0xf5, 0xd7, 0x58, 0x32, 0xb6, 0x1a, 0x15, 0x46, 0xb5, 0x0e, 0xc7, 0xb6, 0x72, 0x01, 0xeb, 0x51, 0xc2, 0xc8, 0xf8, 0x06, 0xb3, 0xde, 0x30, 0x62, 0xa7, 0x9d, 0x2f, 0x2d, 0x18, 0xa8, 0x40, 0x50, 0x0a, 0x5b, 0x74, 0xab, 0xc8, 0x92, 0x61, 0xc4, 0xe4, 0xf2, 0x75, 0x28, 0x2a, 0x28, 0x38, 0x7f, 0x1d, 0xde, 0x1c, 0x47, 0x48, 0xb9, 0xac, 0x29, 0x14, 0x20, 0x1c, 0x7d, 0xe5, 0x67, 0xc5, 0x65, 0x00, 0xaf, 0xaf, 0x40, 0x2a, 0x34, 0xce, 0xf4, 0xc8, 0x90, 0x48, 0x2e, 0xd3, 0xe6, 0x99, 0xdc, 0x81, 0x05, 0x8b, 0xca, 0x7a, 0xf5, 0xc3, 0xa2, 0x71, 0x82, 0xb4, 0xbc, 0xed, 0xc7, 0x28, 0x7f, 0x7d, 0xd1, 0x60, 0x68, 0x6a, 0xe3, 0x29, 0xc6, 0x1f, 0x2e, 0x0f, 0x86, 0xff, 0xee, 0xee, 0x4a, 0xa4, 0x8d, 0x25, 0xf3, 0x98, 0x1d, 0x4c, 0x52, 0x6b, 0xc0, 0xd9, 0x78, 0x9d, 0xf9, 0xb5, 0x2f, 0x08, 0x01, 0x5f, 0x20, 0x26, 0x48, 0xc5, 0xd3, 0xaf, 0x4b, 0x91, 0x76, 0xea, 0xb6, 0xea, 0x15, 0xa7, 0x5b, 0xa3, 0x9e, 0x2a, 0xad, 0x40, 0x02, 0x0b, 0x32, 0x7c, 0xc2, 0x63, 0x68, 0x85, 0xa3, 0x9d, 0xe6, 0x7e, 0xec, 0x84, 0x27, 0x78, 0x6b, 0x68, 0x10, 0x5e, 0x5e, 0x5e, 0x7a, 0xfa, 0x07, 0xb4, 0x2a, 0xfc, 0xff, 0x99, 0xa1, 0x04, 0xa9, 0xf8, 0x05, 0x7d, 0xfb, 0x4d, 0x1e, 0xfb, 0xae, 0x2a, 0xed, 0xa1, 0x84, 0xf4, 0xf6, 0x65, 0x13, 0x7f, 0xcf, 0x9b, 0xb3, 0xb2, 0xb2, 0x16, 0x07, 0x8c, 0x93, 0xac, 0xfc, 0x2f, 0x17, 0x3d, 0xc5, 0x89, 0x74, 0xab, 0x1f, 0x61, 0x69, 0x50, 0xe7, 0xac, 0xf4, 0xb1, 0xa3, 0x9c, 0xc1, 0x80, 0x85, 0x38, 0x8d, 0x4b, 0xa8, 0x7d, 0x1d, 0xb3, 0x6f, 0x39, 0x0d, 0xc6, 0xa7, 0x6c, 0x54, 0x1f, 0x68, 0xf4, 0xfd, 0x77, 0xe2, 0xc1, 0x7e, 0x36, 0x51, 0xf0, 0x1a, 0xde, 0x9b, 0x02, 0xb7, 0xa9, 0x1f, 0x25, 0xbf, 0xdd, 0x06, 0x32, 0xab, 0xae, 0x29, 0x06, 0x92, 0x6b, 0x7e, 0xbc, 0xf5, 0x3b, 0xeb, 0xdb, 0xb2, 0x95, 0x81, 0xa2, 0x8b, 0x4b, 0xa5, 0xda, 0x5d, 0xc5, 0xdb, 0x2e, 0xe3, 0xda, 0xcb, 0xfd, 0xf9, 0xe9, 0x83, 0x77, 0xa5, 0x06, 0xd5, 0x58, 0xc8, 0xd3, 0x5e, 0x2e, 0xac, 0xc4, 0xa2, 0xcb, 0xe4, 0x7d, 0x29, 0x54, 0x19, 0xc8, 0x21, 0x77, 0x96, 0x03, 0xb5, 0xf1, 0x5b, 0x5a, 0x5b, 0x97, 0xf2, 0x75, 0x4d, 0x74, 0x74, 0xba, 0x05, 0x69, 0x5e, 0xc1, 0x8b, 0xe7, 0x6c, 0x05, 0x4e, 0xc2, 0xc3, 0xc3, 0x87, 0x1c, 0xd3, 0x0b, 0x0a, 0x0a, 0xe0, 0x35, 0x86, 0xfb, 0x93, 0x62, 0xd3, 0x99, 0xe1, 0xe1, 0x45, 0xdf, 0x46, 0x9c, 0x11, 0xb1, 0x1e, 0xd9, 0x14, 0x62, 0x90, 0xd2, 0xf4, 0xf7, 0xd7, 0xc1, 0xf0, 0xe8, 0xb4, 0x34, 0x9a, 0xe4, 0xc1, 0x8a, 0x0a, 0xde, 0x48, 0x1a, 0xc1, 0x22, 0xef, 0xa6, 0xb2, 0x32, 0xc2, 0xe7, 0x6f, 0xca, 0x9a, 0x4b, 0xf0, 0x9d, 0x47, 0x50, 0x6f, 0xb6, 0x6e, 0xb7, 0xaf, 0x11, 0x4a, 0xc6, 0x0d, 0x82, 0x48, 0x89, 0x8b, 0x07, 0xd6, 0xb9, 0x50, 0xa1, 0x66, 0xe3, 0x4e, 0x54, 0x9d, 0x7a, 0x10, 0x12, 0x69, 0x61, 0x0e, 0x58, 0x0d, 0xa6, 0x34, 0xac, 0x29, 0x63, 0xfc, 0xb0, 0xc7, 0x97, 0x7c, 0xb9, 0x2d, 0x2b, 0x2b, 0x9b, 0x2c, 0xf8, 0x83, 0x4b, 0x50, 0x30, 0x11, 0x3f, 0x68, 0x45, 0x42, 0xa7, 0x74, 0x64, 0xf4, 0xb0, 0xd1, 0x7f, 0xd0, 0xcf, 0x1e, 0x08, 0x72, 0x77, 0x9f, 0x82, 0x82, 0xc4, 0x1e, 0xf6, 0x77, 0xfb, 0xd5, 0xc9, 0x04, 0x49, 0x71, 0xf1, 0x26, 0x5d, 0x39, 0xbd, 0x42, 0x9d, 0xfd, 0x5d, 0x3a, 0xcf, 0xcd, 0x9f, 0xd4, 0x52, 0xe6, 0xed, 0xa0, 0x64, 0x18, 0x35, 0xfe, 0x6d, 0x9d, 0x6b, 0x66, 0x0a, 0x8a, 0x6a, 0xa0, 0xf1, 0x93, 0x36, 0x0c, 0x48, 0x12, 0xc7, 0xa1, 0xca, 0x6d, 0x24, 0xfc, 0x7e, 0x01, 0x3e, 0xda, 0xc0, 0xb2, 0x41, 0xcc, 0xac, 0x68, 0x2c, 0x90, 0xda, 0xd7, 0xdd, 0x7d, 0xb4, 0xb2, 0x62, 0x9e, 0xbc, 0x0e, 0xea, 0xc8, 0xd6, 0x8b, 0xa1, 0xcf, 0x9b, 0x09, 0x65, 0x45, 0x45, 0x56, 0xd7, 0xd2, 0x32, 0xa3, 0x3d, 0xc5, 0x8c, 0x86, 0x26, 0xa1, 0x4c, 0xaf, 0x78, 0xe3, 0xc3, 0xc5, 0x9e, 0x8b, 0xca, 0x48, 0x7e, 0x7e, 0x7e, 0x33, 0xc0, 0x06, 0xdc, 0x03, 0xde, 0x77, 0xd7, 0xe7, 0xa5, 0xf1, 0xf5, 0x3d, 0x16, 0xab, 0xa9, 0xa9, 0xa9, 0xb7, 0xf9, 0xc9, 0xa6, 0xae, 0x3b, 0x8f, 0x42, 0x37, 0x7f, 0x37, 0x70, 0x9b, 0x54, 0x12, 0xa9, 0xa2, 0x52, 0x29, 0x96, 0x68, 0xdf, 0xcd, 0xd2, 0x4b, 0xf0, 0xd2, 0x36, 0xc3, 0xcc, 0xa4, 0x0b, 0xf8, 0x97, 0x61, 0xcf, 0xfd, 0xb9, 0x29, 0x09, 0xa1, 0xbb, 0x9d, 0x82, 0x4c, 0x0f, 0x95, 0x11, 0xc3, 0xd2, 0x24, 0x1e, 0x93, 0xc6, 0x2f, 0x01, 0x40, 0x42, 0x6f, 0x9b, 0x0e, 0x5b, 0xd7, 0x1f, 0xae, 0xa7, 0xdb, 0xbc, 0x14, 0x14, 0x14, 0x8a, 0x59, 0x0e, 0x6e, 0x99, 0x55, 0xb2, 0x0f, 0x9f, 0x9e, 0xe2, 0xe2, 0x02, 0xf5, 0xe3, 0xc8, 0xac, 0x5a, 0xaa, 0xf5, 0xb2, 0x15, 0x2f, 0x6c, 0xf8, 0x70, 0x72, 0x5c, 0x44, 0x87, 0x8b, 0x85, 0x05, 0x11, 0x91, 0x33, 0x63, 0x5d, 0xd5, 0x7a, 0x15, 0xf3, 0xd6, 0xc8, 0x7c, 0xc5, 0xc8, 0x3f, 0xfd, 0xae, 0x10, 0x55, 0x67, 0x8e, 0x2a, 0xe0, 0x27, 0xbd, 0xbc, 0xd6, 0x0e, 0xa6, 0x1a, 0x35, 0x30, 0x7f, 0x01, 0x1b, 0x05, 0x17, 0x30, 0x2b, 0x1c, 0xc5, 0x0e, 0x2f, 0x80, 0xdd, 0x87, 0x3f, 0x6a, 0xb3, 0x0e, 0x06, 0x5a, 0xff, 0x1a, 0x64, 0xfe, 0x13, 0x1b, 0x19, 0x9a, 0xce, 0x47, 0x68, 0x1b, 0x0e, 0xd2, 0x95, 0xc8, 0x2a, 0x92, 0xa7, 0xfd, 0x8c, 0xe4, 0x33, 0x11, 0x85, 0xc9, 0xe2, 0x9f, 0x5d, 0x1f, 0x43, 0xc2, 0xfd, 0xa8, 0x80, 0x7f, 0x40, 0x80, 0xa0, 0xd0, 0x88, 0x97, 0x4c, 0xcf, 0x34, 0xf3, 0x69, 0x04, 0x54, 0xc1, 0x9d, 0x07, 0x60, 0xc4, 0x7d, 0x0b, 0xf3, 0x93, 0x0c, 0x0a, 0xda, 0x77, 0xee, 0xf1, 0x64, 0xe7, 0x22, 0xb0, 0x10, 0xf2, 0x40, 0x1f, 0x71, 0xd8, 0x1c, 0x3c, 0xd0, 0x12, 0xdd, 0xcd, 0x20, 0xf2, 0x5c, 0x9f, 0x8c, 0x4c, 0x40, 0x54, 0x67, 0x76, 0x1b, 0x17, 0x95, 0x3e, 0x1c, 0x88, 0xe9, 0xce, 0x03, 0x06, 0xa9, 0xbf, 0x33, 0x86, 0xa4, 0x12, 0x51, 0x3d, 0x08, 0xf8, 0x53, 0x79, 0xa9, 0xa1, 0x50, 0x26, 0x67, 0x1e, 0xf4, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x93, 0x8b, 0x92, 0x0e, 0x50, 0xb2, 0x00, 0x00, })) if err != nil { panic("Decompression failed: " + err.Error()) } var b bytes.Buffer io.Copy(&b, gz) gz.Close() return b.Bytes() } ================================================ FILE: icccm/doc.go ================================================ /* Package icccm provides an API for a portion of the ICCCM, namely, getters and setters for many of the properties specified in the ICCCM. There is also a smattering of support for other protocols specified by ICCCM. For example, to satisfy the WM_DELETE_WINDOW protocol, package icccm provides 'IsDeleteProtocol' which returns whether a ClientMessage event satisfies the WM_DELETE_WINDOW protocol. If a property has values that aren't simple strings or integers, struct types are provided to organize the data. In particular, WM_NORMAL_HINTS and WM_HINTS. Also note that properties like WM_NORMAL_HINTS and WM_HINTS contain a 'Flags' field (a bit mask) that specifies which values are "active". This is of importance when setting and reading WM_NORMAL_HINTS and WM_HINTS; one must make sure the appropriate bit is set in Flags. For example, you might want to check if a window has specified a resize increment in the WM_NORMAL_HINTS property. The values in the corresponding NormalHints struct are WidthInc and HeightInc. So to check if such values exist *and* should be used: normalHints, err := icccm.WmNormalHintsGet(XUtilValue, window-id) if err != nil { // handle error } if normalHints.Flags&icccm.SizeHintPResizeInc > 0 { // Use normalHints.WidthInc and normalHints.HeightInc } When you should use icccm Although the ICCCM is extremely old, a lot of it is still used. In fact, the EWMH spec itself specifically states that the ICCCM should still be used unless otherwise noted by the EWMH. For example, WM_HINTS and WM_NORMAL_HINTS are still used, but _NET_WM_NAME replaces WM_NAME. With that said, many applications (like xterm or LibreOffice) have not been updated to be fully EWMH compliant. Therefore, code that finds a window's name often looks like this: winName, err := ewmh.WmNameGet(XUtilValue, window-id) if err != nil || winName == "" { winName, err = icccm.WmNameGet(XUtilValue, window-id) if err != nill || winName == "" { winName = "N/A" } } Something similar can be said for the _NET_WM_ICON and the IconPixmap field in WM_HINTS. Naming scheme The naming scheme is precisely the same as the one found in the ewmh package. The documentation for the ewmh package describes the naming scheme in more detail. The only difference (currently) is that the icccm package only contains functions ending in "Get" and "Set". It is planned to add "Req" functions. (An example of a Req function would be to send a ClientMessage implementing the WM_DELETE_WINDOW protocol to a client window.) */ package icccm ================================================ FILE: icccm/icccm.go ================================================ package icccm import ( "fmt" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/xprop" ) const ( HintInput = (1 << iota) HintState HintIconPixmap HintIconWindow HintIconPosition HintIconMask HintWindowGroup HintMessage HintUrgency ) const ( SizeHintUSPosition = (1 << iota) SizeHintUSSize SizeHintPPosition SizeHintPSize SizeHintPMinSize SizeHintPMaxSize SizeHintPResizeInc SizeHintPAspect SizeHintPBaseSize SizeHintPWinGravity ) const ( StateWithdrawn = iota StateNormal StateZoomed StateIconic StateInactive ) // WM_NAME get func WmNameGet(xu *xgbutil.XUtil, win xproto.Window) (string, error) { return xprop.PropValStr(xprop.GetProperty(xu, win, "WM_NAME")) } // WM_NAME set func WmNameSet(xu *xgbutil.XUtil, win xproto.Window, name string) error { return xprop.ChangeProp(xu, win, 8, "WM_NAME", "STRING", ([]byte)(name)) } // WM_ICON_NAME get func WmIconNameGet(xu *xgbutil.XUtil, win xproto.Window) (string, error) { return xprop.PropValStr(xprop.GetProperty(xu, win, "WM_ICON_NAME")) } // WM_ICON_NAME set func WmIconNameSet(xu *xgbutil.XUtil, win xproto.Window, name string) error { return xprop.ChangeProp(xu, win, 8, "WM_ICON_NAME", "STRING", ([]byte)(name)) } // NormalHints is a struct that organizes the information related to the // WM_NORMAL_HINTS property. Please see the ICCCM spec for more details. type NormalHints struct { Flags uint X, Y int Width, Height, MinWidth, MinHeight, MaxWidth, MaxHeight uint WidthInc, HeightInc uint MinAspectNum, MinAspectDen, MaxAspectNum, MaxAspectDen uint BaseWidth, BaseHeight, WinGravity uint } // WM_NORMAL_HINTS get func WmNormalHintsGet(xu *xgbutil.XUtil, win xproto.Window) (nh *NormalHints, err error) { lenExpect := 18 hints, err := xprop.PropValNums(xprop.GetProperty(xu, win, "WM_NORMAL_HINTS")) if err != nil { return nil, err } if len(hints) != lenExpect { return nil, fmt.Errorf("WmNormalHint: There are %d fields in WM_NORMAL_HINTS, "+ "but xgbutil expects %d.", len(hints), lenExpect) } nh = &NormalHints{} nh.Flags = hints[0] nh.X = int(hints[1]) nh.Y = int(hints[2]) nh.Width = hints[3] nh.Height = hints[4] nh.MinWidth = hints[5] nh.MinHeight = hints[6] nh.MaxWidth = hints[7] nh.MaxHeight = hints[8] nh.WidthInc = hints[9] nh.HeightInc = hints[10] nh.MinAspectNum = hints[11] nh.MinAspectDen = hints[12] nh.MaxAspectNum = hints[13] nh.MaxAspectDen = hints[14] nh.BaseWidth = hints[15] nh.BaseHeight = hints[16] nh.WinGravity = hints[17] if nh.WinGravity <= 0 { nh.WinGravity = xproto.GravityNorthWest } return nh, nil } // WM_NORMAL_HINTS set // Make sure to set the flags in the NormalHints struct correctly! func WmNormalHintsSet(xu *xgbutil.XUtil, win xproto.Window, nh *NormalHints) error { raw := []uint{ nh.Flags, uint(nh.X), uint(nh.Y), nh.Width, nh.Height, nh.MinWidth, nh.MinHeight, nh.MaxWidth, nh.MaxHeight, nh.WidthInc, nh.HeightInc, nh.MinAspectNum, nh.MinAspectDen, nh.MaxAspectNum, nh.MaxAspectDen, nh.BaseWidth, nh.BaseHeight, nh.WinGravity, } return xprop.ChangeProp32(xu, win, "WM_NORMAL_HINTS", "WM_SIZE_HINTS", raw...) } // Hints is a struct that organizes information related to the WM_HINTS // property. Once again, I refer you to the ICCCM spec for documentation. type Hints struct { Flags uint Input, InitialState uint IconX, IconY int IconPixmap, IconMask xproto.Pixmap WindowGroup, IconWindow xproto.Window } // WM_HINTS get func WmHintsGet(xu *xgbutil.XUtil, win xproto.Window) (hints *Hints, err error) { lenExpect := 9 raw, err := xprop.PropValNums(xprop.GetProperty(xu, win, "WM_HINTS")) if err != nil { return nil, err } if len(raw) != lenExpect { return nil, fmt.Errorf("WmHints: There are %d fields in "+ "WM_HINTS, but xgbutil expects %d.", len(raw), lenExpect) } hints = &Hints{} hints.Flags = raw[0] hints.Input = raw[1] hints.InitialState = raw[2] hints.IconPixmap = xproto.Pixmap(raw[3]) hints.IconWindow = xproto.Window(raw[4]) hints.IconX = int(raw[5]) hints.IconY = int(raw[6]) hints.IconMask = xproto.Pixmap(raw[7]) hints.WindowGroup = xproto.Window(raw[8]) return hints, nil } // WM_HINTS set // Make sure to set the flags in the Hints struct correctly! func WmHintsSet(xu *xgbutil.XUtil, win xproto.Window, hints *Hints) error { raw := []uint{ hints.Flags, hints.Input, hints.InitialState, uint(hints.IconPixmap), uint(hints.IconWindow), uint(hints.IconX), uint(hints.IconY), uint(hints.IconMask), uint(hints.WindowGroup), } return xprop.ChangeProp32(xu, win, "WM_HINTS", "WM_HINTS", raw...) } // WmClass struct contains two data points: // the instance and a class of a window. type WmClass struct { Instance, Class string } // WM_CLASS get func WmClassGet(xu *xgbutil.XUtil, win xproto.Window) (*WmClass, error) { raw, err := xprop.PropValStrs(xprop.GetProperty(xu, win, "WM_CLASS")) if err != nil { return nil, err } if len(raw) != 2 { return nil, fmt.Errorf("WmClass: Two string make up WM_CLASS, but "+ "xgbutil found %d in '%v'.", len(raw), raw) } return &WmClass{ Instance: raw[0], Class: raw[1], }, nil } // WM_CLASS set func WmClassSet(xu *xgbutil.XUtil, win xproto.Window, class *WmClass) error { raw := make([]byte, len(class.Instance)+len(class.Class)+2) copy(raw, class.Instance) copy(raw[(len(class.Instance)+1):], class.Class) return xprop.ChangeProp(xu, win, 8, "WM_CLASS", "STRING", raw) } // WM_TRANSIENT_FOR get func WmTransientForGet(xu *xgbutil.XUtil, win xproto.Window) (xproto.Window, error) { return xprop.PropValWindow(xprop.GetProperty(xu, win, "WM_TRANSIENT_FOR")) } // WM_TRANSIENT_FOR set func WmTransientForSet(xu *xgbutil.XUtil, win xproto.Window, transient xproto.Window) error { return xprop.ChangeProp32(xu, win, "WM_TRANSIENT_FOR", "WINDOW", uint(transient)) } // WM_PROTOCOLS get func WmProtocolsGet(xu *xgbutil.XUtil, win xproto.Window) ([]string, error) { raw, err := xprop.GetProperty(xu, win, "WM_PROTOCOLS") return xprop.PropValAtoms(xu, raw, err) } // WM_PROTOCOLS set func WmProtocolsSet(xu *xgbutil.XUtil, win xproto.Window, atomNames []string) error { atoms, err := xprop.StrToAtoms(xu, atomNames) if err != nil { return err } return xprop.ChangeProp32(xu, win, "WM_PROTOCOLS", "ATOM", atoms...) } // WM_COLORMAP_WINDOWS get func WmColormapWindowsGet(xu *xgbutil.XUtil, win xproto.Window) ([]xproto.Window, error) { return xprop.PropValWindows(xprop.GetProperty(xu, win, "WM_COLORMAP_WINDOWS")) } // WM_COLORMAP_WINDOWS set func WmColormapWindowsSet(xu *xgbutil.XUtil, win xproto.Window, windows []xproto.Window) error { return xprop.ChangeProp32(xu, win, "WM_COLORMAP_WINDOWS", "WINDOW", xprop.WindowToInt(windows)...) } // WM_CLIENT_MACHINE get func WmClientMachineGet(xu *xgbutil.XUtil, win xproto.Window) (string, error) { return xprop.PropValStr(xprop.GetProperty(xu, win, "WM_CLIENT_MACHINE")) } // WM_CLIENT_MACHINE set func WmClientMachineSet(xu *xgbutil.XUtil, win xproto.Window, client string) error { return xprop.ChangeProp(xu, win, 8, "WM_CLIENT_MACHINE", "STRING", ([]byte)(client)) } // WmState is a struct that organizes information related to the WM_STATE // property. Namely, the state (corresponding to a State* constant in this file) // and the icon window (probably not used). type WmState struct { State uint Icon xproto.Window } // WM_STATE get func WmStateGet(xu *xgbutil.XUtil, win xproto.Window) (*WmState, error) { raw, err := xprop.PropValNums(xprop.GetProperty(xu, win, "WM_STATE")) if err != nil { return nil, err } if len(raw) != 2 { return nil, fmt.Errorf("WmState: Expected two integers in WM_STATE property "+ "but xgbutil found %d in '%v'.", len(raw), raw) } return &WmState{ State: raw[0], Icon: xproto.Window(raw[1]), }, nil } // WM_STATE set func WmStateSet(xu *xgbutil.XUtil, win xproto.Window, state *WmState) error { raw := []uint{ state.State, uint(state.Icon), } return xprop.ChangeProp32(xu, win, "WM_STATE", "WM_STATE", raw...) } // IconSize is a struct the organizes information related to the WM_ICON_SIZE // property. Mostly info about its dimensions. type IconSize struct { MinWidth, MinHeight, MaxWidth, MaxHeight, WidthInc, HeightInc uint } // WM_ICON_SIZE get func WmIconSizeGet(xu *xgbutil.XUtil, win xproto.Window) (*IconSize, error) { raw, err := xprop.PropValNums(xprop.GetProperty(xu, win, "WM_ICON_SIZE")) if err != nil { return nil, err } if len(raw) != 6 { return nil, fmt.Errorf("WmIconSize: Expected six integers in WM_ICON_SIZE "+ "property, but xgbutil found "+"%d in '%v'.", len(raw), raw) } return &IconSize{ MinWidth: raw[0], MinHeight: raw[1], MaxWidth: raw[2], MaxHeight: raw[3], WidthInc: raw[4], HeightInc: raw[5], }, nil } // WM_ICON_SIZE set func WmIconSizeSet(xu *xgbutil.XUtil, win xproto.Window, icondim *IconSize) error { raw := []uint{ icondim.MinWidth, icondim.MinHeight, icondim.MaxWidth, icondim.MaxHeight, icondim.WidthInc, icondim.HeightInc, } return xprop.ChangeProp32(xu, win, "WM_ICON_SIZE", "WM_ICON_SIZE", raw...) } ================================================ FILE: icccm/protocols.go ================================================ package icccm import ( "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/xevent" "github.com/BurntSushi/xgbutil/xprop" ) // IsDeleteProtocol checks whether a ClientMessage event satisfies the // WM_DELETE_WINDOW protocol. Namely, the format must be 32, the type must // be the WM_PROTOCOLS atom, and the first data item must be the atom // WM_DELETE_WINDOW. // // Note that if you're using the xwindow package, you should use the // WMGracefulClose method instead of directly using IsDeleteProtocol. func IsDeleteProtocol(X *xgbutil.XUtil, ev xevent.ClientMessageEvent) bool { // Make sure the Format is 32. (Meaning that each data item is // 32 bits.) if ev.Format != 32 { return false } // Check to make sure the Type atom is WM_PROTOCOLS. typeName, err := xprop.AtomName(X, ev.Type) if err != nil || typeName != "WM_PROTOCOLS" { // not what we want return false } // Check to make sure the first data item is WM_DELETE_WINDOW. protocolType, err := xprop.AtomName(X, xproto.Atom(ev.Data.Data32[0])) if err != nil || protocolType != "WM_DELETE_WINDOW" { return false } return true } // IsFocusProtocol checks whether a ClientMessage event satisfies the // WM_TAKE_FOCUS protocol. func IsFocusProtocol(X *xgbutil.XUtil, ev xevent.ClientMessageEvent) bool { // Make sure the Format is 32. (Meaning that each data item is // 32 bits.) if ev.Format != 32 { return false } // Check to make sure the Type atom is WM_PROTOCOLS. typeName, err := xprop.AtomName(X, ev.Type) if err != nil || typeName != "WM_PROTOCOLS" { // not what we want return false } // Check to make sure the first data item is WM_TAKE_FOCUS. protocolType, err := xprop.AtomName(X, xproto.Atom(ev.Data.Data32[0])) if err != nil || protocolType != "WM_TAKE_FOCUS" { return false } return true } ================================================ FILE: keybind/callback.go ================================================ package keybind import ( "fmt" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/xevent" ) // connect is essentially 'Connect' for either KeyPress or KeyRelease events. // Namely, it parses the key string, issues a grab request if necessary, // sets up the appropriate event handlers for the main event loop, and attaches // the callback to the keybinding state. func connect(xu *xgbutil.XUtil, callback xgbutil.CallbackKey, evtype int, win xproto.Window, keyStr string, grab, reconnect bool) error { // Get the mods/key first mods, keycodes, err := ParseString(xu, keyStr) if err != nil { return err } // Only do the grab if we haven't yet on this window. for _, keycode := range keycodes { if grab && keyBindGrabs(xu, evtype, win, mods, keycode) == 0 { if err := GrabChecked(xu, win, mods, keycode); err != nil { // If a bad access, let's be nice and give a good error message. switch err.(type) { case xproto.AccessError: return fmt.Errorf("Got a bad access error when trying to "+ "bind '%s'. This usually means another client has "+ "already grabbed this keybinding.", keyStr) default: return fmt.Errorf("Could not bind '%s' because: %s", keyStr, err) } } } // If we've never grabbed anything on this window before, we need to // make sure we can respond to it in the main event loop. // Never do this if we're reconnecting. if !reconnect { var allCb xgbutil.Callback if evtype == xevent.KeyPress { allCb = xevent.KeyPressFun(runKeyPressCallbacks) } else { allCb = xevent.KeyReleaseFun(runKeyReleaseCallbacks) } // If this is the first Key{Press|Release}Event on this window, // then we need to listen to Key{Press|Release} events in the main // loop. if !connectedKeyBind(xu, evtype, win) { allCb.Connect(xu, win) } } // Finally, attach the callback. attachKeyBindCallback(xu, evtype, win, mods, keycode, callback) } // Keep track of all unique key connections. if !reconnect { addKeyString(xu, callback, evtype, win, keyStr, grab) } return nil } // DeduceKeyInfo AND's the "ignored modifiers" out of the state returned by // a Key{Press,Release} event. This is useful to connect a (state, keycode) // tuple from an event with a tuple specified by the user. func DeduceKeyInfo(state uint16, detail xproto.Keycode) (uint16, xproto.Keycode) { mods, kc := state, detail for _, m := range xevent.IgnoreMods { mods &= ^m } return mods, kc } // KeyPressFun represents a function that is called when a particular key // binding is fired. type KeyPressFun xevent.KeyPressFun func (callback KeyPressFun) Connect(xu *xgbutil.XUtil, win xproto.Window, keyStr string, grab bool) error { return connect(xu, callback, xevent.KeyPress, win, keyStr, grab, false) } func (callback KeyPressFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(xevent.KeyPressEvent)) } // KeyReleaseFun represents a function that is called when a particular key // binding is fired. type KeyReleaseFun xevent.KeyReleaseFun func (callback KeyReleaseFun) Connect(xu *xgbutil.XUtil, win xproto.Window, keyStr string, grab bool) error { return connect(xu, callback, xevent.KeyRelease, win, keyStr, grab, false) } func (callback KeyReleaseFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(xevent.KeyReleaseEvent)) } // runKeyPressCallbacks infers the window, keycode and modifiers from a // KeyPressEvent and runs the corresponding callbacks. func runKeyPressCallbacks(xu *xgbutil.XUtil, ev xevent.KeyPressEvent) { mods, kc := DeduceKeyInfo(ev.State, ev.Detail) runKeyBindCallbacks(xu, ev, xevent.KeyPress, ev.Event, mods, kc) } // runKeyReleaseCallbacks infers the window, keycode and modifiers from a // KeyPressEvent and runs the corresponding callbacks. func runKeyReleaseCallbacks(xu *xgbutil.XUtil, ev xevent.KeyReleaseEvent) { mods, kc := DeduceKeyInfo(ev.State, ev.Detail) runKeyBindCallbacks(xu, ev, xevent.KeyRelease, ev.Event, mods, kc) } // Detach removes all handlers for all key events for the provided window id. // This should be called whenever a window is no longer receiving events to make // sure the garbage collector can release memory used to store the handler info. func Detach(xu *xgbutil.XUtil, win xproto.Window) { detach(xu, xevent.KeyPress, win) detach(xu, xevent.KeyRelease, win) } // DetachPress is the same as Detach, except it only removes handlers for // key *press* events. func DetachPress(xu *xgbutil.XUtil, win xproto.Window) { detach(xu, xevent.KeyPress, win) } // DetachRelease is the same as Detach, except it only removes handlers for // key *release* events. func DetachRelease(xu *xgbutil.XUtil, win xproto.Window) { detach(xu, xevent.KeyRelease, win) } // detach removes all handlers for the provided window and event type // combination. This will also issue an ungrab request for each grab that // drops to zero. func detach(xu *xgbutil.XUtil, evtype int, win xproto.Window) { mkeys := keyKeys(xu) detachKeyBindWindow(xu, evtype, win) for _, key := range mkeys { if keyBindGrabs(xu, key.Evtype, key.Win, key.Mod, key.Code) == 0 { Ungrab(xu, key.Win, key.Mod, key.Code) } } } ================================================ FILE: keybind/doc.go ================================================ /* Package keybind provides an easy to use interface to assign callback functions to human readable key sequences. Working with the X keyboard encoding is not an easy task, and the keybind package attempts to encapsulate much of the complexity. Namely, the keybind package exports two function types: KeyPressFun and KeyReleaseFun. Values of these types are functions, and have a method called 'Connect' that attaches an event handler to be run when a particular key press is issued. This is virtually identical to the way calbacks are attached using the xevent package, but the Connect method in the keybind package has a couple extra parameters that are specific to key bindings. Namely, the key sequence to respond to (which is a combination of zero or more modifiers and exactly one key) and whether to establish a passive grab. One can still attach callbacks to Key{Press,Release} events using xevent, but it will be run for *all* Key{Press,Release} events. (This is typically what one might do when setting up an active grab.) Initialization Before using the keybind package, you should *always* make a single call to keybind.Initialize for each X connection you're working with. Key sequence format Key sequences are human readable strings made up of zero or more modifiers and exactly one key. Namely: [Mod[-Mod[...]]-]KEY Where 'Mod' can be one of: shift, lock, control, mod1, mod2, mod3, mod4, mod5, or any. You can view which keys activate each modifier using the 'xmodmap' program. (If you don't have 'xmodmap', you could also run the 'xmodmap' example in the examples directory.) KEY must correspond to a valid keysym. Keysyms can be found by pressing keys using the 'xev' program. Alternatively, you may inspect the 'keysyms' map in xgbutil/keybind/keysymdef.go. An example key sequence might look like 'Mod4-Control-Shift-t'. The keybinding for that key sequence is activated when all three modifiers---mod4, control and shift---are pressed along with the 't' key. When to issue a passive grab One of the parameters of the 'Connect' method is whether to issue a passive grab or not. A passive grab is useful when you need to respond to a key press on some parent window (like the root window) without actually focusing that window. Not using a passive grab is useful when you only need to read key presses when the window is focused. For more information on the semantics of passive grabs, please see http://tronche.com/gui/x/xlib/input/XGrabKey.html. Also, by default, when issuing a grab on a particular (modifiers, keycode) tuple, several grabs are actually made. In particular, for each grab requested, another grab is made with the "num lock" mask, another grab is made with the "caps lock" mask, and another grab is made with both the "num lock" and "caps locks" masks. This allows key events to be reported regardless of whether caps lock or num lock is enabled. The extra masks added can be modified by changing the xevent.IgnoreMods slice. If you modify xevent.IgnoreMods, it should be modified once on program startup (i.e., before any key or mouse bindings are established) and never modified again. Key bindings on the root window example To run a particular function whenever the 'Mod4-Control-Shift-t' key combination is pressed (mod4 is typically the 'super' or 'windows' key, but can vary based on your system), use something like: keybind.Initialize(XUtilValue) // call once before using keybind package keybind.KeyPressFun( func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) { // do something when key is pressed }).Connect(XUtilValue, XUtilValue.RootWin(), "Mod4-Control-Shift-t", true) Note that we issue a passive grab because Key{Press,Release} events on the root window will only be reported when the root window has focus if no grab exists. Key bindings on a window you create example This code snippet attaches an event handler to some window you've created without using a grab. Thus, the function will only be activated when the key sequence is pressed and your window has focus. keybind.Initialize(XUtilValue) // call once before using keybind package keybind.KeyPressFun( func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) { // do something when key is pressed }).Connect(XUtilValue, your-window-id, "Mod4-t", false) Run a function on all key press events example This code snippet actually does *not* use the keybind package, but illustrates how the Key{Press,Release} event handlers in the xevent package can still be useful. Namely, the keybind package discriminates among events depending upon the key sequences pressed, whereas the xevent package is more general: it can only discriminate at the event level. xevent.KeyPressFun( func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) { // do something when any key is pressed }).Connect(XUtilValue, your-window-id) This is the kind of handler you might use to capture all key press events. (i.e., if you have a text box for a user to type in.) Additionally, if you're using this sort of event handler, keybind.LookupString will probably be of some use. Its contract is that given a (modifiers, keycode) tuple (information found in all Key{Press,Release} events) it will return a string representation of the key pressed. We can modify the above example slightly to echo the key pressed: xevent.KeyPressFun( func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) { fmt.Println("Key pressed:", keybind.LookupString(X, ev.State, ev.Detail)) }).Connect(XUtilValue, your-window-id) More examples Complete working examples can be found in the examples directory of xgbutil. Of particular interest are probably 'keypress-english' and 'simple-keybinding'. */ package keybind ================================================ FILE: keybind/encoding.go ================================================ package keybind /* This file contains the logic to implement X's Keyboard Encoding described here: http://goo.gl/qum9q Essentially, LookupString is analogous to Xlib's XLookupString. It's useful in determining the english string representation of modifiers + keycode. It is not for the faint of heart. */ import ( "strings" "unicode" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" ) // LookupString attempts to convert a (modifiers, keycode) to an english string. // It essentially implements the rules described at http://goo.gl/qum9q // Namely, the bulleted list that describes how key syms should be interpreted // when various modifiers are pressed. // Note that we ignore the logic that asks us to check if particular key codes // are mapped to particular modifiers (i.e., "XK_Caps_Lock" to "Lock" modifier). // We just check if the modifiers are activated. That's good enough for me. // XXX: We ignore num lock stuff. // XXX: We ignore MODE SWITCH stuff. (i.e., we don't use group 2 key syms.) func LookupString(xu *xgbutil.XUtil, mods uint16, keycode xproto.Keycode) string { k1, k2, _, _ := interpretSymList(xu, keycode) shift := mods&xproto.ModMaskShift > 0 lock := mods&xproto.ModMaskLock > 0 switch { case !shift && !lock: return k1 case !shift && lock: if len(k1) == 1 && unicode.IsLower(rune(k1[0])) { return k2 } else { return k1 } case shift && lock: if len(k2) == 1 && unicode.IsLower(rune(k2[0])) { return string(unicode.ToUpper(rune(k2[0]))) } else { return k2 } case shift: return k2 } return "" } // ModifierString takes in a keyboard state and returns a string of all // modifiers in the state. func ModifierString(mods uint16) string { modStrs := make([]string, 0, 3) for i, mod := range Modifiers { if mod&mods > 0 && len(NiceModifiers[i]) > 0 { modStrs = append(modStrs, NiceModifiers[i]) } } return strings.Join(modStrs, "-") } // KeyMatch returns true if a string representation of a key can // be matched (case insensitive) to the (modifiers, keycode) tuple provided. // String representations can be found in keybind/keysymdef.go func KeyMatch(xu *xgbutil.XUtil, keyStr string, mods uint16, keycode xproto.Keycode) bool { guess := LookupString(xu, mods, keycode) return strings.ToLower(guess) == strings.ToLower(keyStr) } // interpretSymList interprets the keysym list for a particular keycode as // described in the third and fourth paragraphs of http://goo.gl/qum9q func interpretSymList(xu *xgbutil.XUtil, keycode xproto.Keycode) ( k1 string, k2 string, k3 string, k4 string) { ks1 := KeysymGet(xu, keycode, 0) ks2 := KeysymGet(xu, keycode, 1) ks3 := KeysymGet(xu, keycode, 2) ks4 := KeysymGet(xu, keycode, 3) // follow the rules, third paragraph switch { case ks2 == 0 && ks3 == 0 && ks4 == 0: ks3 = ks1 case ks3 == 0 && ks4 == 0: ks3 = ks1 ks4 = ks2 case ks4 == 0: ks4 = 0 } // Now convert keysyms to strings, so we can do alphabetic shit. k1 = KeysymToStr(ks1) k2 = KeysymToStr(ks2) k3 = KeysymToStr(ks3) k4 = KeysymToStr(ks4) // follow the rules, fourth paragraph if k2 == "" { if len(k1) == 1 && unicode.IsLetter(rune(k1[0])) { k1 = string(unicode.ToLower(rune(k1[0]))) k2 = string(unicode.ToUpper(rune(k1[0]))) } else { k2 = k1 } } if k4 == "" { if len(k3) == 1 && unicode.IsLetter(rune(k3[0])) { k3 = string(unicode.ToLower(rune(k3[0]))) k4 = string(unicode.ToUpper(rune(k4[0]))) } else { k4 = k3 } } return } ================================================ FILE: keybind/keybind.go ================================================ package keybind import ( "fmt" "strings" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/xevent" ) var ( Modifiers []uint16 = []uint16{ // order matters! xproto.ModMaskShift, xproto.ModMaskLock, xproto.ModMaskControl, xproto.ModMask1, xproto.ModMask2, xproto.ModMask3, xproto.ModMask4, xproto.ModMask5, xproto.ModMaskAny, } NiceModifiers = []string{ "shift", "lock", "control", "mod1", "mod2", "mod3", "mod4", "mod5", "", } ) // Initialize attaches the appropriate callbacks to make key bindings easier. // i.e., update state of the world on a MappingNotify. func Initialize(xu *xgbutil.XUtil) { // Listen to mapping notify events xevent.MappingNotifyFun(updateMaps).Connect(xu, xevent.NoWindow) // Give us an initial mapping state... keyMap, modMap := MapsGet(xu) KeyMapSet(xu, keyMap) ModMapSet(xu, modMap) } // updateMaps runs in response to MappingNotify events. // It is responsible for making sure our view of the world's keyboard // and modifier maps is correct. (Pointer mappings should be handled in // a similar callback in the mousebind package.) func updateMaps(xu *xgbutil.XUtil, e xevent.MappingNotifyEvent) { keyMap, modMap := MapsGet(xu) // So we used to go through the old mapping and the new mapping and pick // out precisely where there are changes. But after allowing for a // one-to-many mapping from keysym to keycodes, this process became too // complex. So we're going to bust out our hammer and rebind everything // based on the initial key strings. if e.Request == xproto.MappingKeyboard { // We must ungrab everything first, in case two keys are being swapped. keys := keyKeys(xu) for _, key := range keys { Ungrab(xu, key.Win, key.Mod, key.Code) detach(xu, key.Evtype, key.Win) } // Wipe the slate clean. xu.KeybindsLck.Lock() xu.Keybinds = make(map[xgbutil.KeyKey][]xgbutil.CallbackKey, len(keys)) xu.Keygrabs = make(map[xgbutil.KeyKey]int, len(keys)) keyStrs := xu.Keystrings xu.KeybindsLck.Unlock() // Update our mappings before rebinding. KeyMapSet(xu, keyMap) ModMapSet(xu, modMap) // Now rebind everything in Keystrings for _, ks := range keyStrs { err := connect(xu, ks.Callback, ks.Evtype, ks.Win, ks.Str, ks.Grab, true) if err != nil { xgbutil.Logger.Println(err) } } } else { // We don't have to do something with MappingModifier like we do with // MappingKeyboard. This is due to us requiring that key strings use // modifier names built into X. (i.e., the names seen in the output of // `xmodmap`.) This means that the modifier mappings happen on the X // server side, so we don't *typically* have to care what key is // actually being pressed to trigger a modifier. (There are some // exceptional cases, and when that happens, we simply query on-demand // which keys are modifiers. See the RunKey{Press,Release}Callbacks // functions in keybind/callback.go for the deets.) KeyMapSet(xu, keyMap) ModMapSet(xu, modMap) } } // minMaxKeycodeGet a simple accessor to the X setup info to return the // minimum and maximum keycodes. They are typically 8 and 255, respectively. func minMaxKeycodeGet(xu *xgbutil.XUtil) (xproto.Keycode, xproto.Keycode) { return xu.Setup().MinKeycode, xu.Setup().MaxKeycode } // A convenience function to grab the KeyboardMapping and ModifierMapping // from X. We need to do this on startup (see Initialize) and whenever we // get a MappingNotify event. func MapsGet(xu *xgbutil.XUtil) (*xproto.GetKeyboardMappingReply, *xproto.GetModifierMappingReply) { min, max := minMaxKeycodeGet(xu) newKeymap, keyErr := xproto.GetKeyboardMapping(xu.Conn(), min, byte(max-min+1)).Reply() newModmap, modErr := xproto.GetModifierMapping(xu.Conn()).Reply() // If there are errors, we really need to panic. We just can't do // any key binding without a mapping from the server. if keyErr != nil { panic(fmt.Sprintf("COULD NOT GET KEYBOARD MAPPING: %v\n"+ "THIS IS AN UNRECOVERABLE ERROR.\n", keyErr)) } if modErr != nil { panic(fmt.Sprintf("COULD NOT GET MODIFIER MAPPING: %v\n"+ "THIS IS AN UNRECOVERABLE ERROR.\n", keyErr)) } return newKeymap, newModmap } // ParseString takes a string of the format '[Mod[-Mod[...]]]-KEY', // i.e., 'Mod4-j', and returns a modifiers/keycode combo. // An error is returned if the string is malformed, or if no valid KEY can // be found. // Valid values of KEY should include almost anything returned by pressing // keys with the 'xev' program. Alternatively, you may reference the keys // of the 'keysyms' map defined in keybind/keysymdef.go. func ParseString( xu *xgbutil.XUtil, s string) (uint16, []xproto.Keycode, error) { mods, kcs := uint16(0), []xproto.Keycode{} for _, part := range strings.Split(s, "-") { switch strings.ToLower(part) { case "shift": mods |= xproto.ModMaskShift case "lock": mods |= xproto.ModMaskLock case "control": mods |= xproto.ModMaskControl case "mod1": mods |= xproto.ModMask1 case "mod2": mods |= xproto.ModMask2 case "mod3": mods |= xproto.ModMask3 case "mod4": mods |= xproto.ModMask4 case "mod5": mods |= xproto.ModMask5 case "any": mods |= xproto.ModMaskAny default: // a key code! if len(kcs) == 0 { // only accept the first keycode we see kcs = StrToKeycodes(xu, part) } } } if len(kcs) == 0 { return 0, nil, fmt.Errorf("Could not find a valid keycode in the "+ "string '%s'. Key binding failed.", s) } return mods, kcs, nil } // StrToKeycodes is a wrapper around keycodesGet meant to make our search // a bit more flexible if needed. (i.e., case-insensitive) func StrToKeycodes(xu *xgbutil.XUtil, str string) []xproto.Keycode { // Do some fancy case stuff before we give up. sym, ok := keysyms[str] if !ok { sym, ok = keysyms[strings.Title(str)] } if !ok { sym, ok = keysyms[strings.ToLower(str)] } if !ok { sym, ok = keysyms[strings.ToUpper(str)] } // If we don't know what 'str' is, return 0. // There will probably be a bad access. We should do better than that... if !ok { return []xproto.Keycode{} } return keycodesGet(xu, sym) } // keysymsPer gets the number of keysyms per keycode for the current key map. func keysymsPer(xu *xgbutil.XUtil) int { return int(KeyMapGet(xu).KeysymsPerKeycode) } // Given a keysym, find all keycodes mapped to it in the current X environment. // keybind.Initialize MUST have been called before using this function. func keycodesGet(xu *xgbutil.XUtil, keysym xproto.Keysym) []xproto.Keycode { min, max := minMaxKeycodeGet(xu) keyMap := KeyMapGet(xu) if keyMap == nil { panic("keybind.Initialize must be called before using the keybind " + "package.") } var c byte var keycode xproto.Keycode keycodes := make([]xproto.Keycode, 0) set := make(map[xproto.Keycode]bool, 0) for kc := int(min); kc <= int(max); kc++ { keycode = xproto.Keycode(kc) for c = 0; c < keyMap.KeysymsPerKeycode; c++ { if keysym == KeysymGet(xu, keycode, c) && !set[keycode] { keycodes = append(keycodes, keycode) set[keycode] = true } } } return keycodes } // KeysymToStr converts a keysym to a string if one is available. // If one is found, KeysymToStr also checks the 'weirdKeysyms' map, which // contains a map from multi-character strings to single character // representations (i.e., 'braceleft' to '{'). // If no match is found initially, an empty string is returned. func KeysymToStr(keysym xproto.Keysym) string { symStr, ok := strKeysyms[keysym] if !ok { return "" } shortSymStr, ok := weirdKeysyms[symStr] if ok { return string(shortSymStr) } return symStr } // KeysymGet is a shortcut alias for 'KeysymGetWithMap' using the current // keymap stored in XUtil. // keybind.Initialize MUST have been called before using this function. func KeysymGet(xu *xgbutil.XUtil, keycode xproto.Keycode, column byte) xproto.Keysym { return KeysymGetWithMap(xu, KeyMapGet(xu), keycode, column) } // KeysymGetWithMap uses the given key map and finds a keysym associated // with the given keycode in the current X environment. func KeysymGetWithMap(xu *xgbutil.XUtil, keyMap *xgbutil.KeyboardMapping, keycode xproto.Keycode, column byte) xproto.Keysym { min, _ := minMaxKeycodeGet(xu) i := (int(keycode)-int(min))*int(keyMap.KeysymsPerKeycode) + int(column) return keyMap.Keysyms[i] } // ModGet finds the modifier currently associated with a given keycode. // If a modifier doesn't exist for this keycode, then 0 is returned. func ModGet(xu *xgbutil.XUtil, keycode xproto.Keycode) uint16 { modMap := ModMapGet(xu) var i byte for i = 0; int(i) < len(modMap.Keycodes); i++ { if modMap.Keycodes[i] == keycode { return Modifiers[i/modMap.KeycodesPerModifier] } } return 0 } // Grab grabs a key with mods on a particular window. // This will also grab all combinations of modifiers found in xevent.IgnoreMods. func Grab(xu *xgbutil.XUtil, win xproto.Window, mods uint16, key xproto.Keycode) { for _, m := range xevent.IgnoreMods { xproto.GrabKey(xu.Conn(), true, win, mods|m, key, xproto.GrabModeAsync, xproto.GrabModeAsync) } } // GrabChecked Grabs a key with mods on a particular window. // This is the same as Grab, except that it issue a checked request. // Which means that an error could be returned and handled on the spot. // (Checked requests are slower than unchecked requests.) // This will also grab all combinations of modifiers found in xevent.IgnoreMods. func GrabChecked(xu *xgbutil.XUtil, win xproto.Window, mods uint16, key xproto.Keycode) error { var err error for _, m := range xevent.IgnoreMods { err = xproto.GrabKeyChecked(xu.Conn(), true, win, mods|m, key, xproto.GrabModeAsync, xproto.GrabModeAsync).Check() if err != nil { return err } } return nil } // Ungrab undoes Grab. It will handle all combinations od modifiers found // in xevent.IgnoreMods. func Ungrab(xu *xgbutil.XUtil, win xproto.Window, mods uint16, key xproto.Keycode) { for _, m := range xevent.IgnoreMods { xproto.UngrabKeyChecked(xu.Conn(), key, win, mods|m).Check() } } // GrabKeyboard grabs the entire keyboard. // Returns whether GrabStatus is successful and an error if one is reported by // XGB. It is possible to not get an error and the grab to be unsuccessful. // The purpose of 'win' is that after a grab is successful, ALL Key*Events will // be sent to that window. Make sure you have a callback attached :-) func GrabKeyboard(xu *xgbutil.XUtil, win xproto.Window) error { reply, err := xproto.GrabKeyboard(xu.Conn(), false, win, 0, xproto.GrabModeAsync, xproto.GrabModeAsync).Reply() if err != nil { return fmt.Errorf("GrabKeyboard: Error grabbing keyboard on "+ "window '%x': %s", win, err) } switch reply.Status { case xproto.GrabStatusSuccess: // all is well case xproto.GrabStatusAlreadyGrabbed: return fmt.Errorf("GrabKeyboard: Could not grab keyboard. " + "Status: AlreadyGrabbed.") case xproto.GrabStatusInvalidTime: return fmt.Errorf("GrabKeyboard: Could not grab keyboard. " + "Status: InvalidTime.") case xproto.GrabStatusNotViewable: return fmt.Errorf("GrabKeyboard: Could not grab keyboard. " + "Status: NotViewable.") case xproto.GrabStatusFrozen: return fmt.Errorf("GrabKeyboard: Could not grab keyboard. " + "Status: Frozen.") } return nil } // UngrabKeyboard undoes GrabKeyboard. func UngrabKeyboard(xu *xgbutil.XUtil) { xproto.UngrabKeyboard(xu.Conn(), 0) } // SmartGrab grabs the keyboard for the given window, and redirects all // key events in the xevent main event loop to avoid races. func SmartGrab(xu *xgbutil.XUtil, win xproto.Window) error { err := GrabKeyboard(xu, win) if err != nil { return fmt.Errorf("SmartGrab: %s", err) } // Now redirect all key events to the dummy window to prevent races xevent.RedirectKeyEvents(xu, win) return nil } // SmartUngrab reverses SmartGrab and stops redirecting all key events. func SmartUngrab(xu *xgbutil.XUtil) { UngrabKeyboard(xu) // Stop redirecting all key events xevent.RedirectKeyEvents(xu, 0) } // DummyGrab grabs the keyboard and sends all key events to the dummy window. func DummyGrab(xu *xgbutil.XUtil) error { return SmartGrab(xu, xu.Dummy()) } // DummyUngrab ungrabs the keyboard from the dummy window. func DummyUngrab(xu *xgbutil.XUtil) { SmartUngrab(xu) } ================================================ FILE: keybind/keysymdef.go ================================================ package keybind /* This file contains the keysym definitions from X. Taken from X11/keysymdef.h It also contains the "XFree86 vendor specific keysyms" taken from X11/XF86keysym.h. We store this as a map because we need to be able to do reverse lookups. keysyms is a mapping from english strings to key symbols. strKeysyms is a mapping from key symbols to english strings. */ import "github.com/BurntSushi/xgb/xproto" func init() { strKeysyms = make(map[xproto.Keysym]string, len(keysyms)) for kstr, keysym := range keysyms { // If we already have this keysym as a key, skip it. // (Prefer the first. This may be bad.) if _, ok := strKeysyms[keysym]; !ok { strKeysyms[keysym] = kstr } } } // weirdKeysyms is a feeble attempt to map english words to single // characters. i.e., "bracketleft" -> [ and "exclam" to ! var weirdKeysyms = map[string]rune{ "space": ' ', "exclam": '!', "at": '@', "numbersign": '#', "dollar": '$', "percent": '%', "asciicircum": '^', "ampersand": '&', "asterisk": '*', "parenleft": '(', "parenright": ')', "bracketleft": '[', "bracketright": ']', "braceleft": '{', "braceright": '}', "minus": '-', "underscore": '_', "equal": '=', "plus": '+', "backslash": '\\', "bar": '|', "semicolon": ';', "colon": ':', "apostrophe": '\'', "quoteright": '\'', "quotedbl": '"', "less": '<', "greater": '>', "comma": ',', "period": '.', "slash": '/', "question": '?', "grave": '`', "quoteleft": '`', "asciitilde": '~', "KP_Multiply": '*', "KP_Divide": '/', "KP_Subtract": '-', "KP_Add": '+', "KP_Decimal": '.', "KP_0": '0', "KP_1": '1', "KP_2": '2', "KP_3": '3', "KP_4": '4', "KP_5": '5', "KP_6": '6', "KP_7": '7', "KP_8": '8', "KP_9": '9', } // strKeysyms is the reverse of keysyms. It is built upon initialization. // TODO: Hard code the reverse map to be faster. var strKeysyms map[xproto.Keysym]string var keysyms map[string]xproto.Keysym = map[string]xproto.Keysym{ "VoidSymbol": 0xffffff, "BackSpace": 0xff08, "Tab": 0xff09, "Linefeed": 0xff0a, "Clear": 0xff0b, "Return": 0xff0d, "Pause": 0xff13, "Scroll_Lock": 0xff14, "Sys_Req": 0xff15, "Escape": 0xff1b, "Delete": 0xffff, "Multi_key": 0xff20, "Codeinput": 0xff37, "SingleCandidate": 0xff3c, "MultipleCandidate": 0xff3d, "PreviousCandidate": 0xff3e, "Kanji": 0xff21, "Muhenkan": 0xff22, "Henkan_Mode": 0xff23, "Henkan": 0xff23, "Romaji": 0xff24, "Hiragana": 0xff25, "Katakana": 0xff26, "Hiragana_Katakana": 0xff27, "Zenkaku": 0xff28, "Hankaku": 0xff29, "Zenkaku_Hankaku": 0xff2a, "Touroku": 0xff2b, "Massyo": 0xff2c, "Kana_Lock": 0xff2d, "Kana_Shift": 0xff2e, "Eisu_Shift": 0xff2f, "Eisu_toggle": 0xff30, "Kanji_Bangou": 0xff37, "Zen_Koho": 0xff3d, "Mae_Koho": 0xff3e, "Home": 0xff50, "Left": 0xff51, "Up": 0xff52, "Right": 0xff53, "Down": 0xff54, "Prior": 0xff55, "Page_Up": 0xff55, "Next": 0xff56, "Page_Down": 0xff56, "End": 0xff57, "Begin": 0xff58, "Select": 0xff60, "Print": 0xff61, "Execute": 0xff62, "Insert": 0xff63, "Undo": 0xff65, "Redo": 0xff66, "Menu": 0xff67, "Find": 0xff68, "Cancel": 0xff69, "Help": 0xff6a, "Break": 0xff6b, "Mode_switch": 0xff7e, "script_switch": 0xff7e, "Num_Lock": 0xff7f, "KP_Space": 0xff80, "KP_Tab": 0xff89, "KP_Enter": 0xff8d, "KP_F1": 0xff91, "KP_F2": 0xff92, "KP_F3": 0xff93, "KP_F4": 0xff94, "KP_Home": 0xff95, "KP_Left": 0xff96, "KP_Up": 0xff97, "KP_Right": 0xff98, "KP_Down": 0xff99, "KP_Prior": 0xff9a, "KP_Page_Up": 0xff9a, "KP_Next": 0xff9b, "KP_Page_Down": 0xff9b, "KP_End": 0xff9c, "KP_Begin": 0xff9d, "KP_Insert": 0xff9e, "KP_Delete": 0xff9f, "KP_Equal": 0xffbd, "KP_Multiply": 0xffaa, "KP_Add": 0xffab, "KP_Separator": 0xffac, "KP_Subtract": 0xffad, "KP_Decimal": 0xffae, "KP_Divide": 0xffaf, "KP_0": 0xffb0, "KP_1": 0xffb1, "KP_2": 0xffb2, "KP_3": 0xffb3, "KP_4": 0xffb4, "KP_5": 0xffb5, "KP_6": 0xffb6, "KP_7": 0xffb7, "KP_8": 0xffb8, "KP_9": 0xffb9, "F1": 0xffbe, "F2": 0xffbf, "F3": 0xffc0, "F4": 0xffc1, "F5": 0xffc2, "F6": 0xffc3, "F7": 0xffc4, "F8": 0xffc5, "F9": 0xffc6, "F10": 0xffc7, "F11": 0xffc8, "L1": 0xffc8, "F12": 0xffc9, "L2": 0xffc9, "F13": 0xffca, "L3": 0xffca, "F14": 0xffcb, "L4": 0xffcb, "F15": 0xffcc, "L5": 0xffcc, "F16": 0xffcd, "L6": 0xffcd, "F17": 0xffce, "L7": 0xffce, "F18": 0xffcf, "L8": 0xffcf, "F19": 0xffd0, "L9": 0xffd0, "F20": 0xffd1, "L10": 0xffd1, "F21": 0xffd2, "R1": 0xffd2, "F22": 0xffd3, "R2": 0xffd3, "F23": 0xffd4, "R3": 0xffd4, "F24": 0xffd5, "R4": 0xffd5, "F25": 0xffd6, "R5": 0xffd6, "F26": 0xffd7, "R6": 0xffd7, "F27": 0xffd8, "R7": 0xffd8, "F28": 0xffd9, "R8": 0xffd9, "F29": 0xffda, "R9": 0xffda, "F30": 0xffdb, "R10": 0xffdb, "F31": 0xffdc, "R11": 0xffdc, "F32": 0xffdd, "R12": 0xffdd, "F33": 0xffde, "R13": 0xffde, "F34": 0xffdf, "R14": 0xffdf, "F35": 0xffe0, "R15": 0xffe0, "Shift_L": 0xffe1, "Shift_R": 0xffe2, "Control_L": 0xffe3, "Control_R": 0xffe4, "Caps_Lock": 0xffe5, "Shift_Lock": 0xffe6, "Meta_L": 0xffe7, "Meta_R": 0xffe8, "Alt_L": 0xffe9, "Alt_R": 0xffea, "Super_L": 0xffeb, "Super_R": 0xffec, "Hyper_L": 0xffed, "Hyper_R": 0xffee, "ISO_Lock": 0xfe01, "ISO_Level2_Latch": 0xfe02, "ISO_Level3_Shift": 0xfe03, "ISO_Level3_Latch": 0xfe04, "ISO_Level3_Lock": 0xfe05, "ISO_Level5_Shift": 0xfe11, "ISO_Level5_Latch": 0xfe12, "ISO_Level5_Lock": 0xfe13, "ISO_Group_Shift": 0xff7e, "ISO_Group_Latch": 0xfe06, "ISO_Group_Lock": 0xfe07, "ISO_Next_Group": 0xfe08, "ISO_Next_Group_Lock": 0xfe09, "ISO_Prev_Group": 0xfe0a, "ISO_Prev_Group_Lock": 0xfe0b, "ISO_First_Group": 0xfe0c, "ISO_First_Group_Lock": 0xfe0d, "ISO_Last_Group": 0xfe0e, "ISO_Last_Group_Lock": 0xfe0f, "ISO_Left_Tab": 0xfe20, "ISO_Move_Line_Up": 0xfe21, "ISO_Move_Line_Down": 0xfe22, "ISO_Partial_Line_Up": 0xfe23, "ISO_Partial_Line_Down": 0xfe24, "ISO_Partial_Space_Left": 0xfe25, "ISO_Partial_Space_Right": 0xfe26, "ISO_Set_Margin_Left": 0xfe27, "ISO_Set_Margin_Right": 0xfe28, "ISO_Release_Margin_Left": 0xfe29, "ISO_Release_Margin_Right": 0xfe2a, "ISO_Release_Both_Margins": 0xfe2b, "ISO_Fast_Cursor_Left": 0xfe2c, "ISO_Fast_Cursor_Right": 0xfe2d, "ISO_Fast_Cursor_Up": 0xfe2e, "ISO_Fast_Cursor_Down": 0xfe2f, "ISO_Continuous_Underline": 0xfe30, "ISO_Discontinuous_Underline": 0xfe31, "ISO_Emphasize": 0xfe32, "ISO_Center_Object": 0xfe33, "ISO_Enter": 0xfe34, "dead_grave": 0xfe50, "dead_acute": 0xfe51, "dead_circumflex": 0xfe52, "dead_tilde": 0xfe53, "dead_perispomeni": 0xfe53, "dead_macron": 0xfe54, "dead_breve": 0xfe55, "dead_abovedot": 0xfe56, "dead_diaeresis": 0xfe57, "dead_abovering": 0xfe58, "dead_doubleacute": 0xfe59, "dead_caron": 0xfe5a, "dead_cedilla": 0xfe5b, "dead_ogonek": 0xfe5c, "dead_iota": 0xfe5d, "dead_voiced_sound": 0xfe5e, "dead_semivoiced_sound": 0xfe5f, "dead_belowdot": 0xfe60, "dead_hook": 0xfe61, "dead_horn": 0xfe62, "dead_stroke": 0xfe63, "dead_abovecomma": 0xfe64, "dead_psili": 0xfe64, "dead_abovereversedcomma": 0xfe65, "dead_dasia": 0xfe65, "dead_doublegrave": 0xfe66, "dead_belowring": 0xfe67, "dead_belowmacron": 0xfe68, "dead_belowcircumflex": 0xfe69, "dead_belowtilde": 0xfe6a, "dead_belowbreve": 0xfe6b, "dead_belowdiaeresis": 0xfe6c, "dead_invertedbreve": 0xfe6d, "dead_belowcomma": 0xfe6e, "dead_currency": 0xfe6f, "dead_a": 0xfe80, "dead_A": 0xfe81, "dead_e": 0xfe82, "dead_E": 0xfe83, "dead_i": 0xfe84, "dead_I": 0xfe85, "dead_o": 0xfe86, "dead_O": 0xfe87, "dead_u": 0xfe88, "dead_U": 0xfe89, "dead_small_schwa": 0xfe8a, "dead_capital_schwa": 0xfe8b, "First_Virtual_Screen": 0xfed0, "Prev_Virtual_Screen": 0xfed1, "Next_Virtual_Screen": 0xfed2, "Last_Virtual_Screen": 0xfed4, "Terminate_Server": 0xfed5, "AccessX_Enable": 0xfe70, "AccessX_Feedback_Enable": 0xfe71, "RepeatKeys_Enable": 0xfe72, "SlowKeys_Enable": 0xfe73, "BounceKeys_Enable": 0xfe74, "StickyKeys_Enable": 0xfe75, "MouseKeys_Enable": 0xfe76, "MouseKeys_Accel_Enable": 0xfe77, "Overlay1_Enable": 0xfe78, "Overlay2_Enable": 0xfe79, "AudibleBell_Enable": 0xfe7a, "Pointer_Left": 0xfee0, "Pointer_Right": 0xfee1, "Pointer_Up": 0xfee2, "Pointer_Down": 0xfee3, "Pointer_UpLeft": 0xfee4, "Pointer_UpRight": 0xfee5, "Pointer_DownLeft": 0xfee6, "Pointer_DownRight": 0xfee7, "Pointer_Button_Dflt": 0xfee8, "Pointer_Button1": 0xfee9, "Pointer_Button2": 0xfeea, "Pointer_Button3": 0xfeeb, "Pointer_Button4": 0xfeec, "Pointer_Button5": 0xfeed, "Pointer_DblClick_Dflt": 0xfeee, "Pointer_DblClick1": 0xfeef, "Pointer_DblClick2": 0xfef0, "Pointer_DblClick3": 0xfef1, "Pointer_DblClick4": 0xfef2, "Pointer_DblClick5": 0xfef3, "Pointer_Drag_Dflt": 0xfef4, "Pointer_Drag1": 0xfef5, "Pointer_Drag2": 0xfef6, "Pointer_Drag3": 0xfef7, "Pointer_Drag4": 0xfef8, "Pointer_Drag5": 0xfefd, "Pointer_EnableKeys": 0xfef9, "Pointer_Accelerate": 0xfefa, "Pointer_DfltBtnNext": 0xfefb, "Pointer_DfltBtnPrev": 0xfefc, "3270_Duplicate": 0xfd01, "3270_FieldMark": 0xfd02, "3270_Right2": 0xfd03, "3270_Left2": 0xfd04, "3270_BackTab": 0xfd05, "3270_EraseEOF": 0xfd06, "3270_EraseInput": 0xfd07, "3270_Reset": 0xfd08, "3270_Quit": 0xfd09, "3270_PA1": 0xfd0a, "3270_PA2": 0xfd0b, "3270_PA3": 0xfd0c, "3270_Test": 0xfd0d, "3270_Attn": 0xfd0e, "3270_CursorBlink": 0xfd0f, "3270_AltCursor": 0xfd10, "3270_KeyClick": 0xfd11, "3270_Jump": 0xfd12, "3270_Ident": 0xfd13, "3270_Rule": 0xfd14, "3270_Copy": 0xfd15, "3270_Play": 0xfd16, "3270_Setup": 0xfd17, "3270_Record": 0xfd18, "3270_ChangeScreen": 0xfd19, "3270_DeleteWord": 0xfd1a, "3270_ExSelect": 0xfd1b, "3270_CursorSelect": 0xfd1c, "3270_PrintScreen": 0xfd1d, "3270_Enter": 0xfd1e, "space": 0x0020, "exclam": 0x0021, "quotedbl": 0x0022, "numbersign": 0x0023, "dollar": 0x0024, "percent": 0x0025, "ampersand": 0x0026, "apostrophe": 0x0027, "quoteright": 0x0027, "parenleft": 0x0028, "parenright": 0x0029, "asterisk": 0x002a, "plus": 0x002b, "comma": 0x002c, "minus": 0x002d, "period": 0x002e, "slash": 0x002f, "0": 0x0030, "1": 0x0031, "2": 0x0032, "3": 0x0033, "4": 0x0034, "5": 0x0035, "6": 0x0036, "7": 0x0037, "8": 0x0038, "9": 0x0039, "colon": 0x003a, "semicolon": 0x003b, "less": 0x003c, "equal": 0x003d, "greater": 0x003e, "question": 0x003f, "at": 0x0040, "A": 0x0041, "B": 0x0042, "C": 0x0043, "D": 0x0044, "E": 0x0045, "F": 0x0046, "G": 0x0047, "H": 0x0048, "I": 0x0049, "J": 0x004a, "K": 0x004b, "L": 0x004c, "M": 0x004d, "N": 0x004e, "O": 0x004f, "P": 0x0050, "Q": 0x0051, "R": 0x0052, "S": 0x0053, "T": 0x0054, "U": 0x0055, "V": 0x0056, "W": 0x0057, "X": 0x0058, "Y": 0x0059, "Z": 0x005a, "bracketleft": 0x005b, "backslash": 0x005c, "bracketright": 0x005d, "asciicircum": 0x005e, "underscore": 0x005f, "grave": 0x0060, "quoteleft": 0x0060, "a": 0x0061, "b": 0x0062, "c": 0x0063, "d": 0x0064, "e": 0x0065, "f": 0x0066, "g": 0x0067, "h": 0x0068, "i": 0x0069, "j": 0x006a, "k": 0x006b, "l": 0x006c, "m": 0x006d, "n": 0x006e, "o": 0x006f, "p": 0x0070, "q": 0x0071, "r": 0x0072, "s": 0x0073, "t": 0x0074, "u": 0x0075, "v": 0x0076, "w": 0x0077, "x": 0x0078, "y": 0x0079, "z": 0x007a, "braceleft": 0x007b, "bar": 0x007c, "braceright": 0x007d, "asciitilde": 0x007e, "nobreakspace": 0x00a0, "exclamdown": 0x00a1, "cent": 0x00a2, "sterling": 0x00a3, "currency": 0x00a4, "yen": 0x00a5, "brokenbar": 0x00a6, "section": 0x00a7, "diaeresis": 0x00a8, "copyright": 0x00a9, "ordfeminine": 0x00aa, "guillemotleft": 0x00ab, "notsign": 0x00ac, "hyphen": 0x00ad, "registered": 0x00ae, "macron": 0x00af, "degree": 0x00b0, "plusminus": 0x00b1, "twosuperior": 0x00b2, "threesuperior": 0x00b3, "acute": 0x00b4, "mu": 0x00b5, "paragraph": 0x00b6, "periodcentered": 0x00b7, "cedilla": 0x00b8, "onesuperior": 0x00b9, "masculine": 0x00ba, "guillemotright": 0x00bb, "onequarter": 0x00bc, "onehalf": 0x00bd, "threequarters": 0x00be, "questiondown": 0x00bf, "Agrave": 0x00c0, "Aacute": 0x00c1, "Acircumflex": 0x00c2, "Atilde": 0x00c3, "Adiaeresis": 0x00c4, "Aring": 0x00c5, "AE": 0x00c6, "Ccedilla": 0x00c7, "Egrave": 0x00c8, "Eacute": 0x00c9, "Ecircumflex": 0x00ca, "Ediaeresis": 0x00cb, "Igrave": 0x00cc, "Iacute": 0x00cd, "Icircumflex": 0x00ce, "Idiaeresis": 0x00cf, "ETH": 0x00d0, "Eth": 0x00d0, "Ntilde": 0x00d1, "Ograve": 0x00d2, "Oacute": 0x00d3, "Ocircumflex": 0x00d4, "Otilde": 0x00d5, "Odiaeresis": 0x00d6, "multiply": 0x00d7, "Oslash": 0x00d8, "Ooblique": 0x00d8, "Ugrave": 0x00d9, "Uacute": 0x00da, "Ucircumflex": 0x00db, "Udiaeresis": 0x00dc, "Yacute": 0x00dd, "THORN": 0x00de, "Thorn": 0x00de, "ssharp": 0x00df, "agrave": 0x00e0, "aacute": 0x00e1, "acircumflex": 0x00e2, "atilde": 0x00e3, "adiaeresis": 0x00e4, "aring": 0x00e5, "ae": 0x00e6, "ccedilla": 0x00e7, "egrave": 0x00e8, "eacute": 0x00e9, "ecircumflex": 0x00ea, "ediaeresis": 0x00eb, "igrave": 0x00ec, "iacute": 0x00ed, "icircumflex": 0x00ee, "idiaeresis": 0x00ef, "eth": 0x00f0, "ntilde": 0x00f1, "ograve": 0x00f2, "oacute": 0x00f3, "ocircumflex": 0x00f4, "otilde": 0x00f5, "odiaeresis": 0x00f6, "division": 0x00f7, "oslash": 0x00f8, "ooblique": 0x00f8, "ugrave": 0x00f9, "uacute": 0x00fa, "ucircumflex": 0x00fb, "udiaeresis": 0x00fc, "yacute": 0x00fd, "thorn": 0x00fe, "ydiaeresis": 0x00ff, "Aogonek": 0x01a1, "breve": 0x01a2, "Lstroke": 0x01a3, "Lcaron": 0x01a5, "Sacute": 0x01a6, "Scaron": 0x01a9, "Scedilla": 0x01aa, "Tcaron": 0x01ab, "Zacute": 0x01ac, "Zcaron": 0x01ae, "Zabovedot": 0x01af, "aogonek": 0x01b1, "ogonek": 0x01b2, "lstroke": 0x01b3, "lcaron": 0x01b5, "sacute": 0x01b6, "caron": 0x01b7, "scaron": 0x01b9, "scedilla": 0x01ba, "tcaron": 0x01bb, "zacute": 0x01bc, "doubleacute": 0x01bd, "zcaron": 0x01be, "zabovedot": 0x01bf, "Racute": 0x01c0, "Abreve": 0x01c3, "Lacute": 0x01c5, "Cacute": 0x01c6, "Ccaron": 0x01c8, "Eogonek": 0x01ca, "Ecaron": 0x01cc, "Dcaron": 0x01cf, "Dstroke": 0x01d0, "Nacute": 0x01d1, "Ncaron": 0x01d2, "Odoubleacute": 0x01d5, "Rcaron": 0x01d8, "Uring": 0x01d9, "Udoubleacute": 0x01db, "Tcedilla": 0x01de, "racute": 0x01e0, "abreve": 0x01e3, "lacute": 0x01e5, "cacute": 0x01e6, "ccaron": 0x01e8, "eogonek": 0x01ea, "ecaron": 0x01ec, "dcaron": 0x01ef, "dstroke": 0x01f0, "nacute": 0x01f1, "ncaron": 0x01f2, "odoubleacute": 0x01f5, "udoubleacute": 0x01fb, "rcaron": 0x01f8, "uring": 0x01f9, "tcedilla": 0x01fe, "abovedot": 0x01ff, "Hstroke": 0x02a1, "Hcircumflex": 0x02a6, "Iabovedot": 0x02a9, "Gbreve": 0x02ab, "Jcircumflex": 0x02ac, "hstroke": 0x02b1, "hcircumflex": 0x02b6, "idotless": 0x02b9, "gbreve": 0x02bb, "jcircumflex": 0x02bc, "Cabovedot": 0x02c5, "Ccircumflex": 0x02c6, "Gabovedot": 0x02d5, "Gcircumflex": 0x02d8, "Ubreve": 0x02dd, "Scircumflex": 0x02de, "cabovedot": 0x02e5, "ccircumflex": 0x02e6, "gabovedot": 0x02f5, "gcircumflex": 0x02f8, "ubreve": 0x02fd, "scircumflex": 0x02fe, "kra": 0x03a2, "kappa": 0x03a2, "Rcedilla": 0x03a3, "Itilde": 0x03a5, "Lcedilla": 0x03a6, "Emacron": 0x03aa, "Gcedilla": 0x03ab, "Tslash": 0x03ac, "rcedilla": 0x03b3, "itilde": 0x03b5, "lcedilla": 0x03b6, "emacron": 0x03ba, "gcedilla": 0x03bb, "tslash": 0x03bc, "ENG": 0x03bd, "eng": 0x03bf, "Amacron": 0x03c0, "Iogonek": 0x03c7, "Eabovedot": 0x03cc, "Imacron": 0x03cf, "Ncedilla": 0x03d1, "Omacron": 0x03d2, "Kcedilla": 0x03d3, "Uogonek": 0x03d9, "Utilde": 0x03dd, "Umacron": 0x03de, "amacron": 0x03e0, "iogonek": 0x03e7, "eabovedot": 0x03ec, "imacron": 0x03ef, "ncedilla": 0x03f1, "omacron": 0x03f2, "kcedilla": 0x03f3, "uogonek": 0x03f9, "utilde": 0x03fd, "umacron": 0x03fe, "Babovedot": 0x1001e02, "babovedot": 0x1001e03, "Dabovedot": 0x1001e0a, "Wgrave": 0x1001e80, "Wacute": 0x1001e82, "dabovedot": 0x1001e0b, "Ygrave": 0x1001ef2, "Fabovedot": 0x1001e1e, "fabovedot": 0x1001e1f, "Mabovedot": 0x1001e40, "mabovedot": 0x1001e41, "Pabovedot": 0x1001e56, "wgrave": 0x1001e81, "pabovedot": 0x1001e57, "wacute": 0x1001e83, "Sabovedot": 0x1001e60, "ygrave": 0x1001ef3, "Wdiaeresis": 0x1001e84, "wdiaeresis": 0x1001e85, "sabovedot": 0x1001e61, "Wcircumflex": 0x1000174, "Tabovedot": 0x1001e6a, "Ycircumflex": 0x1000176, "wcircumflex": 0x1000175, "tabovedot": 0x1001e6b, "ycircumflex": 0x1000177, "OE": 0x13bc, "oe": 0x13bd, "Ydiaeresis": 0x13be, "overline": 0x047e, "kana_fullstop": 0x04a1, "kana_openingbracket": 0x04a2, "kana_closingbracket": 0x04a3, "kana_comma": 0x04a4, "kana_conjunctive": 0x04a5, "kana_middledot": 0x04a5, "kana_WO": 0x04a6, "kana_a": 0x04a7, "kana_i": 0x04a8, "kana_u": 0x04a9, "kana_e": 0x04aa, "kana_o": 0x04ab, "kana_ya": 0x04ac, "kana_yu": 0x04ad, "kana_yo": 0x04ae, "kana_tsu": 0x04af, "kana_tu": 0x04af, "prolongedsound": 0x04b0, "kana_A": 0x04b1, "kana_I": 0x04b2, "kana_U": 0x04b3, "kana_E": 0x04b4, "kana_O": 0x04b5, "kana_KA": 0x04b6, "kana_KI": 0x04b7, "kana_KU": 0x04b8, "kana_KE": 0x04b9, "kana_KO": 0x04ba, "kana_SA": 0x04bb, "kana_SHI": 0x04bc, "kana_SU": 0x04bd, "kana_SE": 0x04be, "kana_SO": 0x04bf, "kana_TA": 0x04c0, "kana_CHI": 0x04c1, "kana_TI": 0x04c1, "kana_TSU": 0x04c2, "kana_TU": 0x04c2, "kana_TE": 0x04c3, "kana_TO": 0x04c4, "kana_NA": 0x04c5, "kana_NI": 0x04c6, "kana_NU": 0x04c7, "kana_NE": 0x04c8, "kana_NO": 0x04c9, "kana_HA": 0x04ca, "kana_HI": 0x04cb, "kana_FU": 0x04cc, "kana_HU": 0x04cc, "kana_HE": 0x04cd, "kana_HO": 0x04ce, "kana_MA": 0x04cf, "kana_MI": 0x04d0, "kana_MU": 0x04d1, "kana_ME": 0x04d2, "kana_MO": 0x04d3, "kana_YA": 0x04d4, "kana_YU": 0x04d5, "kana_YO": 0x04d6, "kana_RA": 0x04d7, "kana_RI": 0x04d8, "kana_RU": 0x04d9, "kana_RE": 0x04da, "kana_RO": 0x04db, "kana_WA": 0x04dc, "kana_N": 0x04dd, "voicedsound": 0x04de, "semivoicedsound": 0x04df, "kana_switch": 0xff7e, "Farsi_0": 0x10006f0, "Farsi_1": 0x10006f1, "Farsi_2": 0x10006f2, "Farsi_3": 0x10006f3, "Farsi_4": 0x10006f4, "Farsi_5": 0x10006f5, "Farsi_6": 0x10006f6, "Farsi_7": 0x10006f7, "Farsi_8": 0x10006f8, "Farsi_9": 0x10006f9, "Arabic_percent": 0x100066a, "Arabic_superscript_alef": 0x1000670, "Arabic_tteh": 0x1000679, "Arabic_peh": 0x100067e, "Arabic_tcheh": 0x1000686, "Arabic_ddal": 0x1000688, "Arabic_rreh": 0x1000691, "Arabic_comma": 0x05ac, "Arabic_fullstop": 0x10006d4, "Arabic_0": 0x1000660, "Arabic_1": 0x1000661, "Arabic_2": 0x1000662, "Arabic_3": 0x1000663, "Arabic_4": 0x1000664, "Arabic_5": 0x1000665, "Arabic_6": 0x1000666, "Arabic_7": 0x1000667, "Arabic_8": 0x1000668, "Arabic_9": 0x1000669, "Arabic_semicolon": 0x05bb, "Arabic_question_mark": 0x05bf, "Arabic_hamza": 0x05c1, "Arabic_maddaonalef": 0x05c2, "Arabic_hamzaonalef": 0x05c3, "Arabic_hamzaonwaw": 0x05c4, "Arabic_hamzaunderalef": 0x05c5, "Arabic_hamzaonyeh": 0x05c6, "Arabic_alef": 0x05c7, "Arabic_beh": 0x05c8, "Arabic_tehmarbuta": 0x05c9, "Arabic_teh": 0x05ca, "Arabic_theh": 0x05cb, "Arabic_jeem": 0x05cc, "Arabic_hah": 0x05cd, "Arabic_khah": 0x05ce, "Arabic_dal": 0x05cf, "Arabic_thal": 0x05d0, "Arabic_ra": 0x05d1, "Arabic_zain": 0x05d2, "Arabic_seen": 0x05d3, "Arabic_sheen": 0x05d4, "Arabic_sad": 0x05d5, "Arabic_dad": 0x05d6, "Arabic_tah": 0x05d7, "Arabic_zah": 0x05d8, "Arabic_ain": 0x05d9, "Arabic_ghain": 0x05da, "Arabic_tatweel": 0x05e0, "Arabic_feh": 0x05e1, "Arabic_qaf": 0x05e2, "Arabic_kaf": 0x05e3, "Arabic_lam": 0x05e4, "Arabic_meem": 0x05e5, "Arabic_noon": 0x05e6, "Arabic_ha": 0x05e7, "Arabic_heh": 0x05e7, "Arabic_waw": 0x05e8, "Arabic_alefmaksura": 0x05e9, "Arabic_yeh": 0x05ea, "Arabic_fathatan": 0x05eb, "Arabic_dammatan": 0x05ec, "Arabic_kasratan": 0x05ed, "Arabic_fatha": 0x05ee, "Arabic_damma": 0x05ef, "Arabic_kasra": 0x05f0, "Arabic_shadda": 0x05f1, "Arabic_sukun": 0x05f2, "Arabic_madda_above": 0x1000653, "Arabic_hamza_above": 0x1000654, "Arabic_hamza_below": 0x1000655, "Arabic_jeh": 0x1000698, "Arabic_veh": 0x10006a4, "Arabic_keheh": 0x10006a9, "Arabic_gaf": 0x10006af, "Arabic_noon_ghunna": 0x10006ba, "Arabic_heh_doachashmee": 0x10006be, "Farsi_yeh": 0x10006cc, "Arabic_farsi_yeh": 0x10006cc, "Arabic_yeh_baree": 0x10006d2, "Arabic_heh_goal": 0x10006c1, "Arabic_switch": 0xff7e, "Cyrillic_GHE_bar": 0x1000492, "Cyrillic_ghe_bar": 0x1000493, "Cyrillic_ZHE_descender": 0x1000496, "Cyrillic_zhe_descender": 0x1000497, "Cyrillic_KA_descender": 0x100049a, "Cyrillic_ka_descender": 0x100049b, "Cyrillic_KA_vertstroke": 0x100049c, "Cyrillic_ka_vertstroke": 0x100049d, "Cyrillic_EN_descender": 0x10004a2, "Cyrillic_en_descender": 0x10004a3, "Cyrillic_U_straight": 0x10004ae, "Cyrillic_u_straight": 0x10004af, "Cyrillic_U_straight_bar": 0x10004b0, "Cyrillic_u_straight_bar": 0x10004b1, "Cyrillic_HA_descender": 0x10004b2, "Cyrillic_ha_descender": 0x10004b3, "Cyrillic_CHE_descender": 0x10004b6, "Cyrillic_che_descender": 0x10004b7, "Cyrillic_CHE_vertstroke": 0x10004b8, "Cyrillic_che_vertstroke": 0x10004b9, "Cyrillic_SHHA": 0x10004ba, "Cyrillic_shha": 0x10004bb, "Cyrillic_SCHWA": 0x10004d8, "Cyrillic_schwa": 0x10004d9, "Cyrillic_I_macron": 0x10004e2, "Cyrillic_i_macron": 0x10004e3, "Cyrillic_O_bar": 0x10004e8, "Cyrillic_o_bar": 0x10004e9, "Cyrillic_U_macron": 0x10004ee, "Cyrillic_u_macron": 0x10004ef, "Serbian_dje": 0x06a1, "Macedonia_gje": 0x06a2, "Cyrillic_io": 0x06a3, "Ukrainian_ie": 0x06a4, "Ukranian_je": 0x06a4, "Macedonia_dse": 0x06a5, "Ukrainian_i": 0x06a6, "Ukranian_i": 0x06a6, "Ukrainian_yi": 0x06a7, "Ukranian_yi": 0x06a7, "Cyrillic_je": 0x06a8, "Serbian_je": 0x06a8, "Cyrillic_lje": 0x06a9, "Serbian_lje": 0x06a9, "Cyrillic_nje": 0x06aa, "Serbian_nje": 0x06aa, "Serbian_tshe": 0x06ab, "Macedonia_kje": 0x06ac, "Ukrainian_ghe_with_upturn": 0x06ad, "Byelorussian_shortu": 0x06ae, "Cyrillic_dzhe": 0x06af, "Serbian_dze": 0x06af, "numerosign": 0x06b0, "Serbian_DJE": 0x06b1, "Macedonia_GJE": 0x06b2, "Cyrillic_IO": 0x06b3, "Ukrainian_IE": 0x06b4, "Ukranian_JE": 0x06b4, "Macedonia_DSE": 0x06b5, "Ukrainian_I": 0x06b6, "Ukranian_I": 0x06b6, "Ukrainian_YI": 0x06b7, "Ukranian_YI": 0x06b7, "Cyrillic_JE": 0x06b8, "Serbian_JE": 0x06b8, "Cyrillic_LJE": 0x06b9, "Serbian_LJE": 0x06b9, "Cyrillic_NJE": 0x06ba, "Serbian_NJE": 0x06ba, "Serbian_TSHE": 0x06bb, "Macedonia_KJE": 0x06bc, "Ukrainian_GHE_WITH_UPTURN": 0x06bd, "Byelorussian_SHORTU": 0x06be, "Cyrillic_DZHE": 0x06bf, "Serbian_DZE": 0x06bf, "Cyrillic_yu": 0x06c0, "Cyrillic_a": 0x06c1, "Cyrillic_be": 0x06c2, "Cyrillic_tse": 0x06c3, "Cyrillic_de": 0x06c4, "Cyrillic_ie": 0x06c5, "Cyrillic_ef": 0x06c6, "Cyrillic_ghe": 0x06c7, "Cyrillic_ha": 0x06c8, "Cyrillic_i": 0x06c9, "Cyrillic_shorti": 0x06ca, "Cyrillic_ka": 0x06cb, "Cyrillic_el": 0x06cc, "Cyrillic_em": 0x06cd, "Cyrillic_en": 0x06ce, "Cyrillic_o": 0x06cf, "Cyrillic_pe": 0x06d0, "Cyrillic_ya": 0x06d1, "Cyrillic_er": 0x06d2, "Cyrillic_es": 0x06d3, "Cyrillic_te": 0x06d4, "Cyrillic_u": 0x06d5, "Cyrillic_zhe": 0x06d6, "Cyrillic_ve": 0x06d7, "Cyrillic_softsign": 0x06d8, "Cyrillic_yeru": 0x06d9, "Cyrillic_ze": 0x06da, "Cyrillic_sha": 0x06db, "Cyrillic_e": 0x06dc, "Cyrillic_shcha": 0x06dd, "Cyrillic_che": 0x06de, "Cyrillic_hardsign": 0x06df, "Cyrillic_YU": 0x06e0, "Cyrillic_A": 0x06e1, "Cyrillic_BE": 0x06e2, "Cyrillic_TSE": 0x06e3, "Cyrillic_DE": 0x06e4, "Cyrillic_IE": 0x06e5, "Cyrillic_EF": 0x06e6, "Cyrillic_GHE": 0x06e7, "Cyrillic_HA": 0x06e8, "Cyrillic_I": 0x06e9, "Cyrillic_SHORTI": 0x06ea, "Cyrillic_KA": 0x06eb, "Cyrillic_EL": 0x06ec, "Cyrillic_EM": 0x06ed, "Cyrillic_EN": 0x06ee, "Cyrillic_O": 0x06ef, "Cyrillic_PE": 0x06f0, "Cyrillic_YA": 0x06f1, "Cyrillic_ER": 0x06f2, "Cyrillic_ES": 0x06f3, "Cyrillic_TE": 0x06f4, "Cyrillic_U": 0x06f5, "Cyrillic_ZHE": 0x06f6, "Cyrillic_VE": 0x06f7, "Cyrillic_SOFTSIGN": 0x06f8, "Cyrillic_YERU": 0x06f9, "Cyrillic_ZE": 0x06fa, "Cyrillic_SHA": 0x06fb, "Cyrillic_E": 0x06fc, "Cyrillic_SHCHA": 0x06fd, "Cyrillic_CHE": 0x06fe, "Cyrillic_HARDSIGN": 0x06ff, "Greek_ALPHAaccent": 0x07a1, "Greek_EPSILONaccent": 0x07a2, "Greek_ETAaccent": 0x07a3, "Greek_IOTAaccent": 0x07a4, "Greek_IOTAdieresis": 0x07a5, "Greek_IOTAdiaeresis": 0x07a5, "Greek_OMICRONaccent": 0x07a7, "Greek_UPSILONaccent": 0x07a8, "Greek_UPSILONdieresis": 0x07a9, "Greek_OMEGAaccent": 0x07ab, "Greek_accentdieresis": 0x07ae, "Greek_horizbar": 0x07af, "Greek_alphaaccent": 0x07b1, "Greek_epsilonaccent": 0x07b2, "Greek_etaaccent": 0x07b3, "Greek_iotaaccent": 0x07b4, "Greek_iotadieresis": 0x07b5, "Greek_iotaaccentdieresis": 0x07b6, "Greek_omicronaccent": 0x07b7, "Greek_upsilonaccent": 0x07b8, "Greek_upsilondieresis": 0x07b9, "Greek_upsilonaccentdieresis": 0x07ba, "Greek_omegaaccent": 0x07bb, "Greek_ALPHA": 0x07c1, "Greek_BETA": 0x07c2, "Greek_GAMMA": 0x07c3, "Greek_DELTA": 0x07c4, "Greek_EPSILON": 0x07c5, "Greek_ZETA": 0x07c6, "Greek_ETA": 0x07c7, "Greek_THETA": 0x07c8, "Greek_IOTA": 0x07c9, "Greek_KAPPA": 0x07ca, "Greek_LAMDA": 0x07cb, "Greek_LAMBDA": 0x07cb, "Greek_MU": 0x07cc, "Greek_NU": 0x07cd, "Greek_XI": 0x07ce, "Greek_OMICRON": 0x07cf, "Greek_PI": 0x07d0, "Greek_RHO": 0x07d1, "Greek_SIGMA": 0x07d2, "Greek_TAU": 0x07d4, "Greek_UPSILON": 0x07d5, "Greek_PHI": 0x07d6, "Greek_CHI": 0x07d7, "Greek_PSI": 0x07d8, "Greek_OMEGA": 0x07d9, "Greek_alpha": 0x07e1, "Greek_beta": 0x07e2, "Greek_gamma": 0x07e3, "Greek_delta": 0x07e4, "Greek_epsilon": 0x07e5, "Greek_zeta": 0x07e6, "Greek_eta": 0x07e7, "Greek_theta": 0x07e8, "Greek_iota": 0x07e9, "Greek_kappa": 0x07ea, "Greek_lamda": 0x07eb, "Greek_lambda": 0x07eb, "Greek_mu": 0x07ec, "Greek_nu": 0x07ed, "Greek_xi": 0x07ee, "Greek_omicron": 0x07ef, "Greek_pi": 0x07f0, "Greek_rho": 0x07f1, "Greek_sigma": 0x07f2, "Greek_finalsmallsigma": 0x07f3, "Greek_tau": 0x07f4, "Greek_upsilon": 0x07f5, "Greek_phi": 0x07f6, "Greek_chi": 0x07f7, "Greek_psi": 0x07f8, "Greek_omega": 0x07f9, "Greek_switch": 0xff7e, "leftradical": 0x08a1, "topleftradical": 0x08a2, "horizconnector": 0x08a3, "topintegral": 0x08a4, "botintegral": 0x08a5, "vertconnector": 0x08a6, "topleftsqbracket": 0x08a7, "botleftsqbracket": 0x08a8, "toprightsqbracket": 0x08a9, "botrightsqbracket": 0x08aa, "topleftparens": 0x08ab, "botleftparens": 0x08ac, "toprightparens": 0x08ad, "botrightparens": 0x08ae, "leftmiddlecurlybrace": 0x08af, "rightmiddlecurlybrace": 0x08b0, "topleftsummation": 0x08b1, "botleftsummation": 0x08b2, "topvertsummationconnector": 0x08b3, "botvertsummationconnector": 0x08b4, "toprightsummation": 0x08b5, "botrightsummation": 0x08b6, "rightmiddlesummation": 0x08b7, "lessthanequal": 0x08bc, "notequal": 0x08bd, "greaterthanequal": 0x08be, "integral": 0x08bf, "therefore": 0x08c0, "variation": 0x08c1, "infinity": 0x08c2, "nabla": 0x08c5, "approximate": 0x08c8, "similarequal": 0x08c9, "ifonlyif": 0x08cd, "implies": 0x08ce, "identical": 0x08cf, "radical": 0x08d6, "includedin": 0x08da, "includes": 0x08db, "intersection": 0x08dc, "union": 0x08dd, "logicaland": 0x08de, "logicalor": 0x08df, "partialderivative": 0x08ef, "function": 0x08f6, "leftarrow": 0x08fb, "uparrow": 0x08fc, "rightarrow": 0x08fd, "downarrow": 0x08fe, "blank": 0x09df, "soliddiamond": 0x09e0, "checkerboard": 0x09e1, "ht": 0x09e2, "ff": 0x09e3, "cr": 0x09e4, "lf": 0x09e5, "nl": 0x09e8, "vt": 0x09e9, "lowrightcorner": 0x09ea, "uprightcorner": 0x09eb, "upleftcorner": 0x09ec, "lowleftcorner": 0x09ed, "crossinglines": 0x09ee, "horizlinescan1": 0x09ef, "horizlinescan3": 0x09f0, "horizlinescan5": 0x09f1, "horizlinescan7": 0x09f2, "horizlinescan9": 0x09f3, "leftt": 0x09f4, "rightt": 0x09f5, "bott": 0x09f6, "topt": 0x09f7, "vertbar": 0x09f8, "emspace": 0x0aa1, "enspace": 0x0aa2, "em3space": 0x0aa3, "em4space": 0x0aa4, "digitspace": 0x0aa5, "punctspace": 0x0aa6, "thinspace": 0x0aa7, "hairspace": 0x0aa8, "emdash": 0x0aa9, "endash": 0x0aaa, "signifblank": 0x0aac, "ellipsis": 0x0aae, "doubbaselinedot": 0x0aaf, "onethird": 0x0ab0, "twothirds": 0x0ab1, "onefifth": 0x0ab2, "twofifths": 0x0ab3, "threefifths": 0x0ab4, "fourfifths": 0x0ab5, "onesixth": 0x0ab6, "fivesixths": 0x0ab7, "careof": 0x0ab8, "figdash": 0x0abb, "leftanglebracket": 0x0abc, "decimalpoint": 0x0abd, "rightanglebracket": 0x0abe, "marker": 0x0abf, "oneeighth": 0x0ac3, "threeeighths": 0x0ac4, "fiveeighths": 0x0ac5, "seveneighths": 0x0ac6, "trademark": 0x0ac9, "signaturemark": 0x0aca, "trademarkincircle": 0x0acb, "leftopentriangle": 0x0acc, "rightopentriangle": 0x0acd, "emopencircle": 0x0ace, "emopenrectangle": 0x0acf, "leftsinglequotemark": 0x0ad0, "rightsinglequotemark": 0x0ad1, "leftdoublequotemark": 0x0ad2, "rightdoublequotemark": 0x0ad3, "prescription": 0x0ad4, "minutes": 0x0ad6, "seconds": 0x0ad7, "latincross": 0x0ad9, "hexagram": 0x0ada, "filledrectbullet": 0x0adb, "filledlefttribullet": 0x0adc, "filledrighttribullet": 0x0add, "emfilledcircle": 0x0ade, "emfilledrect": 0x0adf, "enopencircbullet": 0x0ae0, "enopensquarebullet": 0x0ae1, "openrectbullet": 0x0ae2, "opentribulletup": 0x0ae3, "opentribulletdown": 0x0ae4, "openstar": 0x0ae5, "enfilledcircbullet": 0x0ae6, "enfilledsqbullet": 0x0ae7, "filledtribulletup": 0x0ae8, "filledtribulletdown": 0x0ae9, "leftpointer": 0x0aea, "rightpointer": 0x0aeb, "club": 0x0aec, "diamond": 0x0aed, "heart": 0x0aee, "maltesecross": 0x0af0, "dagger": 0x0af1, "doubledagger": 0x0af2, "checkmark": 0x0af3, "ballotcross": 0x0af4, "musicalsharp": 0x0af5, "musicalflat": 0x0af6, "malesymbol": 0x0af7, "femalesymbol": 0x0af8, "telephone": 0x0af9, "telephonerecorder": 0x0afa, "phonographcopyright": 0x0afb, "caret": 0x0afc, "singlelowquotemark": 0x0afd, "doublelowquotemark": 0x0afe, "cursor": 0x0aff, "leftcaret": 0x0ba3, "rightcaret": 0x0ba6, "downcaret": 0x0ba8, "upcaret": 0x0ba9, "overbar": 0x0bc0, "downtack": 0x0bc2, "upshoe": 0x0bc3, "downstile": 0x0bc4, "underbar": 0x0bc6, "jot": 0x0bca, "quad": 0x0bcc, "uptack": 0x0bce, "circle": 0x0bcf, "upstile": 0x0bd3, "downshoe": 0x0bd6, "rightshoe": 0x0bd8, "leftshoe": 0x0bda, "lefttack": 0x0bdc, "righttack": 0x0bfc, "hebrew_doublelowline": 0x0cdf, "hebrew_aleph": 0x0ce0, "hebrew_bet": 0x0ce1, "hebrew_beth": 0x0ce1, "hebrew_gimel": 0x0ce2, "hebrew_gimmel": 0x0ce2, "hebrew_dalet": 0x0ce3, "hebrew_daleth": 0x0ce3, "hebrew_he": 0x0ce4, "hebrew_waw": 0x0ce5, "hebrew_zain": 0x0ce6, "hebrew_zayin": 0x0ce6, "hebrew_chet": 0x0ce7, "hebrew_het": 0x0ce7, "hebrew_tet": 0x0ce8, "hebrew_teth": 0x0ce8, "hebrew_yod": 0x0ce9, "hebrew_finalkaph": 0x0cea, "hebrew_kaph": 0x0ceb, "hebrew_lamed": 0x0cec, "hebrew_finalmem": 0x0ced, "hebrew_mem": 0x0cee, "hebrew_finalnun": 0x0cef, "hebrew_nun": 0x0cf0, "hebrew_samech": 0x0cf1, "hebrew_samekh": 0x0cf1, "hebrew_ayin": 0x0cf2, "hebrew_finalpe": 0x0cf3, "hebrew_pe": 0x0cf4, "hebrew_finalzade": 0x0cf5, "hebrew_finalzadi": 0x0cf5, "hebrew_zade": 0x0cf6, "hebrew_zadi": 0x0cf6, "hebrew_qoph": 0x0cf7, "hebrew_kuf": 0x0cf7, "hebrew_resh": 0x0cf8, "hebrew_shin": 0x0cf9, "hebrew_taw": 0x0cfa, "hebrew_taf": 0x0cfa, "Hebrew_switch": 0xff7e, "Thai_kokai": 0x0da1, "Thai_khokhai": 0x0da2, "Thai_khokhuat": 0x0da3, "Thai_khokhwai": 0x0da4, "Thai_khokhon": 0x0da5, "Thai_khorakhang": 0x0da6, "Thai_ngongu": 0x0da7, "Thai_chochan": 0x0da8, "Thai_choching": 0x0da9, "Thai_chochang": 0x0daa, "Thai_soso": 0x0dab, "Thai_chochoe": 0x0dac, "Thai_yoying": 0x0dad, "Thai_dochada": 0x0dae, "Thai_topatak": 0x0daf, "Thai_thothan": 0x0db0, "Thai_thonangmontho": 0x0db1, "Thai_thophuthao": 0x0db2, "Thai_nonen": 0x0db3, "Thai_dodek": 0x0db4, "Thai_totao": 0x0db5, "Thai_thothung": 0x0db6, "Thai_thothahan": 0x0db7, "Thai_thothong": 0x0db8, "Thai_nonu": 0x0db9, "Thai_bobaimai": 0x0dba, "Thai_popla": 0x0dbb, "Thai_phophung": 0x0dbc, "Thai_fofa": 0x0dbd, "Thai_phophan": 0x0dbe, "Thai_fofan": 0x0dbf, "Thai_phosamphao": 0x0dc0, "Thai_moma": 0x0dc1, "Thai_yoyak": 0x0dc2, "Thai_rorua": 0x0dc3, "Thai_ru": 0x0dc4, "Thai_loling": 0x0dc5, "Thai_lu": 0x0dc6, "Thai_wowaen": 0x0dc7, "Thai_sosala": 0x0dc8, "Thai_sorusi": 0x0dc9, "Thai_sosua": 0x0dca, "Thai_hohip": 0x0dcb, "Thai_lochula": 0x0dcc, "Thai_oang": 0x0dcd, "Thai_honokhuk": 0x0dce, "Thai_paiyannoi": 0x0dcf, "Thai_saraa": 0x0dd0, "Thai_maihanakat": 0x0dd1, "Thai_saraaa": 0x0dd2, "Thai_saraam": 0x0dd3, "Thai_sarai": 0x0dd4, "Thai_saraii": 0x0dd5, "Thai_saraue": 0x0dd6, "Thai_sarauee": 0x0dd7, "Thai_sarau": 0x0dd8, "Thai_sarauu": 0x0dd9, "Thai_phinthu": 0x0dda, "Thai_maihanakat_maitho": 0x0dde, "Thai_baht": 0x0ddf, "Thai_sarae": 0x0de0, "Thai_saraae": 0x0de1, "Thai_sarao": 0x0de2, "Thai_saraaimaimuan": 0x0de3, "Thai_saraaimaimalai": 0x0de4, "Thai_lakkhangyao": 0x0de5, "Thai_maiyamok": 0x0de6, "Thai_maitaikhu": 0x0de7, "Thai_maiek": 0x0de8, "Thai_maitho": 0x0de9, "Thai_maitri": 0x0dea, "Thai_maichattawa": 0x0deb, "Thai_thanthakhat": 0x0dec, "Thai_nikhahit": 0x0ded, "Thai_leksun": 0x0df0, "Thai_leknung": 0x0df1, "Thai_leksong": 0x0df2, "Thai_leksam": 0x0df3, "Thai_leksi": 0x0df4, "Thai_lekha": 0x0df5, "Thai_lekhok": 0x0df6, "Thai_lekchet": 0x0df7, "Thai_lekpaet": 0x0df8, "Thai_lekkao": 0x0df9, "Hangul": 0xff31, "Hangul_Start": 0xff32, "Hangul_End": 0xff33, "Hangul_Hanja": 0xff34, "Hangul_Jamo": 0xff35, "Hangul_Romaja": 0xff36, "Hangul_Codeinput": 0xff37, "Hangul_Jeonja": 0xff38, "Hangul_Banja": 0xff39, "Hangul_PreHanja": 0xff3a, "Hangul_PostHanja": 0xff3b, "Hangul_SingleCandidate": 0xff3c, "Hangul_MultipleCandidate": 0xff3d, "Hangul_PreviousCandidate": 0xff3e, "Hangul_Special": 0xff3f, "Hangul_switch": 0xff7e, "Hangul_Kiyeog": 0x0ea1, "Hangul_SsangKiyeog": 0x0ea2, "Hangul_KiyeogSios": 0x0ea3, "Hangul_Nieun": 0x0ea4, "Hangul_NieunJieuj": 0x0ea5, "Hangul_NieunHieuh": 0x0ea6, "Hangul_Dikeud": 0x0ea7, "Hangul_SsangDikeud": 0x0ea8, "Hangul_Rieul": 0x0ea9, "Hangul_RieulKiyeog": 0x0eaa, "Hangul_RieulMieum": 0x0eab, "Hangul_RieulPieub": 0x0eac, "Hangul_RieulSios": 0x0ead, "Hangul_RieulTieut": 0x0eae, "Hangul_RieulPhieuf": 0x0eaf, "Hangul_RieulHieuh": 0x0eb0, "Hangul_Mieum": 0x0eb1, "Hangul_Pieub": 0x0eb2, "Hangul_SsangPieub": 0x0eb3, "Hangul_PieubSios": 0x0eb4, "Hangul_Sios": 0x0eb5, "Hangul_SsangSios": 0x0eb6, "Hangul_Ieung": 0x0eb7, "Hangul_Jieuj": 0x0eb8, "Hangul_SsangJieuj": 0x0eb9, "Hangul_Cieuc": 0x0eba, "Hangul_Khieuq": 0x0ebb, "Hangul_Tieut": 0x0ebc, "Hangul_Phieuf": 0x0ebd, "Hangul_Hieuh": 0x0ebe, "Hangul_A": 0x0ebf, "Hangul_AE": 0x0ec0, "Hangul_YA": 0x0ec1, "Hangul_YAE": 0x0ec2, "Hangul_EO": 0x0ec3, "Hangul_E": 0x0ec4, "Hangul_YEO": 0x0ec5, "Hangul_YE": 0x0ec6, "Hangul_O": 0x0ec7, "Hangul_WA": 0x0ec8, "Hangul_WAE": 0x0ec9, "Hangul_OE": 0x0eca, "Hangul_YO": 0x0ecb, "Hangul_U": 0x0ecc, "Hangul_WEO": 0x0ecd, "Hangul_WE": 0x0ece, "Hangul_WI": 0x0ecf, "Hangul_YU": 0x0ed0, "Hangul_EU": 0x0ed1, "Hangul_YI": 0x0ed2, "Hangul_I": 0x0ed3, "Hangul_J_Kiyeog": 0x0ed4, "Hangul_J_SsangKiyeog": 0x0ed5, "Hangul_J_KiyeogSios": 0x0ed6, "Hangul_J_Nieun": 0x0ed7, "Hangul_J_NieunJieuj": 0x0ed8, "Hangul_J_NieunHieuh": 0x0ed9, "Hangul_J_Dikeud": 0x0eda, "Hangul_J_Rieul": 0x0edb, "Hangul_J_RieulKiyeog": 0x0edc, "Hangul_J_RieulMieum": 0x0edd, "Hangul_J_RieulPieub": 0x0ede, "Hangul_J_RieulSios": 0x0edf, "Hangul_J_RieulTieut": 0x0ee0, "Hangul_J_RieulPhieuf": 0x0ee1, "Hangul_J_RieulHieuh": 0x0ee2, "Hangul_J_Mieum": 0x0ee3, "Hangul_J_Pieub": 0x0ee4, "Hangul_J_PieubSios": 0x0ee5, "Hangul_J_Sios": 0x0ee6, "Hangul_J_SsangSios": 0x0ee7, "Hangul_J_Ieung": 0x0ee8, "Hangul_J_Jieuj": 0x0ee9, "Hangul_J_Cieuc": 0x0eea, "Hangul_J_Khieuq": 0x0eeb, "Hangul_J_Tieut": 0x0eec, "Hangul_J_Phieuf": 0x0eed, "Hangul_J_Hieuh": 0x0eee, "Hangul_RieulYeorinHieuh": 0x0eef, "Hangul_SunkyeongeumMieum": 0x0ef0, "Hangul_SunkyeongeumPieub": 0x0ef1, "Hangul_PanSios": 0x0ef2, "Hangul_KkogjiDalrinIeung": 0x0ef3, "Hangul_SunkyeongeumPhieuf": 0x0ef4, "Hangul_YeorinHieuh": 0x0ef5, "Hangul_AraeA": 0x0ef6, "Hangul_AraeAE": 0x0ef7, "Hangul_J_PanSios": 0x0ef8, "Hangul_J_KkogjiDalrinIeung": 0x0ef9, "Hangul_J_YeorinHieuh": 0x0efa, "Korean_Won": 0x0eff, "Armenian_ligature_ew": 0x1000587, "Armenian_full_stop": 0x1000589, "Armenian_verjaket": 0x1000589, "Armenian_separation_mark": 0x100055d, "Armenian_but": 0x100055d, "Armenian_hyphen": 0x100058a, "Armenian_yentamna": 0x100058a, "Armenian_exclam": 0x100055c, "Armenian_amanak": 0x100055c, "Armenian_accent": 0x100055b, "Armenian_shesht": 0x100055b, "Armenian_question": 0x100055e, "Armenian_paruyk": 0x100055e, "Armenian_AYB": 0x1000531, "Armenian_ayb": 0x1000561, "Armenian_BEN": 0x1000532, "Armenian_ben": 0x1000562, "Armenian_GIM": 0x1000533, "Armenian_gim": 0x1000563, "Armenian_DA": 0x1000534, "Armenian_da": 0x1000564, "Armenian_YECH": 0x1000535, "Armenian_yech": 0x1000565, "Armenian_ZA": 0x1000536, "Armenian_za": 0x1000566, "Armenian_E": 0x1000537, "Armenian_e": 0x1000567, "Armenian_AT": 0x1000538, "Armenian_at": 0x1000568, "Armenian_TO": 0x1000539, "Armenian_to": 0x1000569, "Armenian_ZHE": 0x100053a, "Armenian_zhe": 0x100056a, "Armenian_INI": 0x100053b, "Armenian_ini": 0x100056b, "Armenian_LYUN": 0x100053c, "Armenian_lyun": 0x100056c, "Armenian_KHE": 0x100053d, "Armenian_khe": 0x100056d, "Armenian_TSA": 0x100053e, "Armenian_tsa": 0x100056e, "Armenian_KEN": 0x100053f, "Armenian_ken": 0x100056f, "Armenian_HO": 0x1000540, "Armenian_ho": 0x1000570, "Armenian_DZA": 0x1000541, "Armenian_dza": 0x1000571, "Armenian_GHAT": 0x1000542, "Armenian_ghat": 0x1000572, "Armenian_TCHE": 0x1000543, "Armenian_tche": 0x1000573, "Armenian_MEN": 0x1000544, "Armenian_men": 0x1000574, "Armenian_HI": 0x1000545, "Armenian_hi": 0x1000575, "Armenian_NU": 0x1000546, "Armenian_nu": 0x1000576, "Armenian_SHA": 0x1000547, "Armenian_sha": 0x1000577, "Armenian_VO": 0x1000548, "Armenian_vo": 0x1000578, "Armenian_CHA": 0x1000549, "Armenian_cha": 0x1000579, "Armenian_PE": 0x100054a, "Armenian_pe": 0x100057a, "Armenian_JE": 0x100054b, "Armenian_je": 0x100057b, "Armenian_RA": 0x100054c, "Armenian_ra": 0x100057c, "Armenian_SE": 0x100054d, "Armenian_se": 0x100057d, "Armenian_VEV": 0x100054e, "Armenian_vev": 0x100057e, "Armenian_TYUN": 0x100054f, "Armenian_tyun": 0x100057f, "Armenian_RE": 0x1000550, "Armenian_re": 0x1000580, "Armenian_TSO": 0x1000551, "Armenian_tso": 0x1000581, "Armenian_VYUN": 0x1000552, "Armenian_vyun": 0x1000582, "Armenian_PYUR": 0x1000553, "Armenian_pyur": 0x1000583, "Armenian_KE": 0x1000554, "Armenian_ke": 0x1000584, "Armenian_O": 0x1000555, "Armenian_o": 0x1000585, "Armenian_FE": 0x1000556, "Armenian_fe": 0x1000586, "Armenian_apostrophe": 0x100055a, "Georgian_an": 0x10010d0, "Georgian_ban": 0x10010d1, "Georgian_gan": 0x10010d2, "Georgian_don": 0x10010d3, "Georgian_en": 0x10010d4, "Georgian_vin": 0x10010d5, "Georgian_zen": 0x10010d6, "Georgian_tan": 0x10010d7, "Georgian_in": 0x10010d8, "Georgian_kan": 0x10010d9, "Georgian_las": 0x10010da, "Georgian_man": 0x10010db, "Georgian_nar": 0x10010dc, "Georgian_on": 0x10010dd, "Georgian_par": 0x10010de, "Georgian_zhar": 0x10010df, "Georgian_rae": 0x10010e0, "Georgian_san": 0x10010e1, "Georgian_tar": 0x10010e2, "Georgian_un": 0x10010e3, "Georgian_phar": 0x10010e4, "Georgian_khar": 0x10010e5, "Georgian_ghan": 0x10010e6, "Georgian_qar": 0x10010e7, "Georgian_shin": 0x10010e8, "Georgian_chin": 0x10010e9, "Georgian_can": 0x10010ea, "Georgian_jil": 0x10010eb, "Georgian_cil": 0x10010ec, "Georgian_char": 0x10010ed, "Georgian_xan": 0x10010ee, "Georgian_jhan": 0x10010ef, "Georgian_hae": 0x10010f0, "Georgian_he": 0x10010f1, "Georgian_hie": 0x10010f2, "Georgian_we": 0x10010f3, "Georgian_har": 0x10010f4, "Georgian_hoe": 0x10010f5, "Georgian_fi": 0x10010f6, "Xabovedot": 0x1001e8a, "Ibreve": 0x100012c, "Zstroke": 0x10001b5, "Gcaron": 0x10001e6, "Ocaron": 0x10001d1, "Obarred": 0x100019f, "xabovedot": 0x1001e8b, "ibreve": 0x100012d, "zstroke": 0x10001b6, "gcaron": 0x10001e7, "ocaron": 0x10001d2, "obarred": 0x1000275, "SCHWA": 0x100018f, "schwa": 0x1000259, "Lbelowdot": 0x1001e36, "lbelowdot": 0x1001e37, "Abelowdot": 0x1001ea0, "abelowdot": 0x1001ea1, "Ahook": 0x1001ea2, "ahook": 0x1001ea3, "Acircumflexacute": 0x1001ea4, "acircumflexacute": 0x1001ea5, "Acircumflexgrave": 0x1001ea6, "acircumflexgrave": 0x1001ea7, "Acircumflexhook": 0x1001ea8, "acircumflexhook": 0x1001ea9, "Acircumflextilde": 0x1001eaa, "acircumflextilde": 0x1001eab, "Acircumflexbelowdot": 0x1001eac, "acircumflexbelowdot": 0x1001ead, "Abreveacute": 0x1001eae, "abreveacute": 0x1001eaf, "Abrevegrave": 0x1001eb0, "abrevegrave": 0x1001eb1, "Abrevehook": 0x1001eb2, "abrevehook": 0x1001eb3, "Abrevetilde": 0x1001eb4, "abrevetilde": 0x1001eb5, "Abrevebelowdot": 0x1001eb6, "abrevebelowdot": 0x1001eb7, "Ebelowdot": 0x1001eb8, "ebelowdot": 0x1001eb9, "Ehook": 0x1001eba, "ehook": 0x1001ebb, "Etilde": 0x1001ebc, "etilde": 0x1001ebd, "Ecircumflexacute": 0x1001ebe, "ecircumflexacute": 0x1001ebf, "Ecircumflexgrave": 0x1001ec0, "ecircumflexgrave": 0x1001ec1, "Ecircumflexhook": 0x1001ec2, "ecircumflexhook": 0x1001ec3, "Ecircumflextilde": 0x1001ec4, "ecircumflextilde": 0x1001ec5, "Ecircumflexbelowdot": 0x1001ec6, "ecircumflexbelowdot": 0x1001ec7, "Ihook": 0x1001ec8, "ihook": 0x1001ec9, "Ibelowdot": 0x1001eca, "ibelowdot": 0x1001ecb, "Obelowdot": 0x1001ecc, "obelowdot": 0x1001ecd, "Ohook": 0x1001ece, "ohook": 0x1001ecf, "Ocircumflexacute": 0x1001ed0, "ocircumflexacute": 0x1001ed1, "Ocircumflexgrave": 0x1001ed2, "ocircumflexgrave": 0x1001ed3, "Ocircumflexhook": 0x1001ed4, "ocircumflexhook": 0x1001ed5, "Ocircumflextilde": 0x1001ed6, "ocircumflextilde": 0x1001ed7, "Ocircumflexbelowdot": 0x1001ed8, "ocircumflexbelowdot": 0x1001ed9, "Ohornacute": 0x1001eda, "ohornacute": 0x1001edb, "Ohorngrave": 0x1001edc, "ohorngrave": 0x1001edd, "Ohornhook": 0x1001ede, "ohornhook": 0x1001edf, "Ohorntilde": 0x1001ee0, "ohorntilde": 0x1001ee1, "Ohornbelowdot": 0x1001ee2, "ohornbelowdot": 0x1001ee3, "Ubelowdot": 0x1001ee4, "ubelowdot": 0x1001ee5, "Uhook": 0x1001ee6, "uhook": 0x1001ee7, "Uhornacute": 0x1001ee8, "uhornacute": 0x1001ee9, "Uhorngrave": 0x1001eea, "uhorngrave": 0x1001eeb, "Uhornhook": 0x1001eec, "uhornhook": 0x1001eed, "Uhorntilde": 0x1001eee, "uhorntilde": 0x1001eef, "Uhornbelowdot": 0x1001ef0, "uhornbelowdot": 0x1001ef1, "Ybelowdot": 0x1001ef4, "ybelowdot": 0x1001ef5, "Yhook": 0x1001ef6, "yhook": 0x1001ef7, "Ytilde": 0x1001ef8, "ytilde": 0x1001ef9, "Ohorn": 0x10001a0, "ohorn": 0x10001a1, "Uhorn": 0x10001af, "uhorn": 0x10001b0, "EcuSign": 0x10020a0, "ColonSign": 0x10020a1, "CruzeiroSign": 0x10020a2, "FFrancSign": 0x10020a3, "LiraSign": 0x10020a4, "MillSign": 0x10020a5, "NairaSign": 0x10020a6, "PesetaSign": 0x10020a7, "RupeeSign": 0x10020a8, "WonSign": 0x10020a9, "NewSheqelSign": 0x10020aa, "DongSign": 0x10020ab, "EuroSign": 0x20ac, "zerosuperior": 0x1002070, "foursuperior": 0x1002074, "fivesuperior": 0x1002075, "sixsuperior": 0x1002076, "sevensuperior": 0x1002077, "eightsuperior": 0x1002078, "ninesuperior": 0x1002079, "zerosubscript": 0x1002080, "onesubscript": 0x1002081, "twosubscript": 0x1002082, "threesubscript": 0x1002083, "foursubscript": 0x1002084, "fivesubscript": 0x1002085, "sixsubscript": 0x1002086, "sevensubscript": 0x1002087, "eightsubscript": 0x1002088, "ninesubscript": 0x1002089, "partdifferential": 0x1002202, "emptyset": 0x1002205, "elementof": 0x1002208, "notelementof": 0x1002209, "containsas": 0x100220B, "squareroot": 0x100221A, "cuberoot": 0x100221B, "fourthroot": 0x100221C, "dintegral": 0x100222C, "tintegral": 0x100222D, "because": 0x1002235, "approxeq": 0x1002248, "notapproxeq": 0x1002247, "notidentical": 0x1002262, "stricteq": 0x1002263, "braille_dot_1": 0xfff1, "braille_dot_2": 0xfff2, "braille_dot_3": 0xfff3, "braille_dot_4": 0xfff4, "braille_dot_5": 0xfff5, "braille_dot_6": 0xfff6, "braille_dot_7": 0xfff7, "braille_dot_8": 0xfff8, "braille_dot_9": 0xfff9, "braille_dot_10": 0xfffa, "braille_blank": 0x1002800, "braille_dots_1": 0x1002801, "braille_dots_2": 0x1002802, "braille_dots_12": 0x1002803, "braille_dots_3": 0x1002804, "braille_dots_13": 0x1002805, "braille_dots_23": 0x1002806, "braille_dots_123": 0x1002807, "braille_dots_4": 0x1002808, "braille_dots_14": 0x1002809, "braille_dots_24": 0x100280a, "braille_dots_124": 0x100280b, "braille_dots_34": 0x100280c, "braille_dots_134": 0x100280d, "braille_dots_234": 0x100280e, "braille_dots_1234": 0x100280f, "braille_dots_5": 0x1002810, "braille_dots_15": 0x1002811, "braille_dots_25": 0x1002812, "braille_dots_125": 0x1002813, "braille_dots_35": 0x1002814, "braille_dots_135": 0x1002815, "braille_dots_235": 0x1002816, "braille_dots_1235": 0x1002817, "braille_dots_45": 0x1002818, "braille_dots_145": 0x1002819, "braille_dots_245": 0x100281a, "braille_dots_1245": 0x100281b, "braille_dots_345": 0x100281c, "braille_dots_1345": 0x100281d, "braille_dots_2345": 0x100281e, "braille_dots_12345": 0x100281f, "braille_dots_6": 0x1002820, "braille_dots_16": 0x1002821, "braille_dots_26": 0x1002822, "braille_dots_126": 0x1002823, "braille_dots_36": 0x1002824, "braille_dots_136": 0x1002825, "braille_dots_236": 0x1002826, "braille_dots_1236": 0x1002827, "braille_dots_46": 0x1002828, "braille_dots_146": 0x1002829, "braille_dots_246": 0x100282a, "braille_dots_1246": 0x100282b, "braille_dots_346": 0x100282c, "braille_dots_1346": 0x100282d, "braille_dots_2346": 0x100282e, "braille_dots_12346": 0x100282f, "braille_dots_56": 0x1002830, "braille_dots_156": 0x1002831, "braille_dots_256": 0x1002832, "braille_dots_1256": 0x1002833, "braille_dots_356": 0x1002834, "braille_dots_1356": 0x1002835, "braille_dots_2356": 0x1002836, "braille_dots_12356": 0x1002837, "braille_dots_456": 0x1002838, "braille_dots_1456": 0x1002839, "braille_dots_2456": 0x100283a, "braille_dots_12456": 0x100283b, "braille_dots_3456": 0x100283c, "braille_dots_13456": 0x100283d, "braille_dots_23456": 0x100283e, "braille_dots_123456": 0x100283f, "braille_dots_7": 0x1002840, "braille_dots_17": 0x1002841, "braille_dots_27": 0x1002842, "braille_dots_127": 0x1002843, "braille_dots_37": 0x1002844, "braille_dots_137": 0x1002845, "braille_dots_237": 0x1002846, "braille_dots_1237": 0x1002847, "braille_dots_47": 0x1002848, "braille_dots_147": 0x1002849, "braille_dots_247": 0x100284a, "braille_dots_1247": 0x100284b, "braille_dots_347": 0x100284c, "braille_dots_1347": 0x100284d, "braille_dots_2347": 0x100284e, "braille_dots_12347": 0x100284f, "braille_dots_57": 0x1002850, "braille_dots_157": 0x1002851, "braille_dots_257": 0x1002852, "braille_dots_1257": 0x1002853, "braille_dots_357": 0x1002854, "braille_dots_1357": 0x1002855, "braille_dots_2357": 0x1002856, "braille_dots_12357": 0x1002857, "braille_dots_457": 0x1002858, "braille_dots_1457": 0x1002859, "braille_dots_2457": 0x100285a, "braille_dots_12457": 0x100285b, "braille_dots_3457": 0x100285c, "braille_dots_13457": 0x100285d, "braille_dots_23457": 0x100285e, "braille_dots_123457": 0x100285f, "braille_dots_67": 0x1002860, "braille_dots_167": 0x1002861, "braille_dots_267": 0x1002862, "braille_dots_1267": 0x1002863, "braille_dots_367": 0x1002864, "braille_dots_1367": 0x1002865, "braille_dots_2367": 0x1002866, "braille_dots_12367": 0x1002867, "braille_dots_467": 0x1002868, "braille_dots_1467": 0x1002869, "braille_dots_2467": 0x100286a, "braille_dots_12467": 0x100286b, "braille_dots_3467": 0x100286c, "braille_dots_13467": 0x100286d, "braille_dots_23467": 0x100286e, "braille_dots_123467": 0x100286f, "braille_dots_567": 0x1002870, "braille_dots_1567": 0x1002871, "braille_dots_2567": 0x1002872, "braille_dots_12567": 0x1002873, "braille_dots_3567": 0x1002874, "braille_dots_13567": 0x1002875, "braille_dots_23567": 0x1002876, "braille_dots_123567": 0x1002877, "braille_dots_4567": 0x1002878, "braille_dots_14567": 0x1002879, "braille_dots_24567": 0x100287a, "braille_dots_124567": 0x100287b, "braille_dots_34567": 0x100287c, "braille_dots_134567": 0x100287d, "braille_dots_234567": 0x100287e, "braille_dots_1234567": 0x100287f, "braille_dots_8": 0x1002880, "braille_dots_18": 0x1002881, "braille_dots_28": 0x1002882, "braille_dots_128": 0x1002883, "braille_dots_38": 0x1002884, "braille_dots_138": 0x1002885, "braille_dots_238": 0x1002886, "braille_dots_1238": 0x1002887, "braille_dots_48": 0x1002888, "braille_dots_148": 0x1002889, "braille_dots_248": 0x100288a, "braille_dots_1248": 0x100288b, "braille_dots_348": 0x100288c, "braille_dots_1348": 0x100288d, "braille_dots_2348": 0x100288e, "braille_dots_12348": 0x100288f, "braille_dots_58": 0x1002890, "braille_dots_158": 0x1002891, "braille_dots_258": 0x1002892, "braille_dots_1258": 0x1002893, "braille_dots_358": 0x1002894, "braille_dots_1358": 0x1002895, "braille_dots_2358": 0x1002896, "braille_dots_12358": 0x1002897, "braille_dots_458": 0x1002898, "braille_dots_1458": 0x1002899, "braille_dots_2458": 0x100289a, "braille_dots_12458": 0x100289b, "braille_dots_3458": 0x100289c, "braille_dots_13458": 0x100289d, "braille_dots_23458": 0x100289e, "braille_dots_123458": 0x100289f, "braille_dots_68": 0x10028a0, "braille_dots_168": 0x10028a1, "braille_dots_268": 0x10028a2, "braille_dots_1268": 0x10028a3, "braille_dots_368": 0x10028a4, "braille_dots_1368": 0x10028a5, "braille_dots_2368": 0x10028a6, "braille_dots_12368": 0x10028a7, "braille_dots_468": 0x10028a8, "braille_dots_1468": 0x10028a9, "braille_dots_2468": 0x10028aa, "braille_dots_12468": 0x10028ab, "braille_dots_3468": 0x10028ac, "braille_dots_13468": 0x10028ad, "braille_dots_23468": 0x10028ae, "braille_dots_123468": 0x10028af, "braille_dots_568": 0x10028b0, "braille_dots_1568": 0x10028b1, "braille_dots_2568": 0x10028b2, "braille_dots_12568": 0x10028b3, "braille_dots_3568": 0x10028b4, "braille_dots_13568": 0x10028b5, "braille_dots_23568": 0x10028b6, "braille_dots_123568": 0x10028b7, "braille_dots_4568": 0x10028b8, "braille_dots_14568": 0x10028b9, "braille_dots_24568": 0x10028ba, "braille_dots_124568": 0x10028bb, "braille_dots_34568": 0x10028bc, "braille_dots_134568": 0x10028bd, "braille_dots_234568": 0x10028be, "braille_dots_1234568": 0x10028bf, "braille_dots_78": 0x10028c0, "braille_dots_178": 0x10028c1, "braille_dots_278": 0x10028c2, "braille_dots_1278": 0x10028c3, "braille_dots_378": 0x10028c4, "braille_dots_1378": 0x10028c5, "braille_dots_2378": 0x10028c6, "braille_dots_12378": 0x10028c7, "braille_dots_478": 0x10028c8, "braille_dots_1478": 0x10028c9, "braille_dots_2478": 0x10028ca, "braille_dots_12478": 0x10028cb, "braille_dots_3478": 0x10028cc, "braille_dots_13478": 0x10028cd, "braille_dots_23478": 0x10028ce, "braille_dots_123478": 0x10028cf, "braille_dots_578": 0x10028d0, "braille_dots_1578": 0x10028d1, "braille_dots_2578": 0x10028d2, "braille_dots_12578": 0x10028d3, "braille_dots_3578": 0x10028d4, "braille_dots_13578": 0x10028d5, "braille_dots_23578": 0x10028d6, "braille_dots_123578": 0x10028d7, "braille_dots_4578": 0x10028d8, "braille_dots_14578": 0x10028d9, "braille_dots_24578": 0x10028da, "braille_dots_124578": 0x10028db, "braille_dots_34578": 0x10028dc, "braille_dots_134578": 0x10028dd, "braille_dots_234578": 0x10028de, "braille_dots_1234578": 0x10028df, "braille_dots_678": 0x10028e0, "braille_dots_1678": 0x10028e1, "braille_dots_2678": 0x10028e2, "braille_dots_12678": 0x10028e3, "braille_dots_3678": 0x10028e4, "braille_dots_13678": 0x10028e5, "braille_dots_23678": 0x10028e6, "braille_dots_123678": 0x10028e7, "braille_dots_4678": 0x10028e8, "braille_dots_14678": 0x10028e9, "braille_dots_24678": 0x10028ea, "braille_dots_124678": 0x10028eb, "braille_dots_34678": 0x10028ec, "braille_dots_134678": 0x10028ed, "braille_dots_234678": 0x10028ee, "braille_dots_1234678": 0x10028ef, "braille_dots_5678": 0x10028f0, "braille_dots_15678": 0x10028f1, "braille_dots_25678": 0x10028f2, "braille_dots_125678": 0x10028f3, "braille_dots_35678": 0x10028f4, "braille_dots_135678": 0x10028f5, "braille_dots_235678": 0x10028f6, "braille_dots_1235678": 0x10028f7, "braille_dots_45678": 0x10028f8, "braille_dots_145678": 0x10028f9, "braille_dots_245678": 0x10028fa, "braille_dots_1245678": 0x10028fb, "braille_dots_345678": 0x10028fc, "braille_dots_1345678": 0x10028fd, "braille_dots_2345678": 0x10028fe, "braille_dots_12345678": 0x10028ff, "XF86ModeLock": 0x1008FF01, "XF86MonBrightnessUp": 0x1008FF02, "XF86MonBrightnessDown": 0x1008FF03, "XF86KbdLightOnOff": 0x1008FF04, "XF86KbdBrightnessUp": 0x1008FF05, "XF86KbdBrightnessDown": 0x1008FF06, "XF86Standby": 0x1008FF10, "XF86AudioLowerVolume": 0x1008FF11, "XF86AudioMute": 0x1008FF12, "XF86AudioRaiseVolume": 0x1008FF13, "XF86AudioPlay": 0x1008FF14, "XF86AudioStop": 0x1008FF15, "XF86AudioPrev": 0x1008FF16, "XF86AudioNext": 0x1008FF17, "XF86HomePage": 0x1008FF18, "XF86Mail": 0x1008FF19, "XF86Start": 0x1008FF1A, "XF86Search": 0x1008FF1B, "XF86AudioRecord": 0x1008FF1C, "XF86Calculator": 0x1008FF1D, "XF86Memo": 0x1008FF1E, "XF86ToDoList": 0x1008FF1F, "XF86Calendar": 0x1008FF20, "XF86PowerDown": 0x1008FF21, "XF86ContrastAdjust": 0x1008FF22, "XF86RockerUp": 0x1008FF23, "XF86RockerDown": 0x1008FF24, "XF86RockerEnter": 0x1008FF25, "XF86Back": 0x1008FF26, "XF86Forward": 0x1008FF27, "XF86Stop": 0x1008FF28, "XF86Refresh": 0x1008FF29, "XF86PowerOff": 0x1008FF2A, "XF86WakeUp": 0x1008FF2B, "XF86Eject": 0x1008FF2C, "XF86ScreenSaver": 0x1008FF2D, "XF86WWW": 0x1008FF2E, "XF86Sleep": 0x1008FF2F, "XF86Favorites": 0x1008FF30, "XF86AudioPause": 0x1008FF31, "XF86AudioMedia": 0x1008FF32, "XF86MyComputer": 0x1008FF33, "XF86VendorHome": 0x1008FF34, "XF86LightBulb": 0x1008FF35, "XF86Shop": 0x1008FF36, "XF86History": 0x1008FF37, "XF86OpenURL": 0x1008FF38, "XF86AddFavorite": 0x1008FF39, "XF86HotLinks": 0x1008FF3A, "XF86BrightnessAdjust": 0x1008FF3B, "XF86Finance": 0x1008FF3C, "XF86Community": 0x1008FF3D, "XF86AudioRewind": 0x1008FF3E, "XF86BackForward": 0x1008FF3F, "XF86Launch0": 0x1008FF40, "XF86Launch1": 0x1008FF41, "XF86Launch2": 0x1008FF42, "XF86Launch3": 0x1008FF43, "XF86Launch4": 0x1008FF44, "XF86Launch5": 0x1008FF45, "XF86Launch6": 0x1008FF46, "XF86Launch7": 0x1008FF47, "XF86Launch8": 0x1008FF48, "XF86Launch9": 0x1008FF49, "XF86LaunchA": 0x1008FF4A, "XF86LaunchB": 0x1008FF4B, "XF86LaunchC": 0x1008FF4C, "XF86LaunchD": 0x1008FF4D, "XF86LaunchE": 0x1008FF4E, "XF86LaunchF": 0x1008FF4F, "XF86ApplicationLeft": 0x1008FF50, "XF86ApplicationRight": 0x1008FF51, "XF86Book": 0x1008FF52, "XF86CD": 0x1008FF53, "XF86Calculater": 0x1008FF54, "XF86Clear": 0x1008FF55, "XF86Close": 0x1008FF56, "XF86Copy": 0x1008FF57, "XF86Cut": 0x1008FF58, "XF86Display": 0x1008FF59, "XF86DOS": 0x1008FF5A, "XF86Documents": 0x1008FF5B, "XF86Excel": 0x1008FF5C, "XF86Explorer": 0x1008FF5D, "XF86Game": 0x1008FF5E, "XF86Go": 0x1008FF5F, "XF86iTouch": 0x1008FF60, "XF86LogOff": 0x1008FF61, "XF86Market": 0x1008FF62, "XF86Meeting": 0x1008FF63, "XF86MenuKB": 0x1008FF65, "XF86MenuPB": 0x1008FF66, "XF86MySites": 0x1008FF67, "XF86New": 0x1008FF68, "XF86News": 0x1008FF69, "XF86OfficeHome": 0x1008FF6A, "XF86Open": 0x1008FF6B, "XF86Option": 0x1008FF6C, "XF86Paste": 0x1008FF6D, "XF86Phone": 0x1008FF6E, "XF86Q": 0x1008FF70, "XF86Reply": 0x1008FF72, "XF86Reload": 0x1008FF73, "XF86RotateWindows": 0x1008FF74, "XF86RotationPB": 0x1008FF75, "XF86RotationKB": 0x1008FF76, "XF86Save": 0x1008FF77, "XF86ScrollUp": 0x1008FF78, "XF86ScrollDown": 0x1008FF79, "XF86ScrollClick": 0x1008FF7A, "XF86Send": 0x1008FF7B, "XF86Spell": 0x1008FF7C, "XF86SplitScreen": 0x1008FF7D, "XF86Support": 0x1008FF7E, "XF86TaskPane": 0x1008FF7F, "XF86Terminal": 0x1008FF80, "XF86Tools": 0x1008FF81, "XF86Travel": 0x1008FF82, "XF86UserPB": 0x1008FF84, "XF86User1KB": 0x1008FF85, "XF86User2KB": 0x1008FF86, "XF86Video": 0x1008FF87, "XF86WheelButton": 0x1008FF88, "XF86Word": 0x1008FF89, "XF86Xfer": 0x1008FF8A, "XF86ZoomIn": 0x1008FF8B, "XF86ZoomOut": 0x1008FF8C, "XF86Away": 0x1008FF8D, "XF86Messenger": 0x1008FF8E, "XF86WebCam": 0x1008FF8F, "XF86MailForward": 0x1008FF90, "XF86Pictures": 0x1008FF91, "XF86Music": 0x1008FF92, "XF86Battery": 0x1008FF93, "XF86Bluetooth": 0x1008FF94, "XF86WLAN": 0x1008FF95, "XF86UWB": 0x1008FF96, "XF86AudioForward": 0x1008FF97, "XF86AudioRepeat": 0x1008FF98, "XF86AudioRandomPlay": 0x1008FF99, "XF86Subtitle": 0x1008FF9A, "XF86AudioCycleTrack": 0x1008FF9B, "XF86CycleAngle": 0x1008FF9C, "XF86FrameBack": 0x1008FF9D, "XF86FrameForward": 0x1008FF9E, "XF86Time": 0x1008FF9F, "XF86Select": 0x1008FFA0, "XF86View": 0x1008FFA1, "XF86TopMenu": 0x1008FFA2, "XF86Red": 0x1008FFA3, "XF86Green": 0x1008FFA4, "XF86Yellow": 0x1008FFA5, "XF86Blue": 0x1008FFA6, "XF86Suspend": 0x1008FFA7, "XF86Hibernate": 0x1008FFA8, "XF86TouchpadToggle": 0x1008FFA9, "XF86TouchpadOn": 0x1008FFB0, "XF86TouchpadOff": 0x1008FFB1, "XF86AudioMicMute": 0x1008FFB2, "XF86Switch_VT_1": 0x1008FE01, "XF86Switch_VT_2": 0x1008FE02, "XF86Switch_VT_3": 0x1008FE03, "XF86Switch_VT_4": 0x1008FE04, "XF86Switch_VT_5": 0x1008FE05, "XF86Switch_VT_6": 0x1008FE06, "XF86Switch_VT_7": 0x1008FE07, "XF86Switch_VT_8": 0x1008FE08, "XF86Switch_VT_9": 0x1008FE09, "XF86Switch_VT_10": 0x1008FE0A, "XF86Switch_VT_11": 0x1008FE0B, "XF86Switch_VT_12": 0x1008FE0C, "XF86Ungrab": 0x1008FE20, "XF86ClearGrab": 0x1008FE21, "XF86Next_VMode": 0x1008FE22, "XF86Prev_VMode": 0x1008FE23, "XF86LogWindowTree": 0x1008FE24, "XF86LogGrabInfo": 0x1008FE25, } ================================================ FILE: keybind/xutil.go ================================================ package keybind /* keybind/xutil.go contains a collection of functions that modify the Keybinds and Keygrabs state of an XUtil value. They could have been placed inside the core xgbutil package, but they would have to be exported for use by the keybind package. In which case, the API would become cluttered with functions that should not be used. */ import ( "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" ) // attachKeyBindCallback associates an (event, window, mods, keycode) // with a callback. // This is exported for use in the keybind package. It should not be used. func attachKeyBindCallback(xu *xgbutil.XUtil, evtype int, win xproto.Window, mods uint16, keycode xproto.Keycode, fun xgbutil.CallbackKey) { xu.KeybindsLck.Lock() defer xu.KeybindsLck.Unlock() // Create key key := xgbutil.KeyKey{evtype, win, mods, keycode} // Do we need to allocate? if _, ok := xu.Keybinds[key]; !ok { xu.Keybinds[key] = make([]xgbutil.CallbackKey, 0) } xu.Keybinds[key] = append(xu.Keybinds[key], fun) xu.Keygrabs[key] += 1 } // addKeyString adds a new key binding string to XUtil.Keystrings. // The invariant is that each key string appears once and only once. func addKeyString(xu *xgbutil.XUtil, callback xgbutil.CallbackKey, evtype int, win xproto.Window, keyStr string, grab bool) { xu.KeybindsLck.Lock() defer xu.KeybindsLck.Unlock() k := xgbutil.KeyString{ Str: keyStr, Callback: callback, Evtype: evtype, Win: win, Grab: grab, } xu.Keystrings = append(xu.Keystrings, k) } // keyBindKeys returns a copy of all the keys in the 'keybinds' map. func keyKeys(xu *xgbutil.XUtil) []xgbutil.KeyKey { xu.KeybindsLck.RLock() defer xu.KeybindsLck.RUnlock() keys := make([]xgbutil.KeyKey, len(xu.Keybinds)) i := 0 for key, _ := range xu.Keybinds { keys[i] = key i++ } return keys } // runKeyBindCallbacks executes every callback corresponding to a // particular event/window/mod/key tuple. // This is exported for use in the keybind package. It should not be used. func runKeyBindCallbacks(xu *xgbutil.XUtil, event interface{}, evtype int, win xproto.Window, mods uint16, keycode xproto.Keycode) { key := xgbutil.KeyKey{evtype, win, mods, keycode} for _, cb := range keyCallbacks(xu, key) { cb.Run(xu, event) } } // keyBindCallbacks returns a slice of callbacks for a particular key. func keyCallbacks(xu *xgbutil.XUtil, key xgbutil.KeyKey) []xgbutil.CallbackKey { xu.KeybindsLck.RLock() defer xu.KeybindsLck.RUnlock() cbs := make([]xgbutil.CallbackKey, len(xu.Keybinds[key])) copy(cbs, xu.Keybinds[key]) return cbs } // ConnectedKeyBind checks to see if there are any key binds for a particular // event type already in play. func connectedKeyBind(xu *xgbutil.XUtil, evtype int, win xproto.Window) bool { xu.KeybindsLck.RLock() defer xu.KeybindsLck.RUnlock() // Since we can't create a full key, loop through all key binds // and check if evtype and window match. for key, _ := range xu.Keybinds { if key.Evtype == evtype && key.Win == win { return true } } return false } // detachKeyBindWindow removes all callbacks associated with a particular // window and event type (either KeyPress or KeyRelease) // Also decrements the counter in the corresponding 'keygrabs' map // appropriately. // This is exported for use in the keybind package. It should not be used. // To detach a window from a key binding callbacks, please use keybind.Detach. // (This method will issue an Ungrab requests, while keybind.Detach will.) func detachKeyBindWindow(xu *xgbutil.XUtil, evtype int, win xproto.Window) { xu.KeybindsLck.Lock() defer xu.KeybindsLck.Unlock() // Since we can't create a full key, loop through all key binds // and check if evtype and window match. for key, _ := range xu.Keybinds { if key.Evtype == evtype && key.Win == win { xu.Keygrabs[key] -= len(xu.Keybinds[key]) delete(xu.Keybinds, key) } } } // keyBindGrabs returns the number of grabs on a particular // event/window/mods/keycode combination. Namely, this combination // uniquely identifies a grab. If it's repeated, we get BadAccess. // The idea is that if there are 0 grabs on a particular (modifiers, keycode) // tuple, then we issue a grab request. Otherwise, we don't. // This is exported for use in the keybind package. It should not be used. func keyBindGrabs(xu *xgbutil.XUtil, evtype int, win xproto.Window, mods uint16, keycode xproto.Keycode) int { xu.KeybindsLck.RLock() defer xu.KeybindsLck.RUnlock() key := xgbutil.KeyKey{evtype, win, mods, keycode} return xu.Keygrabs[key] // returns 0 if key does not exist } // KeyMapGet accessor. func KeyMapGet(xu *xgbutil.XUtil) *xgbutil.KeyboardMapping { return xu.Keymap } // KeyMapSet updates XUtil.keymap. // This is exported for use in the keybind package. You probably shouldn't // use this. (You may need to use this if you're rolling your own event loop, // and still want to use the keybind package.) func KeyMapSet(xu *xgbutil.XUtil, keyMapReply *xproto.GetKeyboardMappingReply) { xu.Keymap = &xgbutil.KeyboardMapping{keyMapReply} } // ModMapGet accessor. func ModMapGet(xu *xgbutil.XUtil) *xgbutil.ModifierMapping { return xu.Modmap } // ModMapSet updates XUtil.modmap. // This is exported for use in the keybind package. You probably shouldn't // use this. (You may need to use this if you're rolling your own event loop, // and still want to use the keybind package.) func ModMapSet(xu *xgbutil.XUtil, modMapReply *xproto.GetModifierMappingReply) { xu.Modmap = &xgbutil.ModifierMapping{modMapReply} } ================================================ FILE: motif/motif.go ================================================ /* Package motif has a few functions to allow easy access to Motif related properties. The main purpose here is that some applications communicate "no window decorations" to the window manager using _MOTIF_WM_HINTS. (Like Google Chrome.) I haven't seen Motif stuff used for other purposes in the wild for a long time. As a result, only the useful bits are implemented here. More may be added on an on-demand basis, but don't count on it. Try not to bash your head against your desk too hard: http://www.opengroup.org/openmotif/hardcopydocs.html Example To test if a window wants decorations or not: mh, err := motif.WmHintsGet(XUtilValue, window-id) if err != nil { log.Fatal(err) } else { log.Println("Decorations? ", motif.Decor(mh)) } */ package motif import ( "fmt" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/xprop" ) const ( HintFunctions = (1 << iota) HintDecorations HintInputMode HintStatus ) const ( FunctionAll = (1 << iota) FunctionResize FunctionMove FunctionMinimize FunctionMaximize FunctionClose FunctionNone = 0 ) const ( DecorationAll = (1 << iota) DecorationBorder DecorationResizeH DecorationTitle DecorationMenu DecorationMinimize DecorationMaximize DecorationNone = 0 ) const ( InputPrimaryApplicationModal = (1 << iota) InputSystemModal InputFullApplicationModal InputModeless = 0 ) const StatusTearoffWindow = 1 // Decor checks a Hints value for whether or not the client has requested // that the window manager paint decorations. // That is, Decor returns false when the hints provided indicate no // decorations and true otherwise. func Decor(mh *Hints) bool { if mh.Flags&HintDecorations > 0 { noDecor := mh.Decoration == DecorationNone || (mh.Decoration&DecorationAll == 0 && mh.Decoration&DecorationTitle == 0 && mh.Decoration&DecorationResizeH == 0) return !noDecor } return true } // Hints is a struct that organizes the information related to the // WM_NORMAL_HINTS property. type Hints struct { Flags uint Function, Decoration, Input, Status uint } // _MOTIF_WM_HINTS get func WmHintsGet(xu *xgbutil.XUtil, win xproto.Window) (mh *Hints, err error) { lenExpect := 5 hints, err := xprop.PropValNums(xprop.GetProperty(xu, win, "_MOTIF_WM_HINTS")) if err != nil { return nil, err } if len(hints) != lenExpect { return nil, fmt.Errorf("motif.WmHintsGet: There are %d fields in "+ "_MOTIF_WM_HINTS, but xgbutil expects %d.", len(hints), lenExpect) } mh = &Hints{} mh.Flags = hints[0] mh.Function = hints[1] mh.Decoration = hints[2] mh.Input = hints[3] mh.Status = hints[4] return } // _MOTIF_WM_HINTS set func WmHintsSet(xu *xgbutil.XUtil, win xproto.Window, mh *Hints) error { raw := []uint{mh.Flags, mh.Function, mh.Decoration, mh.Input, mh.Status} return xprop.ChangeProp32(xu, win, "_MOTIF_WM_HINTS", "_MOTIF_WM_HINTS", raw...) } ================================================ FILE: mousebind/callback.go ================================================ package mousebind import ( "fmt" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/xevent" ) // connect is essentially 'Connect' for either ButtonPress or // ButtonRelease events. func connect(xu *xgbutil.XUtil, callback xgbutil.CallbackMouse, evtype int, win xproto.Window, buttonStr string, sync bool, grab bool) error { // Get the mods/button first mods, button, err := ParseString(xu, buttonStr) if err != nil { return err } // Only do the grab if we haven't yet on this window. // And if we WANT a grab... if grab && mouseBindGrabs(xu, evtype, win, mods, button) == 0 { err := GrabChecked(xu, win, mods, button, sync) if err != nil { // If a bad access, let's be nice and give a good error message. switch err.(type) { case xproto.AccessError: return fmt.Errorf("Got a bad access error when trying to bind "+ "'%s'. This usually means another client has already "+ "grabbed this mouse binding.", buttonStr) default: return fmt.Errorf("Could not bind '%s' because: %s", buttonStr, err) } } } // If we've never grabbed anything on this window before, we need to // make sure we can respond to it in the main event loop. var allCb xgbutil.Callback if evtype == xevent.ButtonPress { allCb = xevent.ButtonPressFun(runButtonPressCallbacks) } else { allCb = xevent.ButtonReleaseFun(runButtonReleaseCallbacks) } // If this is the first Button{Press|Release}Event on this window, // then we need to listen to Button{Press|Release} events in the main loop. if !connectedMouseBind(xu, evtype, win) { allCb.Connect(xu, win) } // Finally, attach the callback. attachMouseBindCallback(xu, evtype, win, mods, button, callback) return nil } // DeduceButtonInfo takes a (modifiers, button) tuple and returns the relevant // modifiers that were activated. This accounts for modifiers in // xevent.IgnoreMods and the the button mask of the button that is pressed. func DeduceButtonInfo(state uint16, detail xproto.Button) (uint16, xproto.Button) { mods, button := state, detail for _, m := range xevent.IgnoreMods { mods &= ^m } // We also need to mask out the button that has been pressed/released, // since it is also typically a modifier. modsTemp := int32(mods) switch button { case 1: modsTemp &= ^xproto.ButtonMask1 case 2: modsTemp &= ^xproto.ButtonMask2 case 3: modsTemp &= ^xproto.ButtonMask3 case 4: modsTemp &= ^xproto.ButtonMask4 case 5: modsTemp &= ^xproto.ButtonMask5 } return uint16(modsTemp), button } // ButtonPressFun represents a function that is called when a particular mouse // binding is fired. type ButtonPressFun xevent.ButtonPressFun // If 'sync' is True, then no further events can be processed until the // grabbing client allows them to be. (Which is done via AllowEvents. Thus, // if sync is True, you *must* make some call to AllowEvents at some // point, or else your client will lock.) func (callback ButtonPressFun) Connect(xu *xgbutil.XUtil, win xproto.Window, buttonStr string, sync bool, grab bool) error { return connect(xu, callback, xevent.ButtonPress, win, buttonStr, sync, grab) } func (callback ButtonPressFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(xevent.ButtonPressEvent)) } // ButtonReleaseFun represents a function that is called when a particular mouse // binding is fired. type ButtonReleaseFun xevent.ButtonReleaseFun // If 'sync' is True, then no further events can be processed until the // grabbing client allows them to be. (Which is done via AllowEvents. Thus, // if sync is True, you *must* make some call to AllowEvents at some // point, or else your client will lock.) func (callback ButtonReleaseFun) Connect(xu *xgbutil.XUtil, win xproto.Window, buttonStr string, sync bool, grab bool) error { return connect(xu, callback, xevent.ButtonRelease, win, buttonStr, sync, grab) } func (callback ButtonReleaseFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(xevent.ButtonReleaseEvent)) } // runButtonPressCallbacks infers the window, button and modifiers from a // ButtonPressEvent and runs the corresponding callbacks. func runButtonPressCallbacks(xu *xgbutil.XUtil, ev xevent.ButtonPressEvent) { mods, button := DeduceButtonInfo(ev.State, ev.Detail) runMouseBindCallbacks(xu, ev, xevent.ButtonPress, ev.Event, mods, button) } // runButtonReleaseCallbacks infers the window, keycode and modifiers from a // ButtonPressEvent and runs the corresponding callbacks. func runButtonReleaseCallbacks(xu *xgbutil.XUtil, ev xevent.ButtonReleaseEvent) { mods, button := DeduceButtonInfo(ev.State, ev.Detail) runMouseBindCallbacks(xu, ev, xevent.ButtonRelease, ev.Event, mods, button) } // Detach removes all handlers for all mouse events for the provided window id. // This should be called whenever a window is no longer receiving events to make // sure the garbage collector can release memory used to store the handler info. func Detach(xu *xgbutil.XUtil, win xproto.Window) { detach(xu, xevent.ButtonPress, win) detach(xu, xevent.ButtonRelease, win) } // DetachPress is the same as Detach, except it only removes handlers for // button *press* events. func DetachPress(xu *xgbutil.XUtil, win xproto.Window) { detach(xu, xevent.ButtonPress, win) } // DetachRelease is the same as Detach, except it only removes handlers for // mouse *release* events. func DetachRelease(xu *xgbutil.XUtil, win xproto.Window) { detach(xu, xevent.ButtonRelease, win) } // detach removes all handlers for the provided window and event type // combination. This will also issue an ungrab request for each grab that // drops to zero. func detach(xu *xgbutil.XUtil, evtype int, win xproto.Window) { mkeys := mouseKeys(xu) detachMouseBindWindow(xu, evtype, win) for _, key := range mkeys { if mouseBindGrabs(xu, key.Evtype, key.Win, key.Mod, key.Button) == 0 { Ungrab(xu, key.Win, key.Mod, key.Button) } } } ================================================ FILE: mousebind/doc.go ================================================ /* Package mousebind provides an easy to use interface to assign callback functions to human readable button sequences. Namely, the mousebind package exports two function types: ButtonPressFun and ButtonReleaseFun. Values of these types are functions, and have a method called 'Connect' that attaches an event handler to be run when a particular button press is issued. This is virtually identical to the way calbacks are attached using the xevent package, but the Connect method in the mousebind package has a couple extra parameters that are specific to mouse bindings. Namely, the button sequence to respond to (which is a combination of zero or more modifiers and exactly one button), whether to establish a passive grab and whether to make the grab synchronous or not. One can still attach callbacks to Button{Press,Release} events using xevent, but it will be run for *all* Button{Press,Release} events. (This is typically what one might do when setting up an active grab.) Initialization Before using the mousebind package, you should *always* make a single call to mousebind.Initialize for each X connection you're working with. Button sequence format Button sequences are human readable strings made up of zero or more modifiers and exactly one button. Namely: [Mod[-Mod[...]]-]BUTTONNUMBER Where 'Mod' can be one of: shift, lock, control, mod1, mod2, mod3, mod4, mod5, button1, button2, button3, button4, button5 or any. You can view which keys activate each modifier using the 'xmodmap' program. (If you don't have 'xmodmap', you could also run the 'xmodmap' example in the examples directory.) The 'button[1-5]' modifiers correspond to the button number in the name. (This implies that buttons 1 through 5 can act as both a button number and a modifier.) BUTTONNUMER must correspond to a valid button number on your mouse. The best way to determine the numbers of each button on your mouse is to launch the xev program in a terminal, click the corresponding button in the new window that opens, and read the event output in the terminal that launched xev. Usually a left click is button 1, a right click is button 3 and a middle click is button 2. An example button sequence might look like 'Mod4-Control-Shift-1'. The mouse binding for that button sequence is activated when all three modifiers---mod4, control and shift---are pressed along with the '1' button on your mouse. When to issue a passive grab One of the parameters of the 'Connect' method is whether to issue a passive grab or not. A passive grab is useful when you need to respond to a button press on some parent window (like the root window) without actually focusing that window. Not using a passive grab is useful when you only need to read button presses when the window is focused. For more information on the semantics of passive grabs, please see http://tronche.com/gui/x/xlib/input/XGrabButton.html. Also, by default, when issuing a grab on a particular (modifiers, button) tuple, several grabs are actually made. In particular, for each grab requested, another grab is made with the "num lock" mask, another grab is made with the "caps lock" mask, and another grab is made with both the "num lock" and "caps locks" masks. This allows button events to be reported regardless of whether caps lock or num lock is enabled. The extra masks added can be modified by changing the xevent.IgnoreMods slice. If you modify xevent.IgnoreMods, it should be modified once on program startup (i.e., before any key or mouse bindings are established) and never modified again. When to use a synchronous binding In the vast majority of cases, 'sync' in the 'Connect' method should be set to false, which indicates that a passive grab should be asynchronous. (The value of sync is irrelevant if 'grab' is false.) This implies that any events generated by the grab are sent to the grabbing window (the second parameter of the 'Connect' method) and only the grabbing window. Sometimes, however, you might want button events to cascade down the window tree. That is, a button press on a parent window is grabbed, but then that button press should be sent to any children windows. With an asynchronous grab, this is impossible. With a synchronous grab, however, the button event can be 'replayed' to all child windows. For example: mousebind.Initialize(XUtilValue) // call once before using mousebind package mousebind.ButtonPressFun( func(X *xgbutil.XUtil, ev xevent.ButtonPressEvent) { // do something when button is pressed // And now replay the pointer event that fired this handler to all // child windows. All event processing is stopped on the // X server until this is called. xproto.AllowEvents(X.Conn(), xproto.AllowReplayPointer, 0) }).Connect(XUtilValue, some-window-id, "Mod4-Control-Shift-1", true, true) This sort of example is precisely how reparenting window managers allow one to click on a window and have it be activated or "raised" *and* have the button press sent to the client window as well. Note that with a synchronous grab, all event processing will be halted by the X server until *some* call to xproto.AllowEvents is made. Mouse bindings on the root window example To run a particular function whenever the 'Mod4-Control-Shift-1' button combination is pressed (mod4 is typically the 'super' or 'windows' key, but can vary based on your system), use something like: mousebind.Initialize(XUtilValue) // call once before using mousebind package mousebind.ButtonPressFun( func(X *xgbutil.XUtil, ev xevent.ButtonPressEvent) { // do something when button is pressed }).Connect(XUtilValue, XUtilValue.RootWin(), "Mod4-Control-Shift-1", false, true) Note that we issue a passive grab because Button{Press,Release} events on the root window will only be reported when the root window has focus if no grab exists. Mouse bindings on a window you create example This code snippet attaches an event handler to some window you've created without using a grab. Thus, the function will only be activated when the button sequence is pressed and your window has focus. mousebind.Initialize(XUtilValue) // call once before using mousebind package mousebind.ButtonPressFun( func(X *xgbutil.XUtil, ev xevent.ButtonPressEvent) { // do something when button is pressed }).Connect(XUtilValue, your-window-id, "Mod4-t", false, false) Run a function on all button press events example This code snippet actually does *not* use the mousebind package, but illustrates how the Button{Press,Release} event handlers in the xevent package can still be useful. Namely, the mousebind package discriminates among events depending upon the button sequences pressed, whereas the xevent package is more general: it can only discriminate at the event level. xevent.ButtonPressFun( func(X *xgbutil.XUtil, ev xevent.ButtonPressEvent) { // do something when any button is pressed }).Connect(XUtilValue, your-window-id) This is the kind of handler you might use to capture all button press events. More examples A complete working example using the mousebind package can be found in 'simple-mousebinding' in the examples directory of the xgbutil package. */ package mousebind ================================================ FILE: mousebind/drag.go ================================================ package mousebind import ( "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/xevent" ) // Drag is the public interface that will make the appropriate connections // to register a drag event for three functions: the begin function, the // step function and the end function. // The 'grabwin' is the window that the grab is placed on (and therefore the // window where all button events are redirected to after the drag has started), // and the 'win' is the window that the initial 'begin' callback is set on. // In typical use cases, these windows should be the same. // If 'grab' is false, then no pointer grab is issued. func Drag(xu *xgbutil.XUtil, grabwin xproto.Window, win xproto.Window, buttonStr string, grab bool, begin xgbutil.MouseDragBeginFun, step xgbutil.MouseDragFun, end xgbutil.MouseDragFun) { ButtonPressFun( func(xu *xgbutil.XUtil, ev xevent.ButtonPressEvent) { DragBegin(xu, ev, grabwin, win, begin, step, end) }).Connect(xu, win, buttonStr, false, grab) // If the grab win isn't the dummy, then setup event handlers for the // grab window. if grabwin != xu.Dummy() { xevent.MotionNotifyFun(dragStep).Connect(xu, grabwin) xevent.ButtonReleaseFun(DragEnd).Connect(xu, grabwin) } } // dragGrab is a shortcut for grabbing the pointer for a drag. func dragGrab(xu *xgbutil.XUtil, grabwin xproto.Window, win xproto.Window, cursor xproto.Cursor) bool { status, err := GrabPointer(xu, grabwin, xu.RootWin(), cursor) if err != nil { xgbutil.Logger.Printf("Mouse dragging was unsuccessful because: %v", err) return false } if !status { xgbutil.Logger.Println("Mouse dragging was unsuccessful because " + "we could not establish a pointer grab.") return false } mouseDragSet(xu, true) return true } // dragUngrab is a shortcut for ungrabbing the pointer for a drag. func dragUngrab(xu *xgbutil.XUtil) { UngrabPointer(xu) mouseDragSet(xu, false) } // DragBegin executes the "begin" function registered for the current drag. // It also initiates the grab with the cursor id return by the begin callback. // // N.B. This function is automatically called in the Drag convenience function. // This should be used when the drag can be started from a source other than // a button press handled by the WM. If you use this function, then there // should also be a call to DragEnd when the drag is done. (This is // automatically done for you if you use Drag.) func DragBegin(xu *xgbutil.XUtil, ev xevent.ButtonPressEvent, grabwin xproto.Window, win xproto.Window, begin xgbutil.MouseDragBeginFun, step xgbutil.MouseDragFun, end xgbutil.MouseDragFun) { // don't start a drag if one is already in progress if mouseDrag(xu) { return } // Run begin first. It may tell us to cancel the grab. // It can also tell us which cursor to use when grabbing. grab, cursor := begin(xu, int(ev.RootX), int(ev.RootY), int(ev.EventX), int(ev.EventY)) // if we couldn't establish a grab, quit // Or quit if 'begin' tells us to. if !grab || !dragGrab(xu, grabwin, win, cursor) { return } // we're committed. set the drag state and start the 'begin' function mouseDragStepSet(xu, step) mouseDragEndSet(xu, end) } // dragStep executes the "step" function registered for the current drag. // It also compresses the MotionNotify events. func dragStep(xu *xgbutil.XUtil, ev xevent.MotionNotifyEvent) { // If for whatever reason we don't have any *piece* of a grab, // we've gotta back out. if !mouseDrag(xu) || mouseDragStep(xu) == nil || mouseDragEnd(xu) == nil { dragUngrab(xu) mouseDragStepSet(xu, nil) mouseDragEndSet(xu, nil) return } // The most recent MotionNotify event that we'll end up returning. laste := ev // We force a round trip request so that we make sure to read all // available events. xu.Sync() xevent.Read(xu, false) // Compress MotionNotify events. for i, ee := range xevent.Peek(xu) { if ee.Err != nil { // This is an error, skip it. continue } // Use type assertion to make sure this is a MotionNotify event. if mn, ok := ee.Event.(xproto.MotionNotifyEvent); ok { // Now make sure all appropriate fields are equivalent. if ev.Event == mn.Event && ev.Child == mn.Child && ev.Detail == mn.Detail && ev.State == mn.State && ev.Root == mn.Root && ev.SameScreen == mn.SameScreen { // Set the most recent/valid motion notify event. laste = xevent.MotionNotifyEvent{&mn} // We cheat and use the stack semantics of defer to dequeue // most recent motion notify events first, so that the indices // don't become invalid. (If we dequeued oldest first, we'd // have to account for all future events shifting to the left // by one.) defer func(i int) { xevent.DequeueAt(xu, i) }(i) } } } xu.TimeSet(laste.Time) // now actually run the step mouseDragStep(xu)(xu, int(laste.RootX), int(laste.RootY), int(laste.EventX), int(laste.EventY)) } // DragEnd executes the "end" function registered for the current drag. // This must be called at some point if DragStart has been called. func DragEnd(xu *xgbutil.XUtil, ev xevent.ButtonReleaseEvent) { if mouseDragEnd(xu) != nil { mouseDragEnd(xu)(xu, int(ev.RootX), int(ev.RootY), int(ev.EventX), int(ev.EventY)) } dragUngrab(xu) mouseDragStepSet(xu, nil) mouseDragEndSet(xu, nil) } ================================================ FILE: mousebind/mousebind.go ================================================ package mousebind import ( "fmt" "strconv" "strings" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/xevent" ) var modifiers []uint16 = []uint16{ // order matters! xproto.ModMaskShift, xproto.ModMaskLock, xproto.ModMaskControl, xproto.ModMask1, xproto.ModMask2, xproto.ModMask3, xproto.ModMask4, xproto.ModMask5, xproto.ButtonMask1, xproto.ButtonMask2, xproto.ButtonMask3, xproto.ButtonMask4, xproto.ButtonMask5, xproto.ButtonMaskAny, } var pointerMasks uint16 = xproto.EventMaskPointerMotion | xproto.EventMaskButtonRelease | xproto.EventMaskButtonPress // Initialize attaches the appropriate callbacks to make mouse bindings easier. // i.e., prep the dummy window to handle mouse dragging events func Initialize(xu *xgbutil.XUtil) { xevent.MotionNotifyFun(dragStep).Connect(xu, xu.Dummy()) xevent.ButtonReleaseFun(DragEnd).Connect(xu, xu.Dummy()) } // ParseString takes a string of the format '[Mod[-Mod[...]]]-BUTTONNUMBER', // i.e., 'Mod4-1', and returns a modifiers/button combination. // "Mod" could also be one of {button1, button2, button3, button4, button5}. // An error is returned if the string is malformed or if no BUTTONNUMBER // could be found. func ParseString(xu *xgbutil.XUtil, str string) (uint16, xproto.Button, error) { mods, button := uint16(0), xproto.Button(0) for _, part := range strings.Split(str, "-") { switch strings.ToLower(part) { case "shift": mods |= xproto.ModMaskShift case "lock": mods |= xproto.ModMaskLock case "control": mods |= xproto.ModMaskControl case "mod1": mods |= xproto.ModMask1 case "mod2": mods |= xproto.ModMask2 case "mod3": mods |= xproto.ModMask3 case "mod4": mods |= xproto.ModMask4 case "mod5": mods |= xproto.ModMask5 case "button1": mods |= xproto.ButtonMask1 case "button2": mods |= xproto.ButtonMask2 case "button3": mods |= xproto.ButtonMask3 case "button4": mods |= xproto.ButtonMask4 case "button5": mods |= xproto.ButtonMask5 case "any": mods |= xproto.ButtonMaskAny default: // a button! if button == 0 { // only accept the first button we see possible, err := strconv.ParseUint(part, 10, 8) if err == nil { button = xproto.Button(possible) } else { return 0, 0, fmt.Errorf("Could not convert '%s' to a "+ "valid 8-bit integer.", part) } } } } if button == 0 { return 0, 0, fmt.Errorf("Could not find a valid button in the "+ "string '%s'. Mouse binding failed.", str) } return mods, button, nil } // Grab grabs a button with mods on a particular window. // Will also grab all combinations of modifiers found in xevent.IgnoreMods // If 'sync' is True, then no further events can be processed until the // grabbing client allows them to be. (Which is done via AllowEvents. Thus, // if sync is True, you *must* make some call to AllowEvents at some // point, or else your client will lock.) func Grab(xu *xgbutil.XUtil, win xproto.Window, mods uint16, button xproto.Button, sync bool) { var pSync byte = xproto.GrabModeAsync if sync { pSync = xproto.GrabModeSync } for _, m := range xevent.IgnoreMods { xproto.GrabButton(xu.Conn(), true, win, pointerMasks, pSync, xproto.GrabModeAsync, 0, 0, byte(button), mods|m) } } // GrabChecked grabs a button with mods on a particular window. It does the // same thing as Grab, but issues a checked request and returns an error // on failure. // Will also grab all combinations of modifiers found in xevent.IgnoreMods // If 'sync' is True, then no further events can be processed until the // grabbing client allows them to be. (Which is done via AllowEvents. Thus, // if sync is True, you *must* make some call to AllowEvents at some // point, or else your client will lock.) func GrabChecked(xu *xgbutil.XUtil, win xproto.Window, mods uint16, button xproto.Button, sync bool) error { var pSync byte = xproto.GrabModeAsync if sync { pSync = xproto.GrabModeSync } var err error for _, m := range xevent.IgnoreMods { err = xproto.GrabButtonChecked(xu.Conn(), true, win, pointerMasks, pSync, xproto.GrabModeAsync, 0, 0, byte(button), mods|m).Check() if err != nil { return err } } return nil } // Ungrab undoes Grab. It will handle all combinations of modifiers found // in xevent.IgnoreMods. func Ungrab(xu *xgbutil.XUtil, win xproto.Window, mods uint16, button xproto.Button) { for _, m := range xevent.IgnoreMods { xproto.UngrabButtonChecked(xu.Conn(), byte(button), win, mods|m).Check() } } // GrabPointer grabs the entire pointer. // Returns whether GrabStatus is successful and an error if one is reported by // XGB. It is possible to not get an error and the grab to be unsuccessful. // The purpose of 'win' is that after a grab is successful, ALL Button*Events // will be sent to that window. Make sure you have a callback attached :-) func GrabPointer(xu *xgbutil.XUtil, win xproto.Window, confine xproto.Window, cursor xproto.Cursor) (bool, error) { reply, err := xproto.GrabPointer(xu.Conn(), false, win, pointerMasks, xproto.GrabModeAsync, xproto.GrabModeAsync, confine, cursor, 0).Reply() if err != nil { return false, fmt.Errorf("GrabPointer: Error grabbing pointer on "+ "window '%x': %s", win, err) } return reply.Status == xproto.GrabStatusSuccess, nil } // UngrabPointer undoes GrabPointer. func UngrabPointer(xu *xgbutil.XUtil) { xproto.UngrabPointer(xu.Conn(), 0) } ================================================ FILE: mousebind/xutil.go ================================================ package mousebind /* mousebind/xutil.go contains a collection of functions that modify the Mousebinds and Mousegrabs state of an XUtil value. They could have been placed inside the core xgbutil package, but they would have to be exported for use by the mousebind package. In which case, the API would become cluttered with functions that should not be used. */ import ( "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" ) // attachMouseBindCallback associates an (event, window, mods, button) // with a callback. func attachMouseBindCallback(xu *xgbutil.XUtil, evtype int, win xproto.Window, mods uint16, button xproto.Button, fun xgbutil.CallbackMouse) { xu.MousebindsLck.Lock() defer xu.MousebindsLck.Unlock() // Create key key := xgbutil.MouseKey{evtype, win, mods, button} // Do we need to allocate? if _, ok := xu.Mousebinds[key]; !ok { xu.Mousebinds[key] = make([]xgbutil.CallbackMouse, 0) } xu.Mousebinds[key] = append(xu.Mousebinds[key], fun) xu.Mousegrabs[key] += 1 } // mouseKeys returns a copy of all the keys in the 'Mousebinds' map. func mouseKeys(xu *xgbutil.XUtil) []xgbutil.MouseKey { xu.MousebindsLck.RLock() defer xu.MousebindsLck.RUnlock() keys := make([]xgbutil.MouseKey, len(xu.Mousebinds)) i := 0 for key, _ := range xu.Mousebinds { keys[i] = key i++ } return keys } // mouseBindCallbacks returns a slice of callbacks for a particular key. func mouseCallbacks(xu *xgbutil.XUtil, key xgbutil.MouseKey) []xgbutil.CallbackMouse { xu.MousebindsLck.RLock() defer xu.MousebindsLck.RUnlock() cbs := make([]xgbutil.CallbackMouse, len(xu.Mousebinds[key])) copy(cbs, xu.Mousebinds[key]) return cbs } // runMouseBindCallbacks executes every callback corresponding to a // particular event/window/mod/button tuple. func runMouseBindCallbacks(xu *xgbutil.XUtil, event interface{}, evtype int, win xproto.Window, mods uint16, button xproto.Button) { key := xgbutil.MouseKey{evtype, win, mods, button} for _, cb := range mouseCallbacks(xu, key) { cb.Run(xu, event) } } // connectedMouseBind checks to see if there are any key binds for a particular // event type already in play. This is to work around comparing function // pointers (not allowed in Go), which would be used in 'Connected'. func connectedMouseBind(xu *xgbutil.XUtil, evtype int, win xproto.Window) bool { xu.MousebindsLck.RLock() defer xu.MousebindsLck.RUnlock() // Since we can't create a full key, loop through all mouse binds // and check if evtype and window match. for key, _ := range xu.Mousebinds { if key.Evtype == evtype && key.Win == win { return true } } return false } // detachMouseBindWindow removes all callbacks associated with a particular // window and event type (either ButtonPress or ButtonRelease) // Also decrements the counter in the corresponding 'Mousegrabs' map // appropriately. func detachMouseBindWindow(xu *xgbutil.XUtil, evtype int, win xproto.Window) { xu.MousebindsLck.Lock() defer xu.MousebindsLck.Unlock() // Since we can't create a full key, loop through all mouse binds // and check if evtype and window match. for key, _ := range xu.Mousebinds { if key.Evtype == evtype && key.Win == win { xu.Mousegrabs[key] -= len(xu.Mousebinds[key]) delete(xu.Mousebinds, key) } } } // mouseBindGrabs returns the number of grabs on a particular // event/window/mods/button combination. Namely, this combination // uniquely identifies a grab. If it's repeated, we get BadAccess. func mouseBindGrabs(xu *xgbutil.XUtil, evtype int, win xproto.Window, mods uint16, button xproto.Button) int { xu.MousebindsLck.RLock() defer xu.MousebindsLck.RUnlock() key := xgbutil.MouseKey{evtype, win, mods, button} return xu.Mousegrabs[key] // returns 0 if key does not exist } // mouseDrag true when a mouse drag is in progress. func mouseDrag(xu *xgbutil.XUtil) bool { return xu.InMouseDrag } // mouseDragSet sets whether a mouse drag is in progress. func mouseDragSet(xu *xgbutil.XUtil, dragging bool) { xu.InMouseDrag = dragging } // mouseDragStep returns the function currently associated with each // step of a mouse drag. func mouseDragStep(xu *xgbutil.XUtil) xgbutil.MouseDragFun { return xu.MouseDragStepFun } // mouseDragStepSet sets the function associated with the step of a drag. func mouseDragStepSet(xu *xgbutil.XUtil, f xgbutil.MouseDragFun) { xu.MouseDragStepFun = f } // mouseDragEnd returns the function currently associated with the // end of a mouse drag. func mouseDragEnd(xu *xgbutil.XUtil) xgbutil.MouseDragFun { return xu.MouseDragEndFun } // mouseDragEndSet sets the function associated with the end of a drag. func mouseDragEndSet(xu *xgbutil.XUtil, f xgbutil.MouseDragFun) { xu.MouseDragEndFun = f } ================================================ FILE: scripts/README ================================================ The 'scripts' directory contains small programs that facilitate the development of xgbutil. Currently, there is only one script: 'write-events'. write-events ============ write-events is a short Python program that can automatically generates two Go source files in the 'xevent' package. Namely, the 'types_auto.go' and 'callbacks.go' files. Both files contain a lot of boiler plate related to definitions of each X event in the core protocol. If and when xgbutil adds support for other extensions (i.e., RandR), more events will need to be added. 'write-events' is run in when calling 'make' in the xgbutil root directory. ================================================ FILE: scripts/write-events ================================================ #!/usr/bin/env python2.7 import sys events = [ ('xproto', 'KeyPressEvent'), ('xproto', 'KeyReleaseEvent'), ('xproto', 'ButtonPressEvent'), ('xproto', 'ButtonReleaseEvent'), ('xproto', 'MotionNotifyEvent'), ('xproto', 'EnterNotifyEvent'), ('xproto', 'LeaveNotifyEvent'), ('xproto', 'FocusInEvent'), ('xproto', 'FocusOutEvent'), ('xproto', 'KeymapNotifyEvent'), ('xproto', 'ExposeEvent'), ('xproto', 'GraphicsExposureEvent'), ('xproto', 'NoExposureEvent'), ('xproto', 'VisibilityNotifyEvent'), ('xproto', 'CreateNotifyEvent'), ('xproto', 'DestroyNotifyEvent'), ('xproto', 'UnmapNotifyEvent'), ('xproto', 'MapNotifyEvent'), ('xproto', 'MapRequestEvent'), ('xproto', 'ReparentNotifyEvent'), ('xproto', 'ConfigureNotifyEvent'), ('xproto', 'ConfigureRequestEvent'), ('xproto', 'GravityNotifyEvent'), ('xproto', 'ResizeRequestEvent'), ('xproto', 'CirculateNotifyEvent'), ('xproto', 'CirculateRequestEvent'), ('xproto', 'PropertyNotifyEvent'), ('xproto', 'SelectionClearEvent'), ('xproto', 'SelectionRequestEvent'), ('xproto', 'SelectionNotifyEvent'), ('xproto', 'ColormapNotifyEvent'), ('xproto', 'ClientMessageEvent'), ('xproto', 'MappingNotifyEvent'), # X Shape extension events ('shape', 'NotifyEvent'), ] assert len(sys.argv) == 2 if sys.argv[1] == 'evtypes': print 'package xevent' print '''/* Defines event types and their associated methods automatically. This file is automatically generated using `scripts/write-events evtypes`. Edit it at your peril. */''' print print 'import (' print '\t"fmt"' print print '\t"github.com/BurntSushi/xgb/shape"' print '\t"github.com/BurntSushi/xgb/xproto"' print ')' print for ext, e in events: # Skip ClientMessageEvent and ConfigureNotifyEvent # We define these manually in xevents/types_manual.go if e in ('ClientMessageEvent', 'ConfigureNotifyEvent'): continue if ext == 'xproto': print 'type %s struct {' % e print ' *%s.%s' % (ext, e) print '}' print print 'const %s = %s.%s' % (e[:-5], ext, e[:-5]) print print 'func (ev %s) String() string {' % e print ' return fmt.Sprintf("%%v", ev.%s)' % e print '}' print else: print 'type %s%s struct {' % (ext.title(), e) print ' *%s.%s' % (ext, e) print '}' print print 'const %s%s = %s.%s' % (ext.title(), e[:-5], ext, e[:-5]) print print 'func (ev %s%s) String() string {' % (ext.title(), e) print ' return fmt.Sprintf("%%v", ev.%s)' % e print '}' print elif sys.argv[1] == 'callbacks': print 'package xevent' print '''/* Does all the plumbing to allow a simple callback interface for users. This file is automatically generated using `scripts/write-events callbacks`. Edit it at your peril. */''' print print 'import (' print '\t"github.com/BurntSushi/xgb/xproto"' print print '\t"github.com/BurntSushi/xgbutil"' print ')' print for ext, e in events: e = e[:-5] if ext != 'xproto': e = '%s%s' % (ext.title(), e) print 'type %sFun func(xu *xgbutil.XUtil, event %sEvent)' % (e, e) print print 'func (callback %sFun) '\ 'Connect(xu *xgbutil.XUtil,\nwin xproto.Window) {' % e print ' attachCallback(xu, %s, win, callback)' % e print '}' print print 'func (callback %sFun) ' \ 'Run(xu *xgbutil.XUtil, event interface{}) {' % e print ' callback(xu, event.(%sEvent))' % e print '}' print ================================================ FILE: session.vim ================================================ au BufWritePost *.go silent!make tags > /dev/null 2>&1 ================================================ FILE: types.go ================================================ package xgbutil /* types.go contains several types used in the XUtil structure. In an ideal world, they would be defined in their appropriate packages, but must be defined here (and exported) for use in some sub-packages. (Namely, xevent, keybind and mousebind.) */ import ( "github.com/BurntSushi/xgb" "github.com/BurntSushi/xgb/xproto" ) // Callback is an interface that should be implemented by event callback // functions. Namely, to assign a function to a particular event/window // combination, simply define a function with type 'SomeEventFun' (pre-defined // in xevent/callback.go), and call the 'Connect' method. // The 'Run' method is used inside the Main event loop, and shouldn't be used // by the user. // Also, it is perfectly legitimate to connect to events that don't specify // a window (like MappingNotify and KeymapNotify). In this case, simply // use 'xgbutil.NoWindow' as the window id. // // Example to respond to ConfigureNotify events on window 0x1 // // xevent.ConfigureNotifyFun( // func(X *xgbutil.XUtil, e xevent.ConfigureNotifyEvent) { // fmt.Printf("(%d, %d) %dx%d\n", e.X, e.Y, e.Width, e.Height) // }).Connect(X, 0x1) type Callback interface { // Connect modifies XUtil's state to attach an event handler to a // particular event. Connect(xu *XUtil, win xproto.Window) // Run is exported for use in the xevent package but should not be // used by the user. (It is used to run the callback function in the // main event loop.) Run(xu *XUtil, ev interface{}) } // CallbackHook works similarly to the more general Callback, but it is // for hooks into the main xevent loop. As such it does not get attached // to a window. type CallbackHook interface { // Connect connects this hook to the main loop of the passed XUtil // instance. Connect(xu *XUtil) // Run is exported for use in the xevent package, but should not be // used by the user. It should return true if it's ok to process // the event as usual, or false if it should be suppressed. Run(xu *XUtil, ev interface{}) bool } // CallbackKey works similarly to the more general Callback, but it adds // parameters specific to key bindings. type CallbackKey interface { // Connect modifies XUtil's state to attach an event handler to a // particular key press. If grab is true, connect will request a passive // grab. Connect(xu *XUtil, win xproto.Window, keyStr string, grab bool) error // Run is exported for use in the keybind package but should not be // used by the user. (It is used to run the callback function in the // main event loop. Run(xu *XUtil, ev interface{}) } // CallbackMouse works similarly to the more general Callback, but it adds // parameters specific to mouse bindings. type CallbackMouse interface { // Connect modifies XUtil's state to attach an event handler to a // particular button press. // If sync is true, the grab will be synchronous. (This will require a // call to xproto.AllowEvents in response, otherwise no further events // will be processed and your program will lock.) // If grab is true, connect will request a passive grab. Connect(xu *XUtil, win xproto.Window, buttonStr string, sync bool, grab bool) error // Run is exported for use in the mousebind package but should not be // used by the user. (It is used to run the callback function in the // main event loop.) Run(xu *XUtil, ev interface{}) } // KeyKey is the type of the key in the map of keybindings. // It essentially represents the tuple // (event type, window id, modifier, keycode). // It is exported for use in the keybind package. It should not be used. type KeyKey struct { Evtype int Win xproto.Window Mod uint16 Code xproto.Keycode } // KeyString is the type of a key binding string used to connect to particular // key combinations. A list of all such key strings is maintained in order to // rebind keys when the keyboard mapping has been changed. type KeyString struct { Str string Callback CallbackKey Evtype int Win xproto.Window Grab bool } // MouseKey is the type of the key in the map of mouse bindings. // It essentially represents the tuple // (event type, window id, modifier, button). // It is exported for use in the mousebind package. It should not be used. type MouseKey struct { Evtype int Win xproto.Window Mod uint16 Button xproto.Button } // KeyboardMapping embeds a keyboard mapping reply from XGB. // It should be retrieved using keybind.KeyMapGet, if necessary. // xgbutil tries quite hard to absolve you from ever having to use this. // A keyboard mapping is a table that maps keycodes to one or more keysyms. type KeyboardMapping struct { *xproto.GetKeyboardMappingReply } // ModifierMapping embeds a modifier mapping reply from XGB. // It should be retrieved using keybind.ModMapGet, if necessary. // xgbutil tries quite hard to absolve you from ever having to use this. // A modifier mapping is a table that maps modifiers to one or more keycodes. type ModifierMapping struct { *xproto.GetModifierMappingReply } // ErrorHandlerFun is the type of function required to handle errors that // come in through the main event loop. // For example, to set a new error handler, use: // // xevent.ErrorHandlerSet(xgbutil.ErrorHandlerFun( // func(err xgb.Error) { // // do something with err // })) type ErrorHandlerFun func(err xgb.Error) // EventOrError is a struct that contains either an event value or an error // value. It is an error to contain both. Containing neither indicates an // error too. // This is exported for use in the xevent package. You shouldn't have any // direct contact with values of this type, unless you need to inspect the // queue directly with xevent.Peek. type EventOrError struct { Event xgb.Event Err xgb.Error } // MouseDragFun is the kind of function used on each dragging step // and at the end of a drag. type MouseDragFun func(xu *XUtil, rootX, rootY, eventX, eventY int) // MouseDragBeginFun is the kind of function used to initialize a drag. // The difference between this and MouseDragFun is that the begin function // returns a bool (of whether or not to cancel the drag) and an X resource // identifier corresponding to a cursor. type MouseDragBeginFun func(xu *XUtil, rootX, rootY, eventX, eventY int) (bool, xproto.Cursor) ================================================ FILE: xcursor/cursordef.go ================================================ package xcursor const ( XCursor = 0 Arrow = 2 BasedArrowDown = 4 BasedArrowUp = 6 Boat = 8 Bogosity = 10 BottomLeftCorner = 12 BottomRightCorner = 14 BottomSide = 16 BottomTee = 18 BoxSpiral = 20 CenterPtr = 22 Circle = 24 Clock = 26 CoffeeMug = 28 Cross = 30 CrossReverse = 32 Crosshair = 34 DiamondCross = 36 Dot = 38 DotBoxMask = 40 DoubleArrow = 42 DraftLarge = 44 DraftSmall = 46 DrapedBox = 48 Exchange = 50 Fleur = 52 Gobbler = 54 Gumby = 56 Hand1 = 58 Hand2 = 60 Heart = 62 Icon = 64 IronCross = 66 LeftPtr = 68 LeftSide = 70 LeftTee = 72 LeftButton = 74 LLAngle = 76 LRAngle = 78 Man = 80 MiddleButton = 82 Mouse = 84 Pencil = 86 Pirate = 88 Plus = 90 QuestionArrow = 92 RightPtr = 94 RightSide = 96 RightTee = 98 RightButton = 100 RtlLogo = 102 Sailboat = 104 SBDownArrow = 106 SBHDoubleArrow = 108 SBLeftArrow = 110 SBRightArrow = 112 SBUpArrow = 114 SBVDoubleArrow = 116 Shuttle = 118 Sizing = 120 Spider = 122 Spraycan = 124 Star = 126 Target = 128 TCross = 130 TopLeftArrow = 132 TopLeftCorner = 134 TopRightCorner = 136 TopSide = 138 TopTee = 140 Trek = 142 ULAngle = 144 Umbrella = 146 URAngle = 148 Watch = 150 XTerm = 152 ) ================================================ FILE: xcursor/doc.go ================================================ /* Package xcursor provides a small interface for using cursors that are predefined in the X 'cursor' font. All available cursors are predefined in cursordef.go. Please see the 'change-cursor' example in the examples directory of the xgbutil package for an example of how to change the cursor when it enters a particular window. */ package xcursor ================================================ FILE: xcursor/xcursor.go ================================================ package xcursor import ( "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" ) // CreateCursor sets some default colors for nice and easy cursor creation. // Just supply a cursor constant from 'xcursor/cursordef.go'. func CreateCursor(xu *xgbutil.XUtil, cursor uint16) (xproto.Cursor, error) { return CreateCursorExtra(xu, cursor, 0, 0, 0, 0xffff, 0xffff, 0xffff) } // CreateCursorExtra features all available parameters to creating a cursor. // It will return an error if there is a problem with any of the requests // made to create the cursor. // (This implies each request is a checked request. The performance loss is // probably acceptable since cursors should be created once and reused.) func CreateCursorExtra(xu *xgbutil.XUtil, cursor, foreRed, foreGreen, foreBlue, backRed, backGreen, backBlue uint16) (xproto.Cursor, error) { fontId, err := xproto.NewFontId(xu.Conn()) if err != nil { return 0, err } cursorId, err := xproto.NewCursorId(xu.Conn()) if err != nil { return 0, err } err = xproto.OpenFontChecked(xu.Conn(), fontId, uint16(len("cursor")), "cursor").Check() if err != nil { return 0, err } err = xproto.CreateGlyphCursorChecked(xu.Conn(), cursorId, fontId, fontId, cursor, cursor+1, foreRed, foreGreen, foreBlue, backRed, backGreen, backBlue).Check() if err != nil { return 0, err } err = xproto.CloseFontChecked(xu.Conn(), fontId).Check() if err != nil { return 0, err } return cursorId, nil } ================================================ FILE: xevent/callback.go ================================================ package xevent /* Does all the plumbing to allow a simple callback interface for users. This file is automatically generated using `scripts/write-events callbacks`. Edit it at your peril. */ import ( "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" ) type KeyPressFun func(xu *xgbutil.XUtil, event KeyPressEvent) func (callback KeyPressFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, KeyPress, win, callback) } func (callback KeyPressFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(KeyPressEvent)) } type KeyReleaseFun func(xu *xgbutil.XUtil, event KeyReleaseEvent) func (callback KeyReleaseFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, KeyRelease, win, callback) } func (callback KeyReleaseFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(KeyReleaseEvent)) } type ButtonPressFun func(xu *xgbutil.XUtil, event ButtonPressEvent) func (callback ButtonPressFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, ButtonPress, win, callback) } func (callback ButtonPressFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(ButtonPressEvent)) } type ButtonReleaseFun func(xu *xgbutil.XUtil, event ButtonReleaseEvent) func (callback ButtonReleaseFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, ButtonRelease, win, callback) } func (callback ButtonReleaseFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(ButtonReleaseEvent)) } type MotionNotifyFun func(xu *xgbutil.XUtil, event MotionNotifyEvent) func (callback MotionNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, MotionNotify, win, callback) } func (callback MotionNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(MotionNotifyEvent)) } type EnterNotifyFun func(xu *xgbutil.XUtil, event EnterNotifyEvent) func (callback EnterNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, EnterNotify, win, callback) } func (callback EnterNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(EnterNotifyEvent)) } type LeaveNotifyFun func(xu *xgbutil.XUtil, event LeaveNotifyEvent) func (callback LeaveNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, LeaveNotify, win, callback) } func (callback LeaveNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(LeaveNotifyEvent)) } type FocusInFun func(xu *xgbutil.XUtil, event FocusInEvent) func (callback FocusInFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, FocusIn, win, callback) } func (callback FocusInFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(FocusInEvent)) } type FocusOutFun func(xu *xgbutil.XUtil, event FocusOutEvent) func (callback FocusOutFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, FocusOut, win, callback) } func (callback FocusOutFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(FocusOutEvent)) } type KeymapNotifyFun func(xu *xgbutil.XUtil, event KeymapNotifyEvent) func (callback KeymapNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, KeymapNotify, win, callback) } func (callback KeymapNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(KeymapNotifyEvent)) } type ExposeFun func(xu *xgbutil.XUtil, event ExposeEvent) func (callback ExposeFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, Expose, win, callback) } func (callback ExposeFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(ExposeEvent)) } type GraphicsExposureFun func(xu *xgbutil.XUtil, event GraphicsExposureEvent) func (callback GraphicsExposureFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, GraphicsExposure, win, callback) } func (callback GraphicsExposureFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(GraphicsExposureEvent)) } type NoExposureFun func(xu *xgbutil.XUtil, event NoExposureEvent) func (callback NoExposureFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, NoExposure, win, callback) } func (callback NoExposureFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(NoExposureEvent)) } type VisibilityNotifyFun func(xu *xgbutil.XUtil, event VisibilityNotifyEvent) func (callback VisibilityNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, VisibilityNotify, win, callback) } func (callback VisibilityNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(VisibilityNotifyEvent)) } type CreateNotifyFun func(xu *xgbutil.XUtil, event CreateNotifyEvent) func (callback CreateNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, CreateNotify, win, callback) } func (callback CreateNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(CreateNotifyEvent)) } type DestroyNotifyFun func(xu *xgbutil.XUtil, event DestroyNotifyEvent) func (callback DestroyNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, DestroyNotify, win, callback) } func (callback DestroyNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(DestroyNotifyEvent)) } type UnmapNotifyFun func(xu *xgbutil.XUtil, event UnmapNotifyEvent) func (callback UnmapNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, UnmapNotify, win, callback) } func (callback UnmapNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(UnmapNotifyEvent)) } type MapNotifyFun func(xu *xgbutil.XUtil, event MapNotifyEvent) func (callback MapNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, MapNotify, win, callback) } func (callback MapNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(MapNotifyEvent)) } type MapRequestFun func(xu *xgbutil.XUtil, event MapRequestEvent) func (callback MapRequestFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, MapRequest, win, callback) } func (callback MapRequestFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(MapRequestEvent)) } type ReparentNotifyFun func(xu *xgbutil.XUtil, event ReparentNotifyEvent) func (callback ReparentNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, ReparentNotify, win, callback) } func (callback ReparentNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(ReparentNotifyEvent)) } type ConfigureNotifyFun func(xu *xgbutil.XUtil, event ConfigureNotifyEvent) func (callback ConfigureNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, ConfigureNotify, win, callback) } func (callback ConfigureNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(ConfigureNotifyEvent)) } type ConfigureRequestFun func(xu *xgbutil.XUtil, event ConfigureRequestEvent) func (callback ConfigureRequestFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, ConfigureRequest, win, callback) } func (callback ConfigureRequestFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(ConfigureRequestEvent)) } type GravityNotifyFun func(xu *xgbutil.XUtil, event GravityNotifyEvent) func (callback GravityNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, GravityNotify, win, callback) } func (callback GravityNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(GravityNotifyEvent)) } type ResizeRequestFun func(xu *xgbutil.XUtil, event ResizeRequestEvent) func (callback ResizeRequestFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, ResizeRequest, win, callback) } func (callback ResizeRequestFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(ResizeRequestEvent)) } type CirculateNotifyFun func(xu *xgbutil.XUtil, event CirculateNotifyEvent) func (callback CirculateNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, CirculateNotify, win, callback) } func (callback CirculateNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(CirculateNotifyEvent)) } type CirculateRequestFun func(xu *xgbutil.XUtil, event CirculateRequestEvent) func (callback CirculateRequestFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, CirculateRequest, win, callback) } func (callback CirculateRequestFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(CirculateRequestEvent)) } type PropertyNotifyFun func(xu *xgbutil.XUtil, event PropertyNotifyEvent) func (callback PropertyNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, PropertyNotify, win, callback) } func (callback PropertyNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(PropertyNotifyEvent)) } type SelectionClearFun func(xu *xgbutil.XUtil, event SelectionClearEvent) func (callback SelectionClearFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, SelectionClear, win, callback) } func (callback SelectionClearFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(SelectionClearEvent)) } type SelectionRequestFun func(xu *xgbutil.XUtil, event SelectionRequestEvent) func (callback SelectionRequestFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, SelectionRequest, win, callback) } func (callback SelectionRequestFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(SelectionRequestEvent)) } type SelectionNotifyFun func(xu *xgbutil.XUtil, event SelectionNotifyEvent) func (callback SelectionNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, SelectionNotify, win, callback) } func (callback SelectionNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(SelectionNotifyEvent)) } type ColormapNotifyFun func(xu *xgbutil.XUtil, event ColormapNotifyEvent) func (callback ColormapNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, ColormapNotify, win, callback) } func (callback ColormapNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(ColormapNotifyEvent)) } type ClientMessageFun func(xu *xgbutil.XUtil, event ClientMessageEvent) func (callback ClientMessageFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, ClientMessage, win, callback) } func (callback ClientMessageFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(ClientMessageEvent)) } type MappingNotifyFun func(xu *xgbutil.XUtil, event MappingNotifyEvent) func (callback MappingNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, MappingNotify, win, callback) } func (callback MappingNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(MappingNotifyEvent)) } type ShapeNotifyFun func(xu *xgbutil.XUtil, event ShapeNotifyEvent) func (callback ShapeNotifyFun) Connect(xu *xgbutil.XUtil, win xproto.Window) { attachCallback(xu, ShapeNotify, win, callback) } func (callback ShapeNotifyFun) Run(xu *xgbutil.XUtil, event interface{}) { callback(xu, event.(ShapeNotifyEvent)) } ================================================ FILE: xevent/doc.go ================================================ /* Package xevent provides an event handler interface for attaching callback functions to X events, and an implementation of an X event loop. The X event loop One of the biggest conveniences offered by xgbutil is its event handler system. That is, the ability to attach an arbitrary callback function to any X event. In order for such things to work, xgbutil needs to control the main X event loop and act as a dispatcher for all event handlers created by you. To run the X event loop, use xevent.Main or xevent.MainPing. The former runs a normal event loop in the current goroutine and processes events. The latter runs the event loop in a new goroutine and returns a pingBefore and a pingAfter channel. The pingBefore channel is sent a benign value right before an event is dequeued, and the pingAfter channel is sent a benign value right after after all callbacks for that event have finished execution. These synchronization points in the main event loop can be combined with a 'select' statement to process data from other input sources. An example of this is given in the documentation for the MainPing function. A complete example called multiple-source-event-loop can also be found in the examples directory of the xgbutil package. To quit the main event loop, you may use xevent.Quit, but there is nothing inherently wrong with stopping dead using os.Exit. xevent.Quit is provided for your convenience should you need to run any clean-up code after the main event loop returns. The X event queue xgbutil's event queue contains values that are either events or errors. (Never both and never neither.) Namely, errors are received in the event loop from unchecked requests. (Errors generated by checked requests are guaranteed to be returned to the caller and are never received in the event loop.) Also, a default error handler function can be set with xevent.ErrorHandlerSet. To this end, xgbutil's event queue can be inspected. This is advantageous when information about what events will be processed in the future could be helpful (i.e., if there is an UnmapNotify event waiting to be processed.) The event queue can also be manipulated to facilitate event compression. (Two events that are common candidates for compression are ConfigureNotify and MotionNotify.) Detach events Whenever a window can no longer receive events (i.e., when it is destroyed), all event handlers related to that window should be detached. (If this is omitted, then Go's garbage collector will not be able to reuse memory occupied by the now-unused event handlers for that window.) Moreover, its possible that a window id can be reused after it has been discarded, which could result in odd behavior in your application. To detach a window from all event handlers in the xevent package, use xevent.Detach. If you're also using the keybind and mousebind packages, you'll need to call keybind.Detach and mousebind.Detach too. So to detach your window from all possible event handlers in xgbutil, use something like: xevent.Detach(XUtilValue, your-window-id) keybind.Detach(XUtilValue, your-window-id) mousebind.Detach(XUtilValue, your-window-id) Quick example A small example that shows how to respond to ConfigureNotify events sent to your-window-id. xevent.ConfigureNotifyFun( func(X *xgbutil.XUtil, e xevent.ConfigureNotifyEvent) { fmt.Printf("(%d, %d) %dx%d\n", e.X, e.Y, e.Width, e.Height) }).Connect(XUtilValue, your-window-id) More examples The xevent package is used in several of the examples in the examples directory in the xgbutil package. */ package xevent ================================================ FILE: xevent/eventloop.go ================================================ package xevent /* xevent/eventloop.go contains code that implements a main X event loop. Namely, it provides facilities to read new events into xevent's event queue, run a normal main event loop and run a main event loop that pings a channel each time an event is about to be dequeued. The latter facility allows one to easily include other input sources for processing in a program's main event loop. */ import ( "github.com/BurntSushi/xgb/shape" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" ) // Read reads one or more events and queues them in XUtil. // If 'block' is True, then call 'WaitForEvent' before sucking up // all events that have been queued by XGB. func Read(xu *xgbutil.XUtil, block bool) { if block { ev, err := xu.Conn().WaitForEvent() if ev == nil && err == nil { xgbutil.Logger.Fatal("BUG: Could not read an event or an error.") } Enqueue(xu, ev, err) } // Clean up anything that's in the queue for { ev, err := xu.Conn().PollForEvent() // No events left... if ev == nil && err == nil { break } // We're good, queue it up Enqueue(xu, ev, err) } } // Main starts the main X event loop. It will read events and call appropriate // callback functions. // N.B. If you have multiple X connections in the same program, you should be // able to run this in different goroutines concurrently. However, only // *one* of these should run for *each* connection. func Main(xu *xgbutil.XUtil) { mainEventLoop(xu, nil, nil, nil) } // MainPing starts the main X event loop, and returns three "ping" channels: // the first is pinged before an event is dequeued, the second is pinged // after all callbacks for a particular event have been called and the last // is pinged when the event loop stops (e.g., after a call to xevent.Quit). // pingAfter channel. // // This is useful if your event loop needs to draw from other sources. e.g., // // pingBefore, pingAfter, pingQuit := xevent.MainPing() // for { // select { // case <-pingBefore: // // Wait for event processing to finish. // <-pingAfter // case val <- someOtherChannel: // // do some work with val // case <-pingQuit: // fmt.Printf("xevent loop has quit") // return // } // } // // Note that an unbuffered channel is returned, which implies that any work // done with 'val' will delay further X event processing. // // A complete example using MainPing can be found in the examples directory in // the xgbutil package under the name multiple-source-event-loop. func MainPing(xu *xgbutil.XUtil) (chan struct{}, chan struct{}, chan struct{}) { pingBefore := make(chan struct{}, 0) pingAfter := make(chan struct{}, 0) pingQuit := make(chan struct{}, 0) go func() { mainEventLoop(xu, pingBefore, pingAfter, pingQuit) }() return pingBefore, pingAfter, pingQuit } // mainEventLoop runs the main event loop with an optional ping channel. func mainEventLoop(xu *xgbutil.XUtil, pingBefore, pingAfter, pingQuit chan struct{}) { for { if Quitting(xu) { if pingQuit != nil { pingQuit <- struct{}{} } break } // Gobble up as many events as possible (into the queue). // If there are no events, we block. Read(xu, true) // Now process every event/error in the queue. processEventQueue(xu, pingBefore, pingAfter) } } // processEventQueue processes every item in the event/error queue. func processEventQueue(xu *xgbutil.XUtil, pingBefore, pingAfter chan struct{}) { for !Empty(xu) { if Quitting(xu) { return } // We send the ping *before* the next event is dequeued. // This is so the queue doesn't present a misrepresentation of which // events haven't been processed yet. if pingBefore != nil && pingAfter != nil { pingBefore <- struct{}{} } ev, err := Dequeue(xu) // If we gobbled up an error, send it to the error event handler // and move on the next event/error. if err != nil { ErrorHandlerGet(xu)(err) if pingBefore != nil && pingAfter != nil { pingAfter <- struct{}{} } continue } // We know there isn't an error. If there isn't an event either, // then there's a bug somewhere. if ev == nil { xgbutil.Logger.Fatal("BUG: Expected an event but got nil.") } hooks := getHooks(xu) for _, hook := range hooks { if !hook.Run(xu, ev) { goto END } } switch event := ev.(type) { case xproto.KeyPressEvent: e := KeyPressEvent{&event} // If we're redirecting key events, this is the place to do it! if wid := RedirectKeyGet(xu); wid > 0 { e.Event = wid } xu.TimeSet(e.Time) runCallbacks(xu, e, KeyPress, e.Event) case xproto.KeyReleaseEvent: e := KeyReleaseEvent{&event} // If we're redirecting key events, this is the place to do it! if wid := RedirectKeyGet(xu); wid > 0 { e.Event = wid } xu.TimeSet(e.Time) runCallbacks(xu, e, KeyRelease, e.Event) case xproto.ButtonPressEvent: e := ButtonPressEvent{&event} xu.TimeSet(e.Time) runCallbacks(xu, e, ButtonPress, e.Event) case xproto.ButtonReleaseEvent: e := ButtonReleaseEvent{&event} xu.TimeSet(e.Time) runCallbacks(xu, e, ButtonRelease, e.Event) case xproto.MotionNotifyEvent: e := MotionNotifyEvent{&event} xu.TimeSet(e.Time) runCallbacks(xu, e, MotionNotify, e.Event) case xproto.EnterNotifyEvent: e := EnterNotifyEvent{&event} xu.TimeSet(e.Time) runCallbacks(xu, e, EnterNotify, e.Event) case xproto.LeaveNotifyEvent: e := LeaveNotifyEvent{&event} xu.TimeSet(e.Time) runCallbacks(xu, e, LeaveNotify, e.Event) case xproto.FocusInEvent: e := FocusInEvent{&event} runCallbacks(xu, e, FocusIn, e.Event) case xproto.FocusOutEvent: e := FocusOutEvent{&event} runCallbacks(xu, e, FocusOut, e.Event) case xproto.KeymapNotifyEvent: e := KeymapNotifyEvent{&event} runCallbacks(xu, e, KeymapNotify, NoWindow) case xproto.ExposeEvent: e := ExposeEvent{&event} runCallbacks(xu, e, Expose, e.Window) case xproto.GraphicsExposureEvent: e := GraphicsExposureEvent{&event} runCallbacks(xu, e, GraphicsExposure, xproto.Window(e.Drawable)) case xproto.NoExposureEvent: e := NoExposureEvent{&event} runCallbacks(xu, e, NoExposure, xproto.Window(e.Drawable)) case xproto.VisibilityNotifyEvent: e := VisibilityNotifyEvent{&event} runCallbacks(xu, e, VisibilityNotify, e.Window) case xproto.CreateNotifyEvent: e := CreateNotifyEvent{&event} runCallbacks(xu, e, CreateNotify, e.Parent) case xproto.DestroyNotifyEvent: e := DestroyNotifyEvent{&event} runCallbacks(xu, e, DestroyNotify, e.Window) case xproto.UnmapNotifyEvent: e := UnmapNotifyEvent{&event} runCallbacks(xu, e, UnmapNotify, e.Window) case xproto.MapNotifyEvent: e := MapNotifyEvent{&event} runCallbacks(xu, e, MapNotify, e.Event) case xproto.MapRequestEvent: e := MapRequestEvent{&event} runCallbacks(xu, e, MapRequest, e.Window) runCallbacks(xu, e, MapRequest, e.Parent) case xproto.ReparentNotifyEvent: e := ReparentNotifyEvent{&event} runCallbacks(xu, e, ReparentNotify, e.Window) case xproto.ConfigureNotifyEvent: e := ConfigureNotifyEvent{&event} runCallbacks(xu, e, ConfigureNotify, e.Window) case xproto.ConfigureRequestEvent: e := ConfigureRequestEvent{&event} runCallbacks(xu, e, ConfigureRequest, e.Window) runCallbacks(xu, e, ConfigureRequest, e.Parent) case xproto.GravityNotifyEvent: e := GravityNotifyEvent{&event} runCallbacks(xu, e, GravityNotify, e.Window) case xproto.ResizeRequestEvent: e := ResizeRequestEvent{&event} runCallbacks(xu, e, ResizeRequest, e.Window) case xproto.CirculateNotifyEvent: e := CirculateNotifyEvent{&event} runCallbacks(xu, e, CirculateNotify, e.Window) case xproto.CirculateRequestEvent: e := CirculateRequestEvent{&event} runCallbacks(xu, e, CirculateRequest, e.Window) case xproto.PropertyNotifyEvent: e := PropertyNotifyEvent{&event} xu.TimeSet(e.Time) runCallbacks(xu, e, PropertyNotify, e.Window) case xproto.SelectionClearEvent: e := SelectionClearEvent{&event} xu.TimeSet(e.Time) runCallbacks(xu, e, SelectionClear, e.Owner) case xproto.SelectionRequestEvent: e := SelectionRequestEvent{&event} xu.TimeSet(e.Time) runCallbacks(xu, e, SelectionRequest, e.Requestor) case xproto.SelectionNotifyEvent: e := SelectionNotifyEvent{&event} xu.TimeSet(e.Time) runCallbacks(xu, e, SelectionNotify, e.Requestor) case xproto.ColormapNotifyEvent: e := ColormapNotifyEvent{&event} runCallbacks(xu, e, ColormapNotify, e.Window) case xproto.ClientMessageEvent: e := ClientMessageEvent{&event} runCallbacks(xu, e, ClientMessage, e.Window) case xproto.MappingNotifyEvent: e := MappingNotifyEvent{&event} runCallbacks(xu, e, MappingNotify, NoWindow) case shape.NotifyEvent: e := ShapeNotifyEvent{&event} runCallbacks(xu, e, ShapeNotify, e.AffectedWindow) default: if event != nil { xgbutil.Logger.Printf("ERROR: UNSUPPORTED EVENT TYPE: %T", event) } } END: if pingBefore != nil && pingAfter != nil { pingAfter <- struct{}{} } } } ================================================ FILE: xevent/types_auto.go ================================================ package xevent /* Defines event types and their associated methods automatically. This file is automatically generated using `scripts/write-events evtypes`. Edit it at your peril. */ import ( "fmt" "github.com/BurntSushi/xgb/shape" "github.com/BurntSushi/xgb/xproto" ) type KeyPressEvent struct { *xproto.KeyPressEvent } const KeyPress = xproto.KeyPress func (ev KeyPressEvent) String() string { return fmt.Sprintf("%v", ev.KeyPressEvent) } type KeyReleaseEvent struct { *xproto.KeyReleaseEvent } const KeyRelease = xproto.KeyRelease func (ev KeyReleaseEvent) String() string { return fmt.Sprintf("%v", ev.KeyReleaseEvent) } type ButtonPressEvent struct { *xproto.ButtonPressEvent } const ButtonPress = xproto.ButtonPress func (ev ButtonPressEvent) String() string { return fmt.Sprintf("%v", ev.ButtonPressEvent) } type ButtonReleaseEvent struct { *xproto.ButtonReleaseEvent } const ButtonRelease = xproto.ButtonRelease func (ev ButtonReleaseEvent) String() string { return fmt.Sprintf("%v", ev.ButtonReleaseEvent) } type MotionNotifyEvent struct { *xproto.MotionNotifyEvent } const MotionNotify = xproto.MotionNotify func (ev MotionNotifyEvent) String() string { return fmt.Sprintf("%v", ev.MotionNotifyEvent) } type EnterNotifyEvent struct { *xproto.EnterNotifyEvent } const EnterNotify = xproto.EnterNotify func (ev EnterNotifyEvent) String() string { return fmt.Sprintf("%v", ev.EnterNotifyEvent) } type LeaveNotifyEvent struct { *xproto.LeaveNotifyEvent } const LeaveNotify = xproto.LeaveNotify func (ev LeaveNotifyEvent) String() string { return fmt.Sprintf("%v", ev.LeaveNotifyEvent) } type FocusInEvent struct { *xproto.FocusInEvent } const FocusIn = xproto.FocusIn func (ev FocusInEvent) String() string { return fmt.Sprintf("%v", ev.FocusInEvent) } type FocusOutEvent struct { *xproto.FocusOutEvent } const FocusOut = xproto.FocusOut func (ev FocusOutEvent) String() string { return fmt.Sprintf("%v", ev.FocusOutEvent) } type KeymapNotifyEvent struct { *xproto.KeymapNotifyEvent } const KeymapNotify = xproto.KeymapNotify func (ev KeymapNotifyEvent) String() string { return fmt.Sprintf("%v", ev.KeymapNotifyEvent) } type ExposeEvent struct { *xproto.ExposeEvent } const Expose = xproto.Expose func (ev ExposeEvent) String() string { return fmt.Sprintf("%v", ev.ExposeEvent) } type GraphicsExposureEvent struct { *xproto.GraphicsExposureEvent } const GraphicsExposure = xproto.GraphicsExposure func (ev GraphicsExposureEvent) String() string { return fmt.Sprintf("%v", ev.GraphicsExposureEvent) } type NoExposureEvent struct { *xproto.NoExposureEvent } const NoExposure = xproto.NoExposure func (ev NoExposureEvent) String() string { return fmt.Sprintf("%v", ev.NoExposureEvent) } type VisibilityNotifyEvent struct { *xproto.VisibilityNotifyEvent } const VisibilityNotify = xproto.VisibilityNotify func (ev VisibilityNotifyEvent) String() string { return fmt.Sprintf("%v", ev.VisibilityNotifyEvent) } type CreateNotifyEvent struct { *xproto.CreateNotifyEvent } const CreateNotify = xproto.CreateNotify func (ev CreateNotifyEvent) String() string { return fmt.Sprintf("%v", ev.CreateNotifyEvent) } type DestroyNotifyEvent struct { *xproto.DestroyNotifyEvent } const DestroyNotify = xproto.DestroyNotify func (ev DestroyNotifyEvent) String() string { return fmt.Sprintf("%v", ev.DestroyNotifyEvent) } type UnmapNotifyEvent struct { *xproto.UnmapNotifyEvent } const UnmapNotify = xproto.UnmapNotify func (ev UnmapNotifyEvent) String() string { return fmt.Sprintf("%v", ev.UnmapNotifyEvent) } type MapNotifyEvent struct { *xproto.MapNotifyEvent } const MapNotify = xproto.MapNotify func (ev MapNotifyEvent) String() string { return fmt.Sprintf("%v", ev.MapNotifyEvent) } type MapRequestEvent struct { *xproto.MapRequestEvent } const MapRequest = xproto.MapRequest func (ev MapRequestEvent) String() string { return fmt.Sprintf("%v", ev.MapRequestEvent) } type ReparentNotifyEvent struct { *xproto.ReparentNotifyEvent } const ReparentNotify = xproto.ReparentNotify func (ev ReparentNotifyEvent) String() string { return fmt.Sprintf("%v", ev.ReparentNotifyEvent) } type ConfigureRequestEvent struct { *xproto.ConfigureRequestEvent } const ConfigureRequest = xproto.ConfigureRequest func (ev ConfigureRequestEvent) String() string { return fmt.Sprintf("%v", ev.ConfigureRequestEvent) } type GravityNotifyEvent struct { *xproto.GravityNotifyEvent } const GravityNotify = xproto.GravityNotify func (ev GravityNotifyEvent) String() string { return fmt.Sprintf("%v", ev.GravityNotifyEvent) } type ResizeRequestEvent struct { *xproto.ResizeRequestEvent } const ResizeRequest = xproto.ResizeRequest func (ev ResizeRequestEvent) String() string { return fmt.Sprintf("%v", ev.ResizeRequestEvent) } type CirculateNotifyEvent struct { *xproto.CirculateNotifyEvent } const CirculateNotify = xproto.CirculateNotify func (ev CirculateNotifyEvent) String() string { return fmt.Sprintf("%v", ev.CirculateNotifyEvent) } type CirculateRequestEvent struct { *xproto.CirculateRequestEvent } const CirculateRequest = xproto.CirculateRequest func (ev CirculateRequestEvent) String() string { return fmt.Sprintf("%v", ev.CirculateRequestEvent) } type PropertyNotifyEvent struct { *xproto.PropertyNotifyEvent } const PropertyNotify = xproto.PropertyNotify func (ev PropertyNotifyEvent) String() string { return fmt.Sprintf("%v", ev.PropertyNotifyEvent) } type SelectionClearEvent struct { *xproto.SelectionClearEvent } const SelectionClear = xproto.SelectionClear func (ev SelectionClearEvent) String() string { return fmt.Sprintf("%v", ev.SelectionClearEvent) } type SelectionRequestEvent struct { *xproto.SelectionRequestEvent } const SelectionRequest = xproto.SelectionRequest func (ev SelectionRequestEvent) String() string { return fmt.Sprintf("%v", ev.SelectionRequestEvent) } type SelectionNotifyEvent struct { *xproto.SelectionNotifyEvent } const SelectionNotify = xproto.SelectionNotify func (ev SelectionNotifyEvent) String() string { return fmt.Sprintf("%v", ev.SelectionNotifyEvent) } type ColormapNotifyEvent struct { *xproto.ColormapNotifyEvent } const ColormapNotify = xproto.ColormapNotify func (ev ColormapNotifyEvent) String() string { return fmt.Sprintf("%v", ev.ColormapNotifyEvent) } type MappingNotifyEvent struct { *xproto.MappingNotifyEvent } const MappingNotify = xproto.MappingNotify func (ev MappingNotifyEvent) String() string { return fmt.Sprintf("%v", ev.MappingNotifyEvent) } type ShapeNotifyEvent struct { *shape.NotifyEvent } const ShapeNotify = shape.Notify func (ev ShapeNotifyEvent) String() string { return fmt.Sprintf("%v", ev.NotifyEvent) } ================================================ FILE: xevent/types_manual.go ================================================ package xevent import ( "fmt" "github.com/BurntSushi/xgb/xproto" ) // ClientMessageEvent embeds the struct by the same name from the xgb library. type ClientMessageEvent struct { *xproto.ClientMessageEvent } const ClientMessage = xproto.ClientMessage // NewClientMessage takes all arguments required to build a ClientMessageEvent // struct and hides the messy details. // The variadic parameters coincide with the "data" part of a client message. // The type of the variadic parameters depends upon the value of Format. // If Format is 8, 'data' should have type byte. // If Format is 16, 'data' should have type int16. // If Format is 32, 'data' should have type int. // Any other value of Format returns an error. func NewClientMessage(Format byte, Window xproto.Window, Type xproto.Atom, data ...interface{}) (*ClientMessageEvent, error) { // Create the client data list first var clientData xproto.ClientMessageDataUnion // Don't support formats 8 or 16 yet. They aren't used in EWMH anyway. switch Format { case 8: buf := make([]byte, 20) for i := 0; i < 20; i++ { if i >= len(data) { break } buf[i] = data[i].(byte) } clientData = xproto.ClientMessageDataUnionData8New(buf) case 16: buf := make([]uint16, 10) for i := 0; i < 10; i++ { if i >= len(data) { break } buf[i] = uint16(data[i].(int16)) } clientData = xproto.ClientMessageDataUnionData16New(buf) case 32: buf := make([]uint32, 5) for i := 0; i < 5; i++ { if i >= len(data) { break } buf[i] = uint32(data[i].(int)) } clientData = xproto.ClientMessageDataUnionData32New(buf) default: return nil, fmt.Errorf("NewClientMessage: Unsupported format '%d'.", Format) } return &ClientMessageEvent{&xproto.ClientMessageEvent{ Format: Format, Window: Window, Type: Type, Data: clientData, }}, nil } // ConfigureNotifyEvent embeds the struct by the same name in XGB. type ConfigureNotifyEvent struct { *xproto.ConfigureNotifyEvent } const ConfigureNotify = xproto.ConfigureNotify // NewConfigureNotify takes all arguments required to build a // ConfigureNotifyEvent struct and returns a ConfigureNotifyEvent value. func NewConfigureNotify(Event, Window, AboveSibling xproto.Window, X, Y, Width, Height int, BorderWidth uint16, OverrideRedirect bool) *ConfigureNotifyEvent { return &ConfigureNotifyEvent{&xproto.ConfigureNotifyEvent{ Event: Event, Window: Window, AboveSibling: AboveSibling, X: int16(X), Y: int16(Y), Width: uint16(Width), Height: uint16(Height), BorderWidth: BorderWidth, OverrideRedirect: OverrideRedirect, }} } ================================================ FILE: xevent/xevent.go ================================================ package xevent import ( "github.com/BurntSushi/xgb" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" ) // Sometimes we need to specify NO WINDOW when a window is typically // expected. (Like connecting to MappingNotify or KeymapNotify events.) // Use this value to do that. var NoWindow xproto.Window = 0 // IgnoreMods is a list of X modifiers that we don't want interfering // with our mouse or key bindings. In particular, for each mouse or key binding // issued, there is a seperate mouse or key binding made for each of the // modifiers specified. // // You may modify this slice to add (or remove) modifiers, but it should be // done before *any* key or mouse bindings are attached with the keybind and // mousebind packages. It should not be modified afterwards. // // TODO: We're assuming numlock is in the 'mod2' modifier, which is a pretty // common setup, but by no means guaranteed. This should be modified to actually // inspect the modifiers table and look for the special Num_Lock keysym. var IgnoreMods []uint16 = []uint16{ 0, xproto.ModMaskLock, // Caps lock xproto.ModMask2, // Num lock xproto.ModMaskLock | xproto.ModMask2, // Caps and Num lock } // Enqueue queues up an event read from X. // Note that an event read may return an error, in which case, this queue // entry will be an error and not an event. // // ev, err := XUtilValue.Conn().WaitForEvent() // xevent.Enqueue(XUtilValue, ev, err) // // You probably shouldn't have to enqueue events yourself. This is done // automatically if you're using xevent.Main{Ping} and/or xevent.Read. func Enqueue(xu *xgbutil.XUtil, ev xgb.Event, err xgb.Error) { xu.EvqueueLck.Lock() defer xu.EvqueueLck.Unlock() xu.Evqueue = append(xu.Evqueue, xgbutil.EventOrError{ Event: ev, Err: err, }) } // Dequeue pops an event/error from the queue and returns it. // The queue item is unwrapped and returned as multiple return values. // Only one of the return values can be nil. func Dequeue(xu *xgbutil.XUtil) (xgb.Event, xgb.Error) { xu.EvqueueLck.Lock() defer xu.EvqueueLck.Unlock() everr := xu.Evqueue[0] xu.Evqueue = xu.Evqueue[1:] return everr.Event, everr.Err } // DequeueAt removes a particular item from the queue. // This is primarily useful when attempting to compress events. func DequeueAt(xu *xgbutil.XUtil, i int) { xu.EvqueueLck.Lock() defer xu.EvqueueLck.Unlock() xu.Evqueue = append(xu.Evqueue[:i], xu.Evqueue[i+1:]...) } // Empty returns whether the event queue is empty or not. func Empty(xu *xgbutil.XUtil) bool { xu.EvqueueLck.RLock() defer xu.EvqueueLck.RUnlock() return len(xu.Evqueue) == 0 } // Peek returns a *copy* of the current queue so we can examine it. // This can be useful when trying to determine if a particular kind of // event will be processed in the future. func Peek(xu *xgbutil.XUtil) []xgbutil.EventOrError { xu.EvqueueLck.RLock() defer xu.EvqueueLck.RUnlock() cpy := make([]xgbutil.EventOrError, len(xu.Evqueue)) copy(cpy, xu.Evqueue) return cpy } // ErrorHandlerSet sets the default error handler for errors that come // into the main event loop. (This may be removed in the future in favor // of a particular callback interface like events, but these sorts of errors // aren't handled often in practice, so maybe not.) // This is only called for errors returned from unchecked (asynchronous error // handling) requests. // The default error handler just emits them to stderr. func ErrorHandlerSet(xu *xgbutil.XUtil, fun xgbutil.ErrorHandlerFun) { xu.ErrorHandler = fun } // ErrorHandlerGet retrieves the default error handler. func ErrorHandlerGet(xu *xgbutil.XUtil) xgbutil.ErrorHandlerFun { return xu.ErrorHandler } type HookFun func(xu *xgbutil.XUtil, event interface{}) bool func (callback HookFun) Connect(xu *xgbutil.XUtil) { xu.HooksLck.Lock() defer xu.HooksLck.Unlock() // COW newHooks := make([]xgbutil.CallbackHook, len(xu.Hooks)) copy(newHooks, xu.Hooks) newHooks = append(newHooks, callback) xu.Hooks = newHooks } func (callback HookFun) Run(xu *xgbutil.XUtil, event interface{}) bool { return callback(xu, event) } func getHooks(xu *xgbutil.XUtil) []xgbutil.CallbackHook { xu.HooksLck.RLock() defer xu.HooksLck.RUnlock() return xu.Hooks } // RedirectKeyEvents, when set to a window id (greater than 0), will force // *all* Key{Press,Release} to callbacks attached to the specified window. // This is close to emulating a Keyboard grab without the racing. // To stop redirecting key events, use window identifier '0'. func RedirectKeyEvents(xu *xgbutil.XUtil, wid xproto.Window) { xu.KeyRedirect = wid } // RedirectKeyGet gets the window that key events are being redirected to. // If 0, then no redirection occurs. func RedirectKeyGet(xu *xgbutil.XUtil) xproto.Window { return xu.KeyRedirect } // Quit elegantly exits out of the main event loop. // "Elegantly" in this case means that it finishes processing the current // event, and breaks out of the loop afterwards. // There is no particular reason to use this instead of something like os.Exit // other than you might have code to run after the main event loop exits to // "clean up." func Quit(xu *xgbutil.XUtil) { xu.Quit = true } // Quitting returns whether it's time to quit. // This is only used in the main event loop in xevent. func Quitting(xu *xgbutil.XUtil) bool { return xu.Quit } // attachCallback associates a (event, window) tuple with an event. // Use copy on write since we run callbacks *a lot* more than attaching them. // (The copy on write only applies to the slice of callbacks rather than // the map itself, since the initial allocation is guaranteed to come before // any use of it.) func attachCallback(xu *xgbutil.XUtil, evtype int, win xproto.Window, fun xgbutil.Callback) { xu.CallbacksLck.Lock() defer xu.CallbacksLck.Unlock() if _, ok := xu.Callbacks[evtype]; !ok { xu.Callbacks[evtype] = make(map[xproto.Window][]xgbutil.Callback, 20) } if _, ok := xu.Callbacks[evtype][win]; !ok { xu.Callbacks[evtype][win] = make([]xgbutil.Callback, 0) } // COW newCallbacks := make([]xgbutil.Callback, len(xu.Callbacks[evtype][win])) copy(newCallbacks, xu.Callbacks[evtype][win]) newCallbacks = append(newCallbacks, fun) xu.Callbacks[evtype][win] = newCallbacks } // runCallbacks executes every callback corresponding to a // particular event/window tuple. func runCallbacks(xu *xgbutil.XUtil, event interface{}, evtype int, win xproto.Window) { // The callback slice for a particular (event type, window) tuple uses // copy on write. So just take a pointer to whatever is there and use that. // We can be sure that the slice won't change from underneathe us. xu.CallbacksLck.RLock() cbs := xu.Callbacks[evtype][win] xu.CallbacksLck.RUnlock() for _, cb := range cbs { cb.Run(xu, event) } } // Detach removes all callbacks associated with a particular window. // Note that if you're also using the keybind and mousebind packages, a complete // detachment should look like: // // keybind.Detach(XUtilValue, window-id) // mousebind.Detach(XUtilValue, window-id) // xevent.Detach(XUtilValue, window-id) // // If a window is no longer receiving events, these methods should be called. // Otherwise, the memory used to store the handler info for that window will // never be released. func Detach(xu *xgbutil.XUtil, win xproto.Window) { xu.CallbacksLck.Lock() defer xu.CallbacksLck.Unlock() for evtype, _ := range xu.Callbacks { delete(xu.Callbacks[evtype], win) } } // SendRootEvent takes a type implementing the xgb.Event interface, converts it // to raw X bytes, and sends it to the root window using the SendEvent request. func SendRootEvent(xu *xgbutil.XUtil, ev xgb.Event, evMask uint32) error { return xproto.SendEventChecked(xu.Conn(), false, xu.RootWin(), evMask, string(ev.Bytes())).Check() } // ReplayPointer is a quick alias to AllowEvents with 'ReplayPointer' mode. func ReplayPointer(xu *xgbutil.XUtil) { xproto.AllowEvents(xu.Conn(), xproto.AllowReplayPointer, 0) } ================================================ FILE: xgbutil.go ================================================ package xgbutil import ( "log" "os" "sync" "github.com/BurntSushi/xgb" "github.com/BurntSushi/xgb/xinerama" "github.com/BurntSushi/xgb/xproto" ) // Logger is used through xgbutil when messages need to be emitted to stderr. var Logger = log.New(os.Stderr, "[xgbutil] ", log.Lshortfile) // The current maximum request size. I think we can expand this with // BigReq, but it probably isn't worth it at the moment. const MaxReqSize = (1 << 16) * 4 // An XUtil represents the state of xgbutil. It keeps track of the current // X connection, the root window, event callbacks, key/mouse bindings, etc. // Regrettably, many of the members are exported, even though they should not // be used directly by the user. They are exported for use in sub-packages. // (Namely, xevent, keybind and mousebind.) In fact, there should *never* // be a reason to access any members of an XUtil value directly. Any // interaction with an XUtil value should be through its methods. type XUtil struct { // conn is the XGB connection object used to issue protocol requests. conn *xgb.Conn // Quit can be set to true, and the main event loop will finish processing // the current event, and gracefully quit afterwards. // This is exported for use in the xevent package. Please us xevent.Quit // to set this value. Quit bool // when true, the main event loop will stop gracefully // setup contains all the setup information retrieved at connection time. setup *xproto.SetupInfo // screen is a simple alias to the default screen info. screen *xproto.ScreenInfo // root is an alias to the default root window. root xproto.Window // Atoms is a cache of atom names to resource identifiers. This minimizes // round trips to the X server, since atom identifiers never change. // It is exported for use in the xprop package. It should not be used. Atoms map[string]xproto.Atom AtomsLck *sync.RWMutex // AtomNames is a cache just like 'atoms', but in the reverse direction. // It is exported for use in the xprop package. It should not be used. AtomNames map[xproto.Atom]string AtomNamesLck *sync.RWMutex // Evqueue is the queue that stores the results of xgb.WaitForEvent. // Namely, each value is either an Event *or* an Error. // It is exported for use in the xevent package. Do not use it. // If you need to interact with the event queue, please use the functions // available in the xevent package: Dequeue, DequeueAt, QueueEmpty // and QueuePeek. Evqueue []EventOrError EvqueueLck *sync.RWMutex // Callbacks is a map of event numbers to a map of window identifiers // to callback functions. // This is the data structure that stores all callback functions, where // a callback function is always attached to a (event, window) tuple. // It is exported for use in the xevent package. Do not use it. Callbacks map[int]map[xproto.Window][]Callback CallbacksLck *sync.RWMutex // Hooks are called by the XEvent main loop before processing the event // itself. These are meant for instances when it's not possible / easy // to use the normal Hook system. You should not modify this yourself. Hooks []CallbackHook HooksLck *sync.RWMutex // eventTime is the last time recorded by an event. It is automatically // updated if xgbutil's main event loop is used. eventTime xproto.Timestamp // Keymap corresponds to xgbutil's current conception of the keyboard // mapping. It is automatically kept up-to-date if xgbutil's event loop // is used. // It is exported for use in the keybind package. It should not be // accessed directly. Instead, use keybind.KeyMapGet. Keymap *KeyboardMapping // Modmap corresponds to xgbutil's current conception of the modifier key // mapping. It is automatically kept up-to-date if xgbutil's event loop // is used. // It is exported for use in the keybind package. It should not be // accessed directly. Instead, use keybind.ModMapGet. Modmap *ModifierMapping // KeyRedirect corresponds to a window identifier that, when set, // automatically receives *all* keyboard events. This is a sort-of // synthetic grab and is helpful in avoiding race conditions. // It is exported for use in the xevent and keybind packages. Do not use // it directly. To redirect key events, please use xevent.RedirectKeyEvents. KeyRedirect xproto.Window // Keybinds is the data structure storing all callbacks for key bindings. // This is extremely similar to the general notion of event callbacks, // but adds extra support to make handling key bindings easier. (Like // specifying human readable key sequences to bind to.) // KeyBindKey is a struct representing the 4-tuple // (event-type, window-id, modifiers, keycode). // It is exported for use in the keybind package. Do not access it directly. Keybinds map[KeyKey][]CallbackKey KeybindsLck *sync.RWMutex // Keygrabs is a frequency count of the number of callbacks associated // with a particular KeyBindKey. This is necessary because we can only // grab a particular key *once*, but we may want to attach several callbacks // to a single keypress. // It is exported for use in the keybind package. Do not access it directly. Keygrabs map[KeyKey]int // Keystrings is a list of all key strings used to connect keybindings. // They are used to rebuild key grabs when the keyboard mapping is updated. // It is exported for use in the keybind package. Do not access it directly. Keystrings []KeyString // Mousebinds is the data structure storing all callbacks for mouse // bindings.This is extremely similar to the general notion of event // callbacks,but adds extra support to make handling mouse bindings easier. // (Like specifying human readable mouse sequences to bind to.) // MouseBindKey is a struct representing the 4-tuple // (event-type, window-id, modifiers, button). // It is exported for use in the mousebind package. Do not use it. Mousebinds map[MouseKey][]CallbackMouse MousebindsLck *sync.RWMutex // Mousegrabs is a frequency count of the number of callbacks associated // with a particular MouseBindKey. This is necessary because we can only // grab a particular mouse button *once*, but we may want to attach // several callbacks to a single button press. // It is exported for use in the mousebind package. Do not use it. Mousegrabs map[MouseKey]int // InMouseDrag is true if a drag is currently in progress. // It is exported for use in the mousebind package. Do not use it. InMouseDrag bool // MouseDragStep is the function executed for each step (i.e., pointer // movement) in the current mouse drag. Note that this is nil when a drag // is not in progress. // It is exported for use in the mousebind package. Do not use it. MouseDragStepFun MouseDragFun // MouseDragEnd is the function executed at the end of the current // mouse drag. This is nil when a drag is not in progress. // It is exported for use in the mousebind package. Do not use it. MouseDragEndFun MouseDragFun // gc is a general purpose graphics context; used to paint images. // Since we don't do any real X drawing, we don't really care about the // particulars of our graphics context. gc xproto.Gcontext // dummy is a dummy window used for mouse/key GRABs. // Basically, whenever a grab is instituted, mouse and key events are // redirected to the dummy the window. dummy xproto.Window // ErrorHandler is the function that handles errors *in the event loop*. // By default, it simply emits them to stderr. // It is exported for use in the xevent package. To set the default error // handler, please use xevent.ErrorHandlerSet. ErrorHandler ErrorHandlerFun } // NewConn connects to the X server using the DISPLAY environment variable // and creates a new XUtil. Most environments have the DISPLAY environment // variable set, so this is probably what you want to use to connect to X. func NewConn() (*XUtil, error) { return NewConnDisplay("") } // NewConnDisplay connects to the X server and creates a new XUtil. // If 'display' is empty, the DISPLAY environment variable is used. Otherwise // there are several different display formats supported: // // NewConn(":1") -> net.Dial("unix", "", "/tmp/.X11-unix/X1") // NewConn("/tmp/launch-12/:0") -> net.Dial("unix", "", "/tmp/launch-12/:0") // NewConn("hostname:2.1") -> net.Dial("tcp", "", "hostname:6002") // NewConn("tcp/hostname:1.0") -> net.Dial("tcp", "", "hostname:6001") func NewConnDisplay(display string) (*XUtil, error) { c, err := xgb.NewConnDisplay(display) if err != nil { return nil, err } return NewConnXgb(c) } // NewConnXgb use the specific xgb.Conn to create a new XUtil. // // NewConn, NewConnDisplay are wrapper of this function. func NewConnXgb(c *xgb.Conn) (*XUtil, error) { setup := xproto.Setup(c) screen := setup.DefaultScreen(c) // Initialize our central struct that stores everything. xu := &XUtil{ conn: c, Quit: false, Evqueue: make([]EventOrError, 0, 1000), EvqueueLck: &sync.RWMutex{}, setup: setup, screen: screen, root: screen.Root, eventTime: xproto.Timestamp(0), // last event time Atoms: make(map[string]xproto.Atom, 50), AtomsLck: &sync.RWMutex{}, AtomNames: make(map[xproto.Atom]string, 50), AtomNamesLck: &sync.RWMutex{}, Callbacks: make(map[int]map[xproto.Window][]Callback, 33), CallbacksLck: &sync.RWMutex{}, Hooks: make([]CallbackHook, 0), HooksLck: &sync.RWMutex{}, Keymap: nil, // we don't have anything yet Modmap: nil, KeyRedirect: 0, Keybinds: make(map[KeyKey][]CallbackKey, 10), KeybindsLck: &sync.RWMutex{}, Keygrabs: make(map[KeyKey]int, 10), Keystrings: make([]KeyString, 0, 10), Mousebinds: make(map[MouseKey][]CallbackMouse, 10), MousebindsLck: &sync.RWMutex{}, Mousegrabs: make(map[MouseKey]int, 10), InMouseDrag: false, MouseDragStepFun: nil, MouseDragEndFun: nil, ErrorHandler: func(err xgb.Error) { Logger.Println(err) }, } var err error = nil // Create a general purpose graphics context xu.gc, err = xproto.NewGcontextId(xu.conn) if err != nil { return nil, err } xproto.CreateGC(xu.conn, xu.gc, xproto.Drawable(xu.root), xproto.GcForeground, []uint32{xu.screen.WhitePixel}) // Create a dummy window xu.dummy, err = xproto.NewWindowId(xu.conn) if err != nil { return nil, err } xproto.CreateWindow(xu.conn, xu.Screen().RootDepth, xu.dummy, xu.RootWin(), -1000, -1000, 1, 1, 0, xproto.WindowClassInputOutput, xu.Screen().RootVisual, xproto.CwEventMask|xproto.CwOverrideRedirect, []uint32{1, xproto.EventMaskPropertyChange}) xproto.MapWindow(xu.conn, xu.dummy) // Register the Xinerama extension... because it doesn't cost much. err = xinerama.Init(xu.conn) // If we can't register Xinerama, that's okay. Output something // and move on. if err != nil { Logger.Printf("WARNING: %s\n", err) Logger.Printf("MESSAGE: The 'xinerama' package cannot be used " + "because the XINERAMA extension could not be loaded.") } return xu, nil } // Conn returns the xgb connection object. func (xu *XUtil) Conn() *xgb.Conn { return xu.conn } // ExtInitialized returns true if an extension has been initialized. // This is useful for determining whether an extension is available or not. func (xu *XUtil) ExtInitialized(extName string) bool { _, ok := xu.Conn().Extensions[extName] return ok } // Sync forces XGB to catch up with all events/requests and synchronize. // This is done by issuing a benign round trip request to X. func (xu *XUtil) Sync() { xproto.GetInputFocus(xu.Conn()).Reply() } // Setup returns the setup information retrieved during connection time. func (xu *XUtil) Setup() *xproto.SetupInfo { return xu.setup } // Screen returns the default screen func (xu *XUtil) Screen() *xproto.ScreenInfo { return xu.screen } // RootWin returns the current root window. func (xu *XUtil) RootWin() xproto.Window { return xu.root } // RootWinSet will change the current root window to the one provided. // N.B. This probably shouldn't be used unless you're desperately trying // to support multiple X screens. (This is *not* the same as Xinerama/RandR or // TwinView. All of those have a single root window.) func (xu *XUtil) RootWinSet(root xproto.Window) { xu.root = root } // TimeGet gets the most recent time seen by an event. func (xu *XUtil) TimeGet() xproto.Timestamp { return xu.eventTime } // TimeSet sets the most recent time seen by an event. func (xu *XUtil) TimeSet(t xproto.Timestamp) { xu.eventTime = t } // GC gets a general purpose graphics context that is typically used to simply // paint images. func (xu *XUtil) GC() xproto.Gcontext { return xu.gc } // Dummy gets the id of the dummy window. func (xu *XUtil) Dummy() xproto.Window { return xu.dummy } // Grabs the server. Everything becomes synchronous. func (xu *XUtil) Grab() { xproto.GrabServer(xu.Conn()) } // Ungrabs the server. func (xu *XUtil) Ungrab() { xproto.UngrabServer(xu.Conn()) } ================================================ FILE: xgraphics/convert.go ================================================ package xgraphics /* A set of conversion functions for some image types defined in the Go standard library. They can be up to 80% faster because the inner loop doesn't use interfaces. Wow. Note that these functions assume that the source and destination are precisely the same size. */ import ( "image" "image/color" ) // convertImage converts any image implementing the image.Image interface to // an xgraphics.Image type. This is *slow*. func convertImage(dest *Image, src image.Image) { var r, g, b, a uint32 var x, y, i int for x = dest.Rect.Min.X; x < dest.Rect.Max.X; x++ { for y = dest.Rect.Min.Y; y < dest.Rect.Max.Y; y++ { r, g, b, a = src.At(x, y).RGBA() i = dest.PixOffset(x, y) dest.Pix[i+0] = uint8(b >> 8) dest.Pix[i+1] = uint8(g >> 8) dest.Pix[i+2] = uint8(r >> 8) dest.Pix[i+3] = uint8(a >> 8) } } } func convertXImage(dest *Image, src *Image) { copy(dest.Pix, src.Pix) } func convertYCbCr(dest *Image, src *image.YCbCr) { var r, g, b uint8 var x, y, i, yi, ci int for x = dest.Rect.Min.X; x < dest.Rect.Max.X; x++ { for y = dest.Rect.Min.Y; y < dest.Rect.Max.Y; y++ { yi, ci = src.YOffset(x, y), src.COffset(x, y) r, g, b = color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci]) i = dest.PixOffset(x, y) dest.Pix[i+0] = b dest.Pix[i+1] = g dest.Pix[i+2] = r dest.Pix[i+3] = 0xff } } } func convertRGBA(dest *Image, src *image.RGBA) { var x, y, i, si int for x = dest.Rect.Min.X; x < dest.Rect.Max.X; x++ { for y = dest.Rect.Min.Y; y < dest.Rect.Max.Y; y++ { si = src.PixOffset(x, y) i = dest.PixOffset(x, y) dest.Pix[i+0] = src.Pix[si+2] dest.Pix[i+1] = src.Pix[si+1] dest.Pix[i+2] = src.Pix[si+0] dest.Pix[i+3] = src.Pix[si+3] } } } func convertRGBA64(dest *Image, src *image.RGBA64) { var x, y, i, si int for x = dest.Rect.Min.X; x < dest.Rect.Max.X; x++ { for y = dest.Rect.Min.Y; y < dest.Rect.Max.Y; y++ { si = src.PixOffset(x, y) i = dest.PixOffset(x, y) dest.Pix[i+0] = src.Pix[si+4] dest.Pix[i+1] = src.Pix[si+2] dest.Pix[i+2] = src.Pix[si+0] dest.Pix[i+3] = src.Pix[si+6] } } } func convertNRGBA(dest *Image, src *image.NRGBA) { var x, y, i, si int var a uint16 for x = dest.Rect.Min.X; x < dest.Rect.Max.X; x++ { for y = dest.Rect.Min.Y; y < dest.Rect.Max.Y; y++ { si = src.PixOffset(x, y) i = dest.PixOffset(x, y) a = uint16(src.Pix[si+3]) dest.Pix[i+0] = uint8((uint16(src.Pix[si+2]) * a) / 0xff) dest.Pix[i+1] = uint8((uint16(src.Pix[si+1]) * a) / 0xff) dest.Pix[i+2] = uint8((uint16(src.Pix[si+0]) * a) / 0xff) dest.Pix[i+3] = src.Pix[si+3] } } } func convertNRGBA64(dest *Image, src *image.NRGBA64) { var x, y, i, si int var a uint16 for x = dest.Rect.Min.X; x < dest.Rect.Max.X; x++ { for y = dest.Rect.Min.Y; y < dest.Rect.Max.Y; y++ { si = src.PixOffset(x, y) i = dest.PixOffset(x, y) a = uint16(src.Pix[si+6]) dest.Pix[i+0] = uint8((uint16(src.Pix[si+4]) * a) / 0xff) dest.Pix[i+1] = uint8((uint16(src.Pix[si+2]) * a) / 0xff) dest.Pix[i+2] = uint8((uint16(src.Pix[si+0]) * a) / 0xff) dest.Pix[i+3] = src.Pix[si+6] } } } ================================================ FILE: xgraphics/doc.go ================================================ /* Package xgraphics defines an X image type and provides convenience functions for reading and writing X pixmaps and bitmaps. It is a work-in-progress, and while it works for some common X server configurations, it does not work for all X server configurations. Package xgraphics also provides some support for drawing text on to images using freetype-go, scaling images using graphics-go, simple alpha blending, finding EWMH and ICCCM window icons and efficiently drawing any image into an X pixmap. (Where "efficient" means being able to specify sub-regions of images to draw, so that the entire image isn't sent to X.) If more elaborate image routines are required, I recommend using draw2d. (The xgraphics.Image type satisfies the draw.Image interface, which allows it to work with draw2d.) In general, xgraphics paints pixmaps to windows using using the BackPixmap approach. (Setting the background pixmap of the window to the pixmap containing your image, and clearing the window's background when the pixmap is updated.) It also provides experimental support for another mechanism: copying the contents of your image's pixmap directly to the window. (This requires responding to expose events to redraw the pixmap.) The former approach requires less book-keeping, but supposedly has some issues with some video cards. The latter approach is probably more reliable, but requires more book-keeping. Note that while text drawing functions are provided, it is not necessary to use them to write text on images. Namely, there is nothing X specific about them. They are strictly for convenience. A quick example This is a simple example the converts any value satisfying the image.Image interface into an *xgraphics.Image value, and creates a new window with that image painted in the window. (The XShow function probably doesn't have any practical applications outside serving as an example, but can be useful for debugging what an image looks like.) imgFile, err := os.Open(imgPath) if err != nil { log.Fatal(err) } img, _, err := image.Decode(imgFile) if err != nil { log.Fatal(err) } ximg := xgraphics.NewConvert(XUtilValue, img) ximg.XShow() A complete working example named 'show-image' that's similar to this can be found in the examples directory of the xgbutil package. More involved examples, 'show-window-icons' and 'pointer-painting', are also provided. Portability The xgraphics package *assumes* a particular kind of X server configuration. Namely, this configuration specifies bits per pixel, image byte order, bitmap bit order, scanline padding and unit length, image depth and so on. Handling all of the possible values for each configuration option will greatly inflate the code, but is on the TODO list. I am undecided (perhaps because I haven't thought about it too much) about whether to hide these configuration details behind multiple xgraphics.Image types or hiding everything inside one xgraphics.Image type. I lean toward the latter because the former requires a large number of types (and therefore a lot of code duplication). One design decision that I've already made is that images should be converted to the format used by the X server (xgraphics currently assumes this is BGRx) once when the image is created. Without this, an xgraphics.Image type wouldn't be required, and images would have to be converted to the X image format every time an image is drawn into a pixmap. This results in a lot of overhead. Moreover, Go's interfaces allow an xgraphics.Image type to work anywhere that an image.Image or a draw.Image value is expected. The obvious down-side to this approach is that optimizations made in image drawing routines in other libraries won't be able to apply to xgraphics.Image values (since the optimizations are probably hard-coded for image types declared in Go's standard library). This isn't well suited to the process of creating some canvas to draw on, and using another library to draw on the canvas. (At least, it won't be as fast as possible.) I can't think of any way around this, other than having the library add an optimization step specifically for xgraphics.Image values. Of course, the other approach is to convert image formats only when drawing to X and completely subvert the xgraphics.Image type, but this seems worse than unoptimized image drawing routines. (Unfortunately, both things need to be fast.) If your X server is not configured to what the xgraphics package expects, messages will be emitted to stderr when a new xgraphics.Image value is created. If you see any of these messages, please report them to xgbutil's project page: https://github.com/BurntSushi/xgbutil. */ package xgraphics ================================================ FILE: xgraphics/image.go ================================================ package xgraphics /* xgraphics/image.go contains an implementation of the draw.Image interface. RGBA could feasibly be used, but the representation of image data is dependent upon the configuration of the X server. For the time being, I'm hard-coding a lot of that configuration for the common case. Namely: Byte order: least significant byte first Depth: 24 Bits per pixel: 32 This will have to be fixed for this to be truly compatible with any X server. Most of the code is based heavily on the implementation of common images in the Go standard library. Manipulating images isn't something I've had much experience with, so if it seems like I'm doing something stupid, I probably am. */ import ( "image" "image/color" "image/png" "io" "os" "github.com/BurntSushi/graphics-go/graphics" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/xwindow" ) // Model for the BGRA color type. var BGRAModel color.Model = color.ModelFunc(bgraModel) type Image struct { // X images must be tied to an X connection. X *xgbutil.XUtil // X images must also be tied to a pixmap (its drawing surface). // Calls to 'XDraw' will draw data to this pixmap. // Calls to 'XPaint' will tell X to show the pixmap on some window. Pixmap xproto.Pixmap // Pix holds the image's pixels in BGRA order, so that they don't need // to be swapped for every PutImage request. Pix []uint8 // Stride corresponds to the number of elements in Pix between two pixels // that are vertically adjacent. Stride int // The geometry of the image. Rect image.Rectangle // Whether this is a sub-image or not. // This is useful to know when sending data or setting surfaces. // Namely, sub-images cannot be set as surfaces and sub-images, when // being drawn, only have its pixels sent to X instead of the whole image. Subimg bool } // New returns a new instance of Image with colors initialized to black // for the geometry given. // New will also create an X pixmap. When you are no longer using this // image, you should call Destroy so that the X pixmap can be freed on the // X server. // If 'X' is nil, then a new connection will be made. This is usually a bad // idea, particularly if you're making a lot of small images, but can be // used to achieve true parallelism. (Particularly useful when painting large // images.) func New(X *xgbutil.XUtil, r image.Rectangle) *Image { var err error if X == nil { X, err = xgbutil.NewConn() if err != nil { xgbutil.Logger.Panicf("Could not create a new connection when "+ "creating a new xgraphics.Image value because: %s", err) } } return &Image{ X: X, Pixmap: 0, Pix: make([]uint8, 4*r.Dx()*r.Dy()), Stride: 4 * r.Dx(), Rect: r, Subimg: false, } } // Destroy frees the pixmap resource being used by this image. // It should be called whenever the image will no longer be drawn or painted. func (im *Image) Destroy() { if im.Pixmap != 0 { xproto.FreePixmap(im.X.Conn(), im.Pixmap) im.Pixmap = 0 } } // Scale will scale the image to the size provided. // Note that this will destroy the current pixmap associated with this image. // After scaling, XSurfaceSet will need to be called for each window that // this image is painted to. (And obviously, XDraw and XPaint will need to // be called again.) func (im *Image) Scale(width, height int) *Image { dimg := New(im.X, image.Rect(0, 0, width, height)) graphics.Scale(dimg, im) im.Destroy() return dimg } // WritePng encodes the image to w as a png. func (im *Image) WritePng(w io.Writer) error { return png.Encode(w, im) } // SavePng writes the Image to a file with name as a png. func (im *Image) SavePng(name string) error { file, err := os.Create(name) if err != nil { return err } return im.WritePng(file) } // ColorModel returns the color.Model used by the Image struct. func (im *Image) ColorModel() color.Model { return BGRAModel } // Bounds returns the rectangle representing the geometry of Image. func (im *Image) Bounds() image.Rectangle { return im.Rect } // At returns the color at the specified pixel. func (im *Image) At(x, y int) color.Color { if !(image.Point{x, y}.In(im.Rect)) { return BGRA{} } i := im.PixOffset(x, y) return BGRA{ B: im.Pix[i], G: im.Pix[i+1], R: im.Pix[i+2], A: im.Pix[i+3], } } // Set satisfies the draw.Image interface by allowing the color of a pixel // at (x, y) to be changed. func (im *Image) Set(x, y int, c color.Color) { if !(image.Point{x, y}.In(im.Rect)) { return } i := im.PixOffset(x, y) cc := BGRAModel.Convert(c).(BGRA) im.Pix[i] = cc.B im.Pix[i+1] = cc.G im.Pix[i+2] = cc.R im.Pix[i+3] = cc.A } // SetBGRA is like set, but without the type assertion. func (im *Image) SetBGRA(x, y int, c BGRA) { if !(image.Point{x, y}.In(im.Rect)) { return } i := im.PixOffset(x, y) im.Pix[i] = c.B im.Pix[i+1] = c.G im.Pix[i+2] = c.R im.Pix[i+3] = c.A } // For transforms every pixel color to the color returned by 'each' given // an (x, y) position. func (im *Image) For(each func(x, y int) BGRA) { for x := im.Rect.Min.X; x < im.Rect.Max.X; x++ { for y := im.Rect.Min.Y; y < im.Rect.Max.Y; y++ { im.SetBGRA(x, y, each(x, y)) } } } // ForExp is like For, but bypasses image.Color types. // (So it should be faster.) func (im *Image) ForExp(each func(x, y int) (r, g, b, a uint8)) { var x, y, i int var r, g, b, a uint8 for x = im.Rect.Min.X; x < im.Rect.Max.X; x++ { for y = im.Rect.Min.Y; y < im.Rect.Max.Y; y++ { i = im.PixOffset(x, y) r, g, b, a = each(x, y) im.Pix[i+0] = b im.Pix[i+1] = g im.Pix[i+2] = r im.Pix[i+3] = a } } } // SubImage provides a sub image of Image without copying image data. // N.B. The standard library defines a similar function, but returns an // image.Image. Here, we return xgraphics.Image so that we can use the extra // methods defined by xgraphics on it. // // This method is cheap to call. It should be used to update only specific // regions of an X pixmap to avoid sending an entire image to the X server when // only a piece of it is updated. // // Note that if the intersection of `r` and `im` is empty, `nil` is returned. func (im *Image) SubImage(r image.Rectangle) image.Image { r = r.Intersect(im.Rect) if r.Empty() { return nil } i := im.PixOffset(r.Min.X, r.Min.Y) return &Image{ X: im.X, Pixmap: im.Pixmap, Pix: im.Pix[i:], Stride: im.Stride, Rect: r, Subimg: true, } } // PixOffset returns the index of the frst element of the Pix data that // corresponds to the pixel at (x, y). func (im *Image) PixOffset(x, y int) int { return (y-im.Rect.Min.Y)*im.Stride + (x-im.Rect.Min.X)*4 } // Window is a convenience function for painting the provided // Image value to a new window, destroying the pixmap created by that image, // and returning the window value. // The window is sized to the dimensions of the image. func (im *Image) Window(parent xproto.Window) *xwindow.Window { win := xwindow.Must(xwindow.Create(im.X, parent)) win.Resize(im.Bounds().Dx(), im.Bounds().Dy()) im.XSurfaceSet(win.Id) im.XDraw() im.XPaint(win.Id) im.Destroy() return win } // BGRA is the representation of color for each pixel in an X pixmap. // BUG(burntsushi): This is hard-coded when it shouldn't be. type BGRA struct { B, G, R, A uint8 } // RGBA satisfies the color.Color interface. func (c BGRA) RGBA() (r, g, b, a uint32) { r = uint32(c.R) r |= r << 8 g = uint32(c.G) g |= g << 8 b = uint32(c.B) b |= b << 8 a = uint32(c.A) a |= a << 8 return } // bgraModel converts from any color to a BGRA color type. func bgraModel(c color.Color) color.Color { if _, ok := c.(BGRA); ok { return c } r, g, b, a := c.RGBA() return BGRA{ B: uint8(b >> 8), G: uint8(g >> 8), R: uint8(r >> 8), A: uint8(a >> 8), } } ================================================ FILE: xgraphics/new.go ================================================ package xgraphics /* xgraphics/new.go contains a few additional constructors for creating an xgraphics.Image. */ import ( "bytes" "fmt" "image" _ "image/gif" _ "image/jpeg" _ "image/png" "os" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/ewmh" "github.com/BurntSushi/xgbutil/xwindow" ) // NewConvert converts any image satisfying the image.Image interface to an // xgraphics.Image type. // If 'img' is an xgraphics.Image, it will be copied and a new image will // be returned. // Also, NewConvert attempts to optimize image conversion for some image // formats. (i.e., *image.RGBA.) func NewConvert(X *xgbutil.XUtil, img image.Image) *Image { ximg := New(X, img.Bounds()) // I've attempted to optimize this loop. // It actually takes more time to convert an image than to send the bytes // over the wire. (I suspect 'copy' is super fast, which can be used in // XDraw, whereas computing each pixel is super slow.) // But how is image decoding so much faster than this? I'll have to // investigate... Maybe the Color interface being used here is the real // slow down. switch concrete := img.(type) { case *image.NRGBA: convertNRGBA(ximg, concrete) case *image.NRGBA64: convertNRGBA64(ximg, concrete) case *image.RGBA: convertRGBA(ximg, concrete) case *image.RGBA64: convertRGBA64(ximg, concrete) case *image.YCbCr: convertYCbCr(ximg, concrete) case *Image: convertXImage(ximg, concrete) default: xgbutil.Logger.Printf("Converting image type %T the slow way. "+ "Optimization for this image type hasn't been added yet.", img) convertImage(ximg, img) } return ximg } // NewFileName uses the image package's decoder and converts a file specified // by fileName to an xgraphics.Image value. // Opening a file or decoding an image can cause an error. func NewFileName(X *xgbutil.XUtil, fileName string) (*Image, error) { srcReader, err := os.Open(fileName) if err != nil { return nil, err } defer srcReader.Close() img, _, err := image.Decode(srcReader) if err != nil { return nil, err } return NewConvert(X, img), nil } // NewBytes uses the image package's decoder to convert the bytes given to // an xgraphics.Imag value. // Decoding an image can cause an error. func NewBytes(X *xgbutil.XUtil, bs []byte) (*Image, error) { img, _, err := image.Decode(bytes.NewReader(bs)) if err != nil { return nil, err } return NewConvert(X, img), nil } // NewEwmhIcon converts EWMH icon data (ARGB) to an xgraphics.Image type. // You should probably use xgraphics.FindIcon instead of this directly. func NewEwmhIcon(X *xgbutil.XUtil, icon *ewmh.WmIcon) *Image { ximg := New(X, image.Rect(0, 0, int(icon.Width), int(icon.Height))) r := ximg.Rect width := r.Dx() var argb, x, y int for x = r.Min.X; x < r.Max.X; x++ { for y = r.Min.Y; y < r.Max.Y; y++ { argb = int(icon.Data[x+(y*width)]) ximg.SetBGRA(x, y, BGRA{ B: uint8(argb & 0x000000ff), G: uint8((argb & 0x0000ff00) >> 8), R: uint8((argb & 0x00ff0000) >> 16), A: uint8(argb >> 24), }) } } return ximg } // NewIcccmIcon converts two pixmap ids (icon_pixmap and icon_mask in the // WM_HINTS properts) to a single xgraphics.Image. // It is okay for one of iconPixmap or iconMask to be 0, but not both. // You should probably use xgraphics.FindIcon instead of this directly. func NewIcccmIcon(X *xgbutil.XUtil, iconPixmap, iconMask xproto.Pixmap) (*Image, error) { if iconPixmap == 0 && iconMask == 0 { return nil, fmt.Errorf("NewIcccmIcon: At least one of iconPixmap or " + "iconMask must be non-zero, but both are 0.") } var pximg, mximg *Image var err error // Get the xgraphics.Image for iconPixmap. if iconPixmap != 0 { pximg, err = NewDrawable(X, xproto.Drawable(iconPixmap)) if err != nil { return nil, err } } // Now get the xgraphics.Image for iconMask. if iconMask != 0 { mximg, err = NewDrawable(X, xproto.Drawable(iconMask)) if err != nil { return nil, err } } // Now merge them together if both were specified. switch { case pximg != nil && mximg != nil: r := pximg.Bounds() var x, y int var bgra, maskBgra BGRA for x = r.Min.X; x < r.Max.X; x++ { for y = r.Min.Y; y < r.Max.Y; y++ { maskBgra = mximg.At(x, y).(BGRA) bgra = pximg.At(x, y).(BGRA) if maskBgra.A == 0 { pximg.SetBGRA(x, y, BGRA{ B: bgra.B, G: bgra.G, R: bgra.R, A: 0, }) } } } return pximg, nil case pximg != nil: return pximg, nil case mximg != nil: return mximg, nil } panic("unreachable") } // NewDrawable converts an X drawable into a xgraphics.Image. // This is used in NewIcccmIcon. func NewDrawable(X *xgbutil.XUtil, did xproto.Drawable) (*Image, error) { // Get the geometry of the pixmap for use in the GetImage request. pgeom, err := xwindow.RawGeometry(X, xproto.Drawable(did)) if err != nil { return nil, err } // Get the image data for each pixmap. pixmapData, err := xproto.GetImage(X.Conn(), xproto.ImageFormatZPixmap, did, 0, 0, uint16(pgeom.Width()), uint16(pgeom.Height()), (1<<32)-1).Reply() if err != nil { return nil, err } // Now create the xgraphics.Image and populate it with data from // pixmapData and maskData. ximg := New(X, image.Rect(0, 0, pgeom.Width(), pgeom.Height())) // We'll try to be a little flexible with the image format returned, // but not completely flexible. err = readDrawableData(X, ximg, did, pixmapData, pgeom.Width(), pgeom.Height()) if err != nil { return nil, err } return ximg, nil } // readDrawableData uses Format information to read data from an X pixmap // into an xgraphics.Image. // readPixmapData does not take into account all information possible to read // X pixmaps and bitmaps. Of particular note is bit order/byte order. func readDrawableData(X *xgbutil.XUtil, ximg *Image, did xproto.Drawable, imgData *xproto.GetImageReply, width, height int) error { format := GetFormat(X, imgData.Depth) if format == nil { return fmt.Errorf("Could not find valid format for pixmap %d "+ "with depth %d", did, imgData.Depth) } switch format.Depth { case 1: // We read bitmaps in as alpha masks. if format.BitsPerPixel != 1 { return fmt.Errorf("The image returned for pixmap id %d with "+ "depth %d has an unsupported value for bits-per-pixel: %d", did, format.Depth, format.BitsPerPixel) } // Calculate the padded width of our image data. pad := int(X.Setup().BitmapFormatScanlinePad) paddedWidth := width if width%pad != 0 { paddedWidth = width + pad - (width % pad) } // Process one scanline at a time. Each 'y' represents a // single scanline. for y := 0; y < height; y++ { // Each scanline has length 'width' padded to // BitmapFormatScanlinePad, which is found in the X setup info. // 'i' is the index to the starting byte of the yth scanline. i := y * paddedWidth / 8 for x := 0; x < width; x++ { b := imgData.Data[i+x/8] >> uint(x%8) if b&1 > 0 { // opaque ximg.Set(x, y, BGRA{0x0, 0x0, 0x0, 0xff}) } else { // transparent ximg.Set(x, y, BGRA{0xff, 0xff, 0xff, 0x0}) } } } case 24, 32: switch format.BitsPerPixel { case 24: bytesPer := int(format.BitsPerPixel) / 8 var i int ximg.For(func(x, y int) BGRA { i = y*width*bytesPer + x*bytesPer return BGRA{ B: imgData.Data[i], G: imgData.Data[i+1], R: imgData.Data[i+2], A: 0xff, } }) case 32: bytesPer := int(format.BitsPerPixel) / 8 var i int ximg.For(func(x, y int) BGRA { i = y*width*bytesPer + x*bytesPer return BGRA{ B: imgData.Data[i], G: imgData.Data[i+1], R: imgData.Data[i+2], A: imgData.Data[i+3], } }) default: return fmt.Errorf("The image returned for pixmap id %d has "+ "an unsupported value for bits-per-pixel: %d", did, format.BitsPerPixel) } default: return fmt.Errorf("The image returned for pixmap id %d has an "+ "unsupported value for depth: %d", did, format.Depth) } return nil } // GetFormat searches SetupInfo for a Format matching the depth provided. func GetFormat(X *xgbutil.XUtil, depth byte) *xproto.Format { for _, pixForm := range X.Setup().PixmapFormats { if pixForm.Depth == depth { return &pixForm } } return nil } // getVisualInfo searches SetupInfo for a VisualInfo value matching // the depth provided. // XXX: This isn't used (yet). func getVisualInfo(X *xgbutil.XUtil, depth byte, visualid xproto.Visualid) *xproto.VisualInfo { for _, depthInfo := range X.Screen().AllowedDepths { fmt.Printf("%#v\n", depthInfo) // fmt.Printf("%#v\n", depthInfo.Visuals) fmt.Println("------------") if depthInfo.Depth == depth { for _, visual := range depthInfo.Visuals { if visual.VisualId == visualid { return &visual } } } } return nil } ================================================ FILE: xgraphics/text.go ================================================ package xgraphics import ( "image" "image/color" "io" "io/ioutil" "github.com/BurntSushi/freetype-go/freetype" "github.com/BurntSushi/freetype-go/freetype/truetype" ) // Text takes an image and, using the freetype package, writes text in the // position specified on to the image. A color.Color, a font size and a font // must also be specified. // Finally, the (x, y) coordinate advanced by the text extents is returned. // // Note that the ParseFont helper function can be used to get a *truetype.Font // value without having to import freetype-go directly. // // If you need more control over the 'context' used to draw text (like the DPI), // then you'll need to ignore this convenience method and use your own. func (im *Image) Text(x, y int, clr color.Color, fontSize float64, font *truetype.Font, text string) (int, int, error) { // Create a solid color image textClr := image.NewUniform(clr) // Set up the freetype context... mostly boiler plate c := ftContext(font, fontSize) c.SetClip(im.Bounds()) c.SetDst(im) c.SetSrc(textClr) // Now let's actually draw the text... pt := freetype.Pt(x, y+int(c.PointToFix32(fontSize)>>8)) newpt, err := c.DrawString(text, pt) if err != nil { return 0, 0, err } return int(newpt.X / 256), int(newpt.Y / 256), nil } // Extents returns the *correct* max width and height extents of a string // given a font. See freetype.MeasureString for the deets. func Extents(font *truetype.Font, fontSize float64, text string) (int, int) { c := ftContext(font, fontSize) w, h, err := c.MeasureString(text) if err != nil { return 0, 0 } return int(w / 256), int(h / 256) } // Returns the max width and height extents of a string given a font. // This is calculated by determining the number of pixels in an "em" unit // for the given font, and multiplying by the number of characters in 'text'. // Since a particular character may be smaller than one "em" unit, this has // a tendency to overestimate the extents. // It is provided because I do not know how to calculate the precise extents // using freetype-go. // TODO: This does not currently account for multiple lines. It may never do so. func TextMaxExtents(font *truetype.Font, fontSize float64, text string) (width int, height int) { c := ftContext(font, fontSize) emSquarePix := int(c.PointToFix32(fontSize) >> 8) return len(text) * emSquarePix, emSquarePix } // ftContext does the boiler plate to create a freetype context func ftContext(font *truetype.Font, fontSize float64) *freetype.Context { c := freetype.NewContext() c.SetDPI(72) c.SetFont(font) c.SetFontSize(fontSize) return c } // ParseFont reads a font file and creates a freetype.Font type func ParseFont(fontReader io.Reader) (*truetype.Font, error) { fontBytes, err := ioutil.ReadAll(fontReader) if err != nil { return nil, err } font, err := freetype.ParseFont(fontBytes) if err != nil { return nil, err } return font, nil } // MustFont panics if err is not nil or if the font is nil. func MustFont(font *truetype.Font, err error) *truetype.Font { if err != nil { panic(err) } if font == nil { panic("font is nil") } return font } ================================================ FILE: xgraphics/util.go ================================================ package xgraphics import ( "fmt" "image" "image/color" "image/draw" "math" "github.com/BurntSushi/graphics-go/graphics" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/ewmh" "github.com/BurntSushi/xgbutil/icccm" ) /* xgraphics/util.go contains a variety of image manipulation functions that are not specific to xgraphics.Image. */ // Scale is a simple wrapper around graphics.Scale. func Scale(img image.Image, width, height int) draw.Image { dimg := image.NewRGBA(image.Rect(0, 0, width, height)) graphics.Scale(dimg, img) return dimg } // Alpha will modify the alpha channel of the image such that: // existingAlpha = existingAlpha * (givenAlpha / 100.0) func Alpha(dest *Image, alpha int) { r := dest.Bounds() var a, x, y, i int for x = r.Min.X; x < r.Max.X; x++ { for y = r.Min.Y; y < r.Max.Y; y++ { i = dest.PixOffset(x, y) a = int(dest.Pix[i+3]) dest.Pix[i+3] = uint8((a * alpha) / 100) } } } // Blend alpha blends the src image (starting at the spt Point) into the // dest image. // If you're blending into a solid background color, use BlendBgColor // instead. (It's more efficient.) // Blend does not (currently) blend with the destination's alpha channel, // only the source's alpha channel. func Blend(dest *Image, src image.Image, sp image.Point) { rsrc, dsrc := src.Bounds(), dest.Bounds() _, smxx, _, smxy := rsrc.Min.X, rsrc.Max.X, rsrc.Min.Y, rsrc.Max.Y dmnx, dmxx, dmny, dmxy := dsrc.Min.X, dsrc.Max.X, dsrc.Min.Y, dsrc.Max.Y var sx, dx, sy, dy int var sr, sg, sb, sa uint32 var bgra BGRA var alpha float64 for sx, dx = sp.X, dmnx; sx < smxx && dx < dmxx; sx, dx = sx+1, dx+1 { for sy, dy = sp.Y, dmny; sy < smxy && dy < dmxy; sy, dy = sy+1, dy+1 { sr, sg, sb, sa = src.At(sx, sy).RGBA() bgra = dest.At(dx, dy).(BGRA) alpha = float64(uint8(sa)) / 255.0 dest.SetBGRA(dx, dy, BGRA{ blend(uint8(bgra.B), uint8(sb), alpha), blend(uint8(bgra.G), uint8(sg), alpha), blend(uint8(bgra.R), uint8(sr), alpha), 0xff, }) } } } // BlendBgColor blends the Image (receiver) into the background color // specified. This is more efficient than creating a background image and // blending with Blend. func BlendBgColor(dest *Image, c color.Color) { r := dest.Bounds() cr32, cg32, cb32, _ := c.RGBA() cr, cg, cb := uint8(cr32), uint8(cg32), uint8(cb32) var bgra BGRA var alpha float64 for x := r.Min.X; x < r.Max.X; x++ { for y := r.Min.Y; y < r.Max.Y; y++ { bgra = dest.At(x, y).(BGRA) alpha = float64(bgra.A) / 255.0 dest.SetBGRA(x, y, BGRA{ B: blend(cb, bgra.B, alpha), G: blend(cg, bgra.G, alpha), R: blend(cr, bgra.R, alpha), A: 0xff, }) } } } // Blend returns the blended alpha color for src and dest colors. // This assumes that the destination has alpha = 1. func BlendBGRA(dest, src BGRA) BGRA { alpha := float64(src.A) / 255.0 return BGRA{ B: blend(dest.B, src.B, alpha), G: blend(dest.G, src.G, alpha), R: blend(dest.R, src.R, alpha), A: 0xff, } } // blend calculates the value of a color given some alpha value in [0, 1] // and a source and destination color. Note that this assumes that the // destination is fully opaque (has an alpha value of 1). func blend(d, s uint8, alpha float64) uint8 { return uint8(float64(s)*alpha + float64(d)*(1-alpha)) } // FreePixmap is a convenience function for destroying a pixmap resource // on the X server. // If you're using an xgraphics.Image value, then its Destroy method will call // this for you. func FreePixmap(X *xgbutil.XUtil, pixid xproto.Pixmap) { xproto.FreePixmap(X.Conn(), pixid) } // FindIcon takes a window id and attempts to return an xgraphics.Image of // that window's icon. // It will first try to look for an icon in _NET_WM_ICON that is closest to // the size specified. // If there are no icons in _NET_WM_ICON, then WM_HINTS will be checked for // an icon. // If an icon is found from either one and doesn't match the size // specified, it will be scaled to that size. // If the width and height are 0, then the largest icon will be returned with // no scaling. // If an icon is not found, an error is returned. func FindIcon(X *xgbutil.XUtil, wid xproto.Window, width, height int) (*Image, error) { var ewmhErr, icccmErr error // First try to get a EWMH style icon. icon, ewmhErr := findIconEwmh(X, wid, width, height) if ewmhErr != nil { // now look for an icccm-style icon icon, icccmErr = findIconIcccm(X, wid) if icccmErr != nil { return nil, fmt.Errorf("Neither a EWMH-style or ICCCM-style icon "+ "could be found for window id %x because: %s *AND* %s", wid, ewmhErr, icccmErr) } } // We should have a valid xgraphics.Image if we're here. // If the size doesn't match what's preferred, scale it. if width != 0 && height != 0 { if icon.Bounds().Dx() != width || icon.Bounds().Dy() != height { icon = icon.Scale(width, height) } } return icon, nil } // findIconEwmh helps FindIcon by trying to return an ewmh-style icon that is // closest to the preferred size specified. func findIconEwmh(X *xgbutil.XUtil, wid xproto.Window, width, height int) (*Image, error) { icons, err := ewmh.WmIconGet(X, wid) if err != nil { return nil, err } icon := FindBestEwmhIcon(width, height, icons) if icon == nil { return nil, fmt.Errorf("Could not find any _NET_WM_ICON icon.") } return NewEwmhIcon(X, icon), nil } // findIconIcccm helps FindIcon by trying to return an icccm-style icon. func findIconIcccm(X *xgbutil.XUtil, wid xproto.Window) (*Image, error) { hints, err := icccm.WmHintsGet(X, wid) if err != nil { return nil, err } // Only continue if the WM_HINTS flags say an icon is specified and // if at least one of icon pixmap or icon mask is non-zero. if hints.Flags&icccm.HintIconPixmap == 0 || (hints.IconPixmap == 0 && hints.IconMask == 0) { return nil, fmt.Errorf("No icon found in WM_HINTS.") } return NewIcccmIcon(X, hints.IconPixmap, hints.IconMask) } // FindBestEwmhIcon takes width/height dimensions and a slice of *ewmh.WmIcon // and finds the best matching icon of the bunch. We always prefer bigger. // If no icons are bigger than the preferred dimensions, use the biggest // available. Otherwise, use the smallest icon that is greater than or equal // to the preferred dimensions. The preferred dimensions is essentially // what you'll likely scale the resulting icon to. // If width and height are 0, then the largest icon found will be returned. func FindBestEwmhIcon(width, height int, icons []ewmh.WmIcon) *ewmh.WmIcon { // nada nada limonada if len(icons) == 0 { return nil } parea := width * height // preferred size best := -1 // If zero area, set it to the largest possible. if parea == 0 { parea = math.MaxInt32 } var bestArea, iconArea int for i, icon := range icons { // the first valid icon we've seen; use it! if best == -1 { best = i continue } // load areas for comparison bestArea = int(icons[best].Width * icons[best].Height) iconArea = int(icon.Width * icon.Height) // We don't always want to accept bigger icons if our best is // already bigger. But we always want something bigger if our best // is insufficient. if (iconArea >= parea && iconArea <= bestArea) || (bestArea < parea && iconArea > bestArea) { best = i } } if best > -1 { return &icons[best] } return nil } ================================================ FILE: xgraphics/xsurface.go ================================================ package xgraphics import ( "fmt" "image" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/ewmh" "github.com/BurntSushi/xgbutil/icccm" "github.com/BurntSushi/xgbutil/keybind" "github.com/BurntSushi/xgbutil/mousebind" "github.com/BurntSushi/xgbutil/xevent" "github.com/BurntSushi/xgbutil/xwindow" ) /* xgraphics/xsurface.go contains methods for the Image type that perform X related requests. Namely, methods that send image data start with 'X'. */ // XSurfaceSet will set the given window's background to this image's pixmap. // Note that an image can have multiple surfaces, which is why the window // id still needs to be passed to XPaint. A call to XSurfaceSet simply tells // X that the window specified should use the pixmap in Image as its // background image. // Note that XSurfaceSet cannot be called on a sub-image. (An error will be // returned if you do.) // XSurfaceSet will also allocate an X pixmap if one hasn't been created for // this image yet. // (Generating a pixmap id can cause an error, so this call could return // an error.) func (im *Image) XSurfaceSet(wid xproto.Window) error { if im.Subimg { return fmt.Errorf("XSurfaceSet cannot be called on sub-images." + "Please set the surface using the original parent image.") } if im.Pixmap == 0 { if err := im.CreatePixmap(); err != nil { return err } } // Tell the surface (window) to use this pixmap. xproto.ChangeWindowAttributes(im.X.Conn(), wid, xproto.CwBackPixmap, []uint32{uint32(im.Pixmap)}) return nil } // CreatePixmap allocates an X resource identifier for a pixmap. (It does not // do any drawing.) You only need to call this if you're using XDraw/XExpPaint. // If you're using XSurfaceSet/XDraw/XPaint, then CreatePixmap is called for // you automatically. func (im *Image) CreatePixmap() error { // Generate the pixmap id. pid, err := xproto.NewPixmapId(im.X.Conn()) if err != nil { return err } // Now actually create the pixmap. err = xproto.CreatePixmapChecked(im.X.Conn(), im.X.Screen().RootDepth, pid, xproto.Drawable(im.X.RootWin()), uint16(im.Bounds().Dx()), uint16(im.Bounds().Dy())).Check() if err != nil { return err } // Now give it to the image. im.Pixmap = pid return nil } // XPaint will write the contents of the pixmap to a window. // Note that painting will do nothing if XDraw hasn't been called. // XPaint is what switches the buffer (drawn to using XDraw) into the window // to be visible. That is, multiple calls to XDraw can be made, and the screen // will only be updated once with a call to XPaint. func (im *Image) XPaint(wid xproto.Window) { // We clear the whole window here because sometimes we rely on the tiling // of a background pixmap. If anyone knows if this is a significant // performance problem, please let me know. (It seems like the whole area // of the window is cleared when it is resized anyway.) xproto.ClearArea(im.X.Conn(), false, wid, 0, 0, 0, 0) } // XExpPaint achieves a similar result as XPaint and XSurfaceSet, but // uses CopyArea instead of setting a background pixmap and using ClearArea. // CreatePixmap must be called before using XExpPaint. // XExpPaint can be called on sub-images. // x and y correspond to the destination x and y to copy the image to. // // This should not be used on the same image with XSurfaceSet and XPaint. func (im *Image) XExpPaint(wid xproto.Window, x, y int) { if im.Pixmap == 0 { return } xproto.CopyArea(im.X.Conn(), xproto.Drawable(im.Pixmap), xproto.Drawable(wid), im.X.GC(), int16(im.Rect.Min.X), int16(im.Rect.Min.Y), int16(x), int16(y), uint16(im.Rect.Dx()), uint16(im.Rect.Dy())) } // XPaintRects is a convenience function for issuing XDraw requests on // each sub-image generated by the rects in the slice provided, and then // painting the updated pixmap all at once to the window provided. // This is efficient because no pixels are copied when taking a SubImage, // and each XDraw call on a sub-image updates the pixels represented by that // sub-image and only that sub-image. func (im *Image) XPaintRects(wid xproto.Window, rects ...image.Rectangle) { for _, rect := range rects { if si := im.SubImage(rect).(*Image); si != nil { si.XDraw() } } im.XPaint(wid) } // XDraw will write the contents of Image to a pixmap. // Note that this is more like a buffer. Drawing does not put the contents // on the screen. // After drawing, it is necessary to call XPaint to put the contents somewhere. // Draw may return an X error if something has gone horribly wrong. // // XSurfaceSet should be called before XDraw. (If not, X will yell at you.) // More specifically, CreatePixmap needs to be called before XDraw, but it is // done automatically in XSurfaceSet. // // If you're using sub-images to update a particular region of the image, XDraw // is where you'll see the performance benefit (not XPaint). func (im *Image) XDraw() { im.xdraw(false) } // XDrawChecked is the same as XDraw, but issues PutImageChecked requests // instead. This should *only* be used for debugging purposes, as each // PutImageChecked request blocks for a round trip to the X server. func (im *Image) XDrawChecked() error { return im.xdraw(true) } func (im *Image) xdraw(checked bool) error { width, height := im.Rect.Dx(), im.Rect.Dy() // Put the raw image data into its own slice. // If this isn't a sub-image, then skip because it isn't necessary. var data []uint8 if !im.Subimg { data = im.Pix } else { data = make([]uint8, width*height*4) for y := im.Rect.Min.Y; y < im.Rect.Max.Y; y++ { i := (y - im.Rect.Min.Y) * width * 4 copy(data[i:i+4*width], im.Pix[im.PixOffset(im.Rect.Min.X, y):]) } } // X's max request size (by default) is (2^16) * 4 = 262144 bytes, which // corresponds precisely to a 256x256 sized image with 32 bits per pixel. // Thus, we check the size of the image data and calculate the number of // rows of the image we'll send in each request. If a single row of an // image exceeds the max request length, we're in trouble. N.B. The // constant 28 comes from the fixed size part of a PutImage request. rowsPer := (xgbutil.MaxReqSize - 28) / (width * 4) bytesPer := rowsPer * width * 4 // The start x position of what we're sending. Doesn't change. xpos := im.Rect.Min.X // The start y position of what we're sending. Increases based on the // number of rows of the image we send in each request. ypos := im.Rect.Min.Y // The height of each PutImage request. It's always rowsPer, unless its // the last request and we're not sending the maximum number of bytes. heightPer := 0 // The start and end positions of the raw bytes being sent. start, end := 0, 0 // The sliced data we're sending, for convenience. var toSend []byte for end < len(data) { end = start + bytesPer if end > len(data) { // make sure end doesn't extend beyond data end = len(data) } toSend = data[start:end] heightPer = len(toSend) / 4 / width if checked { err := xproto.PutImageChecked( im.X.Conn(), xproto.ImageFormatZPixmap, xproto.Drawable(im.Pixmap), im.X.GC(), uint16(width), uint16(heightPer), int16(xpos), int16(ypos), 0, 24, toSend).Check() if err != nil { return err } } else { xproto.PutImage(im.X.Conn(), xproto.ImageFormatZPixmap, xproto.Drawable(im.Pixmap), im.X.GC(), uint16(width), uint16(heightPer), int16(xpos), int16(ypos), 0, 24, toSend) } start = end ypos += rowsPer } return nil } // XShow creates a new window and paints the image to the window. // This is useful for debugging, or if you're creating an image viewer. // XShow also returns the xwindow.Window value, in case you want to do // further processing. (Like attach event handlers.) func (im *Image) XShow() *xwindow.Window { return im.XShowExtra("", false) } // XShowName is just like XShow, except it sets the name of the window to the // name provided, and will quit the current event loop if 'quit' is true when // the window is closed. // If name is empty and quit is false, then the behavior is precisely the same // as XShow. func (im *Image) XShowExtra(name string, quit bool) *xwindow.Window { if len(name) == 0 { name = "xgbutil Image Window" } w, h := im.Rect.Dx(), im.Rect.Dy() win, err := xwindow.Generate(im.X) if err != nil { xgbutil.Logger.Printf("Could not generate new window id: %s", err) return nil } // Create a very simple window with dimensions equal to the image. win.Create(im.X.RootWin(), 0, 0, w, h, 0) // Make this window close gracefully. win.WMGracefulClose(func(w *xwindow.Window) { xevent.Detach(w.X, w.Id) keybind.Detach(w.X, w.Id) mousebind.Detach(w.X, w.Id) w.Destroy() if quit { xevent.Quit(w.X) } }) // Set WM_STATE so it is interpreted as a top-level window. err = icccm.WmStateSet(im.X, win.Id, &icccm.WmState{ State: icccm.StateNormal, }) if err != nil { // not a fatal error xgbutil.Logger.Printf("Could not set WM_STATE: %s", err) } // Set WM_NORMAL_HINTS so the window can't be resized. err = icccm.WmNormalHintsSet(im.X, win.Id, &icccm.NormalHints{ Flags: icccm.SizeHintPMinSize | icccm.SizeHintPMaxSize, MinWidth: uint(w), MinHeight: uint(h), MaxWidth: uint(w), MaxHeight: uint(h), }) if err != nil { // not a fatal error xgbutil.Logger.Printf("Could not set WM_NORMAL_HINTS: %s", err) } // Set _NET_WM_NAME so it looks nice. err = ewmh.WmNameSet(im.X, win.Id, name) if err != nil { // not a fatal error xgbutil.Logger.Printf("Could not set _NET_WM_NAME: %s", err) } // Paint our image before mapping. im.XSurfaceSet(win.Id) im.XDraw() im.XPaint(win.Id) // Now we can map, since we've set all our properties. // (The initial map is when the window manager starts managing.) win.Map() return win } ================================================ FILE: xinerama/doc.go ================================================ /* Package xinerama provides a convenience function to retrieve the geometry of all active heads sorted in order from left to right and then top to bottom. While Xinerama is an old extension that isn't often used in lieu of RandR and TwinView, it can still be used to query for information about all active heads. That is, even if TwinView or RandR is being used, Xinerama will still report the correct geometry of each head. */ package xinerama ================================================ FILE: xinerama/xinerama.go ================================================ package xinerama import "sort" import ( "github.com/BurntSushi/xgb/xinerama" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/xrect" ) // Alias so we use it as a receiver to satisfy sort.Interface type Heads []xrect.Rect // Len satisfies 'Len' in sort.Interface. func (hds Heads) Len() int { return len(hds) } // Less satisfies 'Less' in sort.Interface. func (hds Heads) Less(i int, j int) bool { return hds[i].X() < hds[j].X() || (hds[i].X() == hds[j].X() && hds[i].Y() < hds[j].Y()) } // Swap does just that. Nothing to see here... func (hds Heads) Swap(i int, j int) { hds[i], hds[j] = hds[j], hds[i] } // PhyiscalHeads returns the list of heads in a physical ordering. // Namely, left to right then top to bottom. (Defined by (X, Y).) // Xinerama must have been initialized, otherwise the xinerama.QueryScreens // request will panic. // PhysicalHeads also checks to make sure each rectangle has a unique (x, y) // tuple, so as not to return the geometry of cloned displays. // (At present moment, xgbutil initializes Xinerama automatically during // initial connection.) func PhysicalHeads(xu *xgbutil.XUtil) (Heads, error) { xinfo, err := xinerama.QueryScreens(xu.Conn()).Reply() if err != nil { return nil, err } hds := make(Heads, 0) for _, info := range xinfo.ScreenInfo { head := xrect.New(int(info.XOrg), int(info.YOrg), int(info.Width), int(info.Height)) // Maybe Xinerama is enabled, but we have cloned displays... unique := true for _, h := range hds { if h.X() == head.X() && h.Y() == head.Y() { unique = false break } } if unique { hds = append(hds, head) } } sort.Sort(hds) return hds, nil } ================================================ FILE: xprop/atom.go ================================================ package xprop /* xprop/atom.go contains functions related to interning atoms and retrieving atom names from an atom identifier. It also manages an atom cache so that once an atom is interned from the X server, all future atom interns use that value. (So that one and only one request is sent for interning each atom.) */ import ( "fmt" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" ) // Atm is a short alias for Atom in the common case of interning an atom. // Namely, interning the atom always succeeds. (If the atom does not already // exist, a new one is created.) func Atm(xu *xgbutil.XUtil, name string) (xproto.Atom, error) { aid, err := Atom(xu, name, false) if err != nil { return 0, err } if aid == 0 { return 0, fmt.Errorf("Atm: '%s' returned an identifier of 0.", name) } return aid, err } // Atom interns an atom and panics if there is any error. func Atom(xu *xgbutil.XUtil, name string, onlyIfExists bool) (xproto.Atom, error) { // Check the cache first if aid, ok := atomGet(xu, name); ok { return aid, nil } reply, err := xproto.InternAtom(xu.Conn(), onlyIfExists, uint16(len(name)), name).Reply() if err != nil { return 0, fmt.Errorf("Atom: Error interning atom '%s': %s", name, err) } // If we're here, it means we didn't have this atom cached. So cache it! cacheAtom(xu, name, reply.Atom) return reply.Atom, nil } // AtomName fetches a string representation of an ATOM given its integer id. func AtomName(xu *xgbutil.XUtil, aid xproto.Atom) (string, error) { // Check the cache first if atomName, ok := atomNameGet(xu, aid); ok { return string(atomName), nil } reply, err := xproto.GetAtomName(xu.Conn(), aid).Reply() if err != nil { return "", fmt.Errorf("AtomName: Error fetching name for ATOM "+ "id '%d': %s", aid, err) } // If we're here, it means we didn't have ths ATOM id cached. So cache it. atomName := string(reply.Name) cacheAtom(xu, atomName, aid) return atomName, nil } // atomGet retrieves an atom identifier from a cache if it exists. func atomGet(xu *xgbutil.XUtil, name string) (xproto.Atom, bool) { xu.AtomsLck.RLock() defer xu.AtomsLck.RUnlock() aid, ok := xu.Atoms[name] return aid, ok } // atomNameGet retrieves an atom name from a cache if it exists. func atomNameGet(xu *xgbutil.XUtil, aid xproto.Atom) (string, bool) { xu.AtomNamesLck.RLock() defer xu.AtomNamesLck.RUnlock() name, ok := xu.AtomNames[aid] return name, ok } // cacheAtom puts an atom into the cache. func cacheAtom(xu *xgbutil.XUtil, name string, aid xproto.Atom) { xu.AtomsLck.Lock() xu.AtomNamesLck.Lock() defer xu.AtomsLck.Unlock() defer xu.AtomNamesLck.Unlock() xu.Atoms[name] = aid xu.AtomNames[aid] = name } ================================================ FILE: xprop/doc.go ================================================ /* Package xprop provides a cache for interning atoms and helper functions for dealing with GetProperty and ChangeProperty X requests. Atoms Atoms in X are interned, meaning that strings are assigned unique integer identifiers. This minimizes the amount of data transmitted over an X connection. Once atoms have been interned, they are never changed while the X server is running. xgbutil takes advantage of this invariant and will only issue an intern atom request once and cache the result. To use the xprop package to intern an atom, use Atom: atom, err := xprop.Atom(XUtilValue, "THE_ATOM_NAME", false) if err == nil { println("The atom number: ", atom.Atom) } The 'false' parameter corresponds to the 'only_if_exists' parameter of the X InternAtom request. When it's false, the atom being interned always returns a non-zero atom number---even if the string being interned hasn't been interned before. If 'only_if_exists' is true, the atom being interned will return a 0 atom number if it hasn't already been interned. The typical case is to set 'only_if_exists' to false. To this end, xprop.Atm is an alias that always sets this value to false. The reverse can also be done: getting an atom string if you have an atom number. This can be done with the xprop.AtomName function. Properties The other facility of xprop is to help with the use of GetProperty and ChangeProperty. Please see the source code of the ewmh package for plenty of examples. */ package xprop ================================================ FILE: xprop/xprop.go ================================================ package xprop import ( "fmt" "github.com/BurntSushi/xgb" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" ) // GetProperty abstracts the messiness of calling xgb.GetProperty. func GetProperty(xu *xgbutil.XUtil, win xproto.Window, atom string) ( *xproto.GetPropertyReply, error) { atomId, err := Atm(xu, atom) if err != nil { return nil, err } reply, err := xproto.GetProperty(xu.Conn(), false, win, atomId, xproto.GetPropertyTypeAny, 0, (1<<32)-1).Reply() if err != nil { return nil, fmt.Errorf("GetProperty: Error retrieving property '%s' "+ "on window %x: %s", atom, win, err) } if reply.Format == 0 { return nil, fmt.Errorf("GetProperty: No such property '%s' on "+ "window %x.", atom, win) } return reply, nil } // ChangeProperty abstracts the semi-nastiness of xgb.ChangeProperty. func ChangeProp(xu *xgbutil.XUtil, win xproto.Window, format byte, prop string, typ string, data []byte) error { propAtom, err := Atm(xu, prop) if err != nil { return err } typAtom, err := Atm(xu, typ) if err != nil { return err } return xproto.ChangePropertyChecked(xu.Conn(), xproto.PropModeReplace, win, propAtom, typAtom, format, uint32(len(data)/(int(format)/8)), data).Check() } // ChangeProperty32 makes changing 32 bit formatted properties easier // by constructing the raw X data for you. func ChangeProp32(xu *xgbutil.XUtil, win xproto.Window, prop string, typ string, data ...uint) error { buf := make([]byte, len(data)*4) for i, datum := range data { xgb.Put32(buf[(i*4):], uint32(datum)) } return ChangeProp(xu, win, 32, prop, typ, buf) } // WindowToUint is a covenience function for converting []xproto.Window // to []uint. func WindowToInt(ids []xproto.Window) []uint { ids32 := make([]uint, len(ids)) for i, v := range ids { ids32[i] = uint(v) } return ids32 } // AtomToInt is a covenience function for converting []xproto.Atom // to []uint. func AtomToUint(ids []xproto.Atom) []uint { ids32 := make([]uint, len(ids)) for i, v := range ids { ids32[i] = uint(v) } return ids32 } // StrToAtoms is a convenience function for converting // []string to []uint32 atoms. // NOTE: If an atom name in the list doesn't exist, it will be created. func StrToAtoms(xu *xgbutil.XUtil, atomNames []string) ([]uint, error) { var err error atoms := make([]uint, len(atomNames)) for i, atomName := range atomNames { a, err := Atom(xu, atomName, false) if err != nil { return nil, err } atoms[i] = uint(a) } return atoms, err } // PropValAtom transforms a GetPropertyReply struct into an ATOM name. // The property reply must be in 32 bit format. func PropValAtom(xu *xgbutil.XUtil, reply *xproto.GetPropertyReply, err error) (string, error) { if err != nil { return "", err } if reply.Format != 32 { return "", fmt.Errorf("PropValAtom: Expected format 32 but got %d", reply.Format) } return AtomName(xu, xproto.Atom(xgb.Get32(reply.Value))) } // PropValAtoms is the same as PropValAtom, except that it returns a slice // of atom names. Also must be 32 bit format. // This is a method of an XUtil struct, unlike the other 'PropVal...' functions. func PropValAtoms(xu *xgbutil.XUtil, reply *xproto.GetPropertyReply, err error) ([]string, error) { if err != nil { return nil, err } if reply.Format != 32 { return nil, fmt.Errorf("PropValAtoms: Expected format 32 but got %d", reply.Format) } ids := make([]string, reply.ValueLen) vals := reply.Value for i := 0; len(vals) >= 4; i++ { ids[i], err = AtomName(xu, xproto.Atom(xgb.Get32(vals))) if err != nil { return nil, err } vals = vals[4:] } return ids, nil } // PropValWindow transforms a GetPropertyReply struct into an X resource // window identifier. // The property reply must be in 32 bit format. func PropValWindow(reply *xproto.GetPropertyReply, err error) (xproto.Window, error) { if err != nil { return 0, err } if reply.Format != 32 { return 0, fmt.Errorf("PropValId: Expected format 32 but got %d", reply.Format) } return xproto.Window(xgb.Get32(reply.Value)), nil } // PropValWindows is the same as PropValWindow, except that it returns a slice // of identifiers. Also must be 32 bit format. func PropValWindows(reply *xproto.GetPropertyReply, err error) ([]xproto.Window, error) { if err != nil { return nil, err } if reply.Format != 32 { return nil, fmt.Errorf("PropValIds: Expected format 32 but got %d", reply.Format) } ids := make([]xproto.Window, reply.ValueLen) vals := reply.Value for i := 0; len(vals) >= 4; i++ { ids[i] = xproto.Window(xgb.Get32(vals)) vals = vals[4:] } return ids, nil } // PropValNum transforms a GetPropertyReply struct into an unsigned // integer. Useful when the property value is a single integer. func PropValNum(reply *xproto.GetPropertyReply, err error) (uint, error) { if err != nil { return 0, err } if reply.Format != 32 { return 0, fmt.Errorf("PropValNum: Expected format 32 but got %d", reply.Format) } return uint(xgb.Get32(reply.Value)), nil } // PropValNums is the same as PropValNum, except that it returns a slice // of integers. Also must be 32 bit format. func PropValNums(reply *xproto.GetPropertyReply, err error) ([]uint, error) { if err != nil { return nil, err } if reply.Format != 32 { return nil, fmt.Errorf("PropValIds: Expected format 32 but got %d", reply.Format) } nums := make([]uint, reply.ValueLen) vals := reply.Value for i := 0; len(vals) >= 4; i++ { nums[i] = uint(xgb.Get32(vals)) vals = vals[4:] } return nums, nil } // PropValNum64 transforms a GetPropertyReply struct into a 64 bit // integer. Useful when the property value is a single integer. func PropValNum64(reply *xproto.GetPropertyReply, err error) (int64, error) { if err != nil { return 0, err } if reply.Format != 32 { return 0, fmt.Errorf("PropValNum: Expected format 32 but got %d", reply.Format) } return int64(xgb.Get32(reply.Value)), nil } // PropValStr transforms a GetPropertyReply struct into a string. // Useful when the property value is a null terminated string represented // by integers. Also must be 8 bit format. func PropValStr(reply *xproto.GetPropertyReply, err error) (string, error) { if err != nil { return "", err } if reply.Format != 8 { return "", fmt.Errorf("PropValStr: Expected format 8 but got %d", reply.Format) } return string(reply.Value), nil } // PropValStrs is the same as PropValStr, except that it returns a slice // of strings. The raw byte string is a sequence of null terminated strings, // which is translated into a slice of strings. func PropValStrs(reply *xproto.GetPropertyReply, err error) ([]string, error) { if err != nil { return nil, err } if reply.Format != 8 { return nil, fmt.Errorf("PropValStrs: Expected format 8 but got %d", reply.Format) } var strs []string sstart := 0 for i, c := range reply.Value { if c == 0 { strs = append(strs, string(reply.Value[sstart:i])) sstart = i + 1 } } if sstart < int(reply.ValueLen) { strs = append(strs, string(reply.Value[sstart:])) } return strs, nil } ================================================ FILE: xrect/doc.go ================================================ /* Package xrect defines a Rect interface and an XRect type implementing the Rect interface for working with X rectangles. Namely, X rectangles are specified by the 4-tuple (x, y, width, height) where the origin is the top-left corner and the width and height *must* be non-zero. Some of the main features of this package include finding the area of intersection of two rectangles, finding the largest overlap between some rectangle and a set of rectangles, applying partial struts to rectangles representing all active heads, and a function to subtract two rectangles. */ package xrect ================================================ FILE: xrect/xrect.go ================================================ package xrect import "fmt" // Define a base and simple Rect interface. type Rect interface { X() int Y() int Width() int Height() int XSet(x int) YSet(y int) WidthSet(width int) HeightSet(height int) Pieces() (int, int, int, int) } // RectPieces just returns a four-tuple of x, y, width and height func RectPieces(xr Rect) (int, int, int, int) { return xr.X(), xr.Y(), xr.Width(), xr.Height() } func Pieces(xr Rect) (int, int, int, int) { return RectPieces(xr) } // Provide a simple implementation of a rect. // Maybe this will be all we need? type XRect struct { x, y int width, height int } // Provide the ability to construct an XRect. func New(x, y, w, h int) *XRect { return &XRect{x, y, w, h} } func (r *XRect) String() string { return fmt.Sprintf("[(%d, %d) %dx%d]", r.x, r.y, r.width, r.height) } // Satisfy the Rect interface func (r *XRect) X() int { return r.x } func (r *XRect) Y() int { return r.y } func (r *XRect) Width() int { return r.width } func (r *XRect) Height() int { return r.height } func (r *XRect) XSet(x int) { r.x = x } func (r *XRect) YSet(y int) { r.y = y } func (r *XRect) WidthSet(width int) { r.width = width } func (r *XRect) HeightSet(height int) { r.height = height } // Pieces just returns a four-tuple of x, y, width and height func (r *XRect) Pieces() (int, int, int, int) { return r.X(), r.Y(), r.Width(), r.Height() } // Valid returns whether a rectangle is valid or not. i.e., a width AND height // not equal to zero. func Valid(r Rect) bool { return r.Width() != 0 && r.Height() != 0 } // Subtract subtracts r2 from r1 and returns the result as a // new slice of Rects. // Basically, rectangle subtraction works by cutting r2 out of r1, and returning // the resulting rectangles. // If r1 does not overlap r2, then only one rectangle is returned and is // equivalent to r1. // If r2 covers r1, then no rectangles are returned. // If r1 covers r2, then four rectangles are returned. // If r2 partially overlaps r1, then one, two or three rectangles are returned. func Subtract(r1 Rect, r2 Rect) []Rect { r1x1, r1y1, r1w, r1h := r1.Pieces() r2x1, r2y1, r2w, r2h := r2.Pieces() r1x2, r1y2 := r1x1+r1w, r1y1+r1h r2x2, r2y2 := r2x1+r2w, r2y1+r2h // No intersection; return r1. if r2x1 >= r1x2 || r1x1 >= r2x2 || r2y1 >= r1y2 || r1y1 >= r2y2 { return []Rect{New(r1x1, r1y1, r1w, r1h)} } // r2 covers r1; so subtraction yields no rectangles. if r1x1 >= r2x1 && r1y1 >= r2y1 && r1x2 <= r2x2 && r1y2 <= r2y2 { return []Rect{} } // Now generate each of the four possible rectangles and add them only // if they are valid (i.e., width/height >= 1) result := make([]Rect, 0, 4) rect1 := New(r1x1, r1y1, r1w, r2y1-r1y1) rect2 := New(r1x1, r1y1, r2x1-r1x1, r1h) rect3 := New(r1x1, r2y2, r1w, r1h-((r2y1-r1y1)+r2h)) rect4 := New(r2x2, r1y1, r1w-((r2x1-r1x1)+r2w), r1h) if Valid(rect1) { result = append(result, rect1) } if Valid(rect2) { result = append(result, rect2) } if Valid(rect3) { result = append(result, rect3) } if Valid(rect4) { result = append(result, rect4) } return result } // IntersectArea takes two rectangles satisfying the Rect interface and // returns the area of their intersection. If there is no intersection, return // 0 area. func IntersectArea(r1 Rect, r2 Rect) int { x1, y1, w1, h1 := RectPieces(r1) x2, y2, w2, h2 := RectPieces(r2) if x2 < x1+w1 && x2+w2 > x1 && y2 < y1+h1 && y2+h2 > y1 { iw := min(x1+w1-1, x2+w2-1) - max(x1, x2) + 1 ih := min(y1+h1-1, y2+h2-1) - max(y1, y2) + 1 return iw * ih } return 0 } // LargestOverlap returns the index of the rectangle in 'haystack' that has the // largest overlap with the rectangle 'needle'. // This is commonly used to find which monitor a window should belong on. // (Since it can technically be partially displayed on more than one monitor // at a time.) // Be careful, the return value can be -1 if there is no overlap. func LargestOverlap(needle Rect, haystack []Rect) int { biggestArea := 0 reti := -1 var area int for i, possible := range haystack { area = IntersectArea(needle, possible) if area > biggestArea { biggestArea = area reti = i } } return reti } // ApplyStrut takes a list of Rects (typically the rectangles that represent // each physical head in this case), the root window geometry, // and a set of parameters representing a // strut, and modifies the list of Rects to account for that strut. // That is, it shrinks each rect. // Note that if struts overlap, the *most restrictive* one is used. This seems // like the most sensible response to a weird scenario. // (If you don't have a partial strut, just use '0' for the extra fields.) // See xgbutil/examples/workarea-struts for an example of how to use this to // get accurate workarea for each physical head. func ApplyStrut(rects []Rect, rootWidth, rootHeight uint, left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x uint) { var nx, ny uint // 'n*' are new values that may or may not be used var nw, nh uint var x_, y_, w_, h_ int var x, y, w, h uint var bt, tp, lt, rt bool rWidth, rHeight := rootWidth, rootHeight // The essential idea of struts, and particularly partial struts, is that // one piece of a border of the screen can be "reserved" for some // special windows like docks, panels, taskbars and system trays. // Since we assume that one window can only reserve one piece of a border // (either top, left, right or bottom), we iterate through each rect // in our list and check if that rect is affected by the given strut. // If it is, we modify the current rect appropriately. // TODO: Fix this so old school _NET_WM_STRUT can work too. It actually // should be pretty simple: change conditions like 'if tp' to // 'if tp || (top_start_x == 0 && top_end_x == 0 && top != 0)'. // Thus, we would end up changing every rect, which is what old school // struts should do. We may also make a conscious choice to ignore them // when 'rects' has more than one rect, since the old school struts will // typically result in undesirable behavior. for _, rect := range rects { x_, y_, w_, h_ = RectPieces(rect) x, y, w, h = uint(x_), uint(y_), uint(w_), uint(h_) bt = bottom_start_x != bottom_end_x && (xInRect(bottom_start_x, rect) || xInRect(bottom_end_x, rect)) tp = top_start_x != top_end_x && (xInRect(top_start_x, rect) || xInRect(top_end_x, rect)) lt = left_start_y != left_end_y && (yInRect(left_start_y, rect) || yInRect(left_end_y, rect)) rt = right_start_y != right_end_y && (yInRect(right_start_y, rect) || yInRect(right_end_y, rect)) if bt { nh = h - (bottom - ((rHeight - h) - y)) if nh < uint(rect.Height()) { rect.HeightSet(int(nh)) } } else if tp { nh = h - (top - y) if nh < uint(rect.Height()) { rect.HeightSet(int(nh)) } ny = top if ny > uint(rect.Y()) { rect.YSet(int(ny)) } } else if rt { nw = w - (right - ((rWidth - w) - x)) if nw < uint(rect.Width()) { rect.WidthSet(int(nw)) } } else if lt { nw = w - (left - x) if nw < uint(rect.Width()) { rect.WidthSet(int(nw)) } nx = left if nx > uint(rect.X()) { rect.XSet(int(nx)) } } } } // xInRect is whether a particular x-coordinate is vertically constrained by // a rectangle. func xInRect(xtest uint, rect Rect) bool { x, _, w, _ := RectPieces(rect) return int(xtest) >= x && int(xtest) < (x+w) } // yInRect is whether a particular y-coordinate is horizontally constrained by // a rectangle. func yInRect(ytest uint, rect Rect) bool { _, y, _, h := RectPieces(rect) return int(ytest) >= y && int(ytest) < (y+h) } func min(a, b int) int { if a < b { return a } return b } func max(a, b int) int { if a > b { return a } return b } ================================================ FILE: xwindow/doc.go ================================================ /* Package xwindow defines a window type that provides easy access to common window operations while hiding many of the more obscure X parameters. Examples of such window operations include, but are not limited to, creating a window, mapping a window, moving/resizing a window and getting the geometry of a top-level client window including the window manager's decorations. New and Generate functions are provided as constructors. New should be used when you already have a window id, and it cannot fail. Generate should be used when you need to allocate a new window identifier. Since allocating a new window identifier can fail, an error could be returned. Note that methods starting with 'WM' should only be used with a window manager running that supports the EWMH specification. You should otherwise try to use the corresponding methods without the 'WM' prefix. A quick example To create a window with a blue background that is 500 pixels wide and 200 pixels tall and map the window, use something like: win, err := xwindow.Generate(X) if err != nil { log.Fatal(err) } win.Create(X.RootWin(), 0, 0, 500, 200, xproto.CwBackPixel, 0x0000ff) win.Map() You may also want to use CreateChecked instead of Create if you want to see if there was an error when creating a window. More examples The xwindow package is used in many of the examples in the examples directory of the xgbutil package. Of particular interest is window-name-sizes, which prints the name and size of each top-level client window. (The geometry of the window is found using DecorGeometry.) */ package xwindow ================================================ FILE: xwindow/ewmh.go ================================================ package xwindow /* xwindow/ewmh.go contains several methods that rely on EWMH support in the currently running window manager. */ import ( "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/ewmh" "github.com/BurntSushi/xgbutil/xrect" ) // DecorGeometry retrieves the client's width and height including decorations. // This can be tricky. In a non-parenting window manager, the width/height of // a client can be found by inspecting the client directly. In a reparenting // window manager like Openbox, the parent of the client reflects the true // width/height. Still yet, in KWin, it's the parent of the parent of the // client that reflects the true width/height. // The idea then is to traverse up the tree until we hit the root window. // Therefore, we're at a top-level window which should accurately reflect // the width/height. func (w *Window) DecorGeometry() (xrect.Rect, error) { parent := w for { tempParent, err := parent.Parent() if err != nil || tempParent.Id == w.X.RootWin() { break } parent = tempParent } return RawGeometry(w.X, xproto.Drawable(parent.Id)) } // WMMoveResize is an accurate means of resizing a window, accounting for // decorations. Usually, the x,y coordinates are fine---we just need to // adjust the width and height. // This should be used when moving/resizing top-level client windows with // reparenting window managers that support EWMH. func (w *Window) WMMoveResize(x, y, width, height int) error { neww, newh, err := adjustSize(w.X, w.Id, width, height) if err != nil { return err } return ewmh.MoveresizeWindowExtra(w.X, w.Id, x, y, neww, newh, xproto.GravityBitForget, 2, true, true) } // WMMove changes the position of a window without touching the size. // This should be used when moving a top-level client window with // reparenting winow managers that support EWMH. func (w *Window) WMMove(x, y int) error { return ewmh.MoveWindow(w.X, w.Id, x, y) } // WMResize changes the size of a window without touching the position. // This should be used when resizing a top-level client window with // reparenting window managers that support EWMH. func (w *Window) WMResize(width, height int) error { neww, newh, err := adjustSize(w.X, w.Id, width, height) if err != nil { return err } return ewmh.ResizeWindow(w.X, w.Id, neww, newh) } // adjustSize takes a client and dimensions, and adjust them so that they'll // account for window decorations. For example, if you want a window to be // 200 pixels wide, a window manager will typically determine that as // you wanting the *client* to be 200 pixels wide. The end result is that // the client plus decorations ends up being // (200 + left decor width + right decor width) pixels wide. Which is probably // not what you want. Therefore, transform 200 into // 200 - decoration window width - client window width. // Similarly for height. func adjustSize(xu *xgbutil.XUtil, win xproto.Window, w, h int) (int, int, error) { // raw client geometry cGeom, err := RawGeometry(xu, xproto.Drawable(win)) if err != nil { return 0, 0, err } // geometry with decorations pGeom, err := RawGeometry(xu, xproto.Drawable(win)) if err != nil { return 0, 0, err } neww := w - (pGeom.Width() - cGeom.Width()) newh := h - (pGeom.Height() - cGeom.Height()) if neww < 1 { neww = 1 } if newh < 1 { newh = 1 } return neww, newh, nil } ================================================ FILE: xwindow/icccm.go ================================================ package xwindow import ( "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/icccm" "github.com/BurntSushi/xgbutil/xevent" ) // WMGracefulClose will do all the necessary setup to implement the // WM_DELETE_WINDOW protocol. This will prevent well-behaving window managers // from killing your client whenever one of your windows is closed. (Killing // a client is bad because it will destroy your X connection and any other // clients you have open.) // You must provide a callback function that is called when the window manager // asks you to close your window. (You may provide some means of confirmation // to the user, i.e., "Do you really want to quit?", but you should probably // just wrap things up and call DestroyWindow.) func (w *Window) WMGracefulClose(cb func(w *Window)) { // Get the current protocols so we don't overwrite anything. prots, _ := icccm.WmProtocolsGet(w.X, w.Id) // If WM_DELETE_WINDOW isn't here, add it. Otherwise, move on. wmdelete := false for _, prot := range prots { if prot == "WM_DELETE_WINDOW" { wmdelete = true break } } if !wmdelete { icccm.WmProtocolsSet(w.X, w.Id, append(prots, "WM_DELETE_WINDOW")) } // Attach a ClientMessage event handler. It will determine whether the // ClientMessage is a 'close' request, and if so, run the callback 'cb' // provided. xevent.ClientMessageFun( func(X *xgbutil.XUtil, ev xevent.ClientMessageEvent) { if icccm.IsDeleteProtocol(X, ev) { cb(w) } }).Connect(w.X, w.Id) } // WMTakeFocus will do all the necessary setup to support the WM_TAKE_FOCUS // protocol using the "LocallyActive" input model described in Section 4.1.7 // of the ICCCM. Namely, listening to ClientMessage events and running the // callback function provided when a WM_TAKE_FOCUS ClientMessage has been // received. // // Typically, the callback function should include a call to SetInputFocus // with the "Parent" InputFocus type, the sub-window id of the window that // should have focus, and the 'tstamp' timestamp. func (w *Window) WMTakeFocus(cb func(w *Window, tstamp xproto.Timestamp)) { // Make sure the Input flag is set to true in WM_HINTS. We first // must retrieve the current WM_HINTS, so we don't overwrite the flags. curFlags := uint(0) if hints, err := icccm.WmHintsGet(w.X, w.Id); err == nil { curFlags = hints.Flags } icccm.WmHintsSet(w.X, w.Id, &icccm.Hints{ Flags: curFlags | icccm.HintInput, Input: 1, }) // Get the current protocols so we don't overwrite anything. prots, _ := icccm.WmProtocolsGet(w.X, w.Id) // If WM_TAKE_FOCUS isn't here, add it. Otherwise, move on. wmfocus := false for _, prot := range prots { if prot == "WM_TAKE_FOCUS" { wmfocus = true break } } if !wmfocus { icccm.WmProtocolsSet(w.X, w.Id, append(prots, "WM_TAKE_FOCUS")) } // Attach a ClientMessage event handler. It will determine whether the // ClientMessage is a 'focus' request, and if so, run the callback 'cb' // provided. xevent.ClientMessageFun( func(X *xgbutil.XUtil, ev xevent.ClientMessageEvent) { if icccm.IsFocusProtocol(X, ev) { cb(w, xproto.Timestamp(ev.Data.Data32[1])) } }).Connect(w.X, w.Id) } ================================================ FILE: xwindow/xwindow.go ================================================ package xwindow import ( "fmt" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/keybind" "github.com/BurntSushi/xgbutil/mousebind" "github.com/BurntSushi/xgbutil/xevent" "github.com/BurntSushi/xgbutil/xrect" ) // Window represents an X window. It contains an XUtilValue to simplfy the // parameter lists for methods declared on the Window type. // Geom is updated whenever Geometry is called, or when Move, Resize or // MoveResize are called. type Window struct { X *xgbutil.XUtil Id xproto.Window Geom xrect.Rect Destroyed bool } // New creates a new window value from a window id and an XUtil type. // Geom is initialized to zero values. Use Window.Geometry to load it. // Note that the geometry is the size of this particular window and nothing // else. If you want the geometry of a client window including decorations, // please use Window.DecorGeometry. func New(xu *xgbutil.XUtil, win xproto.Window) *Window { return &Window{ X: xu, Id: win, Geom: xrect.New(0, 0, 1, 1), Destroyed: false, } } // Generate is just like New, but generates a new X resource id for you. // Geom is initialized to (0, 0) 1x1. // It is possible for id generation to return an error, in which case, an // error is returned here. func Generate(xu *xgbutil.XUtil) (*Window, error) { wid, err := xproto.NewWindowId(xu.Conn()) if err != nil { return nil, err } return New(xu, wid), nil } // Create is a convenience constructor that will generate a new window id (with // the Generate constructor) and make a bare-bones call to CreateChecked (with // geometry (0, 0) 1x1). An error can be generated from Generate or // CreateChecked. func Create(xu *xgbutil.XUtil, parent xproto.Window) (*Window, error) { win, err := Generate(xu) if err != nil { return nil, err } err = win.CreateChecked(parent, 0, 0, 1, 1, 0) if err != nil { return nil, err } return win, nil } // Must panics if err is non-nil or if win is nil. Otherwise, win is returned. func Must(win *Window, err error) *Window { if err != nil { panic(err) } if win == nil { panic("win and err are nil") } return win } // Create issues a CreateWindow request for Window. // Its purpose is to omit several boiler-plate parameters to CreateWindow // and expose the commonly useful ones. // The value mask describes which values are present in valueList. // Value masks can be found in xgb/xproto with the prefix 'Cw'. // The value list must contain values in the same order as the constants // are defined in xgb/xproto. // // For example, the following creates a window positioned at (20, 50) with // width 500 and height 700 with a background color of white. // // w, err := xwindow.Generate(X) // if err != nil { // log.Fatalf("Could not generate a new resource identifier: %s", err) // } // w.Create(X.RootWin(), 20, 50, 500, 700, // xproto.CwBackPixel, 0xffffff) func (w *Window) Create(parent xproto.Window, x, y, width, height, valueMask int, valueList ...uint32) { s := w.X.Screen() xproto.CreateWindow(w.X.Conn(), xproto.WindowClassCopyFromParent, w.Id, parent, int16(x), int16(y), uint16(width), uint16(height), 0, xproto.WindowClassInputOutput, s.RootVisual, uint32(valueMask), valueList) } // CreateChecked issues a CreateWindow checked request for Window. // A checked request is a synchronous request. Meaning that if the request // fails, you can get the error returned to you. However, it also forced your // program to block for a round trip to the X server, so it is slower. // See the docs for Create for more info. func (w *Window) CreateChecked(parent xproto.Window, x, y, width, height, valueMask int, valueList ...uint32) error { s := w.X.Screen() return xproto.CreateWindowChecked(w.X.Conn(), s.RootDepth, w.Id, parent, int16(x), int16(y), uint16(width), uint16(height), 0, xproto.WindowClassInputOutput, s.RootVisual, uint32(valueMask), valueList).Check() } // Change issues a ChangeWindowAttributes request with the provided mask // and value list. Please see Window.Create for an example on how to use // the mask and value list. func (w *Window) Change(valueMask int, valueList ...uint32) { xproto.ChangeWindowAttributes(w.X.Conn(), w.Id, uint32(valueMask), valueList) } // Listen will tell X to report events corresponding to the event masks // provided for the given window. If a call to Listen is omitted, you will // not receive the events you desire. // Event masks are constants declare in the xgb/xproto package starting with the // EventMask prefix. func (w *Window) Listen(evMasks ...int) error { evMask := 0 for _, mask := range evMasks { evMask |= mask } return xproto.ChangeWindowAttributesChecked(w.X.Conn(), w.Id, xproto.CwEventMask, []uint32{uint32(evMask)}).Check() } // Geometry retrieves an up-to-date version of the this window's geometry. // It also loads the geometry into the Geom member of Window. func (w *Window) Geometry() (xrect.Rect, error) { geom, err := RawGeometry(w.X, xproto.Drawable(w.Id)) if err != nil { return nil, err } w.Geom = geom return geom, err } // RawGeometry isn't smart. It just queries the window given for geometry. func RawGeometry(xu *xgbutil.XUtil, win xproto.Drawable) (xrect.Rect, error) { xgeom, err := xproto.GetGeometry(xu.Conn(), win).Reply() if err != nil { return nil, err } return xrect.New(int(xgeom.X), int(xgeom.Y), int(xgeom.Width), int(xgeom.Height)), nil } // RootGeometry gets the geometry of the root window. It will panic on failure. func RootGeometry(xu *xgbutil.XUtil) xrect.Rect { geom, err := RawGeometry(xu, xproto.Drawable(xu.RootWin())) if err != nil { panic(err) } return geom } // Configure issues a raw Configure request with the parameters given and // updates the geometry of the window. // This should probably only be used when passing along ConfigureNotify events // (from the perspective of the window manager). In other cases, one should // opt for [WM][Move][Resize] or Stack[Sibling]. func (win *Window) Configure(flags, x, y, w, h int, sibling xproto.Window, stackMode byte) { if win == nil { return } vals := []uint32{} if xproto.ConfigWindowX&flags > 0 { vals = append(vals, uint32(x)) win.Geom.XSet(x) } if xproto.ConfigWindowY&flags > 0 { vals = append(vals, uint32(y)) win.Geom.YSet(y) } if xproto.ConfigWindowWidth&flags > 0 { if int16(w) <= 0 { w = 1 } vals = append(vals, uint32(w)) win.Geom.WidthSet(w) } if xproto.ConfigWindowHeight&flags > 0 { if int16(h) <= 0 { h = 1 } vals = append(vals, uint32(h)) win.Geom.HeightSet(h) } if xproto.ConfigWindowSibling&flags > 0 { vals = append(vals, uint32(sibling)) } if xproto.ConfigWindowStackMode&flags > 0 { vals = append(vals, uint32(stackMode)) } // Nobody should be setting border widths any more. // We toss it out since `vals` must have length equal to the number // of bits set in `flags`. flags &= ^xproto.ConfigWindowBorderWidth xproto.ConfigureWindow(win.X.Conn(), win.Id, uint16(flags), vals) } // MROpt is like MoveResize, but exposes the X value mask so that any // combination of x/y/width/height can be set. It's a strictly convenience // function. (i.e., when you need to set 'y' and 'height' but not 'x' or // 'width'.) func (w *Window) MROpt(flags, x, y, width, height int) { // Make sure only x/y/width/height are used. flags &= xproto.ConfigWindowX | xproto.ConfigWindowY | xproto.ConfigWindowWidth | xproto.ConfigWindowHeight w.Configure(flags, x, y, width, height, 0, 0) } // MoveResize issues a ConfigureRequest for this window with the provided // x, y, width and height. Note that if width or height is 0, X will stomp // all over you. Really hard. Don't do it. // If you're trying to move/resize a top-level window in a window manager that // supports EWMH, please use WMMoveResize instead. func (w *Window) MoveResize(x, y, width, height int) { w.Configure(xproto.ConfigWindowX|xproto.ConfigWindowY| xproto.ConfigWindowWidth|xproto.ConfigWindowHeight, x, y, width, height, 0, 0) } // Move issues a ConfigureRequest for this window with the provided // x and y positions. // If you're trying to move a top-level window in a window manager that // supports EWMH, please use WMMove instead. func (w *Window) Move(x, y int) { w.Configure(xproto.ConfigWindowX|xproto.ConfigWindowY, x, y, 0, 0, 0, 0) } // Resize issues a ConfigureRequest for this window with the provided // width and height. Note that if width or height is 0, X will stomp // all over you. Really hard. Don't do it. // If you're trying to resize a top-level window in a window manager that // supports EWMH, please use WMResize instead. func (w *Window) Resize(width, height int) { w.Configure(xproto.ConfigWindowWidth|xproto.ConfigWindowHeight, 0, 0, width, height, 0, 0) } // Stack issues a configure request to change the stack mode of Window. // If you're using a window manager that supports EWMH, you may want to try // and use ewmh.RestackWindow instead. Although this should still work. // 'mode' values can be found as constants in xgb/xproto with the prefix // StackMode. // A value of xproto.StackModeAbove will put the window to the top of the stack, // while a value of xproto.StackMoveBelow will put the window to the // bottom of the stack. // Remember that stacking is at the discretion of the window manager, and // therefore may not always work as one would expect. func (w *Window) Stack(mode byte) { xproto.ConfigureWindow(w.X.Conn(), w.Id, xproto.ConfigWindowStackMode, []uint32{uint32(mode)}) } // StackSibling issues a configure request to change the sibling and stack mode // of Window. // If you're using a window manager that supports EWMH, you may want to try // and use ewmh.RestackWindowExtra instead. Although this should still work. // 'mode' values can be found as constants in xgb/xproto with the prefix // StackMode. // 'sibling' refers to the sibling window in the stacking order through which // 'mode' is interpreted. Note that 'sibling' should be taken literally. A // window can only be stacked with respect to a *sibling* in the window tree. // This means that a client window that has been wrapped in decorations cannot // be stacked with respect to another client window. (This is why you should // use ewmh.RestackWindowExtra instead.) func (w *Window) StackSibling(sibling xproto.Window, mode byte) { xproto.ConfigureWindow(w.X.Conn(), w.Id, xproto.ConfigWindowSibling|xproto.ConfigWindowStackMode, []uint32{uint32(sibling), uint32(mode)}) } // Map is a simple alias to map the window. func (w *Window) Map() { if w == nil { return } xproto.MapWindow(w.X.Conn(), w.Id) } // Unmap is a simple alias to unmap the window. func (w *Window) Unmap() { if w == nil { return } xproto.UnmapWindow(w.X.Conn(), w.Id) } // Destroy is a simple alias to destroy a window. You should use this when // you no longer intend to use this window. (It will free the X resource // identifier for use in other places.) func (w *Window) Destroy() { if !w.Destroyed { w.Detach() err := xproto.DestroyWindowChecked(w.X.Conn(), w.Id).Check() if err != nil { xgbutil.Logger.Println(err) } w.Destroyed = true } } // Detach will detach this window's event handlers from all xevent, keybind // and mousebind callbacks. func (w *Window) Detach() { keybind.Detach(w.X, w.Id) mousebind.Detach(w.X, w.Id) xevent.Detach(w.X, w.Id) } // Focus tries to issue a SetInputFocus to get the focus. // If you're trying to change the top-level active window, please use // ewmh.ActiveWindowReq instead. func (w *Window) Focus() { mode := byte(xproto.InputFocusPointerRoot) err := xproto.SetInputFocusChecked(w.X.Conn(), mode, w.Id, 0).Check() if err != nil { xgbutil.Logger.Println(err) } } // FocusParent is just like Focus, except it sets the "revert-to" mode to // Parent. This should be used when setting focus to a sub-window. func (w *Window) FocusParent(tstamp xproto.Timestamp) { mode := byte(xproto.InputFocusParent) err := xproto.SetInputFocusChecked(w.X.Conn(), mode, w.Id, tstamp).Check() if err != nil { xgbutil.Logger.Println(err) } } // Kill forcefully destroys a client. It is almost never what you want, and if // you do it to one your clients, you'll lose your connection. // (This is typically used in a special client like `xkill` or in a window // manager.) func (w *Window) Kill() { xproto.KillClient(w.X.Conn(), uint32(w.Id)) } // Clear paints the region of the window specified with the corresponding // background pixmap. If the window doesn't have a background pixmap, // this has no effect. // If width/height is 0, then it is set to the width/height of the background // pixmap minus x/y. func (w *Window) Clear(x, y, width, height int) { xproto.ClearArea(w.X.Conn(), false, w.Id, int16(x), int16(y), uint16(width), uint16(height)) } // ClearAll is the same as Clear, but does it for the entire background pixmap. func (w *Window) ClearAll() { xproto.ClearArea(w.X.Conn(), false, w.Id, 0, 0, 0, 0) } // Parent queries the QueryTree and finds the parent window. func (w *Window) Parent() (*Window, error) { tree, err := xproto.QueryTree(w.X.Conn(), w.Id).Reply() if err != nil { return nil, fmt.Errorf("ParentWindow: Error retrieving parent window "+ "for %x: %s", w.Id, err) } return New(w.X, tree.Parent), nil }